## About The Pull Request
So crew records weren't actually showing the right quirks for
latejoiners, and in at least one instance (heterochromatic eyes) even
the fingerprint was wrong. The latter seemed to be caused by a recent
fix pr making the quirk actually update your dna, for the sake of
paradox clones/changelings.
Looking into it, this seemed to be because we assign quirks to
latejoiners _after_ injecting them into the manifest:
b7225d8486/code/modules/mob/dead/new_player/new_player.dm (L218-L244)
See line 219 and 244.
So we move manifest injection to be _after_ quirk assignment:
```dm
(line 242-246)
if((job.job_flags & JOB_ASSIGN_QUIRKS) && humanc && CONFIG_GET(flag/roundstart_traits))
SSquirks.AssignQuirks(humanc, humanc.client)
if(humanc) // Quirks may change manifest datapoints, so inject only after assigning quirks
GLOB.manifest.inject(humanc)
```
This fixes it.
## Why It's Good For The Game
Makes quirks actually show in the medical records for latejoiners.
Makes latejoiners with heterochromatic eyes not have the wrong
fingerprint in the security records.
_Probably_ fixes#83681.
Fixes#56469.
## Changelog
🆑
fix: Latejoiners with heterochromatic eyes no longer have the wrong
fingerprint in the security records.
fix: Latejoiners actually have their quirks visible in the medical
records.
/🆑
## About The Pull Request
This PR moves random name generation for species onto their languages.
What does this mean?
- For species with a predefined name list, such as Lizards and Moths,
nothing.
- For species without predefined name lists, such as Felinids, their
names will now be randomly generated from their language's syllables.


(In the prefs menu:)

Why?
- Well, we actually had some dead code that did this. All I did was fix
it up and re-enable it.
- Generates some pretty believable in-universe names for various
languages that are lacking name lists. Obviously defined lists would be
preferred, but until they are added, at least.
- Moves some stuff off of species, which is always nice.
- Also hopefully makes it a tad easier to work with name generation.
There's now a standard framework for getting a random name for a mob,
and for getting a random name based on a species.
Misc:
- Adds a generic `species_prototype` global, uses it in a lot of places
in prefs code.
- Makes `GLOB.species_list` init via the global defines
- Deletes Language SS
- Alphabetizes some instances of admin tooling using the list of all
species IDs
- Docs language stuff
- Deletes random_skin_tone, it does pretty much nothin
## Changelog
🆑 Melbert
refactor: Random Name Generation has been refactored. Report any
instances of people having weird (or "Unknown") names.
qol: Felinids, Slimepeople, Podpeople, and some other species without
defined namelists now automatically generate names based on their
primary language(s).
qol: More non-human names can be generated in codewords (and other misc.
areas) than just lizard names.
/🆑
This is just a revitalization of #80275.
## About The Pull Request
On the tin, basically demotes everything related to setting up and
storing these bulky lists generated from reading
`/datum/sprite_accessory` subtypes from living in a global space that
will instead be in a compartmentalized subsystem for accesses. Also a
lot of code modernization and micro-improvements (unquantifiable)
## Why It's Good For The Game
Same exact expected results, just accessed in a different way.

