## About The Pull Request
Empy lists. There are a lot of 'em.
<img width="981" height="512" alt="image"
src="https://github.com/user-attachments/assets/b94b041a-2904-466b-ab89-54bd1de11b4e"
/>
Going through ways to reduce memory I found a few easy ones here. Wires,
the edible component, the seethrough component. None of these are really
a concern when it comes to needing lists in memory for performance
reasons. Wires aren't going to be cut most of the time for each door. A
lot of food does not have any junkiness. Seethrough component lies
dormant most of the round. Etc.
Making lists lazy in these cases should be a no brainer.
Everything I tested still seems to work exactly the same.
## Why It's Good For The Game
Frees memory that is just taking up space a lot of the time.
## Changelog
Not player-facing, this is all under-the-hood stuff.
## About The Pull Request
Moves a lot of the unique renaming implementations described in #82664
to the functions given by the `obj_flag` `UNIQUE_RENAME`.
`UNIQUE_RENAME` has been given new properties to account for
non-standard renaming, these being the `RENAME_NO_DESC` flag that
prevents changing the description, the `nameformat()` and `descformat()`
procs that, when modified, allow for applying naming formats(i.e. "Body
Bag - [input]"), as well as other post-renaming handling such as
changing the name of the output plant of a renamed seed, the
`rename_checks()` proc that allows for unique naming prevention(such as
a locked personal closet), and the `rename_reset()` proc to clean up
other possible renamed variables potentially changed in `nameformat()`
and `descformat()`.
This also adds `/datum/element/tool_renaming` to crayons, which will let
them rename anything that has `UNIQUE_RENAME`. I looked through
everything with that flag, and I didn't see anything that I don't think
should be renameable by a crayon(except things that shouldn't be
renamable with pens), so it shouldn't fuck anything up.
## Why It's Good For The Game
moves all of the non-honorable mentions in #82664 to the same renaming
system, and also moves all of the honorable mentions save for:
- plaques, as they only get renamed once and wouldn't benefit from
`UNIQUE_RENAME` imo
- books, because they're far more than just renaming, and are persistent
- paintings, because they're persistent
- photos, because they're not normal renaming and they're persistent
- endoskeletons, because they're done with a multitool in UI
- cardboard IDs, because they're far more than just renaming
Additionally, this fixes:
- Implanter renaming didn't work because a ! was missing
- Clown borg picket sign renaming didn't work because they didn't use
the correct arguments
This'll make it easier to make renameable objects in the future, as
well.
## Changelog
🆑
fix: fixes implanter renaming not working
fix: fixes clownborg picket sign renaming not working
code: brought most unique renaming implementations under UNIQUE_RENAME
/🆑
## About The Pull Request
Converts the following:
- Medical Kiosk
- Implant case
- Flamethrower
- Chemical implant case
- Pappercutter
Also I've looked at some alt click procs and adjusted some of their
returns
## About The Pull Request
Drawing an outline of someone now makes a proper outline of them, rather
than a decal that faces their direction
<img width="401" height="446" alt="image"
src="https://github.com/user-attachments/assets/4402e66a-2f77-4e45-95dd-1570a449ccd3"
/>
You can also use crayons to draw outlines now, but they won't be as
strong visually
<img width="138" height="143" alt="image"
src="https://github.com/user-attachments/assets/91f2fda8-cd84-46c3-bee9-b9f16efeb975"
/>
This unfortunately uses GFI, I've messed around with it a bit and
couldn't find a good alternative that would work with humans. If there's
anything better please lmk.
## Why It's Good For The Game
Been enjoying some Detective gameplay and thought it would be cool to
make proper outlines of corpses to better visualize the crime scene
rather than use what looks like graffiti.
## Changelog
🆑
qol: You can use crayons to make chalk outlines, not just white ones.
qol: Chalk outlines are now properly outlines of the body you're
outlining.
/🆑
## About The Pull Request
Alleviates #91603
As in it does not fix it because i have not been able to reproduce it.
It now checks for invalid values and defaults to `amount`(which is 1)
during `Initialize()` and not null so we don't have to pass the number
`1` when creating a single sheet.
A stack trace is thrown for <= 0 sheet amounts so we can debug & fix
stuff
## Changelog
🆑
code: stacks error on invalid amounts, removed manual passing of number
`1` when creating a single stack in many cases
/🆑
## About The Pull Request
Fixes#89445 (well, technically. It fixes the bug associated but these
`say`s should really be emotes.)
Three things:
1. Reworks how language translation works.
Rather than scrambling a sentence into a language entirely, sentences
are now scrambled on a per-word basis.
Additionally, the 1000 most common words of a language are *never*
re-scrambled across the duration of a round. Once it's set it's set in
stone.
Example: (Sample / Old / New)

This allows for a number of things:
- More consistent translations, making it (more) viable to actually
"teach" someone words for something
- Maintaining emphasis such as caps (but not `||`, `++`, or `__` - at
least not yet)
- The following:
2. Adds partial language understanding
Some languages can understand portions of other languages.

