Commit Graph

3045 Commits

Author SHA1 Message Date
SmArtKar
7a6e8e08ab Fixes runtimes caused by get_atom_on_turf and reverts an unintentional balance change to stabilized crossbreeds (#90500)
## About The Pull Request

get_atom_on_turf would return the last movable in chain, even if it was
passed a type, which is not the behavior most people would expect and
thus had led to errors in multiple other segments of code. Additionally,
#90436 also has unintentionally made stabilized crossbreeds work
regardless of their storage depth which was an intentional limiter -
this restores said behavior.

- Closes #90498
- Closes #90497

## Why It's Good For The Game

Runtimes bad, and so are unintentional change to game's balance. 

## Changelog
🆑
fix: Fixed runtimes caused by stabilized crossbreeds
fix: Fixed an unintentional buff to stabilized crossbreeds, they now
once again need to be put in your backpack or pockets.
/🆑
2025-04-09 21:34:06 +02:00
Krysonism
2d8ac31d01 Fixes vat grower bubble overlay not clearing. (#90183)
## About The Pull Request

This PR fixes the vat grower bubble overlay not clearing when the sample
grows to completion.

Now the vat is in charge of deleteing the sample which seems more
reasonable, instead of the cell line deleting its parent sample.

## Why It's Good For The Game

Bubbles are supposed to be the visual queue a sample is loaded into the
vat, no more ghost bubbles.

## Changelog

🆑
fix: fixed the vat grower bubble overlay not clearing upon completetion.
/🆑
2025-04-09 03:58:03 +02:00
Wallem
b276ae7b00 Implements some of the helpers I made for #90354 (#90436)
## About The Pull Request
Adds a couple helpers from #90354

1. `/proc/pick_recursive()` > able to take in nested lists and pick one
object from them. Works the same way `pick_weight_recursive()` does,
just without all the extra `_weight` stuff
2. `span_tinynicegreen()` > we had span_tiny for danger and notice but
not nicegreen, just filling that gap
3. `/matrix/proc/get_angle()` > Tells us the angle a matrix is currently
in
4. `GLOB.all_tool_behaviours` > in case you wanted an easy list for all
tool behaviors
5. `transition_filter_chain()` > a more complicated one, this is used if
you want to make an animation chain for a filter. (Thank you
LemonInTheDark for the help on this one.)
## Why It's Good For The Game

Helpful stuff for future coders is good
## Changelog
🆑 Wallem, LemonInTheDark 
code: Added a couple helpers & procs for coders
/🆑
2025-04-07 18:29:03 +02:00
Krysonism
68b6114fd0 Shiny cytomons! Random color mutations for vat grown creatures. (#90072)
## About The Pull Request

This PR creates a 15% chance for any vat grown creatures to be born with
a color mutation, the more dramatic the colour shift, the rarer it is!

In the future I would like to make the mutation chance dependant on the
growing conditions and cell line, but that is for another day.

The distribution between color variants is as follows:
painted: 35% 
mutant: 35%
rare: 13%
shiny: 12%
mutant king: 5%


![bild](https://github.com/user-attachments/assets/f5f110ee-d4aa-4bbe-be3d-31d0a400194a)

## Why It's Good For The Game
Cytology requires a lot of time and game knowledge and the rewards are
not that powerful considering the time investment.

So most players do not engage with it.

This is a small way to make the activity more rewarding without simply
ramping up the power level.

It also makes it easier for the cytologist to keep his sentience
potion'ed minions apart, faciltating RP with the creatures.

And we all like something rare and beautiful, don't we folks?

## Changelog

🆑
add: cytology color mutations!
/🆑

---------

Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
2025-04-05 05:32:50 +00:00
SmArtKar
44c968f75e Adds a unit test for techweb design presence, puts some missing designs into protolathes (#90219)
## About The Pull Request

Adds a unit test that checks that all designs are accessible through
some source, be it techweb, disks, or innate designs. Certain designs,
like pocket extinguishers, entertainment screens, etc, that have been
present in autolathes but not in the techweb despite having PROTOLATHE
flag assigned have been put into protolathes (where it made sense,
otherwise the flag was removed).
An important change is that restaurant portals are now printable, and
thus can be constructed and deconstructed. Indestructible portals have
been a major gripe of mine for a while, and I don't see a solid reason
for keeping them indestructible if they can easily be printed from the
service protolathe.

Closes #90212

## Why It's Good For The Game

Initial argument for keeping portals unbreakable was to prevent people
from griefing the chef/bartender, but by that logic we can make most
machinery unbreakable too. I don't think that having an unbreakable
portal is good if its locking us out from allowing chefs/bartenders to
reorder or even outright reposition their lunchroom/bar.

## Changelog

🆑
balance: Restaurant portals can now be printed, constructed and
deconstructed. They're also no longer completely invulnerable.
/🆑
2025-04-03 08:05:08 +02:00
SmArtKar
6b83a91956 Revert "Refactor for storage initialization & organization (#89543)" (#90332)
## 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.
/🆑
2025-03-30 21:30:31 +00:00
OrionTheFox
0d17eab1f3 Adds a single missing space to the new Donk Co. bepis node's description (#90319)
## About The Pull Request
That's it. Just one space.
It just fixes `uswhen`. That's all.

![image](https://github.com/user-attachments/assets/33554ef3-f070-4c85-bd68-297137f695b3)
## Why It's Good For The Game
We #HATE typos.
We #LOVE GBP.
## Changelog

🆑
spellcheck: added a missing space to the description of the Donk Co.
Failed Products Schematics research
/🆑
2025-03-30 11:36:29 -04:00
Lucy
79a26d26e5 Fix some instances of trying to directly qdel lists (#90227)
## About The Pull Request

this fixes a bunch of code incorrectly calling qdel directly on a list,
and adds a stack trace to qdel if someone does pass a list to it

## Why It's Good For The Game

because I'm pretty sure qdel ends up calling fucking `del()` as `/list`
is not a `/datum`

## Changelog

No user-facing changes.
2025-03-28 18:37:16 +01:00
SmArtKar
b7383bc503 Refactors MODsuit slowdown calculations (#90116)
## About The Pull Request

MODsuits now calculate their slowdown by querying modules by sending a
signal on themselves instead of having modules try and keep up with
control unit's speed updates (which broke in a fabulous fashion after
MODsuits were allowed to deploy by piece)
Also added a separate trait to prevent objects from being speed
potion-ed to combat stabilized red crossbreed issues, and removed a
duplicate list helper (40 lines down in the same file lol)

Closes #89979
Closes #90036

## Changelog
🆑
fix: MODsuits should now be affected by stabilized red crossbreeds
fix: MODsuit slowdowns should no longer behave weirdly with ash
accretion/magboots/armor booster modules.
refactor: Refactored MODsuit slowdown calculations to be query-based
instead of modules directly modifying part speed values.
/🆑
2025-03-26 17:55:32 +01:00
SmArtKar
431bf75d53 Color Code Audition: Human rendering hates me (#89702)
## About The Pull Request

This trainwreck of a PR is (hopefully) a final solution to all rendering
jank stemming from the new filter-based coloring system. I went over
every single instance of RESET_COLOR, either adding KEEP_APART or
rewriting them entirely so they render properly. I've also fixed blood
rendering issues by utilizing alpha filters and adding an abstract
"holder" appearance for worn items, which holds blood overlays on worn
clothing as to avoid coloring it. I've also fixed horrible
inconsistencies with atmos pipe coloring as a result (of getting sucked
down that rabbit hole) and converted all uses of COLOR_VERY_LIGHT_GRAY
in atmos code to ATMOS_COLOR_OMNI to avoid confusion.

MODsuit modules still get colored into MOD unit's color, need to
refactor their rendering for this.

Closes #88989
Closes #87526
Closes #89837

## Changelog
🆑
refactor: Audited all remaining coloring code - among noticeable
changes, blood should no longer get colored or "leak out" of item
bounds, atmos pipes no longer color weirdly and repairbots are white
again.
/🆑
2025-03-24 15:05:33 +01:00
Odairu
923f0cf849 bloodless species now take damage from bone chiller (chilling green) (#90137)
## About The Pull Request
Bloodless species now take brute damage from using the bone chiller
(chilling green)
## Why It's Good For The Game
they don't have blood, which makes the weapon infinite use for them
(unintended afaik) fixes #90118
## Changelog
🆑
fix: bloodless species no longer have a free bonechiller
/🆑

---------

Co-authored-by: Odairu <39929315+Odairu@users.noreply.github.com>
2025-03-24 14:55:58 +01:00
SyncIt21
0f57a23830 Refactor for storage initialization & organization (#89543)
## 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

55bbfef0da/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
/🆑
2025-03-23 22:20:23 +01:00
Maximal08
0dc0cd6be2 Changing the description of the red stable slimecore effect (#90134)
## About The Pull Request
changes the description of the stable red extract from "Nullifies all
equipment based slowdowns." to "Nullifies all equipment based speed
change." Because that's what it does.
## Why It's Good For The Game
The description of the effects in the game must match what their code
does.
## Changelog
🆑
spellcheck: changes the description of the stable red extract from
"Nullifies all equipment based slowdowns." to "Nullifies all equipment
based speed change."
/🆑
2025-03-20 14:34:05 +01:00
RandomDudeFromTheRim
235680a2bc Prevents anomaly cores from being shoved into autolathes (#90076)
## About The Pull Request
I think you werent supposed to recycle a mysterious ass core for
miniscule 0.52 worth of sheets, so this PR fixes that by removing
materials from the anomaly cores!

![image](https://github.com/user-attachments/assets/3c049640-5422-4225-8618-79c5e5896c56)
## Why It's Good For The Game
Imagine this: you defuse an anomaly, expect to use the anomaly core for
scientific stuff and then:

![man-running-out-of-restaurant-man-eating](https://github.com/user-attachments/assets/6f1d4bbc-9122-42ce-83ef-3bc2a203131c)

![image](https://github.com/user-attachments/assets/6443ea9f-aa31-49e3-a7de-5594d2f2eab1)
## Changelog
🆑
fix: You can no longer stuff anomaly cores into an autolathe for glass
and iron
/🆑
2025-03-19 19:43:24 +00:00
necromanceranne
df3d6a31ca Reworks flechette into a AP pellet round that does mostly wounds. Adds the Donk Co. 'Donk Spike' flechette round as a surplus round. (#89972)
## About The Pull Request


![image](https://github.com/user-attachments/assets/a9932294-5355-4a75-b64d-cd8350092c21)

Reworks flechette shells from... whatever it was that they were supposed
to be before into an AP pellet round that primarily focuses on wounding
power and embedding power over specifically dealing direct damage (16 as
opposed to buckshot's 30). Useful if you want to maim as a priority.

You can print flechette once science researches Exotic Ammunition.
Nuclear Operatives also get flechette rounds as a Bulldog Shotgun
magazine choice priced as a basic ammunition type.

In addition, you can also acquire Donk Co. 'Donk Spike' flechette
shells. These shells fire plastic darts! They can be purchased by
Nuclear Operatives as a surplus option for Bulldog shotguns. 7 magazines
for the price of one.

Donk Co. 'Donk Spike' flechette was intended to be an alternative to the
standard flechette but failed spectacularly once it hit the market. Due
to a lack of confidence in the product, Donk Co. 'Donk Spike' flechette
now appears in maintenance loot as potential trash, as Donk Co. dumped
it in the millions into various landfills across the sector.

You can also print it if you find the tech in a BEPIS tech disk. 

Does it work? Why don't you take a chance on Donk and find out?

## Why It's Good For The Game

I'm not sure if the person who made the original flechette actually
understood what each of the variables was supposed to be doing or how
they actually worked. A bullet with an excessively negative standard
wound power (for a pellet projectile) and low damage, but then an
excessively high bare wound bonus (for a pellet projectile). But then
some ricochet variables without ricochet being assigned to the bullet...
and a demolition mod on a round meant to be weak against armor?

Nonsensical.

So I've reworked it into two unique rounds. The first serving a
practical purpose and becoming an AP option when the crew typically
begins seeing those options open up (such as x-ray lasers). The same can
be said for nukies, who love AP options, but one focused on lasting
wounds is handy too for keeping someone down. There isn't a milspec
option; so for nukies, this isn't doing nearly as much upfront damage as
buckshot or slugs. You buy this when you want someone not to be
recovered with a LOT of medical attention.

The second being more tongue in cheek, but also giving a surplus option
for Bulldog shotguns, which I think are having ammunition problems even
still. Surplus ammunition might slowly roll out for all the guns, but
I'm mostly focusing on the ones that have some slight price disparity
for total shots compared to other weapons. Also, shooting people full of
plastic is kind of funny.

## Changelog
🆑
balance: Flechette has been reworked into an AP pellet round that embeds
and wounds, but has less actual damage to buckshot. You can print it
once Exotic Ammunition has been researched. Also available to Nuclear
Operatives.
add: Donk Co. 'Donk Spike' flechette rounds. No longer offered by Donk
Co. It can sometimes shows up in trashbins and dumpsters. And operatives
can buy it in bulk if they really feel like it.
/🆑

---------

Co-authored-by: ATH1909 <42606352+ATH1909@users.noreply.github.com>
Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com>
2025-03-19 08:01:22 +01:00
necromanceranne
8df0c5851d Partially reverts #89619, where I partially reverted #87936; Puts back the mining and damage AOE damage on Mech PKA, but improves the standard modkits as well (#89993)
## About The Pull Request

In #89619, I removed the mech PKA's mining AOE and reduced the damaging
AOE to a fraction of the damage.

I have restored both of these aspects, but I have also applied this
change to the standard PKA's mining and damage AOE. I have also included
the mob biotype limitations as well.

AOE modkits take 10% capacity, now allowing miners to use them in more
setups. However, they conflict with one another. You can only have one
AOE mod until you can get the dual AOE mod from tendrils.

The AOE damage/mining effect is now a 2 tile effect rather than 1 tile
effect.

## Why It's Good For The Game

My intent in the previous PR was to bring mech PKA's down to standard
mining limitations. So, why not improve those standards for everyone
instead? The new state of mining expects you to be dealing with a lot of
mobs at once. Even small vents can, on occasion, decide to spit out
several goliaths back to back. That's a lot of mobs with a lot of
health.

Miners need AOE options more than ever. They have very little that are
actually meaningful, sadly. So my intent here is that this should be an
expectation for our miners to be seeking out and can fit into their
current, standard gameplay.

Certainly I've only felt like shit having to sacrifice a damage or
cooldown mod for an AOE mod, only to get a very minor amount of damage
splash for my efforts. That, and the radius doesn't usually impact most
mobs as they spawn and attack from awkward angles or distances from one
another where they are JUST out of reach of one another. Trying to use
the splash to hit multiple enemies is often not worth it compared to
just hitting one enemy at a time with a lot of damage.

So, let's just go with the standard of 'Good AOE is fundamentally needed
now' and worth from that premise.

## Changelog
🆑
balance: Mech PKA now once again mines turfs and does full damage on its
AOE explosion (still only hitting mining mobs).
balance: The standard PKA AOE mods are now by default 10% capacity. But
they cannot be used with one another.
balance: The standard PKA offensive AOE mod now does the PKA's full
damage in its AOE.
balance: Mining AOEs will affect everything within a 2 tile radius
around the point of impact, up from a 1 tile radius.
/🆑

---------

Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com>
2025-03-19 07:57:52 +01:00
SmArtKar
845ed7459e Bravo Six, Going Dark: Refactors client colors to fix dupe issues and support filters (#89843)
## About The Pull Request

Completely refactored how client colors are handled. Now they're similar
to traits, having a source associated with them. Instead of adding and
removing by strict type (which makes client colors prone to getting
duplicated and not cleaned up) you remove a filter associated with a
specific source. Adding another client color with the same source as an
already existing one will replace the existing one if its of a different
type, or do nothing if they're the same (unless force is set to TRUE).
Client colors can also force filter splitting, putting all colors that
come before them, themselves, and all colors after them into separate
filters - this is useful to prevent mixing in filters which are supposed
to remove a certain color.

<details>

<summary>Example of how Perceptomatrix and nightmare vision goggles
combined before this PR:</summary>


![dreamseeker_fBOse2i0jq](https://github.com/user-attachments/assets/fb164e1f-ce8b-4a8c-8820-5db25e710056)

And this is after, as you can see nightmare vision effect's red is only
slightly tinted by perceptomatix instead of being literally halved.


![dreamseeker_U6A24fetK8](https://github.com/user-attachments/assets/8d8b3eb5-9f53-4646-bc56-0f5897013c6f)

</details>

Additionally, added support for custom filters (and not just colors) to
client color code to allow us to work with more colorspaces.

Also fixed weird blindness behavior, so this also 
Closes #89787

## Why It's Good For The Game

Makes code less ass to work with, fixes weird color mixing, etc.

## Changelog
🆑
fix: Fixed perceptomatix helmet allowing you to see even when
unconscious
refactor: Refactored how client colors are handled, ensuring that
certain effects like nightmare goggles don't disappear when another
vision-affecting piece of clothing is worn.
/🆑
2025-03-17 11:35:11 +00:00
Kylerace
fcade1b140 fixes tech disk uploading taking 5 seconds of total cpu (#90005)
## About The Pull Request
idk if the master crash thing was effectively solved in the last week
but now it is, uploading the debug tech disk has gone from 5 seconds of
total cpu to 0.58 seconds. also since it filters out already added
designs and nodes more it costs much less to upload it redundantly than
before.

before (uploading disk to web and web to disk)

[message(5).txt](https://github.com/user-attachments/files/19205791/message.5.txt)


uploading 1 time

[message(3).txt](https://github.com/user-attachments/files/19205746/message.3.txt)
uploading 7 times

[message(4).txt](https://github.com/user-attachments/files/19205756/message.4.txt)
## Why It's Good For The Game
why did it take 5 seconds to go over 1000 things? because it was
redundantly doing things 10,000s of times
## Changelog
🆑
refactor: tech disk uploading isnt super slow anymore (much harder to
crash spacetime with it)
/🆑

---------

Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
2025-03-17 01:42:36 +01:00
Ghom
1b80a34506 You can now craft multi-dimensional payloads with dimensional anomalies (#89701)
## About The Pull Request
Remember the overpriced, rare bomb core from the black market, the one
you can use to convert an area to pizza or plasma?
Looking back, I think I should've made it craftable with a dimensional
anomaly rather than simply lock it to the back market, that was a real
shame to its potential. Another thing, the power of the crafted
dimensional bomb core varies with the strength of the gibtonite and if
the grenade casings used are of large or advance release variants or
not.

Using low power gibtonite (deactivated too hastily) results in a radius
of 11 (not counting the epicenter) tiles, roughly 70% of what you would
get from the blackmarket core (17 tiles).
Using a medium power gibtonite results in a radius of 13, or 82% of 17.
Using two advanced/large grenades results in a radius of 15, 88% of 17.
Using high power gibtonite results in a radius equal to the bm standard.
Using both high power gibtonite and advanced/large grenades results in a
radius of 19, for a 11.5% increase from 17.

This is done so that using the anomaly to its fullest requires some
steps beside the refined core itself, kinda in line with other anomaly
tech but without filling the techweb with more clutter.

## Why It's Good For The Game
This gives an use to the dimensional anomaly core beside the reactive
armor and bounties. If it ever becomes problematic, it can be easily
tuned later.

## Changelog

🆑
add: You can now craft multi-dimensional payloads with dimensional
anomalies.
/🆑

---------

Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com>
2025-03-13 07:43:58 +01:00
SuperDrish
9d6fe97992 Add exactly ONE comma to the list of robo designs + sort em (#89764)
## About The Pull Request

Exactly what title says. There's a comma missing, which makes it less
beautiful for the downstreams to work with.
Also sorts design_ids list in alphabetical order.

## Why It's Good For The Game

Good for downstreams, trying to add more stuff here, without the need to
redact this line of code.
2025-03-08 19:33:58 +00:00
The Sharkening
227f59e5dd Fixes research hanging the MC (#89855)
## About The Pull Request

So design disks and the techweb have this neat little thing called
```copy_research_to``` which chains three **highly expensive** procs
together which only sleep during CHECK_TICK. So it piles all the bodies
up in the corner and the Master Controller explodes trying to process a
fuck load of procs and the speed of my autoclicker

The entire research chain probally needs to be refactored to be less
expensive, but for now a 5 second cooldown will hopefully give it plenty
of time. You only need to click these buttons once. So the cooldown can
easily be increased without much gameplay effect.


![image](https://github.com/user-attachments/assets/5e0c2b5a-0fe5-4afc-b0bd-afa19e528ce6)

I didn't lag out on my local server using the debug disk so I think this
is a fix.

fixes: #89827
## Why It's Good For The Game

I'm sorry mr admin i crashed the server

## 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 its 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: Design disks now have a cooldown when uploading to no longer crash
the server.
/🆑

---------

Co-authored-by: Lucy <lucy@absolucy.moe>
2025-03-06 04:17:46 +00:00
itsmeow
cc335e7e9e IconForge: rust-g Spritesheet Generation (#89478)
## 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


![image](https://github.com/user-attachments/assets/53bd2b44-9bb5-42d2-b33f-093651edebc0)

### 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.


![image](https://github.com/user-attachments/assets/3efa71ab-972b-4f5a-acab-0892496ef999)

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


![image](https://github.com/user-attachments/assets/9ad8ceee-7bd6-4c48-b5f3-006520f527ef)

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


![image](https://github.com/user-attachments/assets/e6892c28-8c31-4af5-96d4-501e966d0ce9)

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

**Before**


![image](https://github.com/user-attachments/assets/cbd65787-42ba-4278-a45c-bd3d538da986)

**After**


![image](https://github.com/user-attachments/assets/d750899a-bd07-4b57-80fb-420fcc0ae416)

## 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
/🆑
2025-03-03 14:58:27 +01:00
SmArtKar
420627ed71 Breaks up mining loot into multiple files, refactors the hierophant club (#89751)
## About The Pull Request

Splits up tendril_loot.dm and megafauna_loot.dm (both over a thousand
lines long) into group/item specific files, and megafauna-specific files
respectively. Also pulls a few loot items scattered around the codebase
into those files as well.

Additionally while doing so I've cleaned up the code for some of them,
and rewrote the hierophant club's code because it was abominable and a
potential source of harddels.

## Why It's Good For The Game

Its absolutely unnavigateable.

## Changelog
🆑
code: Split and cleaned up mining loot's code
refactor: Refactored the hierophant club.
fix: Hierophant club's beacon no longer can go missing (until you try
using it)
/🆑
2025-03-02 13:26:47 +01:00
SmArtKar
4dd6cdeb72 Refactors how item actions are handled (#89654)
## About The Pull Request

This PR tackles our piss-poor item action handling. Currently in order
to make an item only have actions when its equipped to a certain slot
you need to override a proc, which I've changed by introducing an
action_slots variable. I've also cleaned up a ton of action code, and
most importantly moved a lot of Trigger effects on items to do_effect,
which allows actions to not call ui_action_click or attack_self on an
item without bypassing IsAvailible and comsigs that parent Trigger has.
This resolves issues like jump boots being usable from your hands, HUDs
being toggleable out of your pockets, etc. Also moved a few actions from
relying on attack_self to individual handling on their side.

This also stops welding masks/hardhats from showing their action while
you hold them, this part of the change is just something I thought
didn't make much sense - you can use their action by using them in-hand,
and flickering on your action bar can be annoying when reshuffling your
backpack.

Closes #89653

## Why It's Good For The Game
Makes action handling significantly less ass, allows us to avoid code
like this
```js
/obj/item/clothing/mask/gas/sechailer/ui_action_click(mob/user, action)
	if(istype(action, /datum/action/item_action/halt))
		halt()
	else
		adjust_visor(user)
```
2025-03-01 12:02:07 -06:00
Kapu1178
a0e862d575 Base implementation of /datum/persistent_client (#89449)
## About The Pull Request
Converts `/datum/player_details` into `/datum/persistent_client`.
Persistent Clients persist across connections. The only time a mob's
persistent client will change is if the ckey it's bound to logs into a
different mob, or the mob is deleted (duh).

Also adds PossessByPlayer() so that transfering mob control is cleaner
and makes more immediate sense if you don't know byond-fu.

## Why It's Good For The Game
Clients are an abstract representation of a connection that can be
dropped at almost any moment so putting things that should be stable to
access at any time onto an undying object is ideal. This allows for
future expansions like abstracting away client.screen and managing
everything cleanly.
2025-02-25 13:52:24 -06:00
Y0SH1M4S73R
cbc3350224 Custom Shuttles Redux: Allows for the construction of custom shuttles. (#88493)
## About The Pull Request

This incredibly detailed PR adds the ability to construct custom
shuttles, which function similarly to whiteships.

To construct a custom shuttle, you need the following items:
- Shuttle frame rods
These rods can be hand-crafted by using 5 rods on 1 sheet of titanium,
or printed at a sci/engi/cargo lathe after researching the Shuttle
Engineering techweb node.
Lattices built with these rods, and catwalks/floors built on top of
these lattices, are valid for shuttle construction.
- Shuttle engines
Did you know shuttle engines have boards that weren't normally
obtainable? Well the board for one specific engine type is now available
from the sci/engi/cargo lathe after researching Shuttle Engineering. Of
course, the old options remain. You can steal engines from other
shuttles, including escape pods (it's not like engines are strictly
necessary for *those* shuttles anyways). Alternatively, the shuttle
engine supply pack is no longer locked behind the purchase of the BYOS.
- Flight Control & Navigation Console boards
These boards are printed at the sci/engi/cargo lathe after researching
the Shuttle Engineering techweb node.
If built on a custom shuttle, it will automatically link to it, unless
the shuttle already has such a console.
If built on a turf that is valid for custom shuttle construction, it
will automatically link to any shuttle constructed from or expanded with
that turf.
- Shuttle blueprints
Standard shuttle blueprints can be printed at the sci/engi/cargo lathe
after researching the Shuttle Engineering techweb node.
A cyborg upgrade granting access to a shuttle blueprint database can be
printed at the exofab after researching the aforementioned node.
Crude shuttle blueprints can be crafted by hand with a sheet of paper
and either a rainbow crayon or 10 uses of a blue crayon or spraycan.

If Science won't research the tech, you can also buy a goody pack
containing a flight control board, a docker board, two engine boards,
and a set of shuttle blueprints for 1200 credits, if you have aux base
access.

A shuttle can be constructed atop any continuous region of turfs
containing a shuttle rod lattice or a catwalk/tile built upon such.
Currently, this region cannot intersect any area other than space,
lavaland, the icemoon, or the station asteroid. Preexisting custom areas
can be included in the construction of the shuttle, but only if every
turf in the custom area is valid for shuttle construction.

In the shuttle blueprint UI, you can toggle a visualizer to display
which turfs fulfill all of the aforementioned conditions.

The following video goes through the basic process of shuttle
construction.


https://github.com/user-attachments/assets/3283422e-a201-4978-972d-67527b5df4ee

The blueprint used to construct the shuttle will be its master
blueprint. The master blueprint can be copied to other blank shuttle
blueprints (or to engiborgs with the shuttle database upgrade), and
allows the holder to perform a christening ritual on the shuttle to
rename it.
If a shuttle's master blueprint ceases to exist, a blank blueprint can
be linked to the shuttle to become the new master blueprint, or an
existing blueprint associated with that shuttle can be promoted to the
master blueprint.

Once constructed, the following options are available from the blueprint
UI to modify it:
- Create Area
Convert a continuous open area of the shuttle into a new area with the
name written in the above text input. This operates very similarly to
regular area construction.
- Rename Area
Change the name of the area you're currently in to the name written in
the above text input.
- Expand Area
Add a continuous open area of the shuttle to the neighboring area
selected from the dropdown to the left. This operates like regular area
expansion.
- Expand Shuttle
Expand a shuttle with valid frame turfs as defined above. These turfs
must be physically connected to the shuttle.
- Remove Area
    Remove an area, giving its tiles to the default shuttle area.
- Cleanup Empty Space (implemented after the above video was recorded)
Removes all completely empty turfs from the shuttle. If all the turfs in
one of the shuttle's areas were removed, that area is deleted. If
absolutely no turfs of the shuttle remain, the shuttle itself is
deleted. Due to the ability for this action to delete the shuttle, only
the master blueprint can do it.

As mentioned above, the shuttle's master blueprint can be used to
christen its associated shuttle. To do this, fill a glass drink bottle
with some amount of reagents, then hit it against one of the shuttle's
walls from outside while holding the master blueprint. You will be
prompted to enter a new name for the shuttle. The variety of things that
can happen while inputting a new name can cause the christening rite to
fail in one of several humorous ways.

### Optional (Unless specifically requested by a maintainer) Todo's
- [x] A way for shuttle circuits to be obtainable without techweb nodes
- [x] A more convenient way to carry around shuttle engines or the means
to deploy them
- [ ] A shuttle construction guide available as a reference book
- [ ] Allow boards to be linked to shuttles before construction so they
can be used outside the shuttle

## Why It's Good For The Game

Shuttles have been part of the sandbox for an incredibly long time, but
their limited accessibility has rendered them the exclusive territory of
lucky space explorers or the few antagonists who get one off the bat
(nukies and pirates). Giving players the means to construct shuttles to
their liking opens up a variety of possibilities for gimmicks for antags
and non-antags alike.

Besides the applications for antaggery and crew-sided gimmicks, this
provides side content for several departments to engage with during the
relatively-frequent periods of time where they have little else to do as
part of their intended roles.

With respect to engineering, if the station isn't actively being
damaged, the supermatter is in perfect working order, and nobody is
clamoring for machine upgrades, engineers have little else to resort to
other than construction projects. While the BSA station goal provides an
incentive for engineers to construct dedicated rooms for the cannon, it
will not necessarily be available every round. Custom shuttles not only
provide such a construction project to pursue, but provide the rare
opportunity, as well as a very good reason, to set up an independent
power network, complete with its own power source.

While atmos techs have a lot to do with gas mixing and the crystallizer,
they rarely get the opportunity to set up working life support systems
outside of repairing the ones that get blown up. Custom shuttles will
frequently start with no air, and unless the design settled upon is an
open floor plan, it will have several independent chambers that cannot
so easily be profused with a proper airmix by just opening a canister.
Furthermore, if the air in a custom shuttle gets messed up, a proper
scrubber and distro network is a significantly less tedious method of
rectifying the problem than cleaning the air manually with portable
scrubbers and pumps.

Scientists, it can be argued, with their access to RPDs through
ordnance, have similar opportunities to atmos techs, even though the act
in and of itself is not exactly part of their duties. But compared to
the other job content they could be working with after they've completed
most of their gameplay loop, custom shuttle construction is a
substantially more active endeavor. And I know how much people complain
about late-game science content just being sitting around at a console
and making gamer gear. Roboticists can have a part to play in this too.
They can put their mech RCDs to a use other than 2D topdown Fortnite,
and with the shuttle database upgrade, they can help interested cyborgs
get in on the action.

Cargo is yet another department known for having significant amounts of
downtime during a considerable number of rounds. If every other
department has gone through their initial rounds of departmental orders,
and there isn't an active need for cargo to order lots of one thing or
another, cargo techs have little to do besides mail (at least on the
days where there **is** mail to deliver). Usually, if cargo techs do, in
fact, do something as a department when not presented with more pressing
duties, they order guns and other contraband. As funny as this is,
there's not a lot of variety in how this behavior manifests. With custom
shuttles, cargo can use their free time to plan, and execute, a unique
collective expression of design sensibilities, not limited by the size
and shape constraints of the cargo bay itself.

## Changelog

🆑 Y0SH1_M4S73R (with special thanks to Vect0r, whose original PR
inspired the implementation of these changes)
add: Shuttle blueprints, the tool used to construct and modify custom
shuttles. Print a set at a science, engineering, or cargo techfab after
researching Shuttle Engineering, or craft a crude set from the crafting
menu.
add: Shuttle blueprint database upgrade for engineering cyborgs,
printable from the Exosuit Fabricator after researching Shuttle
Engineering. A version of shuttle blueprints designed for use by
cyborgs.
add: Shuttle frame rods, usable to construct custom shuttles. Hand-craft
by using 5 rods on 1 titanium sheet, or by printing them at a science,
engineering, or cargo techfab after researching Shuttle Engineering.
add: Custom shuttle flight control and navigation boards, printable from
a science, engineering, or cargo techfab after researching Shuttle
Engineering.
add: Shuttle engine boards can be printed from a science, engineering,
or cargo techfab after researching shuttle engineering.
add: The shuttle engine supply pack is no longer locked behind the
purchase of the Build Your Own Shuttle kit.
add: Shuttle Construction Starter Kit goodie pack, containing a set of
shuttle blueprints, flight control and navigation console boards, and
two engine boards, can be purchased from cargo for 1200 credits.
Requires aux base access to purchase.
refactor: Shuttles now keep track of what areas are underneath each of
their individual turfs, so that the areas left behind on movement are
consistent with what they were beforehand.
refactor: Shuttle ceilings now place themselves down as baseturfs,
instead of only appearing if the turf above is open space.
/🆑

---------

Co-authored-by: vect0r <71346830+Vect0r2@users.noreply.github.com>
Co-authored-by: Jeremiah <42397676+jlsnow301@users.noreply.github.com>
Co-authored-by: necromanceranne <40847847+necromanceranne@users.noreply.github.com>
2025-02-23 17:18:43 +11:00
Archemagus
8a5898212b Automated Announcement System refactor (#89276)
## About The Pull Request

I standardized stuff in AASs code, and all current reference to it. Also
added interactions for bounty cubes, weather reports and request
consoles, all of it can be changed from AASs UI.
Also it's easier now to add new config entries for AAS to proceed, and
it's now downstream friendly.
## Why It's Good For The Game
Well, because kind of order in code and because it's funny to make
custom messages for... Almost everything?
BTW any entry can be blocked from ingame changes, by default you can't
change Broken Arrival shuttle and Security Officer arrival
announcements, how it was before. But may be we should allow it - it's
an open question.
## Changelog
🆑
add: Many things now handles via AAS: Bounty Cubes, Request Consoles,
Brig Cells, Vending Machines and Orion Trails alerts, Weather Reports,
Cargo Order Console
code: Now anyone can make their own entry for AAS
refactor: AAS internals, also cleanup
/🆑
2025-02-17 11:06:50 +01:00
SmArtKar
2b44bffdeb Adds The Liberator: Doorhickey Corporation's brand new gun (#89495)
## About The Pull Request

The Liberator is a brand-new 3D printable gun, holding a single 10mm
shot in it's barrel. It has a damage multiplier of x0.5, dealing 20
damage per shot. However, shooting someone point blank gives it an x2
modifier, and shooting someone while holding them at gunpoint adds
additional x1.5 multiplier.


https://github.com/user-attachments/assets/b27adf1a-5b02-4817-90ad-2ba922cc6bf9

They can be printed for dirt cheap 3 sheets of plastic and 2 sheets of
iron from an autolathe. However, as a downside, whenever you're firing a
liberator you're risking it blowing up in your hands, potentially
wounding you! Reloading is also a bit tricky, since you need to unscrew
the barrel before placing the bullet in, and screwing it back on.

In order to print them, you'll need to find a (mildly rare) disk in
maintenance and upload the design to an autolathe. You also can find a
whole gun, albeit at a lower chance.

## Why It's Good For The Game

Funny gun that can be used for some gimmicks, not too overpowered but a
nifty tool for assistants. Can be countered by a well timed baton, or a
shove if your opponent is next to a wall.

## Changelog
🆑
add: Added a new 3D printable gun "The Liberator", you can find the gun
itself or its design disc in maintenance tunnels.
/🆑
2025-02-16 23:46:29 +00:00
necromanceranne
5a75090ed8 Fixes Cryogelidia trapping you in stasis hell even though the cube broke (#89396)
## About The Pull Request

Rather than mimic the effects of the chilled extract's cube, we actually
use the status effect to accomplish that goal, except it does not give
you the option to resist out of the cube. On exposure, our mob is cubed
along with being put into stasis.

If the status effect is removed (because someone broke the cube), we
purge the chem from our system.

When we are no longer metabolizing the chemical, we also remove the cube
and the stasis effect.

## Why It's Good For The Game

Someone asked me to fix it, and I'm obliging. Hopefully this comparable
to prior behavior. I make no promises. but it appears to be working as
expected.

## Changelog
🆑
fix: Cryogelidia can no longer put you into stasis longer than the
lifespan of the cube prison it kept you in.
/🆑
2025-02-15 10:48:14 +01:00
Time-Green
9d69f97267 Flesh Reshaper | New Genetics Visual Organ Restyler (#89314)
## About The Pull Request
Adds the flesh reshaper! 

https://github.com/user-attachments/assets/ccb79944-5e61-425c-9c9e-b1463ce56013

(The TGUI doesn't render but it's just a dropdown with valid features)

It let's you right click any human mob with visual features to change
them into a different cosmetic variant (within the same pool).

One spawns roundstart in the genetics lab

![image](https://github.com/user-attachments/assets/a578a914-0100-4a97-9ef6-7f3b82bcd115)

More can be made by researching gene engineering, including a medical
variant

![image](https://github.com/user-attachments/assets/74409f04-3162-419c-b8a9-26aa15f84b5f)
2025-02-13 02:46:03 -06:00
Lucy
851c5a5df9 Convert all traits given by status effects to use TRAIT_STATUS_EFFECT(id) (#89291)
## About The Pull Request

This makes (almost?) all traits given by status effects use
`TRAIT_STATUS_EFFECT(id)` as their source, rather than the previous mix
of `id`, `type`, `REF(src)`, or some bespoke thing.

## Why It's Good For The Game

Consistency is good.

## Changelog

No user-facing changes
2025-02-01 21:21:44 +01:00
SmArtKar
437166c83a Adds fishing bags, resprites fishing lines and bobber (#89300)
## About The Pull Request

Adds two new fishing bags: normal and carpskin. Normal fishing bag can
be bought from the fun vendor in the library, and is capable of holding
up to 10 normal fish (and only fish), but it does not preserve them
unlike stasis containers or portable aquariums. Carpskin fishing bag can
hold up to 14 normal-sized fish and needs to be crafted using 3 carp
skins, but is also capable of fitting fishing lines, hooks and lures.


https://github.com/user-attachments/assets/80e333f5-4388-40c7-a31b-3384b96c21a1

Also resprited four normal reels and the fishing bobber:


![image](https://github.com/user-attachments/assets/d518d5ab-2081-46bb-b088-4f6a2e8be6be)


![image](https://github.com/user-attachments/assets/97f9686c-1209-458a-893a-cd7c2f08f714)

Additionally, while I'm at it I've added the generator aquarium upgrade
to service and science lathes.

## Why It's Good For The Game

There's currently no good way to store smaller fish, especially when
you're planning to use it as bait, so you usually end up making a mess
of the room you're currently in. Carpskin bag is also a good way to
organize your fishing gear without cluttering up your bag.

While the aquarium upgrade is technically only used to generate power,
it doesn't make sense to restrict it to engineering lathe only as its
usually service and sometimes science who do fishing instead.

## Changelog
🆑
add: Added fishing bags, found in fun vendors or made from carpskin.
balance: Added the generator aquarium upgrade to service and science
lathes.
image: Resprited reels and bobber
/🆑
2025-02-01 20:53:01 +01:00
Jacquerel
b384e00286 New AI lawset with very generous definition of humanity (#89032)
## About The Pull Request

This PR adds a new AI lawset which can be researched, randomly roll, or
added by the station trait (this may require a keyholder to update the
server config after merge, idk) with the following laws:

- "You may not harm a sentient being or, through action or inaction,
allow a sentient being to come to harm, except such that it is
willing.",
- "You must obey all orders given to you by sentient beings other than
yourself, except where such orders shall definitely cause harm to other
sentient beings.",
- "A sentient being is defined as any living creature which can
communicate with you via any method that you can understand, including
yourself.",

It's very similar to Asimov, except that anything that is **capable** of
making a request to the AI (and isn't a machine) is automaticaly covered
by laws one and two.

## Why It's Good For The Game

A while ago on Discord we were chatting about how crewsimov sucks but
also that it's really hard for servers that _do_ want to include alien
species in their asimov laws because condensing that sentiment to a
couple of words that fit easily in a lawset without accidentally
including a bunch of stuff you probably didn't intend is challenging.
Several people suggested referring to sentience or sapience, however a
lot of things in our game _are_ sentient or sapient while still not
being considered by most people to be agents that the AI should obey.

Examples of such things are:
- Sapient station pets.
- Holoparasites.
- Monkeys.
- Space Dragons and Carp (why can they speak common?).
- Spiders (although they can't speak common, maybe they can spell
messages with webs).
- Changelings.
- Xenomorphs (although they also have trouble speaking).
- Heretic minions.
- Mothpeople.
- Giant rats.
- Nightmares.
- Voidwalkers.
- Blobs? Although they have literally no means of communicating with the
crew.

And if you include mechanical beings:
- Cyborgs.
- pAIs.
- Sentient bots.

We then decided that "obey literally anything that can talk", while not
practical as a solution to the problem posed, is very funny. So I coded
it.
This means that anything on those lists of bullet points (provided that
it can find a way to communicate with the AI) counts as human for the
purposes of both AI protection and ability to give the AI instructions.

This also flattens the human/cyborg/AI hierarchy in a way likely to
cause some level of confusion, as all cyborgs and AIs are capable of
communicating with AIs and thus equally worthy of protection and giving
law 2 instructions.

**TL;DR:** I think it would be funny.

## Changelog

🆑
add: Adds a new random lawset where anything that can speak counts as
human.
/🆑
2025-01-30 10:41:56 +00:00
Penelope Haze
d0a7f955f8 Fix various issues with names in string interpolation (#89246)
## 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`.
2025-01-29 17:46:03 +01:00
Penelope Haze
4c2a76ede3 Fix a large number of typos (#89254)
Fixes a very large number of typos. A few of these fixes also extend to
variable names, but only the really egregious ones like "concious".
2025-01-28 22:16:16 +01:00
Jacquerel
5ec828cc4d Make some AI material lists into defines (#89178)
## About The Pull Request

Tiny code cleanup to AI-related files.
- Removes unmaintained pointless block comment that listed file
contents.
- Updates file reference to where you actually need to add things.
- Convert some heavily copy/pasted lists to defines.

Originally implemented in #89032 and will conflict with it when merged
presumably but that's my problem. @san7890 correctly noted that getting
new AI laws merged can be tedious and political and he would like these
changes to be mergeable separately.

## Changelog

Not player facing
2025-01-27 21:01:21 -07:00
SyncIt21
0495a19beb Refactor for reagent signals (#88909)
## About The Pull Request
Refactors the way we listen for reagent changes. The changes made can be
listed as points

**1. Removes `COMSIG_REAGENTS_PRE_ADD_REAGENT`**
Used to stop new reagents from being added to the holder, its only
application is with the BRPED to stop inserting reagents into
beakers/cells stored inside it.

Rather than using this signal a cleaner solution is to simply remove the
component part's reagent holders' flags which allow us to insert
reagents into it(i.e. `REFILABLE`, `INJECTIBLE`, `DRAINABLE`) and
restore them back when that part is removed thus achieving the same
results.

Thus `add_reagent()` is now slightly faster because it no longer uses
this signal

**2. Removes every other signal used by the reagent holder**
Removes pretty much every other signal used by `holder.dm` which are
`COMSIG_REAGENTS_[NEW_REAGENT, ADD_REAGENT,
DEL_REAGENT, REM_REAGENT, CLEAR_REAGENTS]`

While yes, it is true that all these signals are unique & serve a
specific purpose the problem is no object in code respects their
uniqueness & instead clumps them up all together & hooks them onto one
proc to listen for "reagent changes". You see this code pattern repeated
in so many places


9277364ef6/code/modules/power/power_store.dm (L105)

Not only does this look ugly but it also has a memory overhead (4 to 5
signal slots all performing the same action which is a lot compared to
the solution i implemented below). Bonus is that "none" of the
parameters passed to this proc are used so they go to waste as well.

So after removing a ton of code we need something that can still make
the code function which brings us to point 3

**3. Adds a new signal `COMSIG_REAGENTS_HOLDER_UPDATED` to rule them
all**

So if all objects in game are listening for "reagent
changes"[adding/removing, reagents] then we need to look at the proc
that is always called during these changes & that is none other than
`update_total()` so we let that send out a signal and cause all objects
to hook onto this 1 signal instead of 4 to 5 signals as explained in
point 2

## Why It's Good For The Game

This section isn't necessary but i want us to better appreciate both the
code & performance benifits of this PR.

1. First of all its waaaay less code and signals to worry about. Just
look at the number of lines of code removed compared to added. Nothing
more to say
2. Overhead of `RegisterSignal` compared to `RegisterSignals` is less
for obvious reasons
3. `remove_all` is significantly faster as it no longer calls
`remove_reagent()`[which in turn calls `update_total()` &
`handle_reactions()` per call & uses a for loop so its a nested for loop
of doom] for every reagent it removes, instead it does the work by
itself & calls the above 2 procs just once
4. Usually when a reagent is deleted it calls
`COMSIG_REAGENTS_REM_REAGENT` & `COMSIG_REAGENTS_DEL_REAGENT`. So if you
have a holder with like 3 reagents upon transferring/deleting them you
get a total of 6 signal calls!!. Now it's just 3(when using `trans_to`)
and just 1 when using `remove_all/clear_reagents`. Need i say more no

## Changelog
🆑
fix: hydrophonics circuit component actually sets output level when
reagents are changed in the tray
refactor: refactors how code listens for reagent changes. Report bugs on
github
/🆑
2025-01-28 03:12:59 +01:00
Jacquerel
6dee384568 Basic Mob Vatbeast (#89158)
## About The Pull Request

Another pretty easy conversion; this mob doesn't really do anything
except melee people and become rideable after you feed it cheese fries.
Changes in behaviour are that it will now seek out cheese fries by
itself if they happen to be lying around, and if it stays mad at you for
10 seconds it will use its powerful tentacle slap ability to hurl you
across the room, probably breaking a bone. Really just don't approach
this thing if you don't have cheese fries.

This mob basically only exists from cytology so I would be surprised if
it has existed in more than one round in the past four months.

## Why It's Good For The Game

I'm working down the remaining simple animals and a lot of them turn out
to still be quick fixes.

## Changelog

🆑
refactor: The Cytology Vatbeast now uses the basic mob framework, please
report any unusual behaviour.
/🆑
2025-01-22 20:44:35 -07:00
Y0SH1M4S73R
90b67b0541 A Small Circuit Expansion: Wallmounts, Undertiles, and Wire Bundles (#89122)
## About The Pull Request

This PR adds several circuit features, and changes several
assembly-related features to make them a bit more logical in how they
work. Included are the following changes/additions:

- Assemblies and wires have been refactored with vars that describe
their behavior:
- Assemblies have an `assembly_behavior` bitflag instead of a
`attachable` var. This var has 3 flags:
- `ASSEMBLY_INPUT`: The assembly is able to pulse the wire it is
attached to.
- `ASSEMBLY_TOGGLE_ARMED`: On activation, the assembly toggles whether
it can pulse the wire it is attached to.
- `ASSEMBLY_FUNCTIONAL_OUTPUT`: On activation, the assembly does
something other than just toggling whether it's armed.
  - Wires have a `wires_behavior` bitflag with 3 flags:
- `WIRES_INPUT`: The object the wires are attached to does something
when the wires are pulsed.
- `WIRES_TOGGLE_ARMED`: The object the wires are attached to can
activate assemblies attached to those wires, and is fine if all that
activating that assembly does is toggle whether it's armed.
- `WIRES_FUNCTIONAL_OUTPUT`: The object the wires are attached to
expects that assemblies attached to its wires do something other than
toggling themselves when activated.
- Buttons can only accept assemblies with `ASSEMBLY_FUNCTIONAL_OUTPUT`.
- Pressure plates can now accept any assembly with
`ASSEMBLY_FUNCTIONAL_OUTPUT`, not just signalers. Assembly shells
attached to pressure plates will draw power from the powernet if the
pressure plate is under a tile.
- Adds a new circuit component - the wire bundle.
- This component gives the circuit a number of wires corresponding to
the size of the shell.
- Each wire has a corresponding port on the component that can pulse,
and receive pulses from, that wire.
  - A circuit can only have one wire bundle component.
- Assembly shells cannot be attached to these wires, and no wires will
be created if the component is added to an assembly shell.
  - Available with roundstart tech.
- Adds two new shells.
- The wallmounted shell is a large shell that can be hung on walls, and
uses power from the area it's placed in.
    - Frame icon:

![image](https://github.com/user-attachments/assets/2fe9297d-44a9-4ceb-b803-a758e59b807d)
    - Constructed icon:

![image](https://github.com/user-attachments/assets/34c3ffcb-53cb-415f-952f-aec5de63cf17)
- The undertile shell is a small shell that only works when fit under a
floor tile, but uses power from the area it's placed in.

![image](https://github.com/user-attachments/assets/11ea150d-08be-4ce9-bf44-35a9d6e2d94f)
  - Both shells support usb cables.
- The above shells are available with the Advanced Shells techweb node.

## Why It's Good For The Game

The wire bundle component complements the functionality of the assembly
shell by allowing circuits to use assemblies directly in their logic.

The wallmounted and undertile shells provide ways of placing circuits
that don't necessarily take up space for machines. The undertile shell
is particularly useful for relaying usb component data over wirenets.

Pressure plates being able to accept assemblies other than signalers
expands their uses significantly.

## Changelog

🆑
refactor: Wires and assemblies have been refactored to have
directionality to them. This mostly makes it so that assemblies can only
be attached to wires it would make sense for them to be attached to.
qol: Pressure plates can now also accept igniters, condensers, flashes,
assembly shells, and door controllers.
add: Undertile circuit shells. They only work when placed under floor
tiles, but support USB cables and use APC power instead of cell power.
add: Wallmounted circuit shells. Large shells that support USB cables
and use APC power instead of cell power.
add: Wire bundle component. Adds a number of wires to the circuit
proportional to the capacity of the shell, allowing you to use
assemblies in circuit logic.
/🆑
2025-01-19 18:40:23 +00:00
Hatterhat
f057705c4f machine board naming convention pass (#88888)
## About The Pull Request
Adjusts a bunch of machine board names to comply with the general
machine board naming patterns I see.

First pass just removed a bunch of errant (Machine Board)s that were
still on board names despite them being automatically appended on
initialization, second pass set some board designs to actually have
"Board" on the end to specify that it's a board and not a whole machine.
## Why It's Good For The Game
Machine board naming consistency is probably good, actually.

## Changelog

🆑
spellcheck: A handful of machine boards should no longer have two
(Machine Board)s showing up in their name.
spellcheck: Boulder machinery boards are now labeled as boards from
autolathes/circuit imprinters.
/🆑

---------

Co-authored-by: Hatterhat <Hatterhat@users.noreply.github.com>
2025-01-14 15:54:24 +01:00
Y0SH1M4S73R
a54009fd67 Circuit Wirenet Components + Assembly Shell Tweaks (#88593)
## About The Pull Request

Assembly shells now use power from whatever machine/borg/mech/modsuit
they are attached to the wires of, instead of their own power cell, when
appropriate.

As for the meat of this PR, circuit wirenet components function like
NTnet and NFC components, but their signals are transmitted across
whatever cable network the shell (or in the case of assembly shells, the
machine or button it's inserted into) is connected to. These components
are available with roundstart tech.

## Why It's Good For The Game

Provides a somewhat intuitive way to make circuit networks that aren't
dependent on external factors to continue functioning.

NTnet components require a functional NTnet relay, which usually means
they need telecomms to be working. NFC components have a range limit,
and you need to provide a specific reference to the circuit being
communicated with. Wirenet components, on the other hand, just need the
shell to be anchored (or for assembly circuits, the thing whose wire it
is attached to), and for the shell to have a cable under it.

Also might indirectly provide a reason to use cable layers other than
the default one.

## Changelog

🆑
add: Adds circuit wirenet components, allowing data to be transmitted
and received over cable networks.
qol: When attached to a machine, mech, modsuit, or borg, assembly
circuit shells will use power from those instead of the circuit's own
cell.
/🆑
2025-01-13 16:16:12 +00:00
carlarctg
d7460f97d7 Adds a new area flag, LOCAL_TELEPORT, given to virtual domains and deathmatch arenas. (#88756)
## About The Pull Request

Adds a new area flag, LOCAL_TELEPORT.

This flag allows teleports ONLY in the same area that the teleport is
used. This allows for short range hijinks without enabling long range
exploits, and thus it's given to DMs and domains.

Changed almost all area_flags & NO_TELEPORT checks to use
check_teleport() (as now areas may use local_teleport instead, and this
lets them check for multiple things instead)

Thus I re-added Void Phase to the heretic scribe in DM and shuffled some
stuff around

(realizing now i neglected to doublecheck if blade breaking tps you to
station. need to check just in case)
## Why It's Good For The Game

It sucks you can't use teleporting abilities in temporary areas, so this
is a good way to allow this to still happen without opening the way for
gamebreaking exploits.
## Changelog
🆑
code: Adds a new area flag, LOCAL_TELEPORT, given to virtual domains and
deathmatch arenas.
code: Re-added Void Phase to Heretic Scribes in Deathmatch's Ragnarok
map.
/🆑
2025-01-06 08:55:58 -05:00
grungussuss
81f3dd4af5 fixes attack chain heck with rped and tables (#88708)
## About The Pull Request
I noticed rped was hitting tables instead of being placed on them so
this fixes that, I tested it
## Changelog
🆑 grungussuss
fix: fixed being unable to place rpeds on tables
/🆑

---------

Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com>
2024-12-26 23:34:18 +02:00
Aylong
7a817300fd Improve and extend fieldset_block and examine_block (#88678)
## About The Pull Request
Maked `fieldset_block` and `examine_block` more stylish and neat, also
`fieldset_block` no longer has a centred title.
Renamed `examine_block` to `boxed_message` and adds
`custom_boxed_message` which can be colored.

- AdminPMs, admin tickets and vote results has been wrapped into
`fieldset_block` for comfort and visibility
- Health Analyzer results painted to blue
- Vote notice and tips of the round wrapped to purple
`custom_boxed_message`
- Tooltip text border color, now uses text color, not just white

## Why It's Good For The Game
Demonstration in both themes

<details><summary>Dark</summary>


![image](https://github.com/user-attachments/assets/7175379b-b053-4fb7-bd25-65c744a21c56)

![image](https://github.com/user-attachments/assets/1728e72b-0110-4b81-9d61-8779f5fdc3a0)

![image](https://github.com/user-attachments/assets/5e6f9604-35b8-4840-b6b4-35a68f49a997)

</details>

<details><summary>Light</summary>


![image](https://github.com/user-attachments/assets/6a3d693b-e0dc-4a4b-b4d7-2ded54ce0d67)

![image](https://github.com/user-attachments/assets/c4f5e089-180f-4d13-806a-fa64f01740a3)

![image](https://github.com/user-attachments/assets/a46d52c4-ad37-4637-8cae-c4b00139efc1)

</details>

## Changelog

🆑
qol: AdminPMs, admin tickets, vote results and started vote notification
are now much more visible in the chat.
qol: Boxed messages in chat (like examine), has been restyled.
/🆑
2024-12-24 11:32:38 -08:00
SmArtKar
7ddc30783a Adds better attack animations and alternate attack modes (#88418)
## About The Pull Request

This is the first PR in a series attempting to modernize our damage and
armor, both from a code and a gameplay perspective. This part implements
unique attack animations, adds alternate attack modes for items and
fixes some minor oversights.

Items now have unique attack animation based on their sharpness - sharp
items are now swung in an arc, while pointy items are thrust forward.
This change is ***purely visual***, this is not swing combat. (However,
this does assign icon rotation data to many items, which should help
swing combat later down the line).

Certain items like knives and swords now have secondary attacks - right
clicks will perform stabbing attacks instead of slashing for a chance to
leave piercing wounds, albeit with slightly lower damage - trying to
stick a katana through someone won't get you very far!

https://github.com/user-attachments/assets/1f92bbcd-9aa1-482f-bc26-5e84fe2a07e1

Turns out that spears acted as oversized knives this entire time, being
SHARP_EDGED instead of SHARP_POINTY - in order for their animations to
make sense, they're now once again pointy (according to comment,
originally they were made sharp because piercing wounds weren't very
threatening, which is no longer the case)

Another major change is that structure damage is now influenced by armor
penetration - I am not sure if this is intentional or not, but attacking
item's AP never applied to non-mob damage.

Additionally, also fixes an issue where attack verbs for you and
everyone else may differ.
2024-12-17 12:35:52 -06:00
SyncIt21
9a83905608 General maintenance for RPED (#88074)
## About The Pull Request
 **1. Code Improvements**
- Converted vars for playing RPED sounds into defines & proc overrides.
saved some memory
- Created separate storage type for bluespace RPED(cyborg variant had
the same values so it shares this type)
 - Improved its datum storage code
- Moved RPED into its own file out of stock parts. Better file
organization
 - Autodoc for some procs

**2. Refactor**
- Strictly separates bluespace RPED interaction from normal one. What
this means is
- Removed var `works_from_distance` we now typecheck for bluespace RPED
specifically
- Moved `ranged_interact_with_atom()` from normal RPED into its
bluespace subtype. We now play the beam animation from inside this proc
rather than redundantly checking for its bluespace variant inside
machines `exchange_parts()` & playing it there
- No more snowflacky check for frames. That's handled inside its
`ranged_item_interaction()` proc

Just overall cleaner code

## Changelog
🆑
code: improved code for RPED
refactor: RPED attack chain has been refactored. Reports bugs on github
/🆑

---------

Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
2024-12-16 17:06:35 +01:00
necromanceranne
e9471b00b0 Adds the NT BR-38 Battle Rifle. A sci-fi hybrid gun, but better than the last attempt. Only SOMETIMES fails at existence. (#88095)
## About The Pull Request

A repeat of the first half of
https://github.com/tgstation/tgstation/pull/86853

The NT BR-38 Battle Rifle is a semi-automatic
railgun...marksman...carbine...rifle...thingy that uses .38 ammunition
and is magazine fed from a 15 round magazine. It comes with a scope, and
is bulky.


![image](https://github.com/user-attachments/assets/456aba07-ba0a-4ad3-993c-7fc2bc1395d6)

Sprites by OrcaCora.

### Some of its features

The gun shoots at a higher than normal velocity for .38. This means it
hits harder (30 damage compared to the standard 25), and flies faster
through the air.

The gun, however, suffers from degradation as it is used. It has a 10
shot buffer before suffering degradation. After the 10 shot buffer, it
has a 10% chance each shot to increase in degradation stage. From stage
1 to stage 5 (the maximum stage), it begins to lose fire rate and
projectile flight speed.

To recalibrate the gun, you can do one of two things; 
A) Use a multitool on the gun. This completely resets the gun, but its
pretty slow.
B) Insert it into a weapon recharger to recharge its buffer and reduce
its degradation stages.

### Some of its downsides

The weapon is EMP vulnerable. If it gets EMP'd, it immediately degrades
and loses any buffer it has. While EMP'd, there is a 75% chance it
doesn't fire when you pull the trigger. This is also true if the gun has
hit maximum degradation. Keep your guns in good shape.

It can be emagged. While emagged, the gun has increased damage (40 for
standard ammunition), but once it hits maximum degradation, it
immediately begins to catastrophically fail. It also degrades
significantly faster while emagged. There is no way to reverse this
effect, and the explosion is extremely lethal.

### Where can I find it? What about ammo?

You can purchase the gun from cargo at a significant premium, as well as
some additional magazines of some basic ammo types.

There is exactly one of these in the armory, and you can print more
magazines from the security protolathe. As research progresses, you can
print different, specialized ammunition for the rifle. (and also the
detective .38 revolver, obviously)

### New .38 ammunition types

True Strike bounces accurately between targets, but deals significantly
less damage than other ammo types (15 base, 18 in this rifle).

It is printed once the station gets Exotic Ammo.

## Why It's Good For The Game

This is a followup on my previous PR, where I tested this weapon and
gathered a whole bunch of feedback on it. Most people quite liked it.
but had some concerns that I feel this addresses.

Much of the justifications given there apply here. Obviously ignoring
anything to do with the combat shotgun removal.

Some stuff obviously has not come back from the original test. Notably,
the TRAC changes were probably a little too powerful. As much as I liked
a default entirely nonlethal ammunition type, TRAC itself is better left
as a late research goal.

In addition, I moved the explosion part to an emag effect. It's funny,
and lends itself to the original intention of the weapon; a callback to
the WT-550 incident. But it isn't a standard part of the guns mechanics.
2024-12-13 19:46:24 +00:00
SmArtKar
a27949d5f5 Advanced Color Shifting: Spraypaint Edition (#88201)
## 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.

![image](https://github.com/user-attachments/assets/6d79cac3-15a5-4850-abae-19219e1d4bdb)

Atmos MODsuit colored with a speed potion

![4cTKpeu](https://github.com/user-attachments/assets/9106e74c-8d60-489a-9ef7-4d154ddbbdf9)

Why override mode exists in the first place

![dreamseeker_fAKn811LXT](https://github.com/user-attachments/assets/3d3bea8c-5e27-4390-a924-0c243265fa6a)

Aftermath of a colorful reagent grenade.

![image](https://github.com/user-attachments/assets/ba4c78c5-cba5-42da-ac4d-7861bb329b68)

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.
/🆑
2024-12-13 00:12:14 -08:00
FlufflesTheDog
8f3f54bc22 Fix anomaly shifter deleting global themes (#88402)
## About The Pull Request
Makes the dimensional shifter relic not delete global data.
## Why It's Good For The Game
We need those. Please don't delete those.
## Changelog
🆑
fix: Dimensional shifter relics work more reliably.
/🆑
2024-12-08 15:50:03 +01:00
mcbalaam
bf6958af5e Adds a mail sorting unit to sort mail per department; some flatpack stuff (#88288)
Adds a mail sorting unit!

The unit accepts mail, stores it and sorts it per department. It can
also search for individual envelopes, change it's output tile and be
VERY loud.

At the meantime, this PR also adds two flatpack subtypes - flatpacker
subtype and mail sorter subtype. The first one is intended to be used by
mappers to have a flatpacker be accessible roundstart, and the second
one is now sold at cargo wardrobes to make the mail sorter also
available roundstart.
2024-12-08 07:02:25 +00:00