There's a few reasons why I want this to happen.
* The `GLOB` space is too clogged. There are at least a thousand
variables on `GLOB`, and it's extremely painful to access stuff on
production/local through view variables when you're debugging stuff like
this. It's also painful when there is stuff that _should_ live on `GLOB`
that you might want to see in VV/Debugger but are forced to either have
to scroll a mile to find what you want or wait a long while for it to
load. The less bulky lists we have of stored initialized datums, the
better.
* `make_datum_reference_lists()` is a consequence of wack stuff like
this where we're reliant on certain things being initialized in the
`GLOB` portion of world initialization _before_ subsystems/static
variables load - most of these datum lists in the aforementioned proc
doesn't _really_ need to be ready to go before `world.New()` for
example. We'll sadly have to abuse `PreInit()` for now, but it really is
something that has to be ready to go due the critical dependence that
stuff like Preferences has on it.
* We don't have to have the procs live in a global namespace either.
Instead of passing in `GLOB.XList` or `DSstorage.XList` every single
time, we can instead just move the proc setup on the subsystem and use
`XList` in a more native fashion.
* It's easier to find what you need. To me, it's a lot nicer to
ctrl+click the DS and go to the variables to find something I'm looking
for instead of having to scavenge around for any footprint/trace of the
global I want to look for. This is more trivial than the other two, but
that's something I like to think about when I go to bed.
I also had to refactor a bit of the code to accommodate the limitations
of the new DS system, but it should be a lot cleaner anyways.
## Changelog
Not relevant
---
Also nothing should have broken but it's a good thing we have screenshot
unit tests to prove me wrong.
## About The Pull Request
Off shuttle move doesn't need to happen because shuttles use abstract
move which calls it anyway
Similar story for the ghost stuff, this was actually causing pretty
common double calls so we may actually get somethin out of this Oh and
something in air which is past me knifing me in the back
## About The Pull Request
Fixes#82440
This PR just creates a new macro, `LOWER_TEXT()` (yes the irony is not
lost on me) to wrap around all calls of `lowertext()` and ensure that
whatever we input into that proc will be stringified using the `"[]"`
(or `tostring()` for the nerds) operator. very simple.
I also added a linter to enforce this (and prevent all forms of
regression) because I think that machines should do the menial work and
we shouldn't expect maintainers to remember this, let me know if you
disagree. if there is a time when it should be opted out for some
reason, the linter does respect it if you wrap your input with the
`UNLINT()` function.
## About The Pull Request
Using these search regexes:
Ending in 0:
`addtimer\((.*),\s?(\d{1,3})0\b\)`
replacement:
`addtimer($1, $2 SECONDS)`
Two digit ending in odd:
`addtimer\((.*), (\d)([1-9])\)$`
replacement:
`addtimer($1, $2.$3 SECONDS)`
Single digit ending odd:
`addtimer\((.*), ([1-9])\)$`
replacement:
`addtimer($1, 0.$2 SECONDS)`
## Why It's Good For The Game
Code readability
---------
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
## About The Pull Request
On one compile of MetaStation, I saw that there's 45 basic mobs on the
station, 256 on lavaland (the number growing from tendrils), and 59 in
all other z levels combined.
While we do expect Lavaland to be visited every round, at least it won't
be running during the times when no one is there, but even more
importantly, space exploration is something not done every round, so we
don't have any reason to waste our resources on AIs that will never be
interacted with.
Simple animals had an easy solution to this:
If no one is on the Z level, their AI turns off
If someone is on the Z level, they are idle unless needed.
The last simple animals that exists right now are bots, megafauna,
geese, gondolas, and some minor ones like mimic, zombie, dark wizard,
soulscythe, etc.
Point is, we're very much nearly done going through all simple animals,
so this code is being wasted just to ensure things like cleanbots won't
work if no one is on the z level, something I doubt happens often, so I
took their code and made it work for basic mobs instead. I could've done
both but I thought it would look very bad, and maybe this is a good
incentivize to get more basic mob conversions.
There's one major change here and it's that we're missing the "Idle"
mode, some basic mobs like the Lavaland village seems to be made with
intent that they'll be running even if players aren't around, so this
sets up a future PR that makes idle AI easier to add, and I want to make
sure those cases are taken into account.
## Why It's Good For The Game
We don't need to always be processing these basic mobs, and sets us in
the future to hopefully also implement idle AIs.
## Changelog
🆑
balance: Basic mob AIs with no mobs on the Z level now stop.
/🆑
---------
Co-authored-by: san7890 <the@san7890.com>
## About The Pull Request
Refactors a lot of the unused defines.
## Why It's Good For The Game
Refactors a lot of the unused defines.
## Changelog
Nothing player facing
---------
Co-authored-by: san7890 <the@san7890.com>
## About The Pull Request
This PR does many things, I'll try to explain the basic/background stuff
to the main thing first:
1. Adds a new remote that allows a human to function like an AI. It
controls a fly that will fly around the station slowly, and when it
reaches a machine then the person can interact with it as if they were
an AI. This required changing a lot of silicon/AI checks with one that
also checks for this remote, and some messing with shared ui state.
2. Moves req_access from the obj and bot to ``/atom/movable`` which lets
it be shared between the two, no more copy-paste and one side lacking
features/checks/signals the other has.
3. Adds a check for AI config for AI-related station traits, which was
lacking prior
Now for the good part...
Adds a new station trait that replaces the AI with a Human.
This person is equipped with an AI headset (including Binary), an
advanced camera console, an omni door wand, the machine controller, and
their laws.
They are immune to the SAT's turrets (even if set to target borgs) and
are slow outside of the SAT, mimicing the actions of the AI.
They interact with the world through their advanced camera console,
which allows them to do most AI stuff needed, and the holopad they can
connect to without having to ring first (like Command can).
They are given a paper with the laws they must follow, but since they
are human they are able to bend it. Cyborgs that run the default lawset
are "slaved" to them via an unremovable law 0, so the Human AI can bend
the laws if they really need to (for their own survival n such), and
make the cyborgs obey their commands above laws, but in general this
shouldn't be a frequent occurrence. This does take into account the
unique AI trait, so it's not guaranteed Asimov.
When this station trait rolls, all Intellicards, AI uploads, and AI core
boards are destroyed and are unresearchable. They can be spawned by
admins in-game if necessary. Maybe in the future we can also exclude
Oldstation from this but I haven't really decided.
Extra perks:
Human AI spawns with a Robotic voicebox (unless they are a body purist)
and teleport blocking implant, so they can't use teleporters to bypass
their on-station slowdown.
They also have an infinite laser pointer that can be used to blind
through their camera console. This is unfortunately nerfed from the
recent borg balance PR that removed its stun. This was meant to be the
alternative to no longer being able to permanently lock borgs down like
AIs can (or more than one, for that matter).
They aren't affected by Roburgers, Acid, and Fuel's toxicity.
Bots salute them like they do Beepsky (which is now a trait)
They spawn with SyndEye to replace the AI's tracking ability
They do not have a bank account
### The machine remote
The machine remote has a little fly in it that flies to the machines it
is pointed to, working as the arms and legs of the Human AI. It scans
the machine and punches in the action the AI does, and is how the AI
accesses basically anything. This fly slowly moves from one machine to
the next, and can be recalled with Alt Click.
It works on machines and bots.
### Video (Low quality to fit Github)
https://github.com/tgstation/tgstation/assets/53777086/e16509f8-8bed-42b5-9fbf-7e37165a11e8
## Why It's Good For The Game
I've seen a funny screenshot one day of a person replacing the AI by
using a bunch of door remotes, camera console, crew monitoring console,
and a few other things. I've been thinking about that for a few years
and really wanted to make it official if not easier to make possible,
because it is an incredibly funny interaction.
This makes it a reality, and while they aren't as powerful as regular
AIs, I think it makes for better and funnier in-game moments. With the
same weight as Cargorilla (1), I hope this wouldn't be rolling too often
and ruin rounds, but instead show off the different capabilities that
Humans and AIs can do, to do the job of an AI. You win some you lose
some.
## Changelog
🆑 JohnFulpWillard, Tattax
add: Adds a new station trait job: The Human AI.
/🆑
---------
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
## About The Pull Request
Caused by goof's PR. Because for some reason observers overridde `up` to
skip checks but not `down`.
## Changelog
🆑 Melbert
fix: Moving "down" as an observer is no longer janky.
/🆑
## About The Pull Request
Fixes#81578Fixes#81559Fixes#81308
In #69634 mob tag generation was moved to `/mob/New`
But dead mobs also do this in initialize

