## About The Pull Request
This PR refactors ``effect_system``s to be a bit easier to use by
getting rid of ``set_up``, allowing ``attach()`` to be chained into
``start()`` and refactoring most direct system usages in our code to use
helper procs.
``set_up`` was unnecessary and only existed to allow ``New``'s behavior
to be fully overriden, which is not required if we split
sparks/lightning/steam into a new ``/datum/effect_system/basic`` subtype
which houses the effect spreading behavior. This allows us to roll all
logic from ``set_up`` into ``New`` and cut down on code complexity.
Chaining setup as ``system.attach(src).start()`` also helps a bit in
case no helper method exists
I've added ``do_chem_smoke`` and ``do_foam`` helpers, which respectively
allow chemical smoke or foam to be spawned easily without having to
manually create effect datums and reagent holders.
Also turns out we've had some nonfunctional effect systems which either
never set themselves up, or never started, so I fixed those while I was
at it (mostly by moving them to aforementioned helper procs)
## Why It's Good For The Game
Cleaner code, makes it significantly easier for users to work with. Also
most of our effect system usage was copypasta which was passing booleans
as numbers, while perfectly fine helper procs existed in our code.
## Changelog
🆑
refactor: Refactored sparks, foam, smoke, and other miscellaneous effect
systems.
refactor: Vapes now have consistent rigging with cigs using the new
system.
fix: Fixed some effects never working.
/🆑
## About The Pull Request
Floppy disks received a sprite upgrade, as well as unique wraps:
<img width="364" height="150" alt="image"
src="https://github.com/user-attachments/assets/0ac433e3-7432-4c06-bec2-aeae00b6852f"
/>
<img width="786" height="527" alt="image"
src="https://github.com/user-attachments/assets/0f36bd0d-0362-4431-8131-49060a2fe348"
/>
You can now stack floppy disks! They also scatter around when thrown.
The video also showcases new styling options with a selection of
stickers! You can also write something on the disk instead of selecting
an icon:
https://github.com/user-attachments/assets/ff0a8542-9d79-4108-ae46-672ca5d620a2
MOST disks now inherit the `/item/disk` type to properly stack and do...
stuff. An updatepaths script included.
## Why It's Good For The Game
Old school is cool. Stacking disks makes them feel more authentic, while
styling allows for more crearivity!
## Changelog
🆑
add: New unique wraps for floppy disks
qol: Floppy disks can now be stacked
image: New sprites and stickers for floppy disks
map: Added and ran an updatepaths script
refactor: Most disks are now under the base disk item type
/🆑
---------
Co-authored-by: The-Tyrant <tyrantofgaming@gmail.com>
## About The Pull Request
This moves Cyborgs onto using storage datums, removing the remenants of
the shitcode that was Cyborg inventory. It's now done mostly by
equipping/unequipping/storage items, much like how other mobs do.
This allows borgs to take advantage of more hand support stuff and
things like ``dropped()``, so borgs no longer have to copy paste drop
code to ``cyborg_unequip``
It also:
- Removes ``CYBORG_ITEM_TRAIT``
- Removes all borg items being ``NODROP``
https://github.com/user-attachments/assets/11442a10-3443-41f2-8c72-b38fb0126cdb
## Why It's Good For The Game
Currently borgs are able to have their entire inventory open and a bag
below it, which I thought was a little weird. I always assumed they WERE
storage items, so I guess I'm doing it myself.
Cyborgs using storage code makes it easier for contributors to actually
do stuff with, without risking breaking everything. It also hopefully
will make borg items more resilient against breaking in the future, now
that we're not relying on nodrop.
Also just brings them more in line with other mobs, all of which make
use of storages.
## Changelog
🆑
refactor: Cyborg's modules now use storage (so opening a bag will close
modules instead of overlap one over the other).
qol: Observers can now see Cyborg's inventories (like they can for
humans).
/🆑
---------
Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
## About The Pull Request
Replaces the asset subsystem's spritesheet generator with a rust-based
implementation (https://github.com/tgstation/rust-g/pull/160).
This is a rough port of
https://github.com/BeeStation/BeeStation-Hornet/pull/10404, but it
includes fixes for some cases I didn't catch that apply on TG.
(FWIW we've been using this system on prod for over a year and
encountered no major issues.)
### TG MAINTAINER NOTE

### Batched Spritesheets
`/datum/asset/spritesheet_batched`: A version of the spritesheet system
that collects a list of `/datum/universal_icon`s and sends them off to
rustg asynchronously, and the generation also runs on another thread, so
the game doesn't block during realize_spritesheet. The rust generation
is about 10x faster when it comes to actual icon generation, but the
biggest perk of the batched spritesheets is the caching system.
This PR notably does not convert a few things to the new spritesheet
generator.
- Species and antagonist icons in the preferences view because they use
getFlatIcon ~~which can't be converted to universal icons~~.
- Yes, this is still a *massive* cost to init, unfortunately. On Bee, I
actually enabled the 'legacy' cache on prod and development, which you
can see in my PR. That's why I added the 'clear cache' verb and the
`unregister()` procs, because it can force a regeneration at runtime. I
decided not to port this, since I think it would be detrimental to the
large amount of contributors here.
- It is *technically* possible to port parts of this to the uni_icon
system by making a uni_icon version of getFlatIcon. However, some
overlays use runtime-generated icons which are ~~completely unparseable
to IconForge, since they're stored in the RSC and don't exist as files
anywhere~~. This is most noticeable with things like hair (which blend
additively with the hair mask on the server, thus making them invisible
to `get_flat_uni_icon`). It also doesn't help that species and antag
icons will still need to generate a bunch of dummies and delete them to
even verify cache validity.
- It is actually possible to write the RSC icons to the filesystem
(using fcopy) and reference them in IconForge. However, I'm going to
wait on doing this until I port my GAGS implementation because it
requires GAGS to exist on the filesystem as well.
#### Caching
IconForge generates a cache based on the set of icons used, all
transform operations applied, and the source DMIs of each icon used
within the spritesheet. It can compare the hashes and invalidate the
cache automatically if any of these change. This means we can enable
caching on development, and have absolutely no downsides, because if
anything changes, the cache invalidates itself.
The caching has a mean cost of ~5ms and saves a lot of time compared to
generating the spritesheet, even with rust's faster generation. The main
downside is that the cache still requires building the list of icons and
their transforms, then json encoding it to send to rustg.
Here's an abbreviated example of a cache JSON. All of these need to
match for the cache to be valid. `input_hash` contains the transform
definitions for all the sprites in the spritesheet, so if the input to
iconforge changes, that hash catches it. The `sizes` and `sprites` are
loaded into DM.
```json
{
"input_hash": "99f1bc67d590e000",
"dmi_hashes": {
"icons/ui/achievements/achievements.dmi": "771200c75da11c62"
},
"sizes": [
"76x76"
],
"sprites": {
"achievement-rustascend": {
"size_id": "76x76",
"position": 1
}
},
"rustg_version": "3.6.0",
"dm_version": 1
}
```
### Universal Icons
Universal icons are just a collection of DMI, Icon State, and any icon
transformation procs you apply (blends, crops, scales). They can be
convered to DM icons via `to_icon()`. I've included an implementation of
GAGS that produces universal icons, allowing GAGS items to be converted
into them. IconForge can read universal icons and add them to
spritesheets. It's basically just a wrapper that reimplements BYOND icon
procs.
### Other Stuff
Converts some uses of md5asfile within legacy spritesheets to use
rustg_hash_file instead, improving the performance of their generation.
Fixes lizard body markings not showing in previews, and re-adds eyes to
the ethereal color preview. This is a side effect of IconForge having
*much* better error handling than DM icon procs. Invalid stuff that gets
passed around will error instead of silently doing nothing.
Changes the CSS used in legacy spritesheet generation to split
`background: url(...) no-repeat` into separate props. This is necessary
for WebView2, as IE treats these properties differently - adding
`background-color` to an icon object (as seen in the R&D console) won't
work if you don't split these out.
Deletes unused spritesheets and their associated icons (condiments
spritesheet, old PDA spritesheet)
## Why It's Good For The Game
If you press "Character Setup", the 10-13sec of lag is now approximately
0.5-2 seconds.
Tracy profile showing the time spent on get_asset_datum. I pressed the
preferences button during init on both branches. Do note that this was
ran with a smart cache HIT, so no generation occurred.

Much lower worst-case for /datum/asset/New (which includes
`create_spritesheets()` and `register()`)

Here's a look at the internal costs from rustg - as you can see
`generate_spritesheet()` is very fast:

### Comparison for a single spritesheet - chat spritesheet:
**Before**

**After**

## Changelog
🆑
fix: Fixed lizard body markings and ethereal feature previews in the
preference menu missing some overlays.
refactor: Optimized spritesheet asset generation greatly using rustg
IconForge, greatly reducing post-initialization lag as well as reducing
init times and saving server computation.
config: Added 'smart' asset caching, for batched rustg IconForge
spritesheets. It is persistent and suitable for use on local, with
automatic invalidation.
add: Added admin verbs - Debug -> Clear Smart/Legacy Asset Cache for
spritesheets.
fix: Fixed R&D console icons breaking on WebView2/516
/🆑
## About The Pull Request
**1. Code Improvement**
- Moved global pipe crafting recipe list into
`code/__DEFINES/globalvars/list` folder because its a global list & it
should belong there. Reduces size of RPD file
- Moved `datum/pipe_info` into `code/__DEFINES/globalvars` folder
because it's used by both RPD & crafting recipe so its a global var.
Reduces size of RPD file
- Replaced a bunch of `usr` with the proper user variable when available
- Autodoc for procs & vars
**2. Refactor**
- Attack chain for RPD has been refactored to `interact_with_atom()` &
`interact_with_atom_secondary()`
## Changelog
🆑
refactor: improved attack chain code for rapid pipe dispenser
code: organized lists & global vars for rapid pipe dispenser into their
own respective files & improved a bunch of code
/🆑
## About The Pull Request
<details>
- renamed ai folder to announcer
-- announcer --
- moved vox_fem to announcer
- moved approachingTG to announcer
- separated the ambience folder into ambience and instrumental
-- ambience --
- created holy folder moved all related sounds there
- created engineering folder and moved all related sounds there
- created security folder and moved ambidet there
- created general folder and moved ambigen there
- created icemoon folder and moved all icebox-related ambience there
- created medical folder and moved all medbay-related ambi there
- created ruin folder and moves all ruins ambi there
- created beach folder and moved seag and shore there
- created lavaland folder and moved related ambi there
- created aurora_caelus folder and placed its ambi there
- created misc folder and moved the rest of the files that don't have a
specific category into it
-- instrumental --
- moved traitor folder here
- created lobby_music folder and placed our songs there (title0 not used
anywhere? - server-side modification?)
-- items --
- moved secdeath to hailer
- moved surgery to handling
-- effects --
- moved chemistry into effects
- moved hallucinations into effects
- moved health into effects
- moved magic into effects
-- vehicles --
- moved mecha into vehicles
created mobs folder
-- mobs --
- moved creatures folder into mobs
- moved voice into mobs
renamed creatures to non-humanoids
renamed voice to humanoids
-- non-humanoids--
created cyborg folder
created hiss folder
moved harmalarm.ogg to cyborg
-- humanoids --
-- misc --
moved ghostwhisper to misc
moved insane_low_laugh to misc
I give up trying to document this.
</details>
- [X] ambience
- [x] announcer
- [x] effects
- [X] instrumental
- [x] items
- [x] machines
- [x] misc
- [X] mobs
- [X] runtime
- [X] vehicles
- [ ] attributions
## Why It's Good For The Game
This folder is so disorganized that it's vomit inducing, will make it
easier to find and add new sounds, providng a minor structure to the
sound folder.
## Changelog
🆑 grungussuss
refactor: the sound folder in the source code has been reorganized,
please report any oddities with sounds playing or not playing
server: lobby music has been repathed to sound/music/lobby_music
/🆑
## About The Pull Request
Gives the Plumbing Constructor and Rapid-Tiling-Device the same pick up
and UI interaction sounds as the RCD's (Plumbing Constructor already had
the UI one actually)
Additionally fixes an issue where ghosts could interact with the RCD,
Plumbing Constructors and RPDs
https://github.com/user-attachments/assets/c743981c-0231-45c4-b003-e8aa89b8fc12https://github.com/user-attachments/assets/4dc51f6d-eb4d-40c7-bf4e-ed29053796d9
## Why It's Good For The Game
Both of them are meant to be modified RCDs, so it makes sense to give
them the same sounds.
## Changelog
🆑 Hardly
sound: Plumbing Constructor and Rapid-Tiling-Device now has RCD's pick
up and UI sounds
fix: Fixes ghosts being able to interact with the RCD, RPLD and RPDs
/🆑
## About The Pull Request
this is a revival of #82635 . i got permission from potato to reopen
this, he did almost all the work. i only just solved the conflicts and
fixed all the bugs that were preventing the original from being merged
(but it should be TMed first)
## Why It's Good For The Game
slightly improves the performance of basic mob AI
## Changelog
🆑
LemonInTheDark
refactor: able_to_run and incapacitated have been refactored to be event
based
/🆑
---------
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
Co-authored-by: ZephyrTFA <matthew@tfaluc.com>
## About The Pull Request
So while multi-z disposals were added quite a while back, it seems like
it wasn't actually added to the list of disposal pipes the RPD can
place. This makes it so you can't fix multi-z disposals let alone make
new ones.
This pr simply adds both the up and down disposals segments to the RPD.
Additionally, in doing so I noticed the sprites for up disposals were
janky (names changed since image):

