## About The Pull Request
You shouldn't ever qdel a callback. If you don't want to own it free
your ref (remove it from a list/set it to null). When all refs are
cleared it'll get cleaned up by byond itself
## About The Pull Request
Completely reworks how AI tracking is handled, this has no in-game
effects.
This moves nearly all AI tracking handling onto ``/datum/tracking``,
which previously was pretty bad. I tried documenting as much as I can,
making comments actually useful and give accurate information.
Turns ``get_camera_list`` into a global proc, which we now use for
camera consoles (including the app), cutting down on copy paste in 2
areas and standardizing its behavior/backend.
## Why It's Good For The Game
I wanted to generalize this behavior so I can use it for tracking
players in https://github.com/tgstation/tgstation/pull/77713 - This
helps me do that.
Also the current state of AI tracking code is pretty poor and hopefully
this improves that area.
Closes https://github.com/tgstation/tgstation/issues/42355
## Changelog
🆑
refactor: AI's player-tracking eyes received an unwanted obligatory
update, and should now not tell you that a player is untrackable when
they clearly obviously can be.
/🆑
## About The Pull Request
A deal with @Fikou
- https://github.com/DaedalusDock/daedalusdock/pull/106
In layman's terms, you can grab this wrench now.

Adds a new pass_flags_self value for click transparency, allowing
objects to be dense without blocking click attempts.
## Why It's Good For The Game
## Changelog
🆑
add: Lockers, crates, and machines no longer block click attempts in
adjacency checks. Basically, you can reach tables cornered between
lockers/machines.
/🆑
## About The Pull Request
xenos now have a rest button above their combat mode toggle
## Why It's Good For The Game
xenos can rest, but for some reason it was only a verb and wasn't a hud
button like with humans
## Changelog
🆑
qol: xenos rest verb now is a hud button instead
/🆑
## About The Pull Request
I was bored, so did this. Probably one of the neatest refactors I've
done, sorry if there's some oddities because I was experimenting with
some other stuff in this so just tell me to clean them up whenever I
can.
Anyways, morphs are basic mobs now. We are able to easily refactor the
whole "eat items and corpses" stuff in the basic mob framework, but the
whole "morph into objects and people" turned out to be a bit trickier.
That was easily rectified with a datum mob cooldown action and
copy-pasting the old code into that code, as well as doing some nice
stuff with traits and signals to ensure the one-way communication from
the action to the mob.
Old Morph AI didn't seem to be existant whatsoever, they inappropriately
leveraged some old procs and I have no idea how to make it work with new
AI. They DEFINITELY don't spawn outside of admin interference/ the event
anymore, and will always be controlled by a player, so this shouldn't be
too bad of an issue. I gave them something to seem alive just in case
though, but I think adding legitimate prop-hunt AI would be such a
laborious task that I am unwilling to do it in this PR.
## Why It's Good For The Game
If admins want to add the ability for Ian to assume the form of the HoP,
they can do that now! The datum action cooldown is quite nice for simple
and basic mobs... but it is currently not compatible with carbons. That
is not within scope for this PR, but I am dwelling on ways to extend it
to carbon but they all sound really awfully bad.
Also morphs are smarter, and we tick another simple animal in need of
refactoring off the list.
## Changelog
🆑
refactor: Morphs are now basic mobs with a nice new ability to help you
change forms rather than the old shift-click method, much more
intuitive.
admin: With the morph rework comes a new ability you can add to mobs,
"Assume Form". Feel free to add that to any simple or basic mob for le
funnies as Runtime turns into a pen or something.
/🆑
~~Does anyone know if there's a (sane) way to alias a cooldown action as
a keypress? I can't think of a good way to retain the old shift-click
functionality, because that does feel _kinda_ nice, but I think it can
be lived without.~~ I added it. Kinda fugly but whatever.
## About The Pull Request
I was working on some basic mob stuff and noticed this is a little
messy, so I made these changes separately.
I removed ``dextrous_hud_type`` because ``hud_type`` exists and can just
be used instead.
I also removed the ``healable`` var, because it was incorrectly used
(with the expectation that basic mobs had it too). Instead it will rely
on the mob being Organic, the check right under it, and I gave mob
biotypes to mobs that were not healable and had no biotype already.
I made a new biotype for slimes because I didn't find any other ones
that fit it (and gave it to slimepeople), but it is not used anywhere
other than to prevent them from healing from sutures, as I didn't want
to just set it to NONE. Thought this may be useful for the future.
## Why It's Good For The Game
``healable`` is checked on simple animals and basic mobs, despite basic
mobs not having this var. I do not want to add this var to basic mobs
either, I think checking for them being organic makes much more sense
and avoids having to make basic mobs less basic.
## Changelog
Nothing player-facing.
## About The Pull Request
Adds some nice little mouse button indicators (optional), this is a port
of my version at
[Citadel-Station-13/15973](https://github.com/Citadel-Station-13/Citadel-Station-13/pull/15973).
**There is no more intent coloring**
## Why It's Good For The Game
Quick identification of what to do. Eh, i dunno if it's getting
accepted, mothblocks asked me to port it over.
## Changelog
🆑
image: Changed screentips icons to something a lot fancier unified with
the LMB / RMB text.
qol: There are accessibility preferences to disable this! Look for
"Screentip context with images" beside the other screentip preferences.
/🆑
---------
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
Makes the random parallax layer appear more distant, instead of merged
with the planet
In the old behaviour, parallax is merged with the planet, making it one
static image. I changed it to have a slowed speed, so it looks deeper
now:
https://github.com/tgstation/tgstation/assets/7501474/9ea9821d-e06d-4bae-9c35-f2db37a442d6
### Why
The random parallax and planer layers have the same speed, making them
appear as one image. We're already rendering them as seperate parallaxes
with individual speeds, they're just the same. This costs nothing, but
gives the parallax more depth
🆑
qol: The random parallax layer moves more slowly, giving a more deep
feel
/🆑
No excuse, just dumb. Random layer is the randomly generated parallax
layer, which is null 30% of the time, so this would runtime in SSstation
setup in 30% of rounds
Also another thing where I added extra params and didn't add them to the
proc, fucking parallax for some roundstart clients and latejoins
🆑
fix: fixes a runtime in SSstation setup
fix: fixes parallax not rendering correctly for latejoins
/🆑

Listing the changes, off the top of my head:
- Resprited fishing rods, hooks, and the worm bait!
- Added a new, telescopic fishing rod, that can be bought as a goodie.
The master rod is also telescopic now.
- Added a couple hooks. One that lets you move the bait up and down,
otherwise keeping it in place, and another that stops the fish from
escaping, but slowly kills it. The former from the bepis fishing tech
node, the latter frm the black market.
- Added a fishing skill and relative legendary reward: A fishing hat,
like the one that recites "women fear me, fish fear me"
- You can now stop fishing by activating the fishing rod in your hand,
and stops it from stealing all clicks on other things if it isn't in
your active hand.
- Reworked fishing traits into fish traits, which can apply to fish
after it has been caught.
- Expanded the fish breeding system. Traits may be passed down to
offsprings, and offsprings may evolve (mutate?) into different kind of
fishes if conditions when conditions are met.
- Added half a dozen new fishes, each with its own traits: lubefish,
sludgefish (and its purple variant), slimefish, unmarine bonemass and
unmarine mastodon. Also, holodeck fish, as a joke.
- New traits: lubed skin, parthenogenesis, toxic (new reagent), toxin
immunity, predator, necrophage, no mating, crossbreeder, aggressive and
revival. Converted Emulsijack's ability and Donkfish's yuckiness into
traits as well.
- Added a fish analyzer that you can scan aquariums and fishes with.
- Fish can now be blended if you really want to. The number of reagents
from blending, w_class, and the number of fillets you get from cutting
fish now scale with size and weight.
- fish feed is no longer infinite (but it should still be plenty).
- Implemented temperature requirements for aquarium fish.
- You can now buy (dead) fish from the black market for dirt cheap.
- Last but now least, toilets are now valid fishing spots.
## About The Pull Request
When trying to use an item on a mob, check for surgery before wounds.
This fixes surgeries (such as compound fracture) that use consumables
such as bone gel being impossible to complete because it tries to use
the item on the wound as the 'quick' treatment instead of the surgery.
Moved the surgery check to its own mob/living proc because it's now used
in two places.
Closes https://github.com/tgstation/tgstation/issues/76832
Closes https://github.com/tgstation/tgstation/issues/76711
## Why It's Good For The Game
Compound fracture surgery completes successfully instead of making the
patient scream in pain and take brute damage.
## Changelog
🆑 LT3
fix: Consumables like bone gel will first be used for surgery before
wounds
/🆑
## 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
APCs, fire alarms, and holopads now communicate a few more hotkeys for
interaction with silicons via examine. Ex. APCs now tell silicons they
can disable lighting with shift-click.
## Why It's Good For The Game
1. Balloon alerts are cool.
2. UX is also cool.
## Changelog
🆑
qol: APCs, fire alarms, and holopads now communicate some more of their
silicon interactions via screentips.
qol: APCs, fire alarms, holopads and turret control panels now use
balloon alerts for more of their notifications.
/🆑
---------
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
## 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
Due to a mental breakdown caused by unfathomable abomination that is
icons folder, I swore to myself to one day clean it. Today is kind of
that day. Been at it for around 6, you gotta understand I need a rest. I
tracked most changes in descriptions of commits if you are looking for
details.
## Why It's Good For The Game
Saner spriters make better sprites. And also, just helps keep track of
things.
## Changelog
🆑
image: added sprites for different variants of scrolls.
image: modified couple posters with ghost pixels.
/🆑
---------
Co-authored-by: OrionTheFox <76465278+OrionTheFox@users.noreply.github.com>
## About The Pull Request
This PR refactors mind language holders into non-existence
As a result, `update_atom_languages` is no longer necessary
Mind-bound languages are transferred via `/mind/proc/transfer_to`
Species changing no longer deletes and re-creates the mob's language
holder, allowing them to keep any languages they have.
Species languages are sourced from `LANGUAGE_SPECIES` now, meaning they
are removed when they change species. If the mob is not a human with a
species datum, these are effectively just atom level languages.
Makes a bunch of unit tests to ensure language transfer over certain
events works as intended
## Why It's Good For The Game
Mobs with minds having two independent language holders results in a
good few bugs, and simply doesn't make sense when we have sources
(`LANGUAGE_MIND`).
Instead of tracking two language holders, we can simply use sources
better and only track one.
This means that the language holder you start with is your language
holder, period. It doesn't get deleted or re-instantiated or whatever.
## Changelog
🆑 Melbert
refactor: Refactored language holders, making species changes not delete
all of your known languages
/🆑
## About The Pull Request
PR done for bounty:
https://tgstation13.org/phpBB/viewtopic.php?f=5&t=33988
borgs can now turn on stoves and griddles
borg click code has been reworked a bit to be closer to base mob, you
are now able to click on stuff within reach rather than just Adjacent
(might be buggy to introduce this? hopefully not. if anything we can
testmerge this), which lets us make the apparatus work to pick up stoves
on the range and such
Adds the Codex Cibus Mechanicus as an upgrade you can research in RnD
with the other service borg ones. When you use it it shows you the
cooking menu!

## Why It's Good For The Game
The service borg has the tools to prepare ingredients, but it can't
actually do anything with them, which severely limits it, only being
able to do slapcrafted foods.
The apparatus not working on items that are on top of stoves/griddles
seems to be just a bug with how cyborg click code is handled.
## Changelog
🆑 Fikou
fix: service borg apparatus now works on stoves and griddles and ovens
qol: borgs can now activate stoves and griddles
add: rnd can research a cookbook for service borgs
/🆑
## About The Pull Request
Tend Wounds seems to be intentionally written such that you would be
able to perform it on arbitrary mobs, however this had two problems.
- Most mobs can't rest and it requires a resting position, meaning the
surgery can only be initiated on cats and mothroaches.
- The code which picks up surgery steps existed on Carbon not Living, so
after the game tells you that you've started doing surgery on Runtime,
clicking on her with a scalpel will cause you to stab her to death. I
noticed this after a tragic kitten incident.
I have fixed both of these issues by moving surgery catching onto Living
instead of Carbon, and having the resting check only run if you are
capable of resting.
You still can't operate on Beepsky because he is made of metal.
## Why It's Good For The Game
It can actually quite hard to heal pets who were harmed by accident,
this allows people to roleplay as veterinarians.
## Changelog
🆑
fix: You can now correctly Tend Wounds on most non-human animals.
add: You can now Remove Implants from non-human animals, just in case
Ian swallowed a macrobomb.
/🆑
## About The Pull Request
This adds a few hotkeys to APCs for AIs and borgs.
- Toggle environmental (ctrl + shift)
- Toggle lighting (shift)
- Toggle equipment (alt)
- Toggle breaker (ctrl)
These are included as contextual screentips. Also removed the UI popup
when using RMB to toggle the lock as well since it was annoying. Went
and cleaned up quite a bit of one letter var names and `usr` arguments.
## Why It's Good For The Game
Easier controls for equipment.
## Changelog
🆑
qol: Add hotkeys to APCs for AIs and borgs. Toggle environmental (ctrl +
shift), toggle lighting (shift), toggle equipment (alt), and toggle
breaker (ctrl).
qol: Remove APC UI popup when using RMB to toggle the lock.
/🆑
---------
Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com>
## About The Pull Request
At some point with the refactors to offering it was made so that
dropping the item stops the offer, unfortunately too slowing people with
high fives relied on this behavior (dropping not stopping the offer).
Restores that behavior with a bit more code tweaking.
## Why It's Good For The Game
How can I be too slow?
## Changelog
🆑 Melbert
fix: You can once again "too slow" someone with a high five
/🆑
## About The Pull Request
For some reason this was missed when moving attack_obj() to /atom level.
## Why It's Good For The Game
It peeves me that this signal is misnamed
## About The Pull Request
Ghosts can click gateways to teleport again
## Why It's Good For The Game
I *believe* the "gateway visual" update made it so the bumper was
unclickable, not sure why
Seemed easier to move it to the gateway itself rather than be on the
bumper
Also made it so you cant teleport into secret gateways
## Changelog
🆑 Melbert
fix: Ghosts can click on active gateways to teleport to the destination
set. Doesn't work for secret gateways.
/🆑
## About The Pull Request
Signals were initially only usable with component listeners, which while
no longer the case has lead to outdated documentation, names, and a
similar location in code.
This pr pulls the two apart. Partially because mso thinks we should, but
also because they really aren't directly linked anymore, and having them
in this midstate just confuses people.
[Renames comp_lookup to listen_lookup, since that's what it
does](102b79694f)
[Moves signal procs over to their own
file](33d07d01fd)
[Renames the PREQDELETING and QDELETING comsigs to drop the parent bit
since they can hook to more then just comps
now](335ea4ad08)
[Does something similar to the attackby comsigs (PARENT ->
ATOM)](210e57051d)
[And finally passes over the examine
signals](65917658fb)
## Why It's Good For The Game
Code makes more sense, things are better teased apart, s just good imo
## Changelog
🆑
refactor: Pulled apart the last vestiges of names/docs directly linking
signals to components
/🆑
## About The Pull Request
Removes the check for reentering your body when double clicking on
things as a ghost.
## Why It's Good For The Game
Perhaps my experience is not universal, but I have never found an
occasion where I did this and wanted to re-enter my corpse, and
conversely many occasions where I want to orbit my corpse and find
myself re-entering it instead.
Any form of revival will pull you back into your body automatically
these days and there's no real benefit to being in your corpse, and in
the rare circumstance someone wants to do this the verb is still
available.
## Changelog
🆑
qol: Double clicking your corpse or something containing it as a ghost
will now orbit as in other cases instead of re-entering your corpse.
/🆑
## About The Pull Request
HackMD: https://hackmd.io/RE9uRwSYSjCch17-OQ4pjQ?view
Feedback link: https://tgstation13.org/phpBB/viewtopic.php?f=10&t=33972
Adds a Coroner job to the game, they work in the Medical department and
have their office in the Morgue.
I was inspired to make this after I had played my first round on
Paradise and messed around in there. The analyzer is copied from there
(https://github.com/ParadiseSS13/Paradise/pull/20957), and their
jumpsuit is also mostly stolen from it (i just copied the color scheme
onto our own suits).
Coroners can perform autopsies on people to see their stats, like this

They have access to Medbay, and on lowpop will get Pharmacy (to make
their own formaldehyde). They also have their own Secure Morgue access
for their office (doubles as a surgery room because they are edgelords
or whatever) and the secure morgue trays.
Secure Morgue trays spawn with their beepers off and is only accessible
by them, the CMO, and HoS. It's used to morgue Antagonists. Security's
own morgue trays have been removed.
The job in action
https://cdn.discordapp.com/attachments/950489581151735849/1102297675669442570/2023-04-30_14-16-06.mp4
### Surgery changes
Autopsies are a Surgery, and I tried to intertwine this with the
Dissection surgery.
Dissections and Autopsies both require the Autopsy scanner to perform
them, however you can only perform one on any given body. Dissections
are for experiments, Autopsies is for the paper of information.
Dissected bodies now also give a ~20% surgery speed boost, this was
added at the request of Fikou as a way to encourage Doctors to let the
Coroner do their job before reviving a body.
I also remember the Medical skill, which allowed Doctors to do surgery
faster on people, and I hope that this can do something like that
WITHOUT adding the potential for exploiting, which led to the skill's
downfall.
### Morgue Improvements
Morgue trays are no longer named with pens, they instead will steal the
name of the last bodybag to be put in them.
Morgue trays are also removed from Brig Medical areas and Robotics, now
they have to bring their corpses to the Morgue where the Coroner can
keep track and ensure records are properly updated.
### Sprite credits
I can't fit it all in the Changelog, so this is who made what
McRamon
- Autopsy scanner
Tattax
- Table clock sprites and in-hands
CoiledLamb
- Coroner jumpsuits & labcoats (inhand, on sprite, and their respective
alternatives)
- Coroner gloves
- CoronerDrobe (the vending machine)
## Why It's Good For The Game
This is mostly explained in the hackmd, but the goal of this is:
1. Increase the use of the Medical Records console.
2. Add a new and interesting way for Detectives to uncover mysteries.
3. Add a more RP-flavored role in Medical that still has mechanics tied
behind it.
## Changelog
🆑 JohnFulpWillard, sprites by McRamon, tattax, and Lamb
add: The Coroner, a new Medical role revolving around dead corpses and
autopsies.
add: The Coroner's Autopsy Scanner, used for discovering the cause for
someone's death, listing their wounds, the causes of them, their
reagents, and diseases (including stealth ones!)
qol: Morgue Trays are now named after the bodybags inside of them.
balance: The morgue now has 'Secure' morgue trays which by default don't
beep.
balance: Security Medical area and Robotics no longer have their own
morgue trays.
balance: Dissected bodies now have faster surgery speed. Autopsies also
count as dissections, however they're mutually exclusive.
/🆑
---------
Co-authored-by: Fikou <23585223+Fikou@users.noreply.github.com>
## About The Pull Request
A re-open of https://github.com/tgstation/tgstation/pull/66326 with
Fikou's permission
Adds the style meter, it can be bought from the mining vendor for 1500
points, it is an attachment to your glasses.
The style meter creates a display on your hud, with your recent actions,
like attacking enemies, killing them, mining ore etc. Actions like
spinning or flipping increase your score multiplier, making you get more
points.
Your style meter affects how much ore you get from mining rocks. By
default with the meter, you get 20% less ore, but at the highest, you
can get 1.2x the ore from mining. In addition, on B-tier or above, you
can "hotswap" items, by attacking an item in your backpack with one in
your hand (should it fit and all that). Also features a leaderboard for
highest style point count!
New streamable: https://streamable.com/eewi6l
The following are sources of points:
- Killing things
- Killing big things
- Killing small things
- Punching things
- Melee'ing things
- Mining rocks and ores
- Having matrix traps detonate
- Hit, defuse, and detonate gibtonite
- Detonate crusher marks
- Scan geysers
- Parry projectiles (others or your own)
Oh, right. While wearing the style meter, you're able to parry any
lavaland-based projectile by clicking on it or the tile it is on, which
reflects it back in a 7 degree arc, making it 20% faster and 15% more
damaging. Usually not very easy.
Maybe-plan in the future for some syndicate variant of this (with bullet
parrying and appropriate style sources, etc.), but not for this PR
Thanks to Arcane, multitooling the style meter will make it play some
sounds on rank-up.

https://streamable.com/nheaky
Parrying in action
## Why It's Good For The Game
Makes miners bring more ore in a fun way.
## Changelog
🆑 Fikou, Zonespace, Arcane for voicing
add: The mining vendor now has a style meter. This meter gauges your
style points and uses them to improve your ore yield.
/🆑
---------
Co-authored-by: Fikou <23585223+Fikou@users.noreply.github.com>
## About The Pull Request
### Polishes and Reworks Holograms
Hologram generation currently involves a bunch of icon operations, which
are slow.
Not to mention a series of get flats for the human models, which is even
worse.
We lose 0.05 seconds of init to em off just the 2 RCD holograms. it
hurts man.
So instead, let's use filters and render steps to achive the same
effect.
While I'm here I'll dim the holo light and make it blue, make the
hologram and its beam emissive (so they glow), and do some fenangling
with move_hologram() (it doesn't clear the hologram off failure anymore,
instead relying on callers to do that) to ensure holocalls can't be
accidentially ended by moving out of the area.
Ah and I added RESET_ALPHA to the emissive appearance flags, cause the
alpha does override and fuck with color rendering, which ends up looking
dumb. If we're gonna support this stuff it should be first class not
accidential.
### Makes Static Not Shit
While I'm here (since holograms see static) lets ensure the static plane
is always visible if you're seeing through an ai eye.
The old solution was limited to applying it to JUST ais, which isn't
satisfactory for this sort of thing and missed a LOT of cases (I didn't
really get how ai eyes worked before I'ma be honest)
I'm adding a signal off the hud for it detecting a change in its eye
here.
This is semi redundant, but avoids unneeded dupe work, so I'm ok with
it.
The pipeline here is less sane then I'd like, but it works and that's
enough
## Why It's Good For The Game

More pretty, better ux, **static works**
## Changelog
🆑
add: Holograms glow now, pokes at the lighting for holocalls in general
a bit to make em nicer.
qol: You can no longer accidentally end a holocall (as a non ai) by
leaving the area. Felt like garbage
fix: Fixes static rendering improperly if viewed by a non ai
/🆑
## About The Pull Request
Requires #74562 and #74556 be merged first.
Unit tests cult conversion and throws in a case for rev AOE flashes
## Changelog
Not necessary
---------
Co-authored-by: san7890 <the@san7890.com>
## About The Pull Request
Removes emergency meetings. Uh, let me know if I missed anything
## Why It's Good For The Game
We gotta come up with NEW ways to ruin the round each year, this one's
so old and busted
## Changelog
🆑
del: Votes out some sussy emergency meeting code
/🆑
# MAINTAINER - USE THE BUTTON THAT SAYS "MERGE MASTER" THEN SET THE PR
TO AUTO-MERGE! IT'S MUCH EASIER FOR ME TO FIX THINGS BEFORE THEY SKEW
RATHER THAN AFTER THE FACT.
## About The Pull Request
Hey there,
This took a while to do, but here's the gist:
Python file now regexes every file in `/code` except for those that have
some valid reason to be tacking on more global defines. Some of those
reasons are simply just that I don't have the time right now (doing what
you see in this PR took a few hours) to refactor and parse what should
belong and what should be thrown out. For the time being though, this PR
will at least _halt_ people making the mistake of not `#undef`ing any
files they `#define` "locally", or within the scope of a file.
Most people forget to do this and this leads to a lot of mess later on
due to how many variables can be unmanaged on the global level. I've
made this mistake, you've made this mistake, it's a common thing. Let's
automatically check for it so it can be fixed no-stress.
Scenarios this PR corrects:
* Forgetting to undef a define but undeffing others.
* Not undeffing any defines in your file.
* Earmarking a define as a "file local" define, but not defining it.
* Having a define be a "file local" define, but having it be used
elsewhere.
* Having a "local" define not even be in the file that it only shows up
in.
* Having a completely unused define*
(* I kept some of these because they seemed important... Others were
junked.)
## Why It's Good For The Game
If you wanna use it across multiple files, no reason to not make it a
global define (maybe there's a few reasons but let's assume that this is
the 95% case).
Let me know if you don't like how I re-arranged some of the defines and
how you'd rather see it be implemented, and I'd be happy to do that.
This was mostly just "eh does it need it or not" sorta stuff.
I used a pretty cool way to detect if we should use the standardized
GitHub "error" output, you can see the results of that here
https://github.com/san7890/bruhstation/actions/runs/4549766579/jobs/8022186846#step:7:792
## Changelog
Nothing that really concerns players.
(I fixed up all this stuff using vscode, no regexes beyond what you see
in the python script. sorry downstreams)
## About The Pull Request
Clicking on the turf of a fire alarm/light switch with your hand will
activate it, similar to how you can click the turf a door is on to close
it and not pixel hunt. Refers to the turf it *looks* like it's on, not
the one it actually is on, since fire alarms and light switches are
actually on the turf near the wall, pixel shifted up.
False walls are ignored.
## Why It's Good For The Game
Lets our artists do whatever they want to these sprites, or those of
future consumers, without worrying about niche balance stuff. I really
like people using fire alarms for environmental combat and don't want
that to get in the way of spriting.
## Changelog
🆑
qol: Clicking on the turf of a fire alarm/light switch with your hand
will activate it.
/🆑
## About The Pull Request
The Nar'Sie summon message will now only use the original name of the
ritual site area. You can no longer fake out the ritual announcement by
renaming the area with the CE blueprints.
The ritual site locator HUD popup now also uses the original area names,
to prevent the same issue from occurring.
## Why It's Good For The Game
Closes#73036.
## Changelog
🆑
fix: The cultist ritual site locator and Nar'Sie summon message will no
longer use area names modified by the CE's blueprints.
/🆑
Adds the Law Panel.
The Law Panel shows all silicons in the world and their lawsets.
From this panel, an admin can add new laws, remove old laws, edit
existing laws, or even re-arrange law order.
This allows for admins to get a lot more creative in creating custom
silicon lawsets. It also gives a much easier way for admins to deal with
law grief at a glance.
Additionally, the panel allows for admins to force a silicon to state
laws, privately announce the laws to the player, or give them a the
"laws updated" alert as normal.
## About The Pull Request
While I was touching the Creature file for another PR (#73629) I noticed
that an identical proc was implemented here and on Statue.
I moved it into a component and managed to hook it into signals which
have return flags.
This required a bit of a refactor of their abilities too, but that was
for the best because one of them had a reimplementation of Jaunt which
could have just been a subtype of Jaunt, and none of their abilities had
icons.
I also made `spell` send `COMSIG_MOB_ABILITY_STARTED` in `PreActivate`
because it completely overrides the parent and doesn't do that as a
result.
## Why It's Good For The Game
I'll be honest this is mostly because I was looking at the code and
didn't like it, I don't think there were any bugs related to this but it
does reduce chat spam a little bit?
It should make this behaviour more maintainable and useful in the
future, as we're not copying and pasting multiple procs between
different files (for both this behaviour and jaunting).
## Changelog
🆑
refactor: The actions of Statues and Creatures which can't be used while
seen now share logic, and will not spam chat with feedback.
/🆑
<!-- 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
[Fixes a bug where anything fully dark on the floor plane would mask the
lighting
plane](a1a03dc339)
I fucked it up boys, needed to take alpha into account here
[Fixes pais getting parallax on icebox because their location was
nested](81252e0f45)
God I hate this place (Note when I say get I mean they got the plane
master that controls it, not that they actually got it displayed. That
does appear to sometimes happen but I have no idea why)
[Fixes double flashlights not activating if enabled in
place](efb8b641ea)
[efb8b64](efb8b641ea)
cast_directional_light removes the lighting appearance, because it's
gonna modify it, but it turns out because appearances are static when
they're in like underlays/overlays, this could remove the WRONG UNDERLAY
This lead to double held flashlights just... not working until you
rotated. V stupid.
I've also had to move the flag set to make the overlay add in
cast_directional_light work. Depression
## Why It's Good For The Game
Closes#73535, closes#73517, closes#73518, and fixes part of #73471
<!-- 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. -->
🆑
fix: Fixes activating two flashlights without moving only turning on one
flashlight (until you move)
fix: Purely black things drawn on the floor (like carpets, those foam
dispensers, etc) will no longer cause things on top of them to be fully
masked in darkness
/🆑
<!-- 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
Relies on #72886 for some render relay expansion I use for light_mask
stuff.
Hello bestie! Night vision pissed me off, so I've come to burn this
place to the ground.
Two sections to discuss here. First we'll talk about see_in_dark and why
I hate it, second we'll discuss the lighting plane and how we brighten
it, plus introducing color to the party.
### `see_in_dark` and why it kinda sucks
https://www.byond.com/docs/ref/#/mob/var/see_in_dark
See in dark lets us control how far away from us a turf can be before we
hide it/its contents if it's dark (not got luminosity set)
We currently set it semi inconsistently to provide nightvision to mobs.
The trouble is stuff that produces light != stuff that sets luminosity.
The worst case of this can be seen by walking out of escape on icebox,
where you'll see this

Snow draws above the lighting plane, so the snow will intermittently
draw, depending on see_in_dark and the luminosity from tracking lights.
This would in theory be solvable by modifying the area, but the same
problem applies across many things in the codebase.
As things currently stand, to be emissive you NEED to have a light on
your tile. People are bad at this, and honestly it's a bit much to
expect of them. An emissive overlay on a canister shouldn't need an
element or something and a list on turfs to manage it.
This gets worse when you factor in the patterns I'm using to avoid
drawing lights above nothing, which leads to lights that should show,
but are misoffset because their parent pixel offsets.
It's silly. We do it so we can have things like mesons without just
handing out night vision, but even there the effect of just hiding
objects and mobs looks baddddddd when moving. It's always bothered me.
I'll complain about mesons more later, but really just like, they're too
bright as it is.
I'm proposing here that rather then manually hiding stuff based off
distance from the player, we can instead show/hide using just the
lighting plane. This means things like mesons are gonna get dimmer, but
that's fine because they suck.
It does have some side effects, things like view() on mobs won't hide
stuff in darkness, but that's fine because none actually thinks about
view like that, I think.
Oh and I added a case to prevent examining stuff that's in darkness, and
not right next to you when you don't have enough nightvision, to match
the old behavior `see_in_dark` gave us.
Now I'd like to go on a mild tangent about color, please bare with me
### Color and why `lighting_alpha` REALLY sucks
You ever walk around with mesons on when there's a fire going, or an
ethereal or firelocks down.
You notice how there isn't really much color to our lights? Doesn't that
suck?
It's because the way we go about brighting lighting is by making
everything on the lighting plane transparent.
This is fine for brightening things, but it ends up looking kinda crummy
in the end and leads to really washed out colors that should be bright.
Playing engineer or miner gets fucking depressing.
The central idea of this pr, that everything else falls out of, is
instead of making the plane more transparent, we can use color matrixes
to make things AT LEAST x bright.
https://www.byond.com/docs/ref/#/{notes}/color-matrix
Brief recap for color matrixes, fully expanded they're a set of 20
different values in a list
Units generally scale 0-1 as multipliers, though since it's
multiplication in order to make an rgb(1,1,1) pixel fullbright you would
need to use 255s.
A "unit matrix" for color looks like this:
```
list(1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
0, 0, 0, 0
)
```
The first four rows are how much each r, g, b and a impact r, g, b and
well a.
So a first row of `(1, 0, 0, 0)` means 1 unit of r results in 1 unit of
r. and 0 units of green, blue and alpha, and so on.
A first row of `(0, 1, 0, 0)` would make 1 red component into 1 green
component, and leave red, blue and alpha alone, shifting any red of
whatever it's applied to a green.
Using these we can essentially color transform our world. It's a fun
tool. But there's more.
That last row there doesn't take a variable input like the others.
Instead, it ADDS some fraction of 255 to red, green, blue and alpha.
So a fifth row of `(1, 0, 0, 0)` would make every pixel as red as it
could possibly be.
This is what we're going to exploit here. You see all these values
accept negative multipliers, so we can lower colors down instead of
raising them up!
The key idea is using color matrix filters
https://www.byond.com/docs/ref/#/{notes}/filters/color to chain these
operations together.
Pulling alllll the way back, we want to brighten darkness without
affecting brighter colors.
Lower rgb values are darker, higher ones are brighter. This relationship
isn't really linear because of suffering reasons, but it's good enough
for this.
Let's try chaining some matrixes on the lighting plane, which is bright
where fullbright, and dark where dark.
Take a list like this
```
list(1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
-0.2, -0.2, -0.2, 0
)
```
That would darken the lighting a bit, but negative values will get
rounded to 0
A subsequent raising by the same amount
```
list(1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
0.2, 0.2, 0.2, 0
)
```
Will essentially threshold our brightness at that value.
This ensures we aren't washing out colors when we make things brighter,
while leaving higher values unaffected since they basically just had a
constant subtracted and then readded.
### But wait, there's more
You may have noticed, we gain access to individual color components
here.
This means not only can we darken and lighten by thresholds, we can
COLOR those thresholds.
```
list(1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
0.1, 0.2, 0.1, 0
)
```
Something like the above, if applied with its inverse, would tint the
darkness green.
The delta between the different scalars will determine how vivid the
color is, and the actual value will impact the brightness.
Something that's always bothered me about nightvision is it's just
greyscale for the most part, there isn't any color to it.
There was an old idea of coloring the game plane to match their lenses,
but if you've ever played with the colorblind quirk you know that gets
headachey really fast.
So instead of that, lets color just the darkness that these glasses
produce.
It provides some reminder that you're wearing them, instead of just
being something you forget about while playing, and provides a reason to
use flashlights and such since they can give you a clearer, less tinted
view of things while retaining the ability to look around things.
I've so far applied this pattern to JUST headwear for humans (also those
mining wisps)
I'm planning on furthering it to mobs that use nightvision, but I wanted
to get this up cause I don't wanna pr it the day before the freeze.
Mesons are green, sec night vision is red, thermals orange, etc.
I think the effect this gives is really really nice.
I've tuned most things to work for the station, though mesons works for
lavaland for obvious reasons.
I've tuned things significantly darker then we have them set currently,
since I really hate flat lighting and this system suffers when
interacting with it.
My goal with these is to give you a rough idea of what's around you,
without a good eye for detail.
That's the difference between say, mesons, and night vision. One helps
you see outlines, the other gives you detail and prevents missing
someone in the darkness.
It's hard to balance this precisely because of different colored
backgrounds (looking at you icebox)
More can be done on this front in future but I'm quite happy with things
as of now
### **EDIT**
I have since expanded to all uses of nightvision, coloring most all of
them.
Along the way I turned some toggleable nightvision into just one level.
Fullbright sucks, and I'd rather just have one "good" value.
I've kept it for a few cases, mostly eyes you rip out of mobs.
Impacted mobs are nightmares, aliens, zombies, revenants, states and
sort of stands.
I've done a pass on all mobs and items that impact nightvision and added
what I thought was the right level of color to them. This includes stuff
like blobs and shuttle control consoles
As with glasses much of this was around reducing vision, though I kept
it stronger here, since many of these mobs rely on it for engaging with
the game
<details>
<summary>
Technical Changes
</summary>
#### Adds filter proc (the ones that act like templates) support to
filter transitions.
Found this when testing this pr, seemed silly.
#### Makes our emissive mask mask all light instead
This avoids dumbass overlay lighting lighting up wallmounts.
We switch modes if some turfflags are set, to accomplish the same thing
with more overhead, and support showing things through the darkness.
Also fixes a bug where you'd only get one fullscreen object per mob, so
opening and closing a submap would take it away
Also also fixes the lighting backdrop not actually spanning the screen.
It doesn't actually do anything anymore because of the fullscreen light
we have, but just in case that's unsued.
Needs cleanup in future.
#### Moves openspace to its own plane that doesn't draw, maxing its
color with a sprite
This is to support the above
We relay this plane to lighting mask so openspace can like, have
lighting
#### Changes our definition of nightvision to the light cutoff of night
vision goggles and such
Side affect of removing see_in_dark. This logic is a bit weak atm, needs
some work.
#### Removes the nightvision spell
It's a dupe of the nightvision action button, and newly redundant since
I've removed all uses of it
#### Cleans up existing plane master critical defines, ensures
trasnparent won't render
These sucked
Also transparent stuff should never render, if it does you'll get white
blobs which suck
</details>
## Why It's Good For The Game
Videos! (Github doesn't like using a summary here I'm sorry)
<details>
Demonstration of ghost lighting, and color
https://user-images.githubusercontent.com/58055496/215693983-99e00f9e-7214-4cf4-a76a-6e669a8a1103.mp4
Engi-glass mesons and walking in maint (Potentially overtuned, yellow is
hard)
https://user-images.githubusercontent.com/58055496/215695978-26e7dc45-28aa-4285-ae95-62ea3d79860f.mp4
Diagnostic nightvision goggles and see_in_dark not hiding emissives
https://user-images.githubusercontent.com/58055496/215692233-115b4094-1099-4393-9e94-db2088d834f3.mp4
Sec nightvision (I just think it looks neat)
https://user-images.githubusercontent.com/58055496/215692269-bc08335e-0223-49c3-9faf-d2d7b22fe2d2.mp4
Medical nightvision goggles and other colors
https://user-images.githubusercontent.com/58055496/215692286-0ba3de6a-b1d5-4aed-a6eb-c32794ea45da.mp4
Miner mesons and mobs hiding in lavaland (This is basically the darkest
possible environment)
https://user-images.githubusercontent.com/58055496/215696327-26958b69-0e1c-4412-9298-4e9e68b3df68.mp4
Thermal goggles and coloring displayed mobs
https://user-images.githubusercontent.com/58055496/215692710-d2b101f3-7922-498c-918c-9b528d181430.mp4
</details>
I think it's pretty, and see_in_dark sucks butt.
## 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. -->
🆑
add: The darkness that glasses and hud goggles that impact your
nightvision (think mesons, nightvision goggles, etc) lighten is now
tinted to match the glasses. S pretty IMO, and hopefully it helps with
forgetting you're wearing X.
balance: Nightvision is darker. I think bright looks bad, and things
like mesons do way too much
balance: Mesons (and mobs in general) no longer have a static distance
you can see stuff in the dark. If a tile is lit, you can now see it.
fix: Nightvision no longer dims colored lights, instead simply
thresholding off bits of darkness that are dimmer then some level.
/🆑
## About The Pull Request
adds a variable to huds containing all screen objects that should be
permanently there
fov stuff goes there now rather than not being kept on the screen at all
therefore fov no longer disappears
## Why It's Good For The Game
i must torture lemon.
## Changelog
🆑
fix: fixes fov removal f12 exploit
/🆑
## About The Pull Request
[Adds support for pulling z offset context from an atom's
plane](9f215c5316)
This is needed to fix paper bins, since the object we plane set there
isn't actually on a z level.
Useful elsewhere too!
[Fixes compiler errors that came from asserting that plane spokesmen had
a plane
var](b830002443)
[Ensures lighting backdrops ALWAYS exist for each lighting
plane.](0e931169f7)
They can't float becuase we can see more then one plane at once yaknow?
[Fixes parallax going to shit if a mob moved zs without having a
client](244b2b25ba)
Issue lies with how is_outside_bounds just blocked any plane readding
It's possible for a client to not be connected during z moves, so we
need to account for them rejoining in show_to, instead of just blocking
any of our edge cases.
Fixing this involved having parallax override blocks for show_plane and
anything with the right critical flags ensuring mobs have JUST the right
PMs and relays.
It's duped logic but I'm unsure of how else to handle it and frankly
this stuff is just kinda depressing.
Might refactor later
[show_to can be called twice successfully with no hide_from
call.](092581a5c0)
Ensures no runtimes off the registers from this
## Why It's Good For The Game
Fixes#72543
Fixes lighting looking batshit on multiz. None reported this I cry into
the night.
## Changelog
🆑
fix: Fixes parallax showing up ABOVE the game if you moved z levels
while disconnected
/🆑
---------
Co-authored-by: Time-Green <timkoster1@hotmail.com>
<!-- 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
Adds support to underlays to realize_overlays
Ensures decals properly handle plane offsets
Fixes space lighting double applying if it's changeturf'd into. this
will be important later
Makes solar vis_contents block emissives as expected
Moves transit tube overlays to update_overlays, adds emissive blockers
to them
#### Adds render steps
An expansion on render_target based emissive blockers.
They allow us to hijack an object's appearance and draw it somewhere
else, or even modify it, THEN draw it somewhere else.
They chain quite nicely
Fixes shuttles deleting z holder objects
#### Makes space emissive, makes walls and floors block emissives
The core idea here goes like this:
We make space glow, and give its overlays some color
This way, the tile and space parallax remain fullbright, along with
anything that doesn't block emissives, but anything that does block
emissives will instead get shaded the color of starlight
This requires a bit of extra work, see later
This is done automatically with render relays, which now support
specifiying layer and color (Need to make an editor for these one of
these days)
The emissive blocking floor stuff requires making a second render plate
to prevent double scaling
Also adds some new layering defines for lighting, and ensures all turf
lights have a layer. We'll get to this soon
#### Makes things in space blue
We color them the same as starlight, by taking advantage of space being
emissive
This means that things in space that block emissive will block it
correctly and be colored blue by the light overlay, but space itself
will remain fullbright
This does require redefining what always_lit means, but nothing but
cordons use that so it's fineee
#### Makes glass above space glow, and some other stuff
Glass tiles that sit above space will now shine light with matching
color to the glasses color. This includes mat tiles.
Glass tiles (not mat because they have no alpha) also only partially
block emissives.
Adds a new proc that uses render steps to acomplish this, essentially
we're cutting out bits below X alpha and drawing what remains as an
emissive.
#### Modifies partial space showing to support glow
Essentially, alongside displaying space as an underlay, we also display
a light overlay colored like starlight.
That starlight overlay gets masked to only be visible in bits that do
not contain any alpha.
We also mask the turf lighting to not go into bits that have no alpha,
to ensure we get the effect we want.
This is done with that lighting layer thing I mentioned earlier.
#### Makes appearance realization's list output ordered
I want it output in order of overlay, sub overlay suboverlay, next
overlay
Need to use insert for that
## Why It's Good For The Game
Pretty!
Also having space be emissive is a very very good way to test for fucked
emissive blockers (If it's broken why are we even drawing the overlay)
I know for a fact mob blockers on lizards and socks are kinda yorked, I
think there's more
<details>
<summary>
Old
</summary>



</details>
<details>
<summary>
New
</summary>



</details>
## 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. -->
🆑
add: Space now makes things in it starlight faintly blue
fix: Glass floors that display space now properly let space shine
through them, rather then hiding it in the dark
add: Glass floors above space now glow faintly depending on their glass
type
/🆑
<!-- 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. -->
---------
Co-authored-by: Zephyr <12817816+ZephyrTFA@users.noreply.github.com>