So dead mobs skipped over a tag
This is whatever, until it's not:
If something makes a weakref of an observer in `/observer/Initialize`
before its parent call, which shuffles the mob tag around, uh oh now our
weakref points to a non-existent ref!
So what's making the weakref? No clue but apparently chasms
## Changelog
🆑 Melbert
fix: Chasms no longer break your verbs
/🆑
## About The Pull Request
[Fixes static lights not
moving](ffef43c05a)
Worked fine when the owner moved, but if the owner was inside something
else, it would try and trigger an update on the PARENT's lights, which
are obviously not us.
[Renames MOVABLE_LIGHT and STATIC_LIGHT to better describe what they
do](de73a63bd4)
People keep trying to change the lighting system of lamps and it makes
me mad.
I choose OVERLAY_LIGHT and COMPLEX_LIGHT here, I couldn't figure out a
better name for turf matrix lighting. Suggestions welcome
## Why It's Good For The Game
Closes#80005
Hopefully improves understanding of lighting at a glance
## Changelog
🆑
fix: Fixes fancy lights not updating their source location when picked
up and moved
/🆑
## About The Pull Request
[Converts all manual extraction of rbg with rgb2num. It's just
better](ae798eabd5)
[Yanks out old HSV management, replaces it with list
stuff](4997e86051)
There's this old lummy era clunky code that passed HSV as text
We can now cleanly replace it with passing hsv as lists from a rgb2hsv
proc
So let's just do that.
Also, cleans up spraytan code (and ethereal lighting)
## Why It's Good For The Game
Code better
<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may
not be viewable. -->
<!-- You can view Contributing.MD for a detailed description of the pull
request process. -->
## About The Pull Request
I moved the bit that says:
ADMIN: guy started hardcore random with cancer, for a score of 2
into game.log
<!-- Describe The Pull Request. Please be sure every change is
documented or this can delay review and even discourage maintainers from
merging your PR! -->
## Why It's Good For The Game
I don't see why this wound up in Admin.log. Doesn't contain any admin
info, relate to actions done by admins, etc.
<!-- Argue for the merits of your changes and how they benefit the game,
especially if they are controversial and/or far reaching. If you can't
actually explain WHY what you are doing will improve the game, then it
probably isn't good for the game in the first place. -->
## Changelog
<!-- If your PR modifies aspects of the game that can be concretely
observed by players or admins you should add a changelog. If your change
does NOT meet this description, remove this section. Be sure to properly
mark your PRs to prevent unnecessary GBP loss. You can read up on GBP
and it's effects on PRs in the tgstation guides for contributors. Please
note that maintainers freely reserve the right to remove and add tags
should they deem it appropriate. You can attempt to finagle the system
all you want, but it's best to shoot for clear communication right off
the bat. -->
<!-- Both 🆑's are required for the changelog to work! You can put
your name to the right of the first 🆑 if you want to overwrite your
GitHub username as author ingame. -->
<!-- You can use multiple of the same prefix (they're only used for the
icon ingame) and delete the unneeded ones. Despite some of the tags,
changelogs should generally represent how a player might be affected by
the changes rather than a summary of the PR's contents. -->
## About The Pull Request
Ghosts can examine people to see Wanted Status and view their Sec
Records which show crimes
## Why It's Good For The Game
More fun observer experience. You can already see the "W" hud, so more
info is nice

## Changelog
🆑
qol: Ghosts can now view Wanted Status and Sec Records by examining
people
/🆑
## About The Pull Request
Tin. This was another /image hard del that I came across within a given
round. AFAIK this was occurring because `updateallghostimages()` removes
refs of these images from GLOB.ghost_images_default and
GLOB.ghost_images_simple, and this proc was being called after
`QDEL_NULL()`. So they were still in the lists at the time of the
qdeletion. We don't need to be qdeleting them at all though so let's
just set them to null.