That being that the south pipe has a wonky sprite, while the west pipe
looks like a south pipe.
As the other sprites are copied over from trunks, we simply copy those
over to replace the wonky sprites:

## Why It's Good For The Game
Annoying to not be able to make nor repair multi-z disposals, especially
now we have a pile of multi-z maps.
Better when the sprites aren't wonky, like west actually being west
instead of south, and the north pipe not being inexplicably different.
## Changelog
🆑
qol: Multi-z disposal segments can actually be made with an RPD.
image: Upwards multi-z disposal segments no longer have wonky sprites.
/🆑
## 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
Hooked the switch sound on `ui_act`:
- RCD
- RPD
- Plumbing constructor
Added pickup and drop sounds for:
- RCD
- RPD
RPD also does the click sound when placing things.
https://github.com/user-attachments/assets/e6c2cb76-6a0a-4db9-9c25-961d41b84516
## Why It's Good For The Game
Immersion.
## Changelog
🆑 grungussuss
sound: added new sounds for RCD, RPD and Plumbing Constructor.
/🆑
## About The Pull Request
Why are we restricting atmos techs from doing this?
## Why It's Good For The Game
atmos meters are very useful and there is no reason to restrict them
from layer 1 and 5
## Changelog
🆑
qol: atmos meters can now be attached to layer 1 and 5
/🆑
Adds names and icon states to RCD/RPD upgrades
I don't have a pile of 6 disks on the lathe that all look identical and
the RCD going YOU HAVE THAT ONE INSTALLED ALREADY, TRY AGAIN IDIOT as I
fall into further despair
## About The Pull Request
I recently played a game where I rotated my skeleton model while
rotating my own character at the same time and it being in sync gave me
the realization on how cool it would be if the Coroner was able to
simply control the skeleton body.
I find skeleton displays very funny and I want to see more funny things
happen with them, so I thought this would be a good place to start, with
the benefits that it also works on mannequins and statues too so they
aren't left out.
Basically, while it is unanchored, if you have a statue/mannequin
grabbed, it will change its direction as you do, and speak the same
words you do. Your own messages can only be heard if the person is
directly next to you, revealing that it was you talking through it all
along.
I was originally gonna add this to the simple rotation component but
moved off when I decided to add talking through it, I left in the code
improvements I made to the component though since it is one of the
oldest components and hasn't been touched in a while.
Video demonstration (before I added the person also talking, just ignore
that missing)
https://github.com/tgstation/tgstation/assets/53777086/27242fc3-9649-418d-95cb-b31619319e97
While fixing the Toilet bong's rotation stuff I noticed a lot of it
wasn't up to proper code standards so I went over it and fixed issues I
had with it. It now doesn't give text saying you found something nasty
to species that still likes mice (like flypeople), and fixed its update
appearance to match the codebase standard set by the introduction of
``update_appearance`` many years ago.
## Why It's Good For The Game
It's a funny small idea I had and got inspired to add, it's a niche
mechanic that I think fits the aesthetic I am going for with Coroner and
also give a funny interaction with the human-like inanimate objects.
## Changelog
🆑
fix: Species that can eat mice don't get disgusted from seeing one in
the toilet bong.
add: Grabbing an unwrenched statue/mannequin/skeleton model will now
move its direction as you move yours, and you can talk through it.
/🆑
## About The Pull Request
Adds a button to RPD tgui that lets you build multiple pipe layers with
the RPD with 1 click
## Why It's Good For The Game
Saves a lot of time when using multiple layers, especially all 5, and is
very useful for SM setups and other convoluted atmos contraptions
https://github.com/tgstation/tgstation/assets/46101244/04993fee-7b35-483f-8cb1-a8b58ff1246a
## Changelog
🆑
qol: You can now build multiple pipe layers with the RPD, with just 1
click!
/🆑
---------
Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
## About The Pull Request
I woke up today and thought 'what would be easy thing to do today so I
can say I've done something?'. Then I remembered I saw several gangtool
usages the time I split radio up, and I could remedy those. 7 hours
later, device.dmi is split in a folder of its own, and I've also given
unique sprites to door remotes and landing desginators.
## Why It's Good For The Game
The device.dmi was kind of a mess.
## Changelog
🆑
/🆑
## About The Pull Request
Lets you instantly delete pipes/atmos devices with the RPD rather than
wait 0.2s
## Why It's Good For The Game
Playing atmos is a pain because of how time consuming it is, 0.2s adds
up. It's especially annoying if a bomb goes off and you have to click on
every single little loose pipe/heatpipe/device and wait to get rid of
them
## Changelog
🆑
balance: Deleting and reprogramming pipes/devices with RPD is now
INSTANT!
/🆑
## About The Pull Request
Code to handle this flag only ever existed on the `/obj` sublevel, so
there's no need for it to be on the `/atom` level `flags_1`. There was
probably a point in time in which mobs or turfs conducted electricity
but there's zero code for it anymore so we truly just live in a society
now.
## Why It's Good For The Game
Frees up a slot on `flags_1` (which is really nice actually), proper
scoping of certain bitflag stuff, etc.
## Changelog
Not relevant to players.
I may have screwed something up, will be doing a few passes on this
myself to ensure all the search and replaces went alright but we should
be good™️
## About The Pull Request
Third /icon/ cleansing splinter 1. Comments on commits say all it does
pretty much.

