## About The Pull Request

Seeing this pattern repeated over various sections of code was starting
to piss me off
## Why It's Good For The Game
Lessens chance to cause errors with mind traits, ensures consistent
behavior, makes it easier to change how mind traits work if necessary.
## Changelog
hopefully not player facing
---------
Co-authored-by: san7890 <the@san7890.com>
## About The Pull Request
I was going through condensed runtime stastics earlier today and noticed
that we're getting thousands of runtimes from icon2base64 trying to
write into a read only savefile; which can only happen if that savefile
is opened more than once, (or is Locked)
This is likely due to some logic somewhere holding onto a reference it
really shouldn't; but also is almost certainly a byond issue since the
proc also clears the reference immediately after doing its work.
In order to combat this I've added a simple file cycling setup for
icon2base64 so that it can hopefully not run into that issue again and
by the time it gets back to a previous savefile byond has cleaned up its
lock.
## Why It's Good For The Game
See the top of
https://tgstation13.download/parsed-logs/manuel/data/logs/2023/06/28/round-209229/runtime.condensed.txt
## About The Pull Request
- Adds Roach Infusion to the DNA infuser.
- Bonuses include:
- All infused organs are 2x as healthy, notably your heart: Meaning
getting revived after being dead a while is easier
- When being attacked from behind or while lying down, take 50% less
damage from brute attacks
- Lose disgust 32x faster, making it a non-issue
- Higher toxin purge threshold (5 units, up from 3)
- Virus resistance (same as spaceacillin)
- 100 innate bomb armor, preventing explosions from gibbing you
- 90 innate bio armor
- Immunity to appendicitis, radiation, and to being gibbed by nuclear
bombs
- Downsides include:
- Knockdowns are 3x as long
- get 3x as hungry
- Ingest reagents to your stomach 1.5x slower
- Take 2x as much damage from toxins
- Toxins over the purge threshold deal 4x more liver damage (effectively
2x, as the liver has 2x health)
- Becoming a bug
- Roaches are gross
- Adds a way to kill roaches without having them splat. If they are
sprayed with bug spray, they will simply fall over, and can be scooped
up.
https://github.com/tgstation/tgstation/assets/51863163/5078c493-9e28-42cb-ae51-45fa25b67a34
## Why It's Good For The Game
More content for the DNA infuser, which benefits greatly from variety.
While initially it may seem like a lot of bonuses, a lot of them are
very niche, with the exception being the brute resilience which is the
big "actually useful" bonus you gain.
The infusion is intended to be given to Engineers, offering innate
Radiation immunity to allow them to work on the Supermatter without
needing a rad suit. Likewise, if the work goes south and the Supermatter
goes boom, their body will more than likely survive the blast.
## Changelog
🆑 Melbert
add: Adds the Roach infusion to the DNA infuser. Do you want to survive
a nuclear apocalypse? Visit genetics today.
add: Adds a way to kill Roaches without splatting them. Visit botany for
a spray bottle of pestkiller.
qol: Infuser book is more book-like
fix: DNA infuser correctly gives on-success feedback messages
/🆑
---------
Co-authored-by: Jacquerel <hnevard@gmail.com>
## About The Pull Request
- In PR https://github.com/tgstation/tgstation/pull/76356 missed a few
bits of maptext around, such as shuttle signs and the supermatter. Small
text adjustments/fixes here.
- Large amount of feedback about the context tooltips. Increases size,
lightens default color as to not be too imposing.
🆑 LT3
qol: Context tooltip size increased
fix: Fixed remnants of old maptext code on various things
/🆑
## About The Pull Request
Title.
## Why It's Good For The Game
Seriously this shit pisses me off, why are ORGAN_SYNTHETIC and
ORGAN_ROBOTIC two different things?
## Changelog
not applicable unless i fucked up
---------
Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com>
## About The Pull Request
Ok so we currently have 1 (count em) border object that wants to smooth
with other border objects. That's the tram window.
It currently does this manually, via map edits, but that's kinda crappy
so lets be better.
This pr adds a new smoothing mode to handle border objects.
Unlike other smoothing modes, it returns a bitfield of directions the
border object connects in.
I do this by memorizing a calculation of which dirs "connect" at init,
and reading out of a global list with border object direction, direction
between objects, and if it's a border object, the other object's dir.
I'm doing this primarily because it's become useful for wallening (a
spriter saw the tram thing and is doing the same thing to pod windows,
and I want to support that)
I do think it's potentially useful in other applications too tho, and I
like dehardcoding tram windows.
Also fun bonus (or maybe downside), it's nearly 0 cost because I pulled
the bitmask smoothing define into 2 subdefines, and am swapping the
handler one out to do what I want.
Oh also I got rid of a for loop in smoothing code, redundant and costs
time in list iteration
[Moves tram windows over to the new border object
smoothing](https://github.com/tgstation/tgstation/commit/114873679c94d680788edee9665fa18dba8108c0)
Also replaces some typepath chicanery with a setDir override, for
redundancy in future
Oh and there's a update paths script too, to be nice
## Why It's Good For The Game
More visual possibility in future, fixes a hack we have currently, and
makes some spriters happy.
## Changelog
🆑
fix: Dehardcodes some stuff with tram windows, they'll be easier to map
with now
refactor: Border objects can now smooth with each other. I'm sure
something cool will come of this
/🆑
I debated adding @Watermelon914's suggestion about a special value for
broadcasting on 4+, but then I realized that's not backwards compatible
at all.
Hmmm...
Broken by #73623Fixes#75368
I have missed out on like 150 points to this untill I figured out what
was happening
The proc passes the mob, but expects the mind, so it runtimes and never
pays you your hardcore random score
sigh
🆑
fix: Hardcore random pays your score again as non-antag
/🆑
## About The Pull Request
Adds defines for gasses and replaces uses I've found to instead use the
defines.
Can you believe I made this PR while trying to work with Xenos? This
sucks!
## Why It's Good For The Game
There's a lot of different uses of things like "o2" and "plasma", and
they are pretty inconsistent. In some places, it's "hydrogen", in others
it's "h2". In some it's "plasma", others "plasm". This unifies it all
under defines so it has a less chance of breaking in the future.
## Changelog
Nothing player-facing.
## About The Pull Request
It's easier to parse, and makes more sense when you read it. This way
I'll never have to add yet another case to my parser for someone
changing where a space goes or something.
Moves qdel into its own category cause the old name looked ugly (yell if
this is dumb)
Added a bitfield to entries pulled from categories, adds a new flag that
enables pretty printing json lists.
## Why It's Good For The Game
IMPROVES my workflow
## Changelog
🆑
server: del logging is now done by outputting to a json file again, but
this time we're using ACTUAL json and not just a big text string with
newlines and shit
/🆑
---------
Co-authored-by: Zephyr <12817816+ZephyrTFA@users.noreply.github.com>
Disclaimer im mostly making this pr for the experience if anything.
Also anyone can replace the sprites if they want to I`m just making them
so itl be done, idk what a plasteel machine is supposed to look like.
The circuit boards to make these machines are unlocked by the advanced
power manipulation tech
The entire shield
- Has one big healthpool (base of 50)
- Has a configurable radius
- Takes damage from hot gas and emp
- Has regeneration (it gets nerfed by alot of things that I have to talk
about separately)
- When the shield is broken the generator must regenerate at 0.25x speed
before coming online again
- can be configured to either only generate a shield externally (in
space) or both internally and externally at the cost of half the regen
rate
- Regen rate is also reduced based on the ratio of the shield radius and
the max radius that the generator is capable of generating
- Alot more that im too tired to explain at the moment
The base stats of the shield (max health, regen rate, max radius) all
scale with the tier of parts used in the main generator.
4 other machines (3 are finished code-wise as of now) the charger (regen
rate), the relay (max radius) the well (max health) the node (allows for
more connections) can all be connected to the main generator to boost
its core stats based on their part tiers
In the future there is a possibility of specialization / modifications
to the forcefield at the cost to the core stats
## About The Pull Request
We log this information once, on SSgarbage shutdown. Putting it in a
json is kinda pointless, it exists to be read when we see massive
overtime from ssgarbage, that's all.
Something something reee my workflow.
## Changelog
🆑
server: qdel statistics are once again logged in qdel.log, instead of
the otherwise typical json logging system
/🆑
## About The Pull Request
Converts butterflies into basic mobs.
Also a little list organisation.
<details>
<summary>Yep, those are some butterflies alright</summary>

</details>
## Changelog
🆑
refactor: Converted butterflies to the basic mob system
add: Butterflies can now be grown in cytology
/🆑
## About The Pull Request
Converts all logging, excluding perf and investigate, to json.
I focused on making the system as easy to use and as easy to add new
categories as possible.
Due to issues related to logging to world at global creation logger is
now a byond real, which is created directly before Master
Log categories support versioning, secret flagging, and sub-category
filtering. Although all of this is entirely optional for coders.
If you ever want to add a new category and use it, all you need to do is
make the barebones category datum and the define.
I've kept existing procs such as log_game, and simply turned them into a
wrapper for Logger.Log(xxx, ...)
## Why It's Good For The Game
Makes processing and filtering logs much easier in the future, while
only minimally downgrading log crawling experience.
I am also working on a log viewer frontend for admin usage however that
will take a little bit longer to finish up.
Also makes special logging and data tracking much easier thanks to a
data list processing implementation and handling
## Changelog
🆑
server: All logs are now formatted in json, excluding perf and
investigations
/🆑
---------
Signed-off-by: GitHub <noreply@github.com>
Co-authored-by: tattle <66640614+dragomagol@users.noreply.github.com>
Co-authored-by: Kyle Spier-Swenson <kyleshome@gmail.com>
Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com>
## About The Pull Request
I have been debugging this stupid macro for the past nearly five hours,
to finally figure out why it was breaking. If you had something like `a
|| 0` in what you called the macro with, it would somehow manage to
break the cache. This makes it far more foolproof, and will ensure that
it doesn't break here anymore, because debugging this has to be one of
the biggest pains in my ass I've ever had.
## Why It's Good For The Game
So shit like this

Doesn't end up breaking your CI (or even worse, the game in prod), in
places unrelated. At least now it shouldn't be overwriting values in the
cache.
It shouldn't have to do verification that you're doing the right thing,
that should be left on the person using the macro because it was meant
to be faster than a proc call, adding too much verification overhead
kind of just loses some of that speed.
## Changelog
🆑 GoldenAlpharex
fix: Makes checks for the station z level more robust against coders
doing less intuitive stuff, thus protecting it from breaking in weirdly
difficult and seemingly unrelated places (I'm looking at you, nuke
cinematic unit test).
/🆑
## About The Pull Request
Fixes a tiny mistake i made in #73850 which caused a hell a lot of
signal override runtimes during area editing with station blueprints. It
happens allow it.
## Changelog
🆑
fix: signal override & other area sensitive runtimes during area editing
with station blueprints
/🆑
<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may
not be viewable. -->
<!-- You can view Contributing.MD for a detailed description of the pull
request process. -->
## About The Pull Request
So they just had list from 6 coins and not random picking of coins, so
now its random.
It will also spawn chococoin because it's a coin too.
But won't spawn `coin/gold/debug` because it's debug and eldritch coin
because comxy asked about it.
Added chococoin to `/obj/effect/spawner/random/entertainment/coin` and
holdables list of wallet.
<!-- Describe The Pull Request. Please be sure every change is
documented or this can delay review and even discourage maintainers from
merging your PR! -->
## Why It's Good For The Game
Random is funny.
<!-- Argue for the merits of your changes and how they benefit the game,
especially if they are controversial and/or far reaching. If you can't
actually explain WHY what you are doing will improve the game, then it
probably isn't good for the game in the first place. -->
## Changelog
<!-- If your PR modifies aspects of the game that can be concretely
observed by players or admins you should add a changelog. If your change
does NOT meet this description, remove this section. Be sure to properly
mark your PRs to prevent unnecessary GBP loss. You can read up on GBP
and it's effects on PRs in the tgstation guides for contributors. Please
note that maintainers freely reserve the right to remove and add tags
should they deem it appropriate. You can attempt to finagle the system
all you want, but it's best to shoot for clear communication right off
the bat. -->
🆑
add: Indusrial Gold and Regenerative Gold extracts now spawn random
coins and not just list of 6 coins. But no mythril as it has miserable
chance to have summoning effect which have even more miserable chance to
spawn something dangerous and not just mice.
add: Chococoin now has a chance to spawn wherever the coins are used to
spawn (wallets, greed ruins, deltastation bar)
/🆑
<!-- Both 🆑's are required for the changelog to work! You can put
your name to the right of the first 🆑 if you want to overwrite your
GitHub username as author ingame. -->
<!-- You can use multiple of the same prefix (they're only used for the
icon ingame) and delete the unneeded ones. Despite some of the tags,
changelogs should generally represent how a player might be affected by
the changes rather than a summary of the PR's contents. -->
---------
Co-authored-by: Fikou <23585223+Fikou@users.noreply.github.com>
## About The Pull Request
Most calls of runEvent() now provide a cause that is read out to
deadchat. announce_deadchat() has been slightly adjusted to accommodate
this.
Previously, everything that wasn't a truly random event would broadcast
with the same generic "XYZ has just been triggered!" message. Now, you
get a little bit more detail as to why/what triggered the event.
Some helpers in the __HELPERS/events.dm file have been made, for forcing
events normally/async/after a delay (using an addtimer). This also moves
a lot (but not all) instances of events being forced to these helpers.
Some samples:

Traitors using uplink viruses to turn off the power/comms.

Beer nuke!

For when a traitor takes an Space Dragon final objective, which summons
a carp migration event.

Wizard ritual events!

Even this one!
This also changes runEvent() to run_event(), because I figured I'd be
touching every single instance of the proc anyways.
## Why It's Good For The Game
Better feedback, less confusion amongst deadchat's constituents.
Some of them may be a bit self-explanatory, but in some cases
(especially the apocalypse rune) it's beneficial to know that an admin
isn't the one behind it.
<!-- Argue for the merits of your changes and how they benefit the game,
especially if they are controversial and/or far reaching. If you can't
actually explain WHY what you are doing will improve the game, then it
probably isn't good for the game in the first place. -->
## Changelog
🆑 Rhials
qol: Deadchat now gets more juicy details on what has triggered a
non-randomly occurring random event.
code: There are now helpers for forcing events in a variety of ways.
More events! More events!!!!!!!
/🆑
- Removes unnecessary real global vars.
- Adds comments pointing to the init order defined in
/code/game/world.dm.
- Prevent people using `GLOBAL_REAL_VAR` and `GLOBAL_REAL` to circumvent
init order.
- Properly type `PROFILE_STORE` real global.
- Refactored `make_datum_references_lists()` and moved the call to it
into `GLOB` init with duct tape.
- Renamed `GLOB.admin_log` to `GLOB.admin_activities` as it wasn't
actually a log file.
- Whitelist loading happens in config.
- Renamed `SSdbcore`'s `SetRoundID()` to `InitializeRound()`. Now
handles calling `CheckSchemaVersion()`.
- Created macro for setting up log `GLOB`s.
- Removed log line for `GLOB` count.
- Moved call to `make_datum_reference_lists()` to
`/datum/controller/global_vars/Initialize()`. I slimmed it down where
possible too.
- Updated comments about world init order.
- Move `load_admins()` call to after log setup.
- Removes unused function `gib_stack_trace()`.
- Removes a bunch of unused log `GLOB`s.
- Unlocks the secrets of the universe by finally making the first
executed line of code deterministic.
No functional changes. Closes#74792
Testmerge thoroughly.
---------
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
## About The Pull Request
Datum var reads are expensive, and sorting code does a lot of them.
let's work on that together, as a group.
There's maybe 250ms of sorting cost sitting in mostly global variable
work. I'd like to start chopping at that.
My tracy profiles aren't the most helpful, estimating this to save about
14% of timSort over the course of init, tho that's slightly noisy and
not the most reliable
## Why It's Good For The Game
speed
## About The Pull Request
It broke stuff bad and I don't care about the save (0.005 seconds)
enough to work on it
## Why It's Good For The Game
Closes#74907
## About The Pull Request
Moth and I came up with an affront to god and man, and used it to track
the time spent creating /static (and in theory /global) variables (this
happens right at the start of init)
They cost as a sum about 0.05 seconds btw, at least currently.
```
/datum/timer
var/key
/datum/timer/New(file, line)
src.key = "[file]:[line]"
/datum/timer/proc/operator*(x)
rustg_time_reset(key)
return x
/datum/timer/proc/operator+(x)
var/time = rustg_time_microseconds(key)
world.log << "TIMER: [key]: [time]"
return x
Regex:
var/static/([\w/]+) =
-> var/static/$1 = (new /datum/timer(__FILE__, __LINE__)) * (new /datum/timer(__FILE__, __LINE__)) +
```
Output on moth's pc looks like this, time in microseconds
[output_sorted.csv](https://github.com/tgstation/tgstation/files/11241900/output_sorted.csv)
Most of this is either icon_states() memes (which appears to be cached
btw, that's interesting), or a variation on typecacheof()
There is one get_asset_datum call, but that is ALREADY cached and so is
just redundant. That's a good 0.01 seconds saved.
The rest of the time here is slightly more interesting.
The majority of typecacheof() is iterating the output of typesof(), a
byond internal proc that returns a list of types that either are or are
the child of the passed in type.
A decent chunk of time here (0.005 seconds, or 10% of the proc) can be
saved by unrolling the arguments to the proc.
It takes an arbitrary amount of typepaths as input, but we can't like
use arglist() here (cause this is an internal "proc"), so instead we try
a window of args, passing in null if we start to try and take in too
much.
Window size matters, zebra fits better into 4 then 5, especially because
of how grouping needs to work to make this effect happen.
We save about 0.001 for zebra btw, which is around about 7%. It's lower
cause we need to group the paths beforehand I think.
The speedup is minor, but it DOES exist. Plus it's fun.
## Why It's Good For The Game
Microing is a hell of a drug
## About The Pull Request
https://github.com/tgstation/tgstation/blob/0426f7ddbaa91439c7278189101f5db9c7f2ed95/code/game/objects/items/stacks/stack.dm#L449
Ok, but can we not?
This PR refactors sheet crafting to generalize all the cases that were
previously locked behind grille/window type checks and such. In their
stead there are bitflags that can be set to achieve certain behaviors.
All the behavior from before should be preserved, but now it can be
extended to other items. E.g. if you want a railing that can be crafted
underneath directional windows, or an item that behaves like a grille
does--it's just a matter of setting the right obj_flags for it now.
This makes it very simple and painless to add new recipes that use
directional crafting! It's all modular now.
<details><summary>Details</summary>
---
### What I've done:
-Eliminated all the type checks, instead it will now be handled by
object flags and recipe vars, making for a much more configurable
system.
-Added two new obj_flags: `BLOCKS_CONSTRUCTION_DIR` and
`IGNORE_DENSITY`.
-Additionally, I renamed the existing flag `NO_BUILD` to
`BLOCKS_CONSTRUCTION`.
-Changes the proc `valid_window_location` to `valid_build_direction`,
and makes it work for things other than windows.
-Removed a deprecated `window_checks` var from the stack_recipe datum.
-Added three more vars to the stack_recipe datum: `check_direction` and
`check_density`, `is_fulltile`
-Decoupled `on_solid_ground` from the object density check. Now you can
set those separately, allowing you to make recipes that forbid/allow
building things over other things while in space.
---
### What the new flags do:
`BLOCKS_CONSTRUCTION` works as before---prevents objects from being
built on the object. I felt that the previous name was not descriptive
enough, you should know exactly what it does just from looking at the
name.
_example: dna scanner_
`BLOCKS_CONSTRUCTION_DIR` -- setting this on an object will prevent
objects from being built on it when their directions are the same.
_example: directional windows, windoors, railings_
`IGNORE_DENSITY` -- setting this on an object will cause its density to
be ignored when performing the construction density check. This could
have other potential uses as well in the future.
_example: grilles, directional windows, tables_
These three flags cover all the bases for the types of items that are
currently craftable, so there is no more need for any type checking or
weird snowflake window checks. Simply set the appropriate flag and it'll
work as you would expect.
---
### What the recipe vars do:
`check_direction` tells the recipe to check if there's something in that
direction with the `BLOCKS_CONSTRUCTION_DIR` flag set.
`check_density` tells the recipe to run the density check when set. This
is true by default. There are very few items in the game that currently
have this set to false--namely grilles. Setting this to false will make
it so that the object can be constructed regardless of what is in that
tile (unless `one_per_turf` is also set, which will make it so that you
can't craft the same thing twice in the same turf).
`is_fulltile` is used for fulltile windows, but it doesn't necessarily
have to be--you can give this to any recipe and it will adopt the same
properties as that of the fulltile window. Basically they have a special
case where they shouldn't be able to be built over directional
constructions, where normally things would be able to be. Setting this
makes check_direction true as well.
---
### In summary:
Sheet crafting still works just as it did before. But the backend of it
has gotten a glow up and will be able to more easily support new
behaviors.
</details>
## Why It's Good For The Game
This makes the crafting system much more flexible to add recipes to, and
will prevent bad code practices of stacking more conditionals down the
line whenever someone wants to add an item that behaves like grilles or
directional windows in how they are constructed.
It had to be done. Those window checks were a mess.
## Changelog
🆑
qol: added fifty stack versions of remaining glass sheet stacks for ease
of debugging
refactor: refactored sheet crafting to better support directional
constructions that aren't windows
/🆑
---------
Co-authored-by: san7890 <the@san7890.com>
## About The Pull Request
Adds two new global helper procs, find_maintenance_spawn and
find_space_spawn. These check the list of maintenance/space carp spawn
landmarks, and return the turf of a random one.
The find_maintenance_spawn helper has two arguments, for atmos safety
checks and making sure the spawn is properly shrouded in darkness.
This also includes some tidiness changes to the ghost_role event file,
because the helper was originally just going to be a proc on ghost role
events.
**Stuff moved to find_maintenance_spawn:**
- Spiders
- Nightmares
- Fugitives
- Paradox clones
- Morph
**Stuff moved to find_space_spawn:**
- Space Dragon
- Loneop
- Ninja
- Slaughter Demon
- Revenant backup spawn location
If we ignore all of the autodocing, this should remove about a dozen or
two lines of code.
## Why It's Good For The Game
Reduces an amount of duplicated code. Also makes future implementation a
bit easier and less copy-pastey.
## Changelog
🆑 Rhials
code: Adds two new super-duper helpful helper procs for finding a
maintenance/space spawn location, for all of your
event/midround/whatever needs!
code: Moves all midrounds/ghost_role events that hinged on
maintenance/space carp spawns to the aforementioned helpers.
code: The ghost_role event module file is now autodoced.
/🆑
## About The Pull Request
Fixes#74605
the problem starts with `detect_room()` proc. This proc returns turfs
even those with `atmos_adjacent_turfs` = null. This means it returns
turfs that has a wall, airlock, window etc i.e. whatever that stops air
from flowing through it. This coupled together with `create_area()`
causes some wierdness.
Let's take an example

Area A is well defined i.e. it has been created via the station
blueprints and is highlighted in green, Area B however is only
theoretical i.e. we haven't created it yet or we are about to create it.
Now you might be thinking Area A is completely walled & sealed off, it
should be physically impossible to expand it unless we broke down one of
it's walls and so since we are standing in Area B it shoudn't even give
me the option to expand area A Right? right? r.i.g.h.t?

Well PHFUUK. The area editor completely ignores the laws of physics and
allows me expand Area A anyway. This could cause some real power gaming
shit because if you create an area next to an area having an APC you
could use that area power without even making your own apc by simply
expanding that area(like using someone else's wifi from outside their
house without them even knowing)
#73850 accidently built on top of this as it relied on this to detect
duplicate APC's but the checks became way too strict as it would check
areas of surrounding walls for apc's and throw the conflicting apc
error. You can now build room's next to each other even if they have
fuctioning apc's however you still can't build rooms in space on top of
shuttle walls because that's been the default behaviour for years and
hasn't been touched one bit.
## Changelog
🆑
fix: station blueprints no longer expands & detects areas of non atmos
adjacent turfs.
/🆑
The check queue is 5 minutes long because that's the longest a client
can hold onto a reference. Without clients, we can drastically decrease
the time we have to wait. This lowers the time down to 10 seconds
(though everything right now deletes in 5).
This will represent a 5 minute decrease in CI across the board, freeing
up runners.
Makes a few changes to stuff that was being held for more than 10
seconds.
- `VARSET_CALLBACK` now works through weakrefs, to allow for pAIs to
have their holochassis init timers.
- Nar'Sie cleans herself up in GLOB.cult_narsie if she's deleted.
- "Spooky portals" no longer hold onto a reference for 2 minutes.
- `poll_candidates` short circuits to an empty list if there are no
candidates, to avoid several 30 second+ long timers
Originally this was going to be a more clever hack from @MrStonedOne
about short circuiting if everything deletes before the wait, but we
realized that basically nothing actually holds onto references for that
long without clients, and that nothing really should anyway
## About The Pull Request

**This PR:**
- Reworks most* existing soup into reagents.
- Adds Stoves and Ranges. Ranges replace most* existing ovens.
- Adds soup pots, to cook soup
**How does it work?**
In the kitchen you will find a stove now.
Stoves act as a "reagent container heater", essentially a chem heater.
You can set a pot onto the stove.
To make soup, visit the cooking recipe book for a guide. Most recipes
are the same as before, just tweaked slightly - Add water to the pot (50
units for 1 batch generally), then add all the corresponding ingredients
to the pot. Set the pot out on the stove and right click it to turn it
on. If the recipe's correct, shortly it will start to mix and give you
soup!
One soup recipe will give you roughly 3 servings of soup. You can pour
our the soup into a bowl using a ladle or just by pouring it manually.
Of note: **All of the reagent contents of the ingredient are transferred
into the soup.** Better, more nutrient rich ingredients produces more
soup, and poisoned produce will pass it on.
If you place the soup into a chem master, you will notice it's roughly
half "soup reagent" and half a variety of reagents, including nutriments
/ proteins. This is your soup! It is recommended you serve your soup
with the reagents included, as they make up more nutrition for the
customer, however you can separate it out if you're picky.
**Todo:**
- [x] Fill out the PR body a bit more
- [x] Mapping (wait for big merge conflict pr to go past)
- [x] Soup colors
- [x] Balance pass over for soup recipes
- [x] TODOs
- [ ] Unit tests
- [x] Cullen Skink's recipe is invalid
- [x] Try to see if there's an easy way to prevent soup from fattening
you up too easy.
## Why it's good for the game
Adds some more depth to the kitchen and moves chef away from the
click-button-get-food style that exists.
Allows for inherently custom soups by the way of making it reagents, so
no need to support custom soup food items.
## Changelog
🆑 Melbert, stove and pot sprites by Kryson, ladle sprite by Kinneb
add: Kitchens are now stocked with Ranges.
add: You can now print (and create) Stoves.
add: The dinnerware vendor now dispenses ladles.
add: Spoons can now actually spoon... things.
add: Soup has been reworked entirely. Soups are now reagents, cooked via
a soup pot on a Stove or Range. Simply add water and your required
items, then apply heat. Be careful not to boil over!
add: Stoves, Ranges, and Griddles will now heat up their surroundings -
don't turn them on around plasma!
fix: Fixes being able to cook in an Oven while the room is depowered
qol: Hitting a customer bot with an incorrect recipe no longer counts as
a hostile attack leading to your demise shortly after
refactor: Customer bots that request a reagent now use custom orders
code: Cut down a lot of code in the crafting menu code, and removes some
ugly ispaths
del: Soup is no longer food items, so can't appear in random food pools
(at least not yet).
balance: Virus Food recipe now requires you cool it to 200k.
/🆑
## About The Pull Request
The helper proc calculates a list of turfs from the expected destination
and the given error ranges, however when calculating width/height for
grabbing a list of turfs to pull from it incorrectly passed in those two
vars as zero based instead of one based, and so when the define went to
calculate that list of turfs it was actually ending up grabbing a 2x2
list where the bottom left turned into the top right.
## Why It's Good For The Game
Syndicate teleporter is now only randomized in range
## Changelog
🆑
fix: Syndicate teleporter is no longer secretly nerfed due to internal
code mishaps. (-1 range)
fix: Syndicate teleporter now gibs you where it should correctly;
resulting in it being much more dangerous to use
/🆑
## About The Pull Request
Fixes#74376Fixes#69714
This fixes a spelling error which prevented traitors from spawning the
gear they were being given.
Additionally it adds a check for z level 0 in `is_station_level` because
during my testing it was sometimes picking up a dummy mob in presumably
the CI test area and runtiming? This prevented the meteor from spawning
at all.
## Why It's Good For The Game
Makes event work.
## Changelog
🆑
fix: Traitors should be able to summon their satellite hacking supply
kit.
fix: Dark Matteor shouldn't crash on spawn and fail to arrive.
/🆑
## About The Pull Request
Removes emergency meetings. Uh, let me know if I missed anything
## Why It's Good For The Game
We gotta come up with NEW ways to ruin the round each year, this one's
so old and busted
## Changelog
🆑
del: Votes out some sussy emergency meeting code
/🆑
## About The Pull Request
Floating point inaccuracy fun.
Since it's possible to have a `minimum`,`maximum`, and `step` that are
floats we need to round everything to `step` to ensure the comparison
operations work.
If we do not do this, there is no guarantee that `if(min <= number &&
number <= max)` will work correctly.
For example, in the linked issues, this manifested as the minimum value
(0.8) being considered invalid when the input was also 0.8.
Fixes https://github.com/Skyrat-SS13/Skyrat-tg/issues/9507
Fixes https://github.com/Skyrat-SS13/Skyrat-tg/issues/14394
## Why It's Good For The Game
Fixes an obscure bug that has gone unnoticed for a couple years.
## Changelog
🆑
fix: fixes floating point inaccuracies in numeric prefs
/🆑
## About The Pull Request
Refactors regenerate organs to be slightly more intelligent in handling
organ changes and replacements.
Noteably:
- We don't remove organs that were modified by the owner; such as
changing out your heart for a cybernetic
- We early break out of the for loop if they aren't supposed to have an
organ there and remove it
- We check for the organ already being correct, and just healing it and
continuing if it is
Also changes the names of some of the organ helpers into snake_case
### Mapping March
Ckey to receive rewards: N/A
## Why It's Good For The Game
## Changelog
---------
Co-authored-by: Jacquerel <hnevard@gmail.com>
## About The Pull Request
This is a continuation of
https://github.com/tgstation/tgstation/pull/74085 - I announced in the
comments there that this would be my next PR, and this is it.
Removes SSnetwork, ``/datum/ntnet``,
``/datum/component/ntnet_interface``, ``var/network_root_id``, the
network unit test, and a lot of other things related to networks.
- NTNet circuits now check for an Ntnet relay, and uses signals to
operate.
- Logs in Wirecarp is now only for PDA and Ntnet Relay things, so you
can no longer see what ruins exist using it (why should Wirecarp know
that Oldstation spawned? The flavor is that they dont know its there).
- Removed it from MULEbots entirely, I don't think it even did anything
for them? Botkeeper seems to work without it, so it's possibly there
from pre-tgui PDAs.
- Moves assigning random names to a base proc instead of being tied to
network, this is things like random-naming scrubbers/vents. The behavior
hasn't changed at all.
- Makes Ntos work for consoles when relays are down, as the comments
said they're supposed to (because they're wired). I think this was an
accidental change on my part, so this is a revert of that.
## Why It's Good For The Game
Ntnet is ancient code that hasn't given us much that we can't do with
already existing alternatives, we've been slowly moving away from it for
init times, and though a large portion of that was limited to airlocks,
I still don't think this is a system worth keeping around.
It's way too complex to expect feature coders to do anything with it,
and too old with better alternatives for anyone to want to improve any
of it.
## Changelog
🆑
fix: Computers are now properly connected to Ethernet, and can use Ntos
when Relays are down.
refactor: Removes Ntnet and Ntnet interfaces, which was only used by
Ntnet circuits (which now directly checks for a Relay to work) and
MULEbots, which did nothing with it.
balance: Wirecarp no longer tells you what ruins spawned in a round,
instead it's limited to PDA logs, and tells you the source too. This
means the RD can catch someone running illegal programs if they don't
make any attempt at hiding it.
qol: Wirecarp logs is now set to save 300 at once, instead of 100 and
being increased to 300 by the RD during the round. This is pretty
insignificant, since there's no reason to NOT want as many logs as
possible.
/🆑
---------
Co-authored-by: Zephyr <12817816+ZephyrTFA@users.noreply.github.com>