## Why It's Good For The Game
Reduces the lag.
## Changelog
🆑
fix: fixed an /image hard del in ghost code
/🆑
Reverts tgstation/tgstation#80407
Fixes#80460Fixes#80485
I don't think this was a good fix, we should be preventing people from
observing themselves outright. Not "they can observe themselves but skip
the actual observe-part of observing".
Also it breaks observing.
## About The Pull Request
Fixes#77034 by adding in a check to do_observe to prevent observers
from observing themselves. It does prevent them from observing their own
bodies and seeing their hud and entire inventory as a ghost, but that's
not a major problem because they probably either remember what they had
if it's so important to constantly see what's on their mob or it doesn't
matter. Additionally they can just use re-enter corpse so whatever.
## Why It's Good For The Game
Observers can no longer intentionally or even completely accidentally
flood admin logs from their observetarget not resetting due to them
observing themselves.
## Changelog
🆑
fix: Observers observing themselves no longer floods admins' logs.
/🆑
## About The Pull Request
adds a station trait which adds a new role, the bridge assistant
he is designed to help commandeer the bridge and help out other heads
when needed. he is armed with the mini energy gun (the one heads used to
have on kilostation), a flash, a toolbelt (with an inducer), some cool
shades and a swanky scarf.
as he is a nerd he is weak and unable to twohand weapons, preventing him
from wielding the fire axe.
currently he does not have a mindshield but he cannot roll antag
he currently has access to the bridge, announcement console, eva,
teleporter, gateway, maint, and a weapon permit (somewhat (not really
other than for nerds) interestingly this is the first job that isnt
assistant that doesnt have access to any lathes, so he doesnt have orm
access unlike all the other jobs (except assistant))
the trait also makes a coffee machine spawn on the bridge
here is some useful art of your role

and ingame screenshots