## Why It's Good For The Game
Inhand for walkietalkie was requested in the project, gets rid of some
usecases of old 'gangtool', headset splitoff requested by Fazzie.
Inhands reflecting the items they are supposed to represent is nice.
## Changelog
🆑
image: Following now have unique item sprites: syndicate war declaration
radio, curator and chief beacon's, chaplain beacon.
image: Following now have unique inhand sprites: radio, export scanner,
walkie-talkie, syndicate war declaration radio, curator and chief
beacon's, chaplain beacon.
/🆑
## About The Pull Request
Closes#79301
Saw this PR, realized how much this annoyed me whenever I played. Not a
hard fix either, since RCD's were a perfect example.
(In the future perhaps items that use upgrades like this could have one
base type of disk, and a component for 'upgrade_disk_tool', but that's
way, WAY out of my experience. Just something I noticed between the RPD
and RCD disks.)

One on the Left already has the upgrade. Neither try to double-install
it! (Shown for posterity)
Ones on the right are installed both ways. One, the RPD on the Disk. The
other, the Disk on the RPD!
---
Actual PR changes:
- New proc on the RPD called `install_upgrade()` - If the upgrade disk
isn't installed, it installs it onto the RPD and deletes the disk. So,
the same as the RCD one, but fewer checks since the RPD's got a lot
fewer disks. But, easier to add new ones now.
- Since `install_upgrade()` is a thing, the attack chain's code for how
RPD's originally got upgraded is now much shorter. It still functions
the same, though - nothing was removed in this PR!
- Adds an attackby check - if the RPD's attacked by an upgrade disk it
will try to `install_upgrade()`. So basically, what RCD's have.
## Why It's Good For The Game
Consistency between the RPD and RCD upgrade-wise. The RPD's other method
of installing (hitting the disk WITH the RPD) still works, but now
players used to the RCD won't get confused.
## Changelog
🆑
qol: The RPD now accepts upgrade disks inserted by hand, as well as
their original method of hitting the disk with the RPD
/🆑
---------
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
## About The Pull Request
Fixes flipped transit tube stations being inaccessible and adds a new
rotator disposal pipe which rotates the incoming atom 90 degrees no
matter which direction the atom comes from.