This pr adds the following:
- Those who understand Beachtongue can understand 50% of Common and 33%
of Uncommon words.
- Those who understand Common can understand 33% of Beachtongue and 20%
of Uncommon words.
- Those who understand Uncommon can understand 20% of Common and 20% of
Beachtongue words.
3. Bilingual quirk has been expanded to accomodate these changes.
There are now two more preferences:
- Language Speakable
- You can toggle this, so you only understand the language, rather than
understand AND speak.
- Language Skill
- If you choose to be unable to speak the language, you can set how much
of the language you can understand, down to 10%.
## Why It's Good For The Game
Playing around languages is fun, but due to the way our translation
works, ALL context is immediately lost for what the other person may be
saying.
If the other person is shouting in all caps? Output language is normal
chatting. This is lame!
Even if someone is unable to understand you, there's a LOT you can
convey just by how you speak, and getting that across in game is quite
difficult when all translations get mauled so badly.
So this changes that.
- Emphasis like caps lock is maintained, so you see someone shouting in
caps in a foreign language you can probably intuit something is wrong
(but not what is wrong!)
- Some languages can gleam bits of other languages, so you MIGHT be able
to pick out context if you pay close attention
- "Brother" languages will now feel more like "brothers" and not
completely divergent
- You can even "teach" someone words in your language - at least the
most common words! (Until next round)
## Changelog
🆑 Melbert
add: Languages can now have partial understanding of other languages.
More common English words are more likely to be mutually understood.
add: Those who understand Beachtongue can understand 50% of Common and
33% of Uncommon words.
add: Those who understand Common can understand 33% of Beachtongue and
20% of Uncommon words.
add: Those who understand Uncommon can understand 20% of Common and 20%
of Beachtongue words.
add: Bilingual quirk: You can now choose between being able to speak or
not speak the language
add: Bilingual quirk: You can now choose to have partial understanding
of your language, rather than full.
qol: If you speak in ALL CAPS in a foreign language, the translated
words will also be ALL CAPS.
qol: Many more forms of punctuation are now conveyed across
translations.
qol: The 1000 most common English words will now never be scrambled when
translating into other languages for the duration of the round. This
means you can actually "learn" some words if you are especially
attentive! (Until the next round at least)
refactor: Refactored language translations. Report if you see any super
odd looking translations.
fix: Force-says forcing you to speak common (such as cult invocations)
will now correctly force you to speak common (even if you don't know
common)
/🆑
## About The Pull Request
Reverts the storage initialization refactor and all subsequent related
PRs.
The original PR is below our standards both for code quality and
testing, and is majorly flawed at its core. This has been discussed with
other maintainers and headcoder(s?) over on discord. A lot of changes
from the PR could be brought over later, but in its current state it
should not have been merged.
- Closes#90322
- Closes#90313
- Closes#90315
- Closes#90320
- Closes#90312
- Closes#90344
## Why It's Good For The Game
This PR causes a series of major issues which cannot be resolved without
either completely rewriting a lot of the original PR, or bad code.
Not matching our standards is grounds for not merging a PR, and the fact
that a PR should not have been merged is a reason for a revert.
## Changelog
🆑
fix: Fixed a series of storage-related bugs caused by a refactor PR.
/🆑
## About The Pull Request
A Huge chunk of changes just comes from moving existing storage code
into new files & seperating `atom_storage` code into its own subtype
under the already existing `storage/subtypes` folder.
With that the changes in this PR can be organized into 3 categories.
**1. Refactors how `/obj/item/storage/PopulateContents()` initializes
storages**
- Fixes#88747 and every other storage item that has a similar variant
of this problem
The problem with `PopulateContents()` is that it allows you to create
atoms directly inside the storage via `new(src)` thus bypassing all the
access restrictions enforced by `/datum/storage/can_insert()` resulting
in storages holding stuff they shouldn't be able to hold.
Now how this proc works has been changed. It must now only return a list
of items(each item in the list can either be a typepath or a solid atom
or a mix of them in any order) that should be inserted into the storage.
Each item is then passed into `can_insert()` to check if it can fit in
the storage.
If your list contains solid atoms they must be first moved
to/Initialized in nullspace so `can_insert()` won't count it as already
inserted. `can_insert()` has now also been refactored to throw stack
traces but explaining exactly why the item could not fit in the storage
thus giving you more debugging details to fix your stuff.
A large majority of changes is refactoring `PopulateContents()` to
return a list instead of simply creating the item in place so simple 1
line changes & with that we have fixed all broken storages(medical
toolbox. electrical toolbox, cruisader armor boxes & many more) that
hold more items they can handle
**2. Organizes initialization of `atom_storage` for storage subtypes.**
All subtypes of `/obj/item/storage` should(not enforced) create their
own `/datum/storage/` subtype under the folder `storage/subtypes` if the
default values are not sufficient. This is the 2nd change done across
all existing storages
Not only does this bring code cleanliness & organization (separating
storage code from item code like how `/datum/wire` code is separated
into its own sub folder) but it also makes storage initialization
slightly faster (because you are not modifying default values after
`atom_storage` is initialized but you are directly setting the default
value in place).
You now cannot & should not modify `atom_storage` values inside
`PopulateContents()`. This will make that proc as pure as possible so
less side effects. Of course this principle is not enforced and you can
still modify the storage value after `Initialize()` but this should not
be encouraged in the future
**3. Adds support for automatic storage computations**
Most people don't understand how `atom_storage` values work. The comment
here clearly states that
https://github.com/tgstation/tgstation/blob/55bbfef0da70d87455ca8d6fd5c95107eb8dbefb/code/game/objects/items/storage/toolbox.dm#L327-L329
Because of that the linked issue occurs not just for medical toolbox but
for a lot of other items as well.
Which is why if you do not know what you doing, `PopulateContents()` now
comes with a new storage parameter i.e. `/datum/storage_config`
This datum allows you to compute storage values that will perfectly fit
with the initial contents of your storage. It allows you to do stuff
like computing `max_slots`, `max_item_weight`, `max_total_weight` etc
based on your storage initial contents so that all the contents can fit
perfectly leaving no space for excess.
## Changelog
🆑
fix: storages are no longer initialized with items that can't be put
back in after taking them out
refactor: storage initialization has been refactored. Please report bugs
on github
/🆑
## About The Pull Request
The edible component now uses DUPE_SOURCE mode, which is needed to avoid
conflicts between sources. This includes some other tidbits from my
refactor like renaming dcs/flags.dm to ds/declarations.dm (in virtue of
the fact it doesn't only contain flags anymore even before this PR),
meat materials giving protein and fat reagents to affected atoms instead
of generic nutriment and oil, and the pizza material no longer
containing meat, because margherita pizza, which the material is
extracted from, doesn't contain meat either. The pepperonis were
magically conjured space bs.
## Why It's Good For The Game
There are multiple sources of the edible component and we don't want
issues with that. Also atomizing stuff from my refactor.
## Changelog
🆑
balance: objects made out of meat are no longer classified as gross food
on top of being raw and meaty, and actually contain protein and fat
instead of standard nutriment and oil.
balance: the pizza material stacks, crafted with margherita pizza and
rollig pin mind you, no longer magically contain pepperoni.
/🆑
## About The Pull Request
Right now people can use crayons and spraycans to write messages on the
floor to communicate while being illiterate. While this is kinda funny,
it does defeat the purpose of this quirk which is to disable nonverbal
communication methods.
## Why It's Good For The Game
Consistency.
## Changelog
🆑
fix: Fix illiterate people writing messages with crayons and spraycans.
/🆑
## About The Pull Request
#87102 introduced a new clothing dirt component, which increases tint
when you get spraypainted. This PR expands it to work when you are
spraypainted and applies it to space helmets, gas masks and rad/bomb/bio
helmets, and gives all items a fancy overlay when
spraypainted/peppersprayed.


Spraypainting a person wearing an item with this component randomly
applies 2-3 levels of tint, potentially blinding them until they wash
their helmet or mask.
Additionally, driscoll mask has lost its eye covering, and welding gas
mask gained it - doesn't make sense for former to have it, and for
latter to be missing it.
## Why It's Good For The Game
Bomb suits and bio hoods are already extremely weak, while rad suits are
super situational when there are MODsuits with none of the downsides. 90
degree FOV is extremely punishing and makes them essentially unusable.
Space helmet slowdown was added because they gave pepperspray protection
with no downside, which this PR brings, so there's no reason to keep it
around considering how bad slowdown feels in our game.
Also spraypainting someone's visor is just extremely funny to me.
## Changelog
🆑
balance: Space helmets and bio/bomb/rad hoods have lost their
slowdown/FOV respectively, but now can have their visor covered by
spraypaint or pepper spray.
balance: Driscoll mask no longer protects your eyes, unlike welding gas
mask which received said protection.
/🆑
## About The Pull Request
Commit messages should be descriptive of all changes.
The "incorrect `\The` macro capitalization" was intentional when it was
added, but as far as I know TG says "the supermatter" rather than "The
Supermatter," so it's incorrect now.
This is completely untested. I don't even know how you'd go about
testing this, it's just a fuckton of strings.
Someday I want to extract them and run NLP on it to catch grammar
problems...
## Why It's Good For The Game
Basic grammar pass for name strings. Should make `\the` work better and
avoid cases like `the John Smith`.
## About The Pull Request
Colorful reagent (and thus, crayon powders) now color your clothing,
bodyparts (except for crayon powder), hair and organs when you're
exposed to it via smoke, foam or splashed with them. Bodyparts and
organs now change their visuals according to their atom color. Due to
this, going under a shower washes your bodyparts and washing your face
washes your eyeballs (pretty cursed).
After 30 ticks, coloring on your organs becomes permanent so be careful
with crayon smoke bombs!
Additionally, moved spraycan painting for robotic limbs to left click
(since LMB mode does not affect them visually anyways due to their
paleness).
## Why It's Good For The Game
While HUDs no longer get colored with their owner, it still feels odd to
have your clothes get colored with you when you get sprayed with
colorful reagent. This remedies this issue, as your and your clothes'
coloration are now separate.
## Changelog
🆑
add: Changed how colorful reagent and crayon powder work: douse your
victims to color their clothing, bodyparts and even internal organs!
add: You can wash your eyes when washing your face at a sink
fix: You can color robotic limbs with left click (again)
/🆑
## About The Pull Request
"If GAGS is such a good system, why isn't there GAGS 2?" - Sun Tzu
GAGS is very neat but it has one glaring issue: it needs sprites to be
greyscaled in advance to be used. On the other hand we have color
matrices, but they're hard to use and even harder to get good results
from. The logical solution grew out of a discord argument about colors
this morning after @LemonInTheDark decided to toy around with HSL
matrices using filters on live servers.
This PR implements Color Transition Filters as an additional option for
atom colors - passing a transition filter matrix into
``add_atom_colour`` will "recolor" the atom into the passed color by
using an HSL filter (since color only supports RGB values and matrices).
Normal color matrices are now also supported in atom colors, in case
anyone needs to use them there. ``color_transition_filter`` has 2 modes:
``SATURATION_MULTIPLY`` which only changes the hue and shifts saturation
of the original icon, and ``SATURATION_OVERRIDE`` which changes
saturation and light values to more correctly fit the passed color.
Multiply mode does a far better job at recoloring clothing or objects
with obvious highlights, but fails to color pale or white objects, while
Override mode is closer to what we have right now (just doesn't produce
rancid blobs of color nearly as much)
Here are some examples of colored clothes, mechs, items and tiles using
the new system.
Green RD? Sure.

Atmos MODsuit colored with a speed potion

Why override mode exists in the first place

Aftermath of a colorful reagent grenade.

As you can see, the colors are far brighter and significantly less
acidic, since they're no longer just used as multipliers for existing
colors but instead shift the palette of the sprite towards themselves.
In order to bypass the main downside of "default" Multiply mode,
spraycans have received a new right click function "coat with paint",
which will color the item using the Override mode. Left Click mode lost
its coloring restrictions (RMB still has them), and color
sampling/prosthetic recoloring has been moved to Ctrl Click instead.
Here's the full list of all systems/items that now use color transition
filters:
* Drying items
* Deep frying items
* Slime blueprints/potions/coloring crossbreeds
* Colorful reagent
* Spraycans
* Paint buckets
## Why It's Good For The Game
Our coloring system is ***really*** bad, to the point where we're
preventing players from using any dark colors because item icons become
unintelligible when colored into them.
## Changelog
🆑 SmArtKar, LemonInTheDark
add: Changed how spraycans color items - "old" mode is still availible
via right click.
refactor: Refactored how some items and effects color things so that
they look prettier.
/🆑
## About The Pull Request
This PR adds a single spraycan to every roboticist office, and a
screentip that should tell the player that they can restyle augments
with it, should they hover over one. This spraycan has a new sprite,
which is a small edit of the existing spray can, just wearing the
colours of the roboticist jumpsuit. The can's description also mentions
restyling robotic limbs.

This PR also fixes a bug: Peg limbs also brought up the restyling menu,
albeit, every radial button was empty, and clicking on one runtimes. Now
you can no longer do such a thing.
Future improvement: perhaps making augment restyling cheaper would be
nice, but I did not want to add that into this PR.
## Why It's Good For The Game
This is a rarely used feature, some folks thought it has been removed
when the augment painter has been removed from the game. Putting it in
front of the players will make it used more often, and might result in
new augment styles.
## Changelog
🆑
add: Adds a roboticist spraycan, and adds one of them to robotics on
every map
qol: adds a screentip to spraycans that tells you that it can restyle
robotic limbs
fix: fixes peg legs bringing up the augment restyle menu
/🆑
## About The Pull Request
All usages of world.icon_size in code have been replaced with new
`ICONSIZE_X`, `ICONSIZE_Y` and `ICONSIZE_ALL` defines depending on
context
Replaces some "32" magic numbers with the defines
A few bits of code have been modified to split up x/y math as well
## Why It's Good For The Game
Magic number bad, code more readable, code more flexible and I'm told
there's an access cost to doing world.icon_size so minor performance
gains
## Changelog
🆑 tonty
code: made some code relating to the world's icon size more readable
/🆑
---------
Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
Fixes#86784
## About The Pull Request
Although some of the issues found were a direct result from #86692
(c698196766), there was still 40% of
length-related issues that wouldn't be covered anyways that are fixed in
this PR. I.E.:
* Name inputs without `MAX_NAME_LEN`
* Desc inputs without `MAX_DESC_LEN`
* Plaque inputs without `MAX_PLAQUE_LEN`
* Some people just screwed up the arguments so it would prefill
something like "40" in the `default` var because they didn't name their
vars.
To help me audit I added a lot of `max_length` named arguments to help
people understand it better. I think it might be kinder to have a
wrapper that handles adding `MAX_MESSAGE_LEN` in a lot of these cases
but I think there is some reason for a coder to be cognitive about input
texts? Let me know what you think. I didn't update anything
admin-related from what I can recall, let me know if anything needs to
be unlimited again.
## Why It's Good For The Game
The change to `INFINITY` notwithstanding, there were still an abundance
of issues that we needed to check up on. A lot of these are filtered on
down the line but it is clear that there needs to be something to catch
these issues. Maybe we could lint to make `max_length` a mandatory
argument? I don't know if that's necessary at all but I think that the
limit should be set by the invoker due to the wide arrangement of cases
that this proc could be used in.
This could all be a big nothingburger if the aforementioned PR is
reverted but a big chunk of cases fixed in this PR need to be fixed
regardless of that since people could put in 1024 character names for
stuff like guardians (or more now with the change). Consider this
"revert agnostic".
## Changelog
🆑
fix: A lot of instances where you could fill in 1024-character names
(normal limit is 42) have been patched out, along with too-long plaque
names, too-long descriptions, and more.
/🆑
Because the wings were in fact made of wax
## About The Pull Request
Storage goes to the very bottom of the interaction chain, hardcoded in
on `/atom`.
This is not preferred, obviously, but it ends up being a lot less
snowflaking overall.
Tables also go at the very bottom by extending `base_item_interaction`.
Fixes#83742Fixes#84434Fixes#83982Fixes#85516Fixes#84990Fixes#84890Closes#85036Closes#84025 (RMB places it on the table.)
Closes#86616
Other changes:
Refactored pod storage to be less jank. Patches some exploits around it.
## Why It's Good For The Game
Should make a lot more interactions a lot more reliable... hopefully
## Changelog
🆑 Melbert
refactor: Storage and Tables are now a lower priority action, meaning
some uses of items on storage should work... better, now. Here's hoping
at least, report any oddities.
refactor: Note: For an overwhelming majority of items, **combat mode**
will attempt to attack/insert into the target, while **non-combat-mode**
will attempt to use on a target. This means screwdrivering or emagging a
MODsuit must be done on non-combat-mode, as combat mode will simply put
the screwdriver or emag into its storage. Same applies to tables, though
when in doubt, RMB may help (for things which are also weapons, like
mops).
refactor: Refactored escape pod storage, now they actually properly show
as unlocked on red alert and above.
/🆑
## About The Pull Request
Closes#86567
Don't think any of these were found/reported or actually could trigger
in-game
## Why It's Good For The Game
Glory to OpenDream
## Changelog
🆑
code: Fixed multiple minor logic issues with code found by OpenDream's
new pragma
/🆑
## About The Pull Request
Creamed component has been refactored into a more generic face_decal
component, with pie-unique logic moved to a subtype instead.
Spraypainting someone in the face now uses the new component instead of
modifying their... lipstick.
Closes#83614 by adding monkey and lizard spraypaint sprites, just like
with creampies
Fixes an issue with spraypaint overlay being removed when something is
covering your hair due to how lipstick and beards are rendered.
## Why It's Good For The Game
Easier to use, could be used for more cases.
## Changelog
🆑
refactor: Refactored creampies and spray paint to use the same
component.
sprites: Monkeys and lizards now have their own face spraypaint overlays
/🆑
## About The Pull Request
Currently to check for Silicon access, we do:
``if is silicon or is admin ghost or has unlimited silicon privileges or
has machine remote in hand``
What has unlimited silicon privileges? Bots, Drones, and admin ghosts.
To check for AI access, it just checks for AI instead of silicon, and
doesnt check for unlimited silicon privileges.
This was kinda silly, so I thought I should make this a little easier to
understand.
Now all silicon/ai traits come from ``AI_ACCESS_TRAIT`` or
``SILICON_ACCESS_TRAIT``. I made a single exception to keep Admin ghost,
since now instead of being a var on the client, we moved it to using the
same trait but giving it to the client instead, but since we have to
keep parity with previous functionality (admins can spawn in and not
have this on, it only works while as a ghost), I kept previous checks as
well.
No more type checks, removes a silly var on the mob level and another on
the client.
Now while I was doing this, I found a lot of tgui's ``ui_act`` still
uses ``usr`` and the wrong args, so I fixed those wherever I saw them,
and used a mass replace for the args.
Other changes:
- machinery's ``ui_act`` from
https://github.com/tgstation/tgstation/pull/81250 had ``isAI`` replaced
with ``HAS_AI_ACCESS``, this has been reverted. Machine wands and admin
ghosts no longer get kicked off things not on cameras. This was my
fault, I overlooked this when adding Human AI.
- Human AI's wand gives AI control as long as it's in your hand, you can
swap to your offhand. I hope this doesn't end up going horribly,
otherwise I'll revert this part. It should let human AIs not have their
UI closed on them when swapping to eat food or use their door wand or
whatnot.
- Bots previously had special checks to scan reagents and be
unobservant, I replaced this with giving them the trait. I also fixed an
instance of unobservant not being used, so now statues don't affect the
basic creature, whatever that is.
## Why It's Good For The Game
This is an easier to understand way of handling silicon access and makes
these mobs more consistent between eachother.
Other than what I've mentioned above, this should have no impact on
gameplay itself.
## Changelog
🆑
fix: Statues don't count as eyes to creatures.
fix: Human AIs and Admin ghosts no longer get kicked off of machines
that aren't on cameranets.
/🆑
## About The Pull Request

*The Miami Mutilator is at large once again. Thank god we have such
hardboiled detectives as Manny Pardo on the case.*
This pull request allows for players to use white crayons, which have
now been renamed to sticks of chalk, to generate outlines of dead or
"dead" bodies found throughout the station in an attempt to let
detectives actually set up crime scenes as opposed to, more typically,
just causing them.
Players will attempt to draw a chalk outline if the target is a mob and
the mob is dead (or fake-dead), using a single charge of the
crayon/chalk. Also, adds a quick macro so that we can get the proper
left/right orientation of the dead mob for reference.
## Why It's Good For The Game
Detective should have more thematic, simple ways to organize crime
scenes in-round, and what better way to do that then through existing
items and mechanics that we already have. Also, I was 100% shocked to
learn that these have always been white crayons as opposed to sticks of
chalk, which certainly seems odd. In essence, this change doesn't really
let you do anything "new", but just makes it easier and simpler to do so
in a regular round without nearly as much fiddling.
This mechanic exists exclusively within the afterattack of sticks of
chalk as opposed to all crayons for thematic reasons, but I'm not 100%
sold on that and it would be simple to move over to all crayons if
people feel strongly about that.
## Changelog
🆑
add: White crayons (Renamed to Sticks of Chalk) may now be used on dead
bodies to draw a body outline onto the ground easily.
/🆑
---------
Co-authored-by: Zephyr <12817816+ZephyrTFA@users.noreply.github.com>
## About The Pull Request
Found by Melbert on discord, caused by paint mode not applying when
painting random decals.
## Changelog
🆑
fix: Random spraypaint setting now properly paints large decals
/🆑
## About The Pull Request
It was only checking for eye protection, since light-sensitives can have
0 or less eye protection even with sunglasses on, this doesn't make
sense.
There is now more redundancy, the same check for blind carbons and
another check for `is_eyes_covered` which takes in account if your eyes
are covered by eyewear or masks.
## Changelog
🆑
fix: spray can face spraying will no longer work on light-sensitives
with eyewear and people wearing eye covering masks
/🆑
## About The Pull Request
Converts slapcrafting into a bespoke element, used to be ac omponent
## Why It's Good For The Game
Noticed this was a big C and realized there was no real reason for that.
It's the same recipe shared across different items.
## Changelog
N/A
---------
Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
## About The Pull Request
I did an oopsie and forgot that spraycans would inherit can_use_on of
crayons. This should add all valid spraycan uses back.
## Why It's Good For The Game
Closes#84333
## About The Pull Request
Crayons always returned ITEM_INTERACT_BLOCKING from their
interact_with_atom, now only doing so when targeting a valid object.
This should allow them to be used on objects once more.
## Why It's Good For The Game
Closes#84229
## About The Pull Request
- Afterattack is a very simple proc now: All it does is this, and all
it's used for is for having a convenient place to put effects an item
does after a successful attack (IE, the attack was not blocked)

- An overwhelming majority of afterattack implementations have been
moved to `interact_with_atom` or the new `ranged_interact_with_atom`
I have manually tested many of the refactored procs but there was 200+
so it's kinda hard
## Why It's Good For The Game
Afterattack is one of the worst parts of the attack chain, as it
simultaneously serves as a way of doing random interactions NOT AT ALL
related to attacks (despite the name) while ALSO serving as the defacto
way to do a ranged interaction with an item
This means careless coders (most of them) may throw stuff in afterattack
without realizing how wide reaching it is, which causes bugs. By making
two well defined, separate procs for handing adjacent vs ranged
interactions, it becomes WAY WAY WAY more easy to develop for.
If you want to do something when you click on something else and you're
adjacent, use `interact_with_atom`
If you want to do something when you click on something else and you're
not adjacent, use 'ranged_interact_with_atom`
This does result in some instances of boilerplate as shown here:

But I think it's acceptable, feel free to oppose if you don't I'm sure
we can think of another solution
~~Additionally it makes it easier to implement swing combat. That's a
bonus I guess~~
## Changelog
🆑 Melbert
refactor: Over 200 item interactions have been refactored to use a
newer, easier-to-use system. Report any oddities with using items on
other objects you may see (such as surgery, reagent containers like cups
and spray bottles, or construction devices), especially using something
at range (such as guns or chisels)
refactor: Item-On-Modsuit interactions have changed slightly. While on
combat mode, you will attempt to "use" the item on the suit instead of
inserting it into the suit's storage. This means being on combat mode
while the suit's panel is open will block you from inserting items
entirely via click (but other methods such as hotkey, clicking on the
storage boxes, and mousedrop will still work).
refactor: The detective's scanner will now be inserted into storage
items if clicked normally, and will scan the storage item if on combat
mode
/🆑
## About The Pull Request
Adds a missing flag that was causing the chat to be spammed when you
were too far away from the spraycan.
## Why It's Good For The Game
Bugfix
closes: https://github.com/tgstation/tgstation/issues/80880
## Changelog
🆑
fix: Spraycan no longer spams your chat when you mouse over it.
/🆑
---------
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
## About The Pull Request
Allows you to alt-click a bunch of items while resting.
Fixes#82788
## Why It's Good For The Game
Some of these, such as storage, are bugfixes. You shouldn't need to be
standing up to configure a spray can, or change the direction of your
bedsheet
Others are just sensible changes.
## Changelog
🆑 Melbert
fix: You can open bags with alt click while resting again
qol: Many items which previously required you to stand to alt-click now
don't, such as bedsheets and spray cans
/🆑
## About The Pull Request
Rewrites how alt click works.
Based heavily on #82625. What a cool concept, it flows nicely with
#82533.
Fixes#81242
(tm bugs fixed)
Fixes#82668
<details><summary>More info for devs</summary>
Handy regex used for alt click s&r:
`AltClick\((.*).*\)(\n\t.*\.\.\(\))?`
`click_alt($1)` (yes I am aware this only copies the first arg. there
are no other args!)
### Obj reskins
No reason for obj reskin to check on every single alt click for every
object. It applies to only a few items.
- Moved to obj/item
- Made into signal
- Added screentips
### Ventcrawling
Every single atmospherics machine checked for ventcrawling capability on
alt click despite only 3 objects needing that functionality. This has
been moved down to those individual items.
</details>
## Why It's Good For The Game
For players:
- Alt clicking should work more logically, not causing double actions
like eject disk and open item window
- Added context menus for reskinnable items
- Removed adjacency restriction on loot panel
For devs:
- Makes alt click interactions easier to work with, no more click chain
nonsense and redundant guard clauses.
- OOP hell reduced
- Pascal Case reduced
- Glorious snake case
## Changelog
🆑
add: The lootpanel now works at range.
add: Screentips for reskinnable items.
fix: Alt click interactions have been refactored, which may lead to
unintentional changes to gameplay. Report any issues, please.
/🆑
## About The Pull Request
You can now type up to 4 letters on a tile at once, one for each corner
of the tile, an ability lost when max interactions was added.

## Why It's Good For The Game
Currently if you're typing on the floor with a crayon, you either spend
a million years going letter by letter, or do the alternative of typing
every second letter to write on 3 tiles at once, and repeat, which is
stupid that we even have to do that.
## Changelog
🆑
qol: Crayons can now draw up to 4 letters at a time per tile.
/🆑
## 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
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
While on the floor, you can:
- Use the UIs of Atmos machinery (except thermomachine and bluespace gas
vendor), Holopads, Crayons (spray cans too), radios, and Disposal bins
- Close extinguisher cabinets with Right-Click
- Click and drag yourself onto a photocopier to climb onto it.
I also changed all instances of ``ui_status`` to have all the args it's
being passed, I was messing with it a bit but it's gonna be for a later
PR.
## Why It's Good For The Game
It's an extra layer of harmless realism, also nice QoL for people who do
not have functional legs and do not have a wheelchair.
## Changelog
🆑
qol: You can use atmos machines, holopads, crayons, spray cans, and
disposal bins while floored.
fix: You can close extinguisher cabinets while floored.
fix: You can climb onto a photocopier from the floor.
/🆑
## About The Pull Request
- Large amount of storage datum cleanup.
- Documentation.
- Maybe more consistent use of parent vs real_location.
- Removes the weakrefs, replaces it with just references.
- These were already managed references anyways so why bother?
- Removes a bunch of arguments no one used and would ever used so only
the most useful args are left.
- Some bugfixes.
## Why It's Good For The Game
Aiming to make storage easier to work with. The whole intent of this was
to bugfix the whole "weight class" thing that keeps popping up but I had
to do this first.
## Changelog
🆑 Melbert
fix: When placing an item into storage (such as backpacks), all nearby
mobs now get a message, rather than just the first mob.
fix: TGC decks of cards should act a bit less odd when looking inside.
refactor: Refactored a bit of storage, cleaned up a fair bit of its
code. Let me know if you notice anything funky about storage (like
backpacks).
/🆑
## About The Pull Request
This gives the tagger quirk a 50% speed boost when drawing graffiti.
There was also some unused variable intended to make large graffiti more
time consuming that is now fixed.
## Why It's Good For The Game
It'd be nice to be able to spraypaint messages on the floor quicker.
Especially if you are doing a gimmick that requires making a shop sign
using letters.
## Changelog
🆑
add: Add 50% graffiti speed boost to tagger quirk
fix: Fix time duration of large graffiti not applying properly
/🆑
## About The Pull Request
This adds screentips to spraycans for:
- AltClick - toggle cap
- RMB - copy
- LMB - paint
## Why It's Good For The Game
Better UI/UX.
## Changelog
🆑
qol: Add UI screentips to spraycans
/🆑
---------
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
## About The Pull Request
The check for a successful augmented limb repainting was using the proc
incorrectly. Instead of checking for TRUE or FALSE, it tried to see if
the returned value was exactly 5 or not. This PR fixes that.
## Why It's Good For The Game
My augmented arms crave fashion.
Fixes: #77429
## Changelog
🆑
fix: You can once again repaint robotic limbs to use alternate skins
/🆑

## About The Pull Request
Made pipe painter properly paint pipe colors, work on pipe items, and
added the same functionality to regular spraycans.
Spraycans now have the color presets in UI for easier selection of the
valid pipe colors.
## Why It's Good For The Game
Bug fixing is good.
It was weird that spraycans couldn't paint pipes, but some other device
could.
Also custom spraycan color is too clunky, presets are nice for quick
spraycan color selection.
## Changelog
🆑
fix: fixed pipe painter not applying pipe color properly
qol: made spraycans work also as pipe painters
qol: spraycans now have basic color presets for quick selection
/🆑
## About The Pull Request
- Refactored `bullet_act`. Adds `should_call_parent` and refactors
associated children to support that.
- Fixes silicons sparking off when hit by disabler fire.
- Desnowflakes firing range target integrity and cleans up its
bullet-hole code a bit.
- Cleans up changeling tentacle code a fair bit and fixes it not taking
off throw mode if you fail to catch something.
- The Sleeping Carp deflection is now signalized
- Nightmare projectile dodging is now signalized and sourced from the
Nightmare's brain rather than species
- Refactored how cardboard cutouts get knocked over to be less
snowflaked / use integrity
- Also adds projectile `on_hit` `should_call_parent` and cleans up a bit
of that, particularly their arguments.
- On hit arguments were passed wrong this entire time, it's a good thing
nothing relied on that.
## Why It's Good For The Game
This is cringe.
https://github.com/tgstation/tgstation/blob/1863eb2cd82e7cee4fdfff37b42d3fd0c7edd797/code/modules/mob/living/carbon/human/_species.dm#L1430-L1442
Bullets should overall act more consistent across mob types and objects.
## Changelog
🆑 Melbert
fix: Silicons don't spark when shot by disablers
fix: Changelings who fail to catch something with a tencacle will have
throw mode disabled automatically
fix: Fixes occasions where you can reflect with Sleeping Carp when you
shouldn't be able to
fix: Fixes some projectiles causing like 20x less eye blur than they
should be
refactor: Refactored bullet-mob interactions
refactor: Nightmare "shadow dodge" projectile ability is now sourced
from their brain
/🆑
## About The Pull Request
Converts slapcrafting into a component!
The component is added on to an ingredient (presumably the main
ingredient) with a list of recipes attached. If you interact an
ingredient (if no ignredients, a tool) with it, you will start crafting
the recipe. If there's multiple, pick between them with a radial menu.
Opening on draft as there's just a liiiiil bit left to do. The actual
wired rod was left for last.
## Why It's Good For The Game
Slapcrafting is simply better and more accessible and less laggy than
menu crafting. By making it a component we can attach it to things in
which it'd make sense to while stopping unintended weirdness that might
arise from this being global.
Additionally the way examine lets you see crafting recipes opens up
visibility for those, which allows new players to learn about them in a
intuitive manner.
## Changelog
🆑
refactor: Turned slapcrafting into a component! You can examine
compatible items to see what recipes they can be used in, and what the
ingredients for them are. For example, spears and the head-on-spear
crafting recipe.
/🆑
## About The Pull Request
Transferred.
## Why It's Good For The Game
How did this get to be in 71 files?! This bothers me.
Also changes 'quality_oil' typepath in the reactions to 'olive_oil' to
match its rename post-foodening.
## Changelog
N/A
## About The Pull Request
Syndicate duffelbags can fit 2 extra bulky items, down from three.
Reduced syndicate duffelbag's unzipped slowdown from '1' to '0.3', and
set its zipping-up sped to 0.5, same as unzipping.
Added the following items to the Syndicate Duffelbag bulky exception
list: Greentext, mech removal tool, gibtonite, skub, golem shells, mech
ammo. Roughly sorted the list by item category.
Fixed the syndie surgery duffelbag having more items than it can hold by
removing the redundant surgical drill (Upgraded cauteries can turn into
one anyways)
Any storage item with a can_hold description can be examined twice to
see what it can hold now.
## Why It's Good For The Game
> Syndicate duffelbags can fit 2 extra bulky items, down from three.
> Reduced syndicate duffelbag's unzipped slowdown from '1' to '0.3', and
set its zipping-up sped to 0.5, same as unzipping.
For most intents and purposes, it seems the syndicate duffelbag has gone
from 'bland upgrade to backpack', to 'useless'. This is especially made
apparent because it isn't exactly shown to the player that these
duffelbags can carry bulky items (I didn't even know about it until I
was making this PR!)
The extra bulky item hold concept is great, but I have my issues with
the item as-is that I seek to fix with this PR. There are TONS of issues
with being unable to access your bag quickly, which is twice as relevant
when your bag is an incredibly conspicious traitor item. Sure, you can
have it in your hand, but then why even have it in the first place?
That's why I want to reduce the slowdown significantly. '1' slowdowns
are thrown around the whole game like they're reasonable (galoshes,
water back-tanks, biosuits) - they aren't. '1' slowdown is CRIPPLING. It
makes you frustratingly slow and effectively destroys any combat
maneuvering you can do. This is very relevant for a traitorious item.
The zip speed helps one use the duffelbag as a storage item dynamically,
letting the item be an actual trade-off rather than mostly a downside.
Gives you a reason to use it rather than just buying a smuggler satchel
for more storage.
Of course these are some hefty buffs, so I lowered the bulky storage to
make up for it. I can bring it back up to 3 if wanted.
> Added the following items to the Syndicate Duffelbag bulky exception
list: Greentext, mech removal tool, gibtonite, skub, golem shells, mech
ammo. Roughly sorted the list by item category.
Some traitorious items that felt like they should be allowed in.
Honestly, I think this shouldn't even be an exception hold except for
blacklisting clearly bonkers things like backpacks, but whatevs.
> Any storage item with a can_hold description can be examined twice to
see what it can hold now.
Generalization is awesome. Hardcoding is cringe!
## Changelog
🆑
balance: Syndicate duffelbags can fit 2 extra bulky items, down from
three.
balance: Reduced syndicate duffelbag's unzipped slowdown from '1' to
'0.3', and set its zipping-up sped to 0.5, same as unzipping.
add: Added the following items to the Syndicate Duffelbag bulky
exception list: Greentext, mech removal tool, gibtonite, skub, golem
shells, mech ammo. Roughly sorted the list by item category.
fix: Fixed the syndie surgery duffelbag having more items than it can
hold by removing the redundant surgical drill (Upgraded cauteries can
turn into one anyways)
qol: Any storage item with a can_hold description can be examined twice
to see what it can hold now.
fix: The parent crayon's name is 'crayon' to prevent any weirdness with
things that show the parent type's name.
/🆑
## About The Pull Request
I left `bite_consumption` be `charges / 5` which led to -1 being
depleted on 5 and not giving any reagents on bite.
Also i somehow managed to change the total volume of crayons from 50 to
30 for usual ones and 100 for infinite. I'm a bit confused if number 50
was intended even. I tested it on the older branch and it was 30 and
100, so i dunno.
`override_infinity` is used just so you can't infinitely chew infinite
crayons.
## Why It's Good For The Game
Stuff should work like intended.
## Changelog
🆑
fix: eating mime's and rainbow crayons now properly transfers reagents.
fix: I somehow fixed the amount of reagents in crayons to what it was
before.
/🆑
---------
Co-authored-by: Jacquerel <hnevard@gmail.com>