## Why It's Good For The Game
Adds upon the station trait job system with a straight forward role that
IS just a human (unlike the cargorilla), and is pretty basic with no
custom assets or whatever other than hud icons
Having the bridge assistant in some rounds seems like a neat way to
protect it since it gets fucked up in like half the time, while also not
having enough mechanical depth or gameplay as to warrant it as a
permanent role
## Changelog
🆑
add: Bridge Assistant job accessible from a station trait.
/🆑
---------
Co-authored-by: san7890 <the@san7890.com>
## About The Pull Request
If the station rolls the "Cargo Gorilla" trait, a button will now be
visible on the lobby.
Clicking on this button before the round has started will add you to a
list of participants, one of whom will be selected to become a gorilla
when the round begins.
If nobody signs up (because they're really boring I guess) the job will
instead appear on the latejoin menu.
Once someone has become the gorilla the button will disappear.

While implementing this I noticed that an inverted check means we were
never populating the "GLOB.cargo_sloth" field which means the station
trait wasn't even working.
BEHIND THE SCENES
This also adds a generic "job station trait" which can be expanded in
the future.
Future developers can extend this to add other "rare jobs" with relative
ease.
By default I have made it so all subtypes of this trait are mutually
exclusive, only one can roll at a time.
This also means that I have converted "cargo gorilla" into a job, which
applies most of the code previously located in the mob's typepath or in
the station trait.
The fact that it is a job means that **admins** can enable any number of
gorillas to be present on the latejoin menu (but not the roundstart one,
as it is not possible to add Cargo Gorilla to your occupation
preferences) if they so desire.
The random beurocratic station trait, event, and traitor item (and the
job console) are not able to add gorilla slots.
Because I changed "Cargo Gorilla" to a job it now no longer exists on
the map until a player gains the role, and there wasn't a non-hacky way
to copy the name of this round's cargo sloth. Instead I just added a
small cargo gorilla name list.
## Why It's Good For The Game
Makes the presence of a fun trait more visible to players.
Means that people who aren't observing get a chance to be a monkey.
This is a framework several other people have wanted to exist for their
own features.
## Changelog
🆑 Jacquerel and Fikou
qol: If the station rolls the "Cargo Gorilla" station trait. you will be
able to sign up for the role from the game lobby.
qol: If nobody signs up to be the Cargo Gorilla then you can select it
from the Late Join menu and arrive on the arrival shuttle.
fix: The Cargo Gorilla will actually spawn.
/🆑
<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may
not be viewable. -->
<!-- You can view Contributing.MD for a detailed description of the pull
request process. -->
## About The Pull Request
Renames
- `/mob/proc/notify_ghost_cloning` to `/mob/proc/notify_revival`
- `/mob/dead/observer/proc/notify_cloning` to
`/mob/dead/observer/proc/send_revival_notification`
- `/atom/movable/screen/alert/notify_cloning` to
`/atom/movable/screen/alert/revival`.
I could have found a way to merge both procs together but default
parameters keep me up at night.
<!-- Describe The Pull Request. Please be sure every change is
documented or this can delay review and even discourage maintainers from
merging your PR! -->
## Why It's Good For The Game
Conciseness, code that is named after a removed feature is silly.
<!-- Argue for the merits of your changes and how they benefit the game,
especially if they are controversial and/or far reaching. If you can't
actually explain WHY what you are doing will improve the game, then it
probably isn't good for the game in the first place. -->
## Changelog
<!-- If your PR modifies aspects of the game that can be concretely
observed by players or admins you should add a changelog. If your change
does NOT meet this description, remove this section. Be sure to properly
mark your PRs to prevent unnecessary GBP loss. You can read up on GBP
and it's effects on PRs in the tgstation guides for contributors. Please
note that maintainers freely reserve the right to remove and add tags
should they deem it appropriate. You can attempt to finagle the system
all you want, but it's best to shoot for clear communication right off
the bat. -->
nothing playerfacing
<!-- Both 🆑's are required for the changelog to work! You can put
your name to the right of the first 🆑 if you want to overwrite your
GitHub username as author ingame. -->
<!-- You can use multiple of the same prefix (they're only used for the
icon ingame) and delete the unneeded ones. Despite some of the tags,
changelogs should generally represent how a player might be affected by
the changes rather than a summary of the PR's contents. -->
I don't remember what was hard about this last time it took me like 20
minutes this time so I'm scared.
Removes dynamic simulations, only I have used them and it's a lot more
complicated now with this. I plan on making Dynamic simulations a part
of moth.fans anyway
## About The Pull Request

I had this runtime sitting around for who-knows-how-long so I decided I
would just fix it today. `ghostize()` is expected to work on all
subtypes of `/mob` so it's a bad idea to access a variable that only
exists on `/mob/living` (and there is no real point to move
`timeofdeath` up a level imo, we already have too much clutter there and
`/mob/camera/imaginary_friend` would _never_ need it).
## Why It's Good For The Game
We should only access variables like these when when they exist.
## Changelog
No shot a player would ever notice this
## About The Pull Request
Fixes#78114.
Fixes#78505.
Grumble grumble, code rot.
#77727 inadvertently broke hardcore random quirk selection, making it
not actually check the compatibility of quirks before adding them. This
means that quirks that were never meant to go together could be randomly
assigned, which broke all kinds of things. I've simply made it properly
check for the typepath rather than checking typepaths against names,
making it actually function as intended.
## Why It's Good For The Game
Certain quirks are incompatible for a reason. Prevents unintended combos
that break in unexpected ways.
## Changelog
🆑
fix: Hardcore Random will no longer assign incompatible quirks.
/🆑
## About The Pull Request
I'm still not satisfied with how ghost notifications work. This gives
every notification with a source (99% of all notifications, in other
words) a link to jump/orbit. Currently, notifications with "play"
interactions would only get the interact link, so jumping to the source
was pretty annoying.
It removes posting the entire message in the alert tooltip, as some got
pretty lengthy and it didn't seem to fit. To replace this, they will
always use headers
After:



NOTIFY_JUMP and NOTIFY_ORBIT have been merged, since the only difference
seems to be whether it's a turf. The result shaves off some redundant
lines of code, since most-every usage of notify_ghosts uses
NOTIFY_ORBIT.
## Why It's Good For The Game
More standardization for the ghost notification system. Adds a few alert
headers that never had them. All in all, makes it easier for creators to
throw alerts at ghosts
## Changelog
🆑
qol: Nearly every ghost alert should now feature a "VIEW" button, even
those with click interaction.
del: Ghost alerts no longer show the entire message in the tooltip,
instead have been replaced with titles.
/🆑
## About The Pull Request
#79139 turned out to be quite annoying, it wasn't taken into account
that these alerts can stack (ie: spiders).
Of course, I poked around the code and found some inconsistencies in the
process. For instance, there were usages of Topic for custom action
behavior which could've been consolidated. There were other instances
where jump (the default action) doesn't give a link at all, which I
think it should anyway, since the screen toast gives you this.
I've standardized it more, meaning you can use "NOTIFY_PLAY" without
writing a custom link and topic handler (for instance, MMIs)
## Why It's Good For The Game
Fixes#79198Fixes#79195
## Changelog
🆑
fix: Ghost alerts have been tuned down a bit.
/🆑
This adds a tracker for sources of invisibility and a priority system. I
needed this for another thing so I'm doing this first since it touches a
lot of code. As for the bugs fixed in the changelog, it's only what I
noticed while going through everything and there's likely a few more
things fixed with this. This should be testmerged for a while, I'll
bring this out of draft when it feels safe.
🆑
admin: Invisimin can now be used on mobs that are already invisible,
whether through temporary or permanent effects.
fix: Monkeyize/Humanize mob transformations no longer permanently reveal
invisible mobs if they had effects making them invisible otherwise.
fix: Objects with the undertile element that have been made invisible
through other means are no longer revealed by being uncovered.
/🆑
## About The Pull Request
It's exactly 6 months from April 1st, so this is a date for very serious
PRs only.
We've all seen that one tip at the beginning of the round:

So the afro must be really big, right? Having one must be a very large
sacrifice in the realm of pixel-based combat, right?
WRONG.

This is the largest afro currently available. Absolutely pathetic. It's
not even the largest hairstyle in terms of pixel volume.
Here's a bigger one.


The sprite overlaps the tile above by 6 pixels, which is noticeable, but
not enough to interfere significantly with gameplay (apart from having a
sacrificially larger hitbox).

This could already be done by creating a new .dmi file with larger,
non-square pixel bounds, but that's a less than elegant solution.
Instead, added a y offset var to hair sprite accessory datums.
## Why It's Good For The Game
The self-expressive merits of having more hairstyles should be
self-evident, so I will make a mathematical argument here.
Everyone knows that the coolness of an afro is determined by its volume.
As a 2-D sprite, the closet equivalent we have is area. An afro is,
approximately, a circle, so the area can be calculated as πR^2, with R
being the maximum distance from the top of the head to the top of the
sprite bounding box.
The current largest afro has a height of 6 pixels. This new afro has a
height of 12 pixels. As a result, impressiveness increases by a factor
of 4:
```math
coolness_{new\ \ afro} \over coolness_{old\ \ afro}
```
```math
π12^2 \over π6^2
```
```math
12^2 \over 6^2
```
```math
144 \over 36
```
```math
4
```
This means that, for the intrusion of a mere 6 pixels into our northern
neighbor's bounding box, we get **quadruple** the coolness.
## Changelog
🆑
add: Added Afro (Huge) hairstyle
/🆑
---------
Co-authored-by: Cruix <discoveryian2@gmail.com>
## About The Pull Request
Adds an option to the respawn config which forces you to pick another
character (slot) before you respawn.
## Why It's Good For The Game
Just an idea i'm throwing out there, not necessarily pushing for it to
be enabled on any servers.
Respawning as an alternative character can be a good way to make people
less frustrated at dying, particularly if paired with the cooldown
config that already exists:
"Oh shucks, I died and got my head cut off and got absorbed and got
spaced by some changeling. I won't be able to finish my project or
whatever. At least in 15 minutes I may be able to join as my botanist
character to try something else rather than having to wait an hour and a
half for the round to tick over."
Also nice for downstream support.
(Obviously you can just, *ban* people who respawn as the same character,
use an honor system, but codifying it seems better than not.)
## Changelog
🆑 Melbert
config: Adds a config option for player respawning that enables
respawns, but forces you pick a new character.
config: "NORESPAWN" has been replaced with "ALLOW_RESPAWN 0". Unlimited
respawns is "ALLOW_RESPAWN 1" and character limited respawns is
"ALLOW_RESPAWN 2".
/🆑
---------
Co-authored-by: san7890 <the@san7890.com>
There were a few exploits with free antags that would double your score.
This happened to me once by accident, but anyone could essentially
guarantee a point doubling.
I've changed the whole thing to only work for:
- Traitor
- Changeling
- Heretic
- Blood brother
- Headrev
- Wizard (you could get this with die of fate)
- Obsessed
- Magic and gun survivalists
- Holding the greentext book (because a cripple fighting for their life
for the greentext just seems funny and is rare enough)
Notably, revolutionairies, cult converts and brainwashed now no longer
pay out. Cult is pointless since you can't greentext without gibbing
(trust me I tried) and revolutionairy takes no effort other than having
strong teammates and doing nothing. There are a lot of other antags this
excludes, but those are mostly midrounds and non-humans (which are by
default excluded)
🆑
balance: Only traitor, changeling, heretic, blood brother, headrev,
wizard, obsessed, magic/gun survivalists and greentext book holders can
now double their hardcore random score
qol: Redtexting as antag with hardcore random score will pay you default
points, instead of none (normal survival rules)
fix: End report screen will properly report hardcore random survival in
case of station destruction
/🆑
## About The Pull Request
Hey there,
There were more than a few times (like in cinematic code) where we might
need to accurately know the source of what's adding this trait (or have
multiple sources for the whole 'we don't want this mob to do shit while
we transform this mob'), so in order to rectify this potential issue,
let's refactor it into a trait.
## Why It's Good For The Game
Some code already declared that there might be issues with this being a
boolean var (with no way of knowing _why_ we don't want this mob to not
transform (or not do anything idk). Let's remove those comments and any
future doubt in those instances with the trait macros. Also, stuff like
`TRAIT_IMMOBILIZED` which does a similar thing in many contexts was
already a trait that was regularly added in conjunction with flipping
the variable, so we're able to flatten all that stuff into
`add_traits()` and `remove_traits()` now. nice
I also cleaned up quite a bit of code as I saw it, let me know if it
should be split out but I guarantee that if I didn't do it- no one will
for the next two years.
## Changelog
🆑
refactor: If you transform into another mob and notice bugs with
interacting with the game world, please create a bug report as this
framework was recently refactored.
/🆑
Probably fucked up somewhere, lmk
---------
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
## About The Pull Request
**Simplified version of #72179**
### SOUNDS
Changes next sound files:
- airraid.ogg
- bloblarm.ogg
- alert.ogg
Adds next sound files:
- notice3.ogg
- announce_syndi.ogg
Now `announce.ogg` plays when a Captain joins round, and
`announce_dig.ogg` for Requests Console announcements.
The `announce_syndi.ogg` plays when an announcement is made through an
emagged communications console. It also plays when the evacuation
shuttle is fully hijacked or Cultists fully corrupt the evacuation
shuttle.
You can listen to them all here:
https://github.com/tgstation/tgstation/assets/42353186/10c5e597-6db7-464a-b693-f5a2672dc3d0
_All of the sound files are either made by me from existing sounds in
the game or taken from freesound.org and properly credited._
### STATUS DISPLAYS
Status displays are fully replaced with the addition of a few new ones.
<details>
<summary>Status display monitor</summary>


</details>
<details>
<summary>Misc displays</summary>



</details>
<details>
<summary>Alert displays</summary>




</details>
Now the communications console Status Display menu replaced the "Red
Alert" display option with the "Current Alert" which showcases the
current alert display.
Also, the Status Display menu has an additional "Radiation" display
option.
## Why It's Good For The Game
I believe this Pull Request is a good game for a couple of reasons:
1. It better conveys the gravity of emergency situations, such as Code
Red, by utilizing a more intimidating and recognizable sound. This gives
more weight to these situations, making them feel more urgent and
important in the game. Players always tend to not notice that it's in
action.
2. The replacement of the old and outdated Status Display sprites with
newer, more eye-catching ones is a great improvement. This helps to
emphasize the importance of emergency situations even further by making
them more noticeable. Status Displays was one of the last wall-mounts
using ancient sprites.
3. The Captain's arrival using another sound effect from other
announcements gives more status to the Captain as the ultimate head of
the station.
4. Heads announcement using `announce_dig.ogg` makes the sound itself
more used outside of SM cascade, and also makes Head announcements more
noticeable.
5. Emagged console using `announce_syndi.ogg` making Traitor
announcements more noticeable. Also, it is played after evac shuttle is
fully hijacked or corrupted by Cultists giving a more ominous effect
## Changelog
🆑
sound: Adds/modifies next sound files: airraid.ogg, bloblarm.ogg,
alert.ogg, notice3.ogg, announce_syndi.ogg
sound: Code Red, Delta, and other extreme emergencies now possess more
unique alarm sound effect
sound: Captain's arrival now is announced by Captain's announcement
sound, but not for Acting Captain's
sound: Making Captain announcement through emagged console; hijacking or
fully corrupting evacuation shuttle now plays more ominous sound
sound: Making announcements through Requests Console now plays a more
noticeable sound
image: Status Displays sprites have been fully changed. Now they include
displays for every Security Level
qol: The "Red Alert" button in the Communications console status display
menu has been replaced with a "Current Alert" button showing the current
station Security Level display on Status Displays
qol: Communications console status display menu got a new "Radiation"
button which shows radiation symbol on Status Displays
/🆑
## About The Pull Request
Do_after bars always draw based on the top-left corner of the targetted
atom, for atoms with sprites that are larger than 32x32 this gives them
a weird offset instead of being centred, which bugs me.
I have tried my best to figure out a way to reverse this which does not
interfere with atoms which use pixel_x/pixel_y to visually appear to be
on a different tile.
## Why It's Good For The Game
Before:

he hates how you missed him completely 😦
After:

now you're cleaning his feet 🙂
## Changelog
🆑
image: progress bars and cleaning particles are now centered on the tile
occupied by the target, if it is a big sprite
/🆑
`mind.transfer_to` sets mind to null.
`mind.set_original_character` thus, should not work, but happens to
because BYOND incorrectly caches this.
This is causing problems with OpenDream because they do not have this
same bug.
## About The Pull Request
The string list is awful for maintainability and is the reason the
filter_invalid_quirks() proc wouldn't work properly.
randomise_quirks() is still broken though.
## Why It's Good For The Game
## Changelog
🆑
fix: Incompatible quirks in existing savefiles shouldn't be possible
anymore.
/🆑
## About The Pull Request
I literally can't focus on anything nowadays, so I just did this to
break a never-ending chain of distress. Anyways, regal rats! These
fellas are mostly player controlled, but did have _some_ AI capabilities
(mainly tied to their actions), so that was incorporated too. Everything
should work as-expected (as well as look a shitload cleaner).
Instead of doing weird and awful conditional signals being sent out, I
made the `COMSIG_REGAL_RAT_INTERACT` (not the actual name) have a return
value so we can always rely on that working whenever we have that signal
registered on something we attack. I also cleaned up pretty much every
proc related to regal rats, gave them AIs to reflect their kingly nature
(and action capabilities (as well as move the action to
`mob_cooldown`)).
Since I thought they needed it, Regal Rats now get a special moniker!
This is stuff like "the Big Cheese" and what-not, like actual regents in
history. That's nice.
## Why It's Good For The Game
Two more off the list. Much better code to read. Way smarter rats with
spawning their army as part of a retaliatory assault (war). More sovl
with better regal rat names. The list goes on.
## Changelog
🆑
refactor: Regal Rats have been refactored into basic mobs. They should
be a bit smarter and retain their docility (until attacked, in which
case you should prepare to get rekt by summoned rats), and properly flee
when they can instead of just sit there as you beat them to death. The
framework for them interacting with stuff (i.e. opening doors while
slobbering on food) is a bit more unified too, now. They also have
cooler names too!
/🆑
FYI: Beyond a few code touchups, I haven't touched the actions at all. I
do not believe myself to be enthusiastic about fixing anything involving
the actions code as of this moment so that this PR is more overbloated
unless it's unbelievably stupid or easy to fix.
## About The Pull Request
This PR adds a bunch of sanity checking to the `prefs.chat_toggles` var
accesses.
Prefs can be null when client is creating/deleting and this causes a
runtime where you might not be able to use emotes.

EDIT: as per suggestion I stopped masking the issue and added stack
traces instead. And made them into helper procs to avoid code
duplication.
For some of these procs it is important that we are able to continue
running to get to the end. **A ghost having null prefs should not stop
everyone else from hearing/seeing the emote.**
So now they will put the stack trace and keep on trucking if that issue
occurs. This is the main 'point' of the PR, which has seemingly gotten
bogged down in the creation of the two helper procs--apologies.
See https://github.com/tgstation/tgstation/pull/70404 for essentially
the same issue but applied to chat messages. I have gone back and
replaced the duplicated code from that to use the new helper procs
instead.
## Why It's Good For The Game
Anything chat related is a bad place to runtime. Some messages can take
a while to type out and to have it not display is frustrating at worst,
possibly detrimental if you have to communicate something urgently.
## Changelog
🆑
fix: fixes a bug that can cause emotes to stop working if a client is
being created or deleted
/🆑
## About The Pull Request
I saw this pop up on a port of one of my PRs and realized "damn that is
an issue"
`COMSIG_GLOB_CREWMEMBER_JOINED` was sent twice for latejoins, once in
`transfer_character` and once at the end of `AttemptLateSpawn`
This caused latejoiners to get the signal twice, so in the case of
Summon Guns, they'd get two guns
## About The Pull Request
Adds an arg in huds' screens to add the hud owner in the Initialize,
instead of manually setting it every time we need to.
This is already done in ``New()`` for lobby screens, which I left intact
as lobby screens are used for new players, and are given out before
atoms are Initialized. Everything else, however, uses Initialize, so it
does not mess with any other args in their own Initializes (like the
Escape menu).
This also allows us to set the screens' HUDs as a private var, to ensure
this won't be messed with in the future.
Lastly I replaced instances of ``client`` with ``cannon_client`` to be
consistent with a lot of other parts of hud code.
## Why It's Good For The Game
Huds are easy to break when they do not have a hud owner, and for
something as important as that I believe it should be something you
opt-out of when you don't want it, rather than something you opt-into by
manually setting hud owner every time.
This cuts down on a lot of copy paste in hud code for humans, aliens,
etc.
## Changelog
🆑
refactor: Huds now have their hud owner set in Initialize
/🆑
## About The Pull Request
Adds a button to the new player HUD that allows collapsing and expanding
the menu buttons.
Also gives the buttons names so they can show up in the BYOND's prompt
on the bottom left.
Readiness is now also displayed in the status tab.
The menu HUD can be reset with a verb Reset Lobby Menu HUD in the OOC
tab.
### I SAW FOOTAGE
https://github.com/tgstation/tgstation/assets/75863639/2054c09d-48d7-4736-b862-4406667dde67
#### Here be dragons (dev progress footage)
#### GACHI BGM WARNING
<details><summary>Mk. I </summary>
https://github.com/tgstation/tgstation/assets/75863639/3e886254-bebd-4aa3-b7f7-5fdd8b7c9040
</details>
___
<details><summary>Mk. II</summary>
https://github.com/tgstation/tgstation/assets/75863639/14d84a2d-1732-4700-aad0-df85c9befa86
</details>
___
<details><summary>Mk. III (featuring: the shutter!) ((NOT featuring:
gachi BGM))</summary>
https://github.com/tgstation/tgstation/assets/75863639/98576c1f-6877-41b9-bec6-e11207501965
</details>
___
<details><summary>Mk. IV (new collapse button sprite )</summary>
~~& shutter graffiti~~ (in a followup PR)
this video has a bug with the poll button lighting up without an active
poll, this was fixed before it was pushed
https://github.com/tgstation/tgstation/assets/75863639/6c0489e2-c80a-4682-b543-5d7c74071a39
</details>
___
<details><summary>Mk. IV with updated shutter sprite and animation
speed</summary>
<sub>TIL github sanitizes ♂ and probably other ascii from file
names</sub>
https://github.com/tgstation/tgstation/assets/75863639/61ed85fe-8df6-4f38-91aa-1f70258289e7
</details>
## TO-DO
- [x] A shutter that comes down and hides the buttons away.
- [ ] The shutter will have a chance to have silly graffiti on it.
- [x] Redesign and move the collapse/expand button to be a part of the
menu.
## Why It's Good For The Game
Banishes the curse cast upon lobby art. Ties in with the on-going lobby
art contest.
## Changelog
🆑
qol: Lobby Menu buttons can now be collapsed. Rejoice!
qol: Lobby Menu buttons have names, which can be seen in the prompt on
the bottom left of the viewport.
qol: you may see your readiness status during pre-game in the Status
Bar.
qol: Reset Lobby Menu HUD verb added in case you manage to break the
damn thing.
/🆑
## About The Pull Request
Fixes#76553
Sleeping inputs my beloved
Observetarget was overridden and thus we couldn't remove the original
target, so got to keep their stuff rather than removing it
## Why It's Good For The Game
Exploity
## Changelog
🆑 Melbert
fix: Fixed an exploit involving observers
/🆑