## Why It's Good For The Game
Adds new disposal pipe usage for cool projects and fixes a bug.
## Changelog
🆑
add: New rotator disposal pipe.
fix: Flipped transit tube stations are now accessible in the RPD again.
image: New rotator disposal pipe sprite.
/🆑
---------
Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
## About The Pull Request
Further continous organizing and cleaning the Icons folder. There are
still some minior nitpicks left to do, but I reached my daily sanity
expenses limit again, and the faster these get in the less issues for
both me and others later. Also cleans some mess I caused by my blindness
last PR.
## Why It's Good For The Game
Saner spriters = better sprites
## About The Pull Request
Fixes mousewheel changing the selected piping layer when the RCD is
in-hands, but not in the active hand.
Also dmdocs, changes some var names, grammar checks some stuff and adds
balloon alerts when installing the wrench upgrade and reprogramming a
pipe.
Removes `activate()` proc that was just a `playsound()`, makes the sound
used for that a define here so it's obvious why's the sound being played
## Why It's Good For The Game
Closes#54844 (it was fixed at some point actually so you couldn't
mousewheel to change layers on an RPD on your belt slot, but the in-hand
inconsistency remained)
Code's a little cleaner
Installing an upgrade's a little more obvious
## Changelog
🆑
fix: fixed RPD switching layers on mousescroll when not in active hand
qol: installing an RPD wrench upgrade & reprogramming a pipe via RMB
produces a balloon alert
/🆑
## About The Pull Request
**1. Craftable & Removed from RPD UI**
1. Air sensor's are now craftable
2. You can turn them on/off with hand. Even though turning off the
sensor will change it to a diffrent type[from `obj/machinery/air_sensor`
-> `obj/item/air_sensor`] it's I/O port's are sill preserved when
turning them on although you have to assign it a new name again which is
usefull if you want to change the sensor's purpose in game.
3. They can now only be deconstructed by a welding tool and should be
wrenched in place to turn them on.
4. Turned off air sensor's once unwrenched can be picked up like any
regular item
5. Air sensor's are removed from the RPD UI because they don't go with
pipes so it logically doesn't make sense to group them with pipe related
device's
Removed unused code in the process
https://github.com/tgstation/tgstation/assets/110812394/3439a0f3-9c48-43ac-8f4b-98135435ec13
**2. New ID System**
The problem with air sensor's is that each sensor is assigned a unique
ID which is then stored in `GLOB.objects_by_id_tag` list. Each sensor
name it's assigned based on the gas it's trying to sense(for naming only
even though it can detect other gases) So if 2 sensor's having the same
ID are made they will overwrite each other in this list leaving one
sensor orphaned in the world which cannot be referenced because it's
value was overwritten by a new sensor having the same ID in this list.
The Solution? Rather than having all atmos computer's look up sensor's
from this 1 global list make each computer keep track of all sensor's
it's responsible for in it's own local list[which i called
`connected_sensor's`] this way 2 sensor's can have randomly generated
names in the global `GLOB.objects_by_id_tag` list but the computer will
know what sensor to look up in this list based on the stored sensor ID's
in the `connected_sensor's` list
Basically what i am getting at is now you can make as many air sensor's
as you wish but you will know have to connect that sensor to the
computer using a multitool.
Notice in the video how i made 2 sensor's called `Supermatter Chamber
Sensor's`] and every time you try to connect an sensor which has the
same name[`Supermatter Chamber Sensor's` in this case] they will
ovewrite the old sensor in it's list as shown in the video
https://github.com/tgstation/tgstation/assets/110812394/b5283c3b-c8a1-4b94-a6a8-8ba7a0007615
**Why it's good for the game**

I agree. Also air sensor's taking up a full Tab/Section in the RPD UI
wasted a lot of UI space so that's removed now. Also making the air
sensor's wrenchable and pickable item's was also requested in
https://github.com/tgstation/tgstation/pull/72019#issuecomment-1355499873
so you relate them to device's like meter's
Another huge issue was that the number of air sensor's you can make in
the world was limited because each sensor in the world must have a
unique ID but that's finally fixed now so yeah make as many sensor's as
you want.
## Changelog
🆑
add: air sensor's are craftable
refactor: air sensor's can now be turned off by hand and can only be
deconstructed by a welding tool
refactor: removed `Params()` proc
qol: unwrenched air sensors can be picked up & recycled like regular
item's
del: air sensor are removed from the RPD UI
qol: air sensor's are no longer restricted by their unique ID's which
mean you can craft as many air sensors as you want.
/🆑
---------
Co-authored-by: Time-Green <timkoster1@hotmail.com>


## About The Pull Request
The recent changes were aimed at better UX, yet there were reports about
their flaws.
This PR should address some of the concerns.
The Devices tab was reduced, creating a new tab for Pumps and Valves,
called "Binary" (perfect timing for such tab 🤭) No scrolling required
now.
Also moved options to the left side for less mouse movements and
consistency with RCD and Plumbing RCD.
## Why It's Good For The Game
Better UI according to feedback from the main users - atmos techs.
## Changelog
🆑
qol: RPD UI: Devices split in two categories, options are aligned to the
left
/🆑
Ladies, Gentlemen, Gamers. You're probably wondering why I've called you
all here (through the automatic reviewer request system). So, mineral
balance! Mineral balance is less a balance and more of a nervous white
dude juggling spinning plates on a high-wire on his first day. The fact
it hasn't failed after going on this long is a miracle in and of itself.
This PR does not change mineral balance. What this does is moves over
every individual cost, both in crafting recipes attached to an object
over to a define based system. We have 3 defines:
`sheet_material_amount=2000` . Stock standard mineral sheet. This being
our central mineral unit, this is used for all costs 2000+.
`half_sheet_material_amount=1000` . Same as above, but using iron rods
as our inbetween for costs of 1000-1999.
`small_material_amount=100` . This hits 1-999. This covers... a
startlingly large amount of the codebase. It's feast or famine out here
in terms of mineral costs as a result, items are either sheets upon
sheets, or some fraction of small mats.
Shout out to riot darts for being the worst material cost in the game. I
will not elaborate.
Regardless, this has no functional change, but it sets the groundwork
for making future changes to material costs much, MUCH easier, and moves
over to a single, standardized set of units to help enforce coding
standards on new items, and will bring up lots of uncomfortable balance
questions down the line.
For now though, this serves as some rough boundaries on how items costs
are related, and will make adjusting these values easier going forward.
Except for foam darts.
I did round up foam darts.
Adjusting mineral balance on the macro scale will be as simple as
changing the aforementioned mineral defines, where the alternative is a
rats nest of magic number defines. ~~No seriously, 11.25 iron for a foam
dart are you kidding me what is the POINT WHY NOT JUST MAKE IT 11~~
Items individual numbers have not been adjusted yet, but we can
standardize how the conversation can be held and actually GET SOMEWHERE
on material balance as opposed to throwing our hands up or ignoring it
for another 10 years.
Lowercased RPD name and lowered the speeds for building atmos pipes/devices, reprogramming stuff and destroying stuff
atmos 0.5s -> 0.3s
reprogram/destroy 0.5s->0.3s
Why It's Good For The Game
QOL for atmos, makes big atmos/engi projects more viable
Loose pipes/devices don't even have gas in them no point in taking a lot of time to destroy them, they don't cost any materials to make either so nothing is wasted
This especially helps with fixing huge explosions since that leads to 50 pipe fittings being spammed everywhere and takes ages to clean up
Changelog
cl
qol: Lowered the atmos build, reprogram, and destroy delays on the RPD
/cl
## About The Pull Request
1. `pre_attack()` was defined twice, removed one
2. `attackby()` does the exact same thing as `pre_attack()` for
installing upgrades so removed that
3. Fixes runtime

When you attempt to unwrench a pipe via the RPD but you interrupt the
`do_after()` proc by moving. it doesn't need to crash but simply return
if unwrenching was unsuccessful see
`/obj/machinery/atmospherics/wrench_act()`
## Changelog
🆑
refactor: removed duplicate `pre_attack()` & redundant `attackby()`
procs which did the same thing
fix: unnecessary crash when unwrenching pipes/devices with the RPD
/🆑
## About The Pull Request
1. Debloats the RCD.dm file i.e. renames it to RHD[Rapid handheld device
the base for all rcd like devices] and moves its subtypes into their
respective files
`/obj/item/construction/rcd` moved to RCD.dm
`/obj/item/construction/rld` moved to RLD.dm
`/obj/item/construction/plumbing` moved to RPLD.dm
`/obj/item/construction/rtd` stays in RTD.dm
Other rcd like device i.e. RPD, RFC, RWD, along with the above mentioned
files are now all moved into 1 folder called "rcd"
majority of the `to_chat()` are now replaced with `balloon_alert()` to
reduce spam
2. Adds early returns, optimizes & adds extra resource sanity checks
before and after the `do_after()` proc for the RLD. RLD silo links now
works again.
- RLD now uses an ammo bar just like the RCD for updating only its
overlays & not its entire icon state, it also has a blinking yellow icon
state when low on ammo
- Remove unused empty blinking yellow icon state for plumbing RCD.
nobody designed the ammo bars for them so having`has_ammobar = TRUE`
caused the unit tests to fail
4. Adds extra structure placement & resource sanity checks for RCD, RTD
& Plumbing RCD before & after the `do_after()` proc
RCD Patches
- removes unused vars window_type & window_glass, these can be infered
from window_type directly
- removes furnish type & cost and let the rcd_vals() proc decide those
for consistency
- copies the rcd stuff from turf/floor to turf/open/misc with some
exceptions, It wasen't updated in a long time
- rcd vals i.e. cost & delay for window types are set for each
directional, full-tile, reinforced types. These all used constant values
& now they are adjusted accordingly
RTD patches
- Fixes#74526 RTD can lay floor tiles on all types of plating's
- The cost of deconstructing tiles was not calculated correctly i.e. it
always used the cost of the selected design & not the cost of the actual
floor type we are trying to deconstruct
- The construction & deconstruction time was constant & very fast for
all tile types, now the delay is adjusted based on the cost of the type
of tile in question
- RTD now has a blinking yellow empty icon state just like the RCD when
low on ammo
6. Fixes#73479 RCL now updates its pipe cleaning coil appearance when
changing colours & selecting white colour no longer yields a random coil
colour
7. makes sure `useResource() ` actually succeeds before doing any
action. The return value of this proc was not previously checked for
some devices
## Why It's Good For The Game
1. rcd like devices all moved into 1 folder for better organization
2. splits the original RCD.dm file into more logical & manageable files
for better maintainability
3. removes unused code & adds some extra sanity checks for everything
4. adds missing sprites for RLD & RTD
## Changelog
🆑
code: RCD & all its subtypes and other devices like it[RTD, RLD,
Plumbing RCD, RWD, RFC, RPD] now moved into 1 folder, removes unused
vars
refactor: RCD window type cost & delay are set based on the window type
selected.
refactor: RLD, RCD & plumbing RCD now has extra resource & target
placement sanity checks, optimizes RLD and code readability.
refactor: RTD now sets the correct delay with the cost of the tile type
currently being constructed/deconstructed taken into account
refactor: large majority of to_chat() replaced with balloon alerts
fix: RLD silo link now works again
fix: RTD can place tiles on any subtype of plating
fix: RCL now lays the correct colour of pipe cleaner when its colour is
changed
imageadd: empty blinking yellow icon states for RTD & RLD & an ammo bar
for RLD
/🆑