Commit Graph

3259 Commits

Author SHA1 Message Date
Bloop faaa1f1516 Ghosts now have (better) runechat (#95843)
## About The Pull Request

Ports our optimizations to the version of ghost runechat introduced by
https://github.com/tgstation/tgstation/pull/95223

Instead of looping through all the mobs a second time it will do it in
deadchat_broadcast(). Also adds a global for if drunechat is
enabled/disabled and an admin verb for toggling it on or off.

<details><summary>still works</summary>

<img width="330" height="220" alt="dreamseeker_kkNBPBjbMv"
src="https://github.com/user-attachments/assets/4706ad98-fafe-4f88-9de0-6b72983ab044"
/>

</details>

## Why It's Good For The Game

Better option for performance

## Changelog

🆑
code: speeds ghost runechat up a bit, and makes it show as italic
admin: adds a 'toggle dead runechat' admin verb in case you need to
disable it midround for an event or something
/🆑
2026-05-05 14:54:04 -04:00
Bloop e6e0200edb Makes quirk points configs get loaded into vars on the subsystem, + a small biome fix (#95941) 2026-05-03 20:23:12 +02:00
levels0 d2f84512b5 [No GBP] Actually fix random recipes for real (#95895)
## About The Pull Request
Just the fix parts from #95892
Fixes #95876
## Why It's Good For The Game
## Changelog
🆑
fix: metalgen and secret sauce should now generate properly
/🆑

---------

Co-authored-by: l0 <-->
2026-04-27 18:23:15 +02:00
John Willard aa4dc56835 Removes Station-time (more time changes) (#95744)
## About The Pull Request

Removes Station-Time entirely
Server Time is now NST (Nanotrasen Standard Time). SS13 takes place
exactly 540 years in the future of the current day, so every second is 1
second in-game.
Round Time is now PT (Pay-Time), how Nanotrasen keeps track of how long
the current rotation of Employees has been working for.

Telecomms uses NST due to its importance of being the communication to
the blackbox.

Autopsy report, clocks, scientific reports and requisitions use both
timestamps due to them being more official documents that NT may need to
know beyond just the current round (just for flavortext).

Pretty much everything else (Det scanner, PDA, IC logs, Time-of-Death,
AI law changes, Cyborg file downloading) uses PT

PT
<img width="305" height="217" alt="image"
src="https://github.com/user-attachments/assets/cef73025-6292-4f9c-8565-197397bda2ca"
/>
<img width="168" height="59" alt="image"
src="https://github.com/user-attachments/assets/a99db568-045d-45fc-8206-0d9a7b13c7d2"
/>
<img width="308" height="122" alt="image"
src="https://github.com/user-attachments/assets/37ca6f17-8916-4af2-9c91-0f0707038ca5"
/>



https://github.com/user-attachments/assets/29445051-c98b-4af3-a657-812083aab91a


Clock (Literate)
<img width="748" height="292" alt="image"
src="https://github.com/user-attachments/assets/c824e812-91b5-4737-858d-768336e9a7c4"
/>

Clock (Illiterate)
<img width="446" height="94" alt="image"
src="https://github.com/user-attachments/assets/90d5ea0d-eaff-4ced-aa31-ffdf0b4832a5"
/>

New paperwork time working properly

<img width="311" height="190" alt="image"
src="https://github.com/user-attachments/assets/6d048926-db61-4c91-893b-ce93e1ea7775"
/>

NST
<img width="800" height="115" alt="image"
src="https://github.com/user-attachments/assets/35ffde49-13c1-4ce7-ab24-858e48b608bd"
/>
<img width="1288" height="142" alt="image"
src="https://github.com/user-attachments/assets/40c30d16-e0de-4efc-b460-9486eeb901d6"
/>

# Other changes

1. Circuit time checker will now get the value of the given input (Hour,
Minute, Second) rather than the full dedisecond time converted into
hour/minutes/seconds

<img width="270" height="67" alt="image"
src="https://github.com/user-attachments/assets/097440cc-1c45-447f-9976-18de7f9c722c"
/>

2. Turns nightshift into a round event that'll last approximately 22
minutes
3. 12-hour pref (doesn't apply to the stat panel because it's global
info) & removal of "TCT" time

<img width="569" height="440" alt="image"
src="https://github.com/user-attachments/assets/d39083b1-d248-41c0-9a1c-b2398ca203a7"
/>

4. The chocolate pudding negative moodlet is now based on the server's
IRL time.
5. Admins can now use ``class``, ``style`` and ``background`` (they were
already given perms to use ``img`` so hiding background, which was
removed to prevent image embedding, is pointless)
6. Also fixes ``year`` being off on localhost.


## Why It's Good For The Game

Server Time is approximately 1s = 12s converted, not including it
desyncing from lag (I believe?).
This makes it pretty much impossible for people to actually use this as
a unit of measurement for in-game actions.
Different things also uses different timestamps which is a bit more
confusing.

The main change here is for accessibility and, hopefully, using time as
a source of immersion. "20 minutes ago" is no longer OOC, they're just
speaking in PT. There's no timezones in space, Nanotrasen Standard Time
is the closest there is, but Pay Time is how NT considers when you get
your paychecks, so it's what is more commonly used.

It also fixes major inconsistencies between "IC time" and "Station
time", things like breakfast moodlet was the first 15mins of the round
despite the round starting like 7 hours in? Nukies with an L6 SAW firing
down the halls was shooting like 1 bullet every 3 seconds (assuming 4
bullets per second), overall there was just a disconnect between how
long time actually is in the universe.

The secondary reason for this change (though it is what pushed me to
actually get around to making this change) is the greater stat-panel
removal. This hopes to lessen the dependence on the stat panel for
station-time by making it easier to understand, and the end-goal I have
is for this information to be limited to Admins & the AI (AI will get
the IC version with the accurate year), so until that happens I would
like to improve the use of station-time by making it consistent (for
example, you should only care for PT for IC, which is also what your PDA
displays), so that when it gets removed it won't leave players timeless.

If you haven't already, and is interested in helping remove the stat
panel, every entry that needs to be removed can be found here -
https://hackmd.io/443_dE5lRWeEAp9bjGcKYw?view

Closes https://github.com/tgstation/tgstation/issues/94988

## Changelog

🆑
del: Removed Station Time, now we use NST (Nanotrasen Standard Time),
which is IRL server time +540 years, and PT (Pay Time), the amount of
time since the round has started.
del: Station nightshift is now a Station event rather than being based
on Server time.
balance: Time circuit's Unit of Measure now tells the amount of time in
hour/minute/seconds rather than giving the whole time translated to
hours/minutes/seconds.
qol: Added a 12-hour clock pref for people who prefer it.
qol: Hovering over NST timestamps on official documents will now
translate how much it is in PT/Shift Time.
admin: Admins can now use style/class/background in their papercode.
/🆑

---------

Co-authored-by: Isratosh <Isratosh@hotmail.com>
2026-04-25 14:13:31 -06:00
Ghom 5110eef308 Express consoles have crab rockets once again... (#95817)
## About The Pull Request
Alternative to https://github.com/tgstation/tgstation/pull/95658 that
involves fewer lines rather than more.

## Why It's Good For The Game
Makes it possible to order crab rockets on the express console without
copypasta. I'm not sure if express consoles are supposed to be usable
for special/emag orders (there was a check against that in the code for
some reason), but because they've had the exact same options of a
standard cargo delivery console for such a long time and because I
haven't found any explicit reason for that to not be the case (in lieu
of that, I found a bit of a reference to homoerotic material in the code
comments), I guess it's fine and nothing bad will happen.

## Changelog

🆑
fix: Packs exclusive to the express console (crab rockets for example)
can now be ordered from express consoles.
/🆑
2026-04-23 09:39:26 +12:00
Tsar-Salat bb357ce892 Fix tattoo persistence version (#95839)
## About The Pull Request

Hi, strange thing with tattoos.


https://github.com/tgstation/tgstation/blob/55366497a3f156f5553a6446edf4c0b0cbba6716/code/controllers/subsystem/persistence/tattoos.dm#L25-L42

The tattoo persistence version seems to be setting based on engravings'
persistence version, ``ENGRAVING_PERSISTENCE_VERSION``

Yet, in ``load_prisoner_tattoos()``, the conditional checks the value of
TATTOO_PERSISTENCE_VERSION

https://github.com/tgstation/tgstation/blob/55366497a3f156f5553a6446edf4c0b0cbba6716/code/controllers/subsystem/persistence/tattoos.dm#L10-L11

This PR just replaces the engraving version being set with the tattoo
version being set.
## Why It's Good For The Game

This seems rather blatantly incorrect. 
The TATTOO_PERSISTENCE_VERSION has no setter for its value other than
when defined.

Realistically? This does nothing. They are both 0 lol.
2026-04-23 08:58:49 +12:00
Lucy 9b6e752f3e Makes lighting objects objects again (#95332)
## About The Pull Request

Continuation of https://github.com/tgstation/tgstation/pull/78857

FOR TOOO LONG WE HAVE SUFF-
Ok yeah so like, we made them overlays to save on maptick, but with
threaded maptick that is potentially not an issue anymore.
I'm opening this pr so I can tm it and see. If it works, it'll save
about 50% of lighting object update costs, which is pretty damn good.

I'm also removing the fullbright light icon state, since it is barely
ever used (it was added as a clientside op, but we don't hit fullbright
very much at all so it does nothing but eat my cpu time)

Also also changing how SSlighting does its resolution. Rather then
waiting for all sources to process, then working on corners and objects,
instead we will do all the sources we had at the start, then all the
sources after, and so on.
The goal is to avoid churn causing the system to constantly choke. it is
better to potentially double operate then it is for things to feel
horrifically slow.

## Why It's Good For The Game

Faster. Also you won't be able to see lights through walls anymore, so
mesons will be less dumb. Can maybe bump their nightvision a bit idk
we'll see.

## Current Issues

to be found

## Changelog
🆑 Absolucy, LemonInTheDark
fix: You can no longer see lights through walls when using mesons or
when ventcrawling.
/🆑

---------

Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
2026-04-23 08:55:26 +12:00
SmArtKar 2680aafa3f [MDB IGNORE] Lavaland Mineral Rework: Yapmining 2026 (#95682) 2026-04-20 10:52:59 -04:00
mrmanlikesbt 928df286a6 Kills /datum/asset/var/_abstract, uses abstract_type instead (#95756)
## About The Pull Request

It's all in the title

## Why It's Good For The Game

Forgotten in #92909

## Changelog

no player facing changes
2026-04-13 17:20:12 -04:00
Tim d2e5e35d68 Keen Nose Quirk - The Smell of Discovery (#95697)
## About The Pull Request
This adds a new positive quirk called "**Keen Nose**" that costs 3
points.

It lets you examine any open container with reagents to smell them. It
generates the smell based on the taste description. Also added an effect
to pepper spray, where it causes you to lose your sense of smell
temporarily.

This quirk is blacklisted against the Anosmia quirk, which is the
opposite. (no sense of smell)

## Why It's Good For The Game
Since there is a serious lack of positive quirks, I figured this one
might be useful as a utility quirk. It's a niche thing that could come
in handy. Keep in mind, there are several ways to identify chemicals,
like using the bartender's beer goggles, the science goggles, a chem
machine, or just eyeballing the color. Also, many chems have overlapping
taste descriptions (several different things taste like "death") so it's
not foolproof.
2026-04-13 13:03:26 -05:00
Tim 2e35b8bc13 Fix admin shuttle recall revealing admin location (#95733)
## About The Pull Request
- Fixes #95441

Using the admin shuttle recall command no longer reveals the admins
location.

## Why It's Good For The Game
Less bugs.
2026-04-13 12:40:40 -05:00
Leland Kemble 41ce7bf46c fixes second-choice headrevs having their preferences ignored (#95751)
## About The Pull Request

Second-choice headrevs after a first choice became indisposed did not
check client preferences.
Also, moves `ROLE_HEAD_REV` define into roundstart section of defines
because it is a roundstart ruleset

## Why It's Good For The Game

fixes #95742
2026-04-13 12:37:10 -05:00
Lucy 79e7aa569e fixes up some math defines to use byond builtins instead of workarounds (#95652)
## About The Pull Request

this translates some various
- `FLOOR(x, 1)` -> `floor(x)`
- `CEILING(x, 1)` -> `ceil(x)`
- `SIGN(x)` define is gone, just uses the native BYOND `sign()` now.

Also, the `MODULUS` define is just a wrapper for the [BYOND `%%`
operator](https://ref.harry.live/operator/modulomodulo) now.

would be nice if someone double checked to make sure there's no
potential subtle oddities resulting from this.

## Why It's Good For The Game

These procs presumably did not exist whenever the defines were written -
and they are BYOND builtins, meaning it will just be, say, one `sign`
instruction, instead of two comparisons and a subtraction.

## Changelog

no player-facing changes
2026-04-13 15:32:42 +12:00
SmArtKar 93ea8085cb Datumizes material effects, slots, and material spears (#95341) 2026-04-11 09:15:07 +10:00
MrMelbert fbfacd2792 Let's make sure solo rulesets work too (#95694) 2026-04-10 00:53:11 +02:00
SmArtKar 43c59a17d2 Prevents people crashing into their own mounts if they're thrown together (#95647)
## About The Pull Request

Throwing code checked for the obstacle being buckled to the thrown
object, but not vise versa. In some cases (such as riding a mob) this
could cause you to violently crash into your own mount while flying but
still continue your flight.

## Changelog
🆑
fix: Fixed people crashing into their own mounts if they're thrown
together
/🆑
2026-04-07 15:27:13 -04:00
MrMelbert b79743df08 Randomize tts voice more appropriately (#95272)
## About The Pull Request

Adds a helper `SStts.random_tts_voice(gender)` which attempts to pick an
appropriate voice for the passed gender

## Why It's Good For The Game

Randomization into a completely wrong voice kinda ruins it

## Changelog

🆑 Melbert
qol: TTS voice is more appropriately randomized to gender
qol: Getting randomized through means such as mulligan toxin randomizes
TTS voices
/🆑

---------

Co-authored-by: Watermelon914 <37270891+Watermelon914@users.noreply.github.com>
2026-04-04 12:25:12 +00:00
MrMelbert a3bfe66765 Fixes wizard, cult, nukies, revs, and malf from unable to be be rolled roundstart (#95609)
## About The Pull Request

#94899 did not fix all instances where `pick_roundstart_rulesets` added
rulesets to the list

## Changelog

🆑 Melbert
fix: Fixes wizard, cult, nukies, revs, and malf being unable to be
selected for roundstart antag (yes, you read that right)
/🆑
2026-04-02 23:30:43 -04:00
MrMelbert f94302188b Admins can actually ban from recovered crew, blood worm, fugitive(/hunter), paradox clone, monkey helmet, glitch (#95522)
## About The Pull Request

`ROLE_RECOVERED_CREW` jobban flag was used for recovered crew,
experimental cloner, and now Thantorenasia, but it was never actually an
option in the banning panel. Now it is.

While investigating this, I noticed there was several polls that checked
for an role that you couldn't ban from, so they were either added or
folded into a different preference. (Blood worms, fugitive, fugitive
hunter, paradox clone, glitch, monkey helmet)

## Changelog
🆑 Melbert
admin: Admins can ban from "recovered crew", "blood worm", "fugitive" /
"fugitive hunter", "glitch", and "paradox clone"
admin: Mind Magnification Monkeys are now affected by a sentience ban
(previously unbannable)
/🆑
2026-03-29 17:10:39 +01:00
SyncIt21 e0ffb2e962 General maintenance for random chemical reactions (#95339)
## About The Pull Request
- `/datum/chemical_reaction/randomized` is now created along with the
main chemical reaction list and not loaded separately inside the
persistent subsystem. This ensures slightly faster init time and less
snowflake code for adding those chemical reactions later on
- Removed vars that are unused inside
`/datum/chemical_reaction/randomized` but keep those that could be
potentially changed for future recipes
- Merged procs and moves loading recipe data into `New()` making the
code clean and slightly faster
- Random reactions now retry 5 times to be re-added when collisions
happen before giving up
- Removed global lists `GLOB.food_reagents` and
`GLOB.medicine_reagents`. This significantly saves memory for global
lists and makes init faster because we no longer create and delete food
items to init the former list
- `/obj/item/paper/secretrecipe` now picks from all valid random recipes
by default making it robust

## Changelog
🆑
refactor: random recipes like metalgen & secret sause have been
refactored. Please report bugs on github
/🆑
2026-03-28 09:20:54 +01:00
ArcaneMusic 8a6649c8a9 Adds a cargo shuttle upgrade for plastic flaps and air refills. (#95393)
## About The Pull Request

We've all been there before. You send the cargo shuttle, you return it
only to find the blast doors were wide open, and air is now venting out
into space, and with the airlock cycling you are now trapped in a
freezing death trap of your own unwitting design.

This is funny and I want us to keep doing this.

But in an effort to continue to offer interesting things for cargo to
buy in a given shift, this PR offers the ability for cargo to buy an
upgrade to the cargo shuttle itself, that being 2 ~~tiny fans~~ Plastic
Flaps that are installed into the shuttle, as denoted by landmarks
mapped into the cargo shuttle.

Upon being picked up, also includes a certificate of installation. to go
onto the shuttle. Honestly, this is mostly so that I can be lazy and not
just spawn an empty crate but Ideally I open this up for future
categories of "cargo upgrades" that just spawn onto the station.

The other feature here is in shuttles having their air refilled on the
way to/from the station, as part of their subscription to air ™️

It's currently offered for the fairly steep price of 8,000 credits.

## Why It's Good For The Game

This is admittedly a luxury purchase, but, for players who are doing
well enough on credits, either through stocks, bounties, shuttle loans,
cargo events, whatever, this is something that players may want to
purchase for peace of mind, while being entirely optional in-game. The
cargo shuttle can be finicky in many ways and can tend towards easy
mistakes causing lots of pressure-related injuries in a round.

Again, this is intentionally offered at a high price point to avoid this
being an automatic purchase early into the round, but also something
that feels like an earned luxury if you have it, allowing you to focus
on your loop of buying and selling items, hustling if you will, without
caring if Larry over there is going to vent the shuttle for the
umpteenth time.

Like other tiny fans, these are not deconstruct-able and intentionally
should be locked to the cargo shuttle in practice.
2026-03-26 17:37:48 -05:00
MrMelbert af27eda051 Adds support for gags underclothing / Uses it to make them look less jank on lizards (#95454)
## About The Pull Request

1. Underclothes have all been repathed as
`/datum/sprite_accessory/clothing`

2. Underclothes now have support for GAGS. Currently it ONLY supports
static GAGS colors, ie only preset colors, however prefs support could
easily be added in the future

3. Uses the GAGS support to implement the existing digitigrade
templating system for some undergarmants - lizards will use a generic
template for their underclothings when applicable

Example

<img width="169" height="124" alt="image"
src="https://github.com/user-attachments/assets/30b6689b-13a4-4cf9-811c-0d5d0bd5da59"
/>

## Why It's Good For The Game

Existing undergarmants look really jank on lizards

<img width="170" height="140" alt="image"
src="https://github.com/user-attachments/assets/de0704e0-d403-4bdb-a4c5-432d704b9c99"
/>

<img width="118" height="102" alt="image"
src="https://github.com/user-attachments/assets/7ec47327-c2a9-4a90-aab5-fb57105d5111"
/>

I would like to solve this, and well... the two solutions are "we force
lizards to run around naked" or "we use the cool templating system". The
latter seemed preferable


<img width="165" height="125" alt="image"
src="https://github.com/user-attachments/assets/6a8e4225-10a4-4044-9a12-c220713cd613"
/>

I did yoink the template from the jumpsuit template so it might look too
similar, might need to tweak it

## Changelog

🆑 Melbert
add: Some undergarmants will now use a generic replacement on lizard
body shapes that fit more appropriately
refactor: Refactored how undergarmants generate their icons, report any
oddities with that
/🆑
2026-03-23 20:06:58 -07:00
LemonInTheDark f2360d64fd Gives subsystem controllers a bitfield def to make vv easier, renames their flags var (#95439) 2026-03-22 19:06:30 -04:00
MrMelbert 284e23c504 Vendors in audit log are no longer prefixed with "the" (#95389)
## About The Pull Request

Uses `vendor.name` if possible, so it's referred to as "VendingMachine"
rather than "The VendingMachine"

## Why It's Good For The Game

Reads a bit better with all the entries presented

## Changelog

🆑 Melbert
qol: Audit log formats vendors without "the"
/🆑
2026-03-22 17:29:54 -04:00
LemonInTheDark 9d14e327b5 Begins Improving Sparks/Flares Somewhat, Adds Animatable Light Overlays (#95362)
## About The Pull Request

[Adds a visual tick helper, integrates it into SSmove and
such](https://github.com/tgstation/tgstation/commit/e97035f9f74fad5c67c5bf19d8d5d3bb4bd476b4)

Basically, if we do "stuff" during verb time then the next chance
clients have to actually see it is on the next visual tick (rather then
the normal "this tick"). This is cause clients get their next frame
during maptick, and maptick runs before verbs.

We want to be able to handle this properly because if you say, create an
object and then move it on the same VISUAL tick (NOT game tick), it will
just teleport instead of playing out the move. I don't want this for
stuff like sparks, so we need a way to work around it.

[Moves most users of the _FAST flag to
_INSTANT](https://github.com/tgstation/tgstation/commit/6f96daac00519c69adc7554f52114798a65f3ad5)

These are the kids that don't immediately spawn something and the move
it, and we want to allow them to move actually as soon as possible
(important for stuff like space)

[Improves basic effect systems, makes their products delete when they
stop
moving](https://github.com/tgstation/tgstation/commit/172cb25d80ed34e1ec523172a1677fb524239fba)

Moves some stuff out to getters or vars so children can better decide
how long effects should last/how fast they should move. Uses this to
clean up weird dupe code used by explosions.

Makes all these effects delete on contact with something that stops
them. I'm doing this because an effect just hanging in the air looks
really really odd. Does have consequences for sparks that are already
moving at a wall though, might need a better way to handle that.

Makes all these effects use _FAST loops so they don't just hang in the
air for a second on spawn

Adds a setter proc on sparks for their duration, gonna use this to
improve their effects some

[Refactors overlay lights, adds support for animating their
images](https://github.com/tgstation/tgstation/commit/3ad0083cf2b536df51a6d93dca40eac20c1d62d1)

Implements light_render_source and relevant setters, this allows us to
replace the components of an overlay light with basically whatever we
want

Refactors overlay lighting to handle its images more consistently,
allowing us to hook into an image being modified

Combining the two of these will allow us to consistently copy a light's
image, modify it in some way, and then relay that modification back
down. Allowing us to animate it or do more advanced effects painlessly

Also, fixes ranges of 1 or less not rendering at all on initial set
(thank you kapu)

[In which I get fed up and add a macro helper for UID
generation](https://github.com/tgstation/tgstation/commit/aab48b03d407104d4f9cf9acb034494237def911)

[adds vv hooking for all existing lighting
vars](https://github.com/tgstation/tgstation/commit/b81c6200a0d74c36b440aa3f4c1f22c422090a2d)

[Upgrade effect system's dir picking to avoid duplicates when
possible](https://github.com/tgstation/tgstation/commit/18b622586b509c6be4c4bca4e3e7c175ad75fe91)

[Uses the technique described above to animate spark's lights out as
they
move](https://github.com/tgstation/tgstation/commit/67ba177982213799984a70e89536c5efb3d17e14)

This is a decently nice effect imo, it allows us to bump their power
(read, alpha) since it'll get animated away. I try to sync the animation
to the actual icon state's flow (it's 0.7s long). I also sped them up
somewhat to hopefully have a nicer looking effect? we'll see.

[Abstracts away intercepting overlay lights into a holder
datum](https://github.com/tgstation/tgstation/pull/95362/commits/b3f1fe74f2c3bab1d8912ab8a666bd05677ad032)

This should make it far easier to reuse this pattern!

[Fixes overlay lights flashing to double intensity when picked up off
the
ground](https://github.com/tgstation/tgstation/pull/95362/commits/1d83f2031fa2b33312b2aea4359c0c37c9d04ac7)

We needed to clear out their underlays BEFORE the animation

[Adds a flickering effect to flares and their
children](https://github.com/tgstation/tgstation/pull/95362/commits/b7a858e04a607c58b6c7fbe1476ffe2239e63bde)

I'm still not 100% happy with this, I was trying to avoid it feeling
like a heartbeat with random noise and I.. THINK it worked? it's
honestly quite hard to tell

[Adds the same flickering to lighters, welding tools and life
candles](https://github.com/tgstation/tgstation/pull/95362/commits/3ec44027e17835ae96702cec5f0b12d1f4deb32b)

Also, updated light candles to mirror the appearance of normal candles
and use overlay lighting

EDIT:
I realized while working on flares that I accidentally double applied
color, so if you saw the sparks animations before now it was different
(less vibrant). IDK if I like this better or worse but it is RIGHT and
that's what matters.

## Why It's Good For The Game

I got mad about how bad these looked, and this is a start at improving
them.
Also, adds a framework for more dynamic effects applied to overlay
lights (you could use this to apply a sort of "emergency rotating"
effect, or flicker/buzz for example).

<details>
 <summary>Before</summary>


https://github.com/user-attachments/assets/66437f27-ee3c-4f14-a7ee-4a1c3e68533a


https://github.com/user-attachments/assets/ed14fff8-a7eb-47fe-bab5-9a490ac96629

</details>

<details>
 <summary>After</summary>


https://github.com/user-attachments/assets/fb24ff2e-c745-42a5-8e11-c8a1eeef35a5


https://github.com/user-attachments/assets/fd8c2116-cb92-4fe6-ad3e-786a6538e52a

</details>

## Changelog
🆑
add: Reworks how sparks render. They're now a bit brighter, will fade
out as they move/if they hit something, will stack with each other less
and also won't start hang in the air on spawn.
add: Added a flickering effect to lighters, welding tools, flares,
torches and candles (since they're flames).
fix: Overlay based lights (think flashlights) will no longer flash to
double intensity while being picked up.
refactor: Reworked how some effects (explosion particles, sparks, some
reagent stuff) function, report any bugs!
/🆑
2026-03-20 14:48:57 +13:00
LemonInTheDark 3729ee3ef3 Getting Mad at Parallax (Includes Boomerspace!) (#95382)
## About The Pull Request

I want to do stuff with parallax (like placing stuff in the backdrop and
moving it around), but I'm in my not doing 100 things in one pr arc so
we're doing this piecemeal.

To start, I wanted to try adding oldspace back as a parallax layer. This
is something I was considering when it was first removed but never got
around to, so here we are.

I started by [writing a rust
program](https://github.com/LemonInTheDark/old_space_gen) to fabricate
the required icon state, then realized that all the different parts of
space have their own animation delays. There's no way I could make one
icon state with all them looping, so instead I split them up into
multiple components and then overlayed them together.

This works, but is infeasible (my gpu died) at the scale required for
parallax (17 480x480 sets, 15 unique delays per 1 set) so I used render
targets to render one copy, then mirror it to the rest of the overlays.
This works wonderfully, and gets us down to (on my machine) a gpu cost
comprable with about medium parallax intensity.

I'm open to making these tile bound but I thought making them look "far
away" feels better.

In the process of all this I got very mad at the existing parallax code,
soooooooo

Parallax layers are no longer stored on the client, they are stored on
and managed by the parallax home atom that holds them for display. Said
atom also tracks all the information about how they are selected.

Parallax layers no longer take a hud as input, instead expecting a
client. (we were just swapping them back and forth and I thought it was
dumb).

Parallax no longer tries to support passing in a mob that does not
actually own the hud it is displayed on. This feature wasn't even being
used anymore because it was fully broken, so all it was doing was making
the code worse.

Parallax no longer has to do a full refresh anytime something about WHAT
layers are displayed might have changed. We cache based off the
variables we care about, and use the change in state to determine what
should happen (this is improved by moving "rendering the layers" fully
to the control of the home datum).

Parallax no longer directly modifies the hud's plane masters, instead
relying on trait based signals to manipulate them (this avoids wasted
time in the common event of a needless parallax prefs check).

Parallax no longer has 2 procs that are only called together to
"remove/readd/update" the layers, instead doing both in a new check()
proc.

Cleans up some plane master cruft to do with tracking/managing huds
(might break, tested, think it's fine).

## Why It's Good For The Game


https://github.com/user-attachments/assets/79138a0f-9f6d-447d-843e-0d237db13276

## Changelog
🆑
add: Added an option for rendering space parallax with old space sprites
(the ones from before we invented parallax), they're animated and I feel
quite pretty.
fix: Space parallax should hopefully behave a little more consistently
now
refactor: Rewrote a lot of how space parallax handled itself, please
yell at me if any bugs make themselves known
/🆑
2026-03-20 14:46:30 +13:00
MrMelbert da64374423 Reverts "Add prosthetic limb" surgery to involve targeting limbs, rather than targeting chest. (Adds stumps) (#95252)
## About The Pull Request

- The `prosthetic replacement` surgical operation has been reverted to
be closer to how it used to work: The operation is done targeting the
limb that's missing

The change was made out of necessity, as surgical state was tied to
limbs - you had to operate on the chest to re-attach limbs because there
was no limb to operate on.

To circumvent that, I have done the unthinkable of adding stumps when
you are dismembered.

- Missing limbs are now represented as an invisible, un-removable,
un-interactable limb.

Making this change was not as difficult as originally anticipated, and
(at least surface level) seems to have broken very little.

Surprisingly little had to change to make this work. 

Direct accesses to `mob.bodyparts` was changed to `mob.get_bodyparts()`
with an optional `include_stumps` argument.
Similarly, `get_bodypart()` had an optional `include_stumps` added. 

This means we ultimately barely needed to change anything, and in fact,
some loops/checks were able to be streamlined.

## Why It's Good For The Game

- As mentioned, this change was out of necessity and was easily the
least intuitive part of the broader changes. Reverting it back to how it
used to work should make it far easier for people to pick up on, and
means we can cut out a bunch of bespoke instruction sets that I had to
include.

- The addition of stumps also adds a ton of future potential - code wise
it allows for stuff like better damage tracking (we can transfer damage
between limb <-> stump rather than limb <-> chest), and feature we can
do "fun" stuff like have stumps bleed on dismemberment that you can
bandage.

## Changelog

🆑 Melbert
del: "Add prosthetic limb" surgical operation has been reverted to be a
bit closer to how it used to work - you operate on the missing limb /
limb stump, rather than on the chest.
refactor: Missing limbs are now represented as limb stumps. In practice
this should change nothing (for now), as no features were rewritten to
make use of these besides surgery. Please report any oddities with
missing limbs, however.
/🆑
2026-03-20 14:32:41 +13:00
John Willard d1086750d9 Moves Reboot timer to the game screen (#95357)
## About The Pull Request

Since I'm trying to move away from the stat panel as part of my project
here - https://hackmd.io/443_dE5lRWeEAp9bjGcKYw?view - I thought the
reboot timer should be moved out before the stat panel could be made
optional, due to its importance to post-round players (especially to
know if the round is rebooted).

Once the round is over the whole screen kinda becomes pointless, so we
can take as much screen space as we can.

I put this under the tooltips, using similar behavior to it, like the
layer & outline.

This is inspired by the Goon roundend, which does pretty much 1:1 what
this is.

#### Goon's, for reference:

<img width="1397" height="787" alt="image"
src="https://github.com/user-attachments/assets/309b5d6e-c4dd-4f6f-8b83-2256eecd4569"
/>

#### Ours:



https://github.com/user-attachments/assets/b14efae2-e280-47e9-b3db-f57b2060cce7


It's also non-widescreen friendly


## Why It's Good For The Game

Moving things away from the stat panel and to being more player visible
is a positive IMO.
It's also a necessary step to taking away from reliance away from said
stat panel.

## Changelog

🆑
add: The endround timer telling you when a reboot is happening has been
taken out of the stat panel and is instead text over your screen
(similar to Goon)
/🆑
2026-03-13 16:08:56 -06:00
Sutures 096c4a0e10 Fix bugs with area contents system (#95337)
## About The Pull Request
Contains two changes cherry-picked from my CM PR,
https://github.com/cmss13-devs/cmss13/pull/11826.

1) Fixes incorrect args to `block()` in `increase_max_y()` that caused
it to add turfs to every z-level's world.area contents list instead of
just the correct one. This is probably left over from when the area
contents list wasn't split by z-level.

2) Avoids a case where turfs could be removed from area contents twice
if the subsystem returned early on a later Z-level.

## Why It's Good For The Game
Fixes two bugs with the area contents system.

## Changelog

🆑 MoondancerPony
fix: fixed turfs sometimes not being in any area's contents
/🆑
2026-03-08 05:12:24 -07:00
Y0SH1M4S73R 0208b29e74 [TM First] The Paintening: Part 2 of ? - NanoPaint: The Modular Computer Paint App (and related modular computer changes) (#95213) 2026-03-08 05:02:22 -04:00
SyncIt21 56212d2712 Cleans up chemical reaction & reagent look up code (#95281)
## About The Pull Request
- Removed global list `fake_reagent_blacklist` in favour of
`abstract_type`. Saved memory
- Removed proc `get_chemical_reaction()` in favor of
`GLOB.chemical_reaction_list`. No proc overhead and faster access
- Remove unused proc `remove_chemical_reaction()`
- Removed proc `find_reagent()` in favour of
`GLOB.chemical_reagents_list`. No proc overhead and faster access
- Directly access name of reagents via `::` operator from typepaths
instead of looking up the datum in global chemical reagents list for
some operations. Faster variable access
- Removed unit test `reagent_id_typos`. The typepaths will error at
compile time because they aren't strings so there's no need for this
test

## Changelog
🆑
code: cleaned up code pertaining to reagent & reaction lookup
/🆑
2026-03-07 10:39:20 +01:00
John Willard 9a87ffeb6f Removes Spells tab (#95293) 2026-03-03 19:42:30 +01:00
ArcaneMusic fb58e99934 Admins can add new custom blackmarket listings, and tweaks the "Launch" shipping option. (#95191)
## About The Pull Request

Two main items:

1: Admins can now use the new "Create new Blackmarket Item" verb, which
prompts them about the item, price, quantity, name and description of
the item they'd like to list. If successful, the item will be listed to
the black market, available to purchase by the crew.

Prices can be set very, very high, though I've limited the available
quantity to 100 per listing as a nice middle-ground value. The verb can
be used any number of times, allowing for admins to use the black market
to run events, as such. Of note, this verb will spawn a fresh typepath
of the object listed, so it cannot be used to list var-edited objects
as-is, but it's still quite useful for offering unique or rare items to
the crew based on the needs of the round.


2: This PR does a few tweaks to the "launch" shipping option on the
black market. The text displayed when having an object launched to the
station has been adjusted to reduce some ambiguity on if the item is
potentially deleted when launched. The launch behavior has not been
modified in this way, as the object is still launched at the station
using similar logic as before.

**However**, the item is now launched to the station in a faux-energy
bubble, which destroys itself and empties it's contents when it makes
thrown impact or is opened by hand. In practice, this is only noticeable
if you were outside when the order is launched at the station, or if the
crate makes impact with you. This allows for black market objects that
create spawners to arrive at the station harmlessly, which also
potentially reducing some of the randomness of an object being thrown at
the station, and then leaving the z-level immediately based on the extra
collision involved. Additionally, I've lowered the **shipping cost to
0** of launched items.

Misc:
Did some code cleanup by adding defines for each of the categories of
black market items, and a list-define for every category together.

## Why It's Good For The Game

I've wanted to have the option for admins to be able to list things for
the crew to buy for quite awhile now, without requiring them to barter
by hand or through a reliable means that can't be bypassed by 3
assistants with baseball bats. This offers that option, while also
having some flavor of being offered on the black market, if that's
desirable. Otherwise, it's no impact on the average round as it's
admin-only.

Regarding the launch options, this started as a grammar tweak as I was
talking with Arm on discord and the lack of clarity raised the whole
shipping option to our attention. After confirming that launching things
to the station was NOT, in fact a literal noob trap, just an awful
choice, I started work on the shield-bubble idea in an attempt to see if
I could try and reduce some of the randomness involved with that
shipping option. It already sucks due to the risk of going out into
space, there's no need to make it suck worse by potentially losing any
of the cooler items available on the black market at the same time. So,
price down and a mild consistency up. I also ran into #95183 while I was
testing all of this, so this should fix #95183.

Lastly, code cleanup. Made a few things look 3% nicer.
2026-03-02 16:42:04 -06:00
itsmeow 57144e0243 IconForge: Antag and species icons, greyscale previews optimization (#94954)
## About The Pull Request

Converts species and antagonist icon generation to the batched
spritesheet system using IconForge, thanks to the new
`get_flat_uni_icon` implementation. Unfortunately the cost of *building*
the sprite is still expensive (GFI is always expensive, even a fancy
list-based one), but the generation is SIGNIFICANTLY faster. We will see
evidence of parity in the screenshot tests. but here:

<img width="892" height="634" alt="image"
src="https://github.com/user-attachments/assets/2a17f2e3-c024-41f6-9d1e-c2cb70642a81"
/>

The main advantage is that species and antag icons can now take
advantage of the development-time smart cache which invalidates
automatically. On the server this PR does very little except make antag
icon generation a little bit more likely to find and announce errors
(BYOND has a habit of silently eating weird icon proc calls).

Also optimizes the greyscale preview generator from #90940 (~2x speedup)
using `rustg_iconforge_generate_headless` instead of `Insert()` to build
the resulting sheets. This can be further optimized in the future by
implementing a smart cache, like batched spritesheets, and storing it in
the repo, but for now it's not important/slow enough to be worth the
effort. Also fixes a silent compilation error that would always happen
outside unit tests, but for some reason doesn't appear on local? Notice
how `map_icon_key` is not a defined variable anywhere. That's because
`USE_RUSTG_ICONFORGE_GAGS` is *never* defined at this point, so it was
always using the 'slow' generation.

I also took the liberty of cleaning up the cultist and heretic icon
generation randomly initializing a blade object when it could just use a
static access.

## Why It's Good For The Game

The subsystem timing may not be much faster, but the interactivity
benefits during spritesheet realization are undeniable. Opening the
preferences menu during init on local is orders of magnitude faster.

**Old**
Early Assets: 5.02 seconds
Greyscale Previews: 1.38 seconds

**Fresh (No Cache)**
Early Assets: 4.21 seconds
Greyscale Previews: 0.5 seconds

**Cache Invalidated**
Early Assets: 4.27 seconds

**Cache Hit**
Early Assets: 4.05~4.2 seconds

**Preferences lag:**
~6 sec to open to ~2 sec to open due to caching in dev

## Changelog

🆑
code: Optimized species and antagonist icon loading in the preferences
menu on local, speeding up time to open in development.
fix: GAGS map preview generation no longer silently errors outside of
unit tests due to a compilation error.
/🆑
2026-03-02 17:25:16 -05:00
SmArtKar a3498fdcd7 Material Science 1: A bunch of math (#95090) 2026-02-22 16:53:51 +11:00
LemonInTheDark 546dc7fdfa Quarters camera chunk area, Implements better yielding to subsystem on update. (#94530)
## About The Pull Request

[cameras should actually show all of their
view](https://github.com/tgstation/tgstation/commit/a8ef0f3bd7f16e590b9fae193f645c6cb6255f8f)

Melb fucked up luminosity a bit (cries)

[Implements camera range as the deciding factor for who can see a
chunk](https://github.com/tgstation/tgstation/commit/bf4f9776dfce1c15e756ae1933a96ff0cff2dbf0)

This allows us to safely modify chunk size (which I do, down to 8, which
increases the actual cost involved in doing a full z update, but
decreases the cost per chunk significantly)

I use the range to macro optimize chunk New, we can safely use a
bounding box instead of multiple urange calls and get about 1/3 the
performance hit, even with a lower range (and thus 4x as many chunks)

Standard caching and such applies

[Fixes cameras not looking down
correctly](https://github.com/tgstation/tgstation/commit/99b23f25203f34f04c0f92bb7d191699b91a439a)

[Implements yielding support for individual
chunks](https://github.com/tgstation/tgstation/commit/bdd2d01106465b8498307c16f83e9dd90706652a)

This should functionally remove lagspikes from the cameras subsystem,
which just leaves the problem of ais flying around.

Much better tick obedience:


https://github.com/user-attachments/assets/607d61a4-ad96-450c-acdf-10da967ab49b

I tested this pr with #94522 to confirm that halving chunk sizes would
have a benefit, see below:

<img width="364" height="176" alt="image"
src="https://github.com/user-attachments/assets/19f3ae7f-408b-4da5-8e38-a691030138fe"
/>
<img width="462" height="195" alt="image"
src="https://github.com/user-attachments/assets/492b93bf-93ae-4227-9c6d-c5b2f0be9711"
/>
<img width="469" height="229" alt="image"
src="https://github.com/user-attachments/assets/dba92982-09e4-4c3a-96e2-15e1a299676b"
/>
<img width="444" height="233" alt="image"
src="https://github.com/user-attachments/assets/40b1e0dc-c03a-4acd-bba9-f1e4c68bffad"
/>

Things to note:
Mean cost of finding turfs goes from 2ms to 1ms
Max cost of finding turfs goes down by somewhere between 30% and 50%.

I'd call this worthwhile, even if total cost of updating has gone up
slightly.

[Properly manages the camera refs in
chunks](https://github.com/tgstation/tgstation/pull/94530/commits/00c97183ca83a91d95b9afcde70814c36a8f9a5e)

[00c9718](https://github.com/tgstation/tgstation/pull/94530/commits/00c97183ca83a91d95b9afcde70814c36a8f9a5e)

Turns out our solution for moving cameras in chunk code was to just...
NOT CARE!! This means any moving camera is going to cause hard deletes.

This was an issue during unit tests because of a stripping unit test. I
suspect it only showed up here because I reduced the chunk size so we
actually enter/leave a new set of chunks.

I fixed this by reworking things to use a "leaving/joining" pattern.

There's some other stuff here, mostly cleaning up old copypasta'd cruft
in the code adjacent to moving cameras. I also changed the cameras and
processing cameras alists back into lists, mostly for the sake of vv
ability this didn't actually break anything.

The harddel wasn't showing up because it was a number keyed alist, and
reference tracking isn't built to find those (yet, pr up)

## Why It's Good For The Game

I want AIs flying around to not cause massive lag spikes. That + the
camera subsystem are one of like 4 things that's causing reliable tidi
on live and it makes me upset.

## Changelog
🆑
fix: Cameras should work a little better (won't fail in the dark, will
display multiz correctly
refactor: Changed how static turf generation thinks about cameras.
Shouldn't break anything but it MIGHT so keep an eye out for that. The
chunks we use to divvy up the world for them are also 1/4th the area
now, which should make flying around as ai less lagsikey
/🆑

---------

Co-authored-by: Lucy <lucy@absolucy.moe>
2026-02-20 20:58:39 -05:00
MrMelbert 7d3c761150 Minor addiction refactor (#95080)
## About The Pull Request

### Rewrite stuff

Reagent addictions are written in terms of "units to addict" kinda like
how they were ages ago

For example `addiction_types = list(/datum/addiction/hallucinogens =
60)` says "We can expect to get addicted if we consume 60 units of this
reagent alone"

For easily converting units, I used the following equation
```
x = 1 / ((o * 0.2 / m / 2) / 600)

o = the old addiction number
m = the metabolism rate
x = the converted threshold
```
Example (Nicotine)
```
x = 1 / ((o * 0.2 / m / 2) / 600)

o = 15
m = 0.025
x = 10 (10 units to addict)
```

FULL TRANSPARENCY: Some reagents had some really weird results like
`33.33u` or `685.78u`
I rounded them to nicer numbers like `30u` or `685u`. I don't think
anyone would really care.

I anticipate this being easier to work with than the arbitrary point
values

### Mechanics stuff

Addiction gained is now calculated based on units metabolized, rather
than the static metabolism rate.
So if you metabolize less than a full metabolism tick, you aren't given
the full addiction points.

## Why It's Good For The Game

### Rewrite stuff 

Addiction rates are kinda insane.

If you look at nicotine you see: `list(/datum/addiction/nicotine = 15)`
Then if you look at maintenance powder:
`list(/datum/addiction/maintenance_drugs = 14)`

You would assume that these give you addiction at a similar rate... but
ACTUALLY
you would get nicotine addiction from 10u consumed
and you would get maintenance drug addiction from 50u consumed

This was because nicotine's metabolism rate is 0.025 vs maintenance
powder's 0.1 metabolism rate - this is not exactly obvious at a glance
which makes tweaking addiction values kind of painful

Putting them in terms of "units to addict" makes it a lot easy to parse
at a glance - metabolism rate nor any other variable is necessary to
know how potent a substance is

(In particular you can see some reagents take **upwards of 1,200u** to
addict on their own. Which is INSANEEE. I want to go through in a second
pr and tweak all these values down)

### Mechanics stuff

This ultimately changes very little, it just makes sense that
metabolizing more or less of a reagent at once would give you more or
less addiction progress.

## Changelog

🆑 Melbert
refactor: Rewrites how addiction points are applied from reagents. Some
reagents may be marginally more or less addictive as a consequence.
balance: Addiction gained per metabolism tick now scales to the amount
of reagents metabolized. In other words if you metabolize 0.2 units
instead of the expected 0.4 units, you get 0.5x of the amount of
addiction gain. This ultimately changes very little and I would imagine
it's how most people expected it to work in the first place...
/🆑
2026-02-13 20:02:58 -05:00
sesametg c2618c5d6b Clear the recent map list if there aren't enough players (#95120)
## About The Pull Request and Why It's Good For The Game

/tg/station has a feature that excludes maps from map votes if they have
been played too much recently. It also forces metastation when there are
no/very few players connected, which in practice leads to metastation
being unvotable during active hours.

This PR clears the recent map list if there aren't enough players
connected, so that the vote exclusion works as (I assume) intended.

(I don't know what tags apply below so feel free to mess with that. Also
this needs a config change to enable it.)

## Changelog
🆑
server: fix: HR have reopened positions at unstaffed stations
/🆑

Co-authored-by: Sesame <nope@nope.com>
Co-authored-by: Jordan Dominion <dominion@tgstation13.org>
2026-02-12 08:33:29 +00:00
ArcaneMusic 44f6846306 Adds structural weakpoints that can spawn on station (#94839)
## About The Pull Request

This PR was originally described to me by @AnturK and I implemented a
few elements of it to the best of my ability, then I promptly forgot
about it for the last 2 months.

This PR adds in randomly spawning structural weakpoints, using much of
the same mechanics of spawning in hidden satchels. If identified using a
T-ray scanner, they can be fixed using a welder by crew. More
excitingly, if a weakpoint is subject to an explosion, it will propagate
a crack, using a random line of turfs, then calling `ex_act()` on each
one with a small callback chain. Finally, cracks will form additional
weakpoints if caused this way, though are almost certainly going to be
noticeable, unlike before where they can spawn undertile.

With this addition, I've added a negative station trait, that will
increase the number of structural weakpoints that will spawn in a given
round. In a normal round, 3 weakpoints will spawn on the station, where
with the station trait, 4-8 weakpoints will spawn across the map.

Weakpoints come in 1 flavor practically, with a larger subtype being
spawnable by admins. The vars for weakpoints also happen to be fully
var-edit-able for admin purposes, including the explosion intensity that
can cause the weakpoint to trigger, the number of sub-cracks, if
additional weakpoints can spawn, etc.

You may also seal weakpoints using sticky tape.

## Why It's Good For The Game

Weakpoints feel like an interesting modifier to a map, where if caught
early can prevent a bad situation becoming worse. Otherwise, weakpoints
could very quickly cause chaos on the map, but despite their
description, aren't capable of causing **too** much destruction that
they can cause a shuttle call unless they're being manipulated by
traitors or antagonists. Though low odds, the idea of a player
welder-bombing a door or an IED going off related to the current
situation in a round, being exacerbated by pure chance due to being near
an IED seems really, REALLY funny.

## Changelog

🆑
add: Stations can now spawn with Structural weakpoints. If they're
subject to an explosion, they'll crack open a tear in the station's
turfs. If you spot one, make sure to weld it or seal it with sticky tape
to fix one. Or not!
add: Adds a negative station trait that greatly increases the number of
weakpoints that can spawn on station.
/🆑

---------

Co-authored-by: san7890 <the@san7890.com>
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
2026-02-06 16:12:31 -05:00
MrMelbert e4f533111f Deafness is now solely tracked by trait (#95029)
## About The Pull Request

Deletes `can_hear`, replaces it with trait-checking deafness.

The only two non-trait sources of deafness (hardcrit and lacking ears)
were refactored into using the trait.

## Why It's Good For The Game

Many places inconsistently check for the deaf trait rather than use
can_hear which meant behavior was not consistent.
Some code would treat "do we lack ears?" as being deaf, some would not. 

This unifies all the behavior so being deaf means you're deaf
everywhere.

It also means we can now easily react to gaining and losing deafness via
signal, where before we could not react to it without hooking the trait,
organ remove, AND stat change. Which no one did, of course, because who
would ever think to do that?

## Changelog

🆑 Melbert
refactor: Refactored how deafness is tracked. Please report any weird
interactions with sounds, like messages or sfx being missing.
fix: Lacking ears and being in hard crit now consistently treats you as
"being deaf". This affects a few minor interactions like empath, the
jukebox, and sleeping.
/🆑
2026-02-05 20:19:56 -05:00
MrMelbert 05748b6e8c Addictions don't process in stasis (#95089)
## About The Pull Request

Moves addiction processing in life to within the inverted stasis check 

Note, this includes both withdrawal effects and addiction healing

## Why It's Good For The Game

Addictions have several ticking maluses that you would expect stasis to
stop, but doesn't

So it seems sensible, for consistency reasons, to stop addictions from
ticking up or down while in stasis

## Changelog

🆑 Melbert
balance: Stasis now stops addiction ticks while active - meaning
addictions will not apply their ticking withdrawal effects, but also
won't heal over time
/🆑
2026-02-05 20:17:00 -05:00
Kashargul ff752cc75f fix Tgui error year display (#95086)
## About The Pull Request
If we look closely at the world init, we clearly see that GLOBS are not
populated by the time Subsystem PreInit is called. This led to the
current year never being properly displayed in the TGUI bluescreen
```
 * WORLD INITIALIZATION
 * THIS IS THE INIT ORDER:
 *
 * BYOND =>
 * - (secret init native) =>
 *   - world.Genesis() =>
 *     - world.init_byond_tracy()
 *     - (Start native profiling)
 *     - world.init_debugger()
 *     - Master =>
 *       - config *unloaded
 *       - (all subsystems) PreInit()
 *       - GLOB =>
 *         - make_datum_reference_lists()
 *   - (/static variable inits, reverse declaration order)
 * - (all pre-mapped atoms) /atom/New()
 * - world.New() =>
 *   - config.Load()
 *   - world.InitTgs() =>
 *     - TgsNew() *may sleep
 *     - GLOB.rev_data.load_tgs_info()
 *   - world.ConfigLoaded() =>
 *     - SSdbcore.InitializeRound()
 *     - world.SetupLogs()
 *     - load_admins()
 *     - ...
 *   - Master.Initialize() =>
 *     - (all subsystems) Initialize()
 *     - Master.StartProcessing() =>
 *       - Master.Loop() =>
 *         - Failsafe
 *   - world.RunUnattendedFunctions()
 ```
## Why It's Good For The Game
## Changelog
🆑
fix: tgui error year display
/🆑
2026-02-04 18:45:10 -05:00
SmArtKar f58b8511f0 Refactors effect_system (#94999)
## About The Pull Request

This PR refactors ``effect_system``s to be a bit easier to use by
getting rid of ``set_up``, allowing ``attach()`` to be chained into
``start()`` and refactoring most direct system usages in our code to use
helper procs.

``set_up`` was unnecessary and only existed to allow ``New``'s behavior
to be fully overriden, which is not required if we split
sparks/lightning/steam into a new ``/datum/effect_system/basic`` subtype
which houses the effect spreading behavior. This allows us to roll all
logic from ``set_up`` into ``New`` and cut down on code complexity.
Chaining setup as ``system.attach(src).start()`` also helps a bit in
case no helper method exists

I've added ``do_chem_smoke`` and ``do_foam`` helpers, which respectively
allow chemical smoke or foam to be spawned easily without having to
manually create effect datums and reagent holders.

Also turns out we've had some nonfunctional effect systems which either
never set themselves up, or never started, so I fixed those while I was
at it (mostly by moving them to aforementioned helper procs)

## Why It's Good For The Game

Cleaner code, makes it significantly easier for users to work with. Also
most of our effect system usage was copypasta which was passing booleans
as numbers, while perfectly fine helper procs existed in our code.

## Changelog
🆑
refactor: Refactored sparks, foam, smoke, and other miscellaneous effect
systems.
refactor: Vapes now have consistent rigging with cigs using the new
system.
fix: Fixed some effects never working.
/🆑
2026-02-03 22:23:09 -05:00
FalloutFalcon 8f1a925afa More abstract types (#95064) 2026-02-03 23:25:31 +01:00
Jordan Dominion 193023cc3c Check if the HEAD commit is publicly available on GitHub. If it is, set it in the database (#95043)
## About The Pull Request

TGS provides two SHA's to the game. The first is the closest commit on
the tracked branch (`master`) the second is the true revision of the
game. The latter may be equal to the first, but not when test merges are
active.

We normally set the database `commit_hash` to the first because we can't
guarantee the latter is on GitHub. TGS **does** try to push it there
however (i.e.
https://github.com/tgstation/tgstation/commit/b7c18d2bdb6b091255716fa801113be4d73be987)
provided it has proper credentials.

This PR will ping the HEAD SHA on GitHub to see if it exists there. If
it does, it'll be set as the round's `commit_hash`.

## Why It's Good For The Game

Allows statbus to link to the EXACT commit of the round which includes
test merges. Currently it lies when test merges are active by linking
the `master` commit.

## Changelog

🆑
server: If TGS is configured to push test merge commits to a publicly
accessible GitHub, the exact game revision will be set as the
`round`.`commit_hash` in the database.
/🆑

@nfreader

---------

Co-authored-by: Jordan Dominion <Cyberboss@users.noreply.github.com>
2026-02-01 14:09:42 -08:00
Mike Long c7c61ec373 Enhance bitrunner domain creation blackbox logging (#94913)
## About The Pull Request

Improves some blackbox logging for bitrunner domain creation, by also
logging how much information they had when they chose it.

Also some minor code improvements, by making methods for whether the
name/reward of a domain is visible.

## Why It's Good For The Game

Right now, if we just look at blackbox logs, we cannot easily tell if a
domain is being deliberately avoided when possible, as we cannot tell if
it's run unintentionally or intentionally. Now we will record that
information, so we can act on it, and hopefully perform actions to
improve the domains that people attempt to avoid.
2026-01-28 11:40:33 -06:00
MrMelbert 71166c45ef Rips out the rest of NAP code (#94982)
## About The Pull Request

Deletes the remainder of NAP code on `/machinery` 

Keeps the NAP code on Securitrons, but rethemes it and allows admins (or
mappers IG) to enable it by editing a var

## Why It's Good For The Game

There are only two NAP machinery interactions, sleepers and stasis beds.
One, you can't get anymore outside of space.
The other just seems to confuse people as to why stasis ("the only way
medical doctors know how to treat people") suddenly doesn't work

It's stinky code, it barely works, no one uses it, it can go bye bye. 
If someone wants to re-add it they should do it via components, it'd be
much cleaner.

...

HOWEVER, the Securitron code is perfectly fine on its own so I left it
in for admemery or future mapping. Idk it might be funny to put a
securitron on the luxury shuttle that charges you money

## Changelog

🆑 Melbert
del: Admins can no longer use the NAP button 
/🆑
2026-01-26 11:13:37 -05:00
SyncIt21 7fc6e1402a Additional maintenance for plumbing related stuff (#94753)
## About The Pull Request
**Qol**
- Adds examines & screen tips for washing items in sinks
- Adds examines & screen tips for wall frame items i.e deconstructing
with wrench & what structures you can mount them on

**Fixes**
- Plumbing components inside shuttles now properly reconnect 
- Plumbing iv drip has their connectors (red & blue pipes) visible again
- Sinks consume reagents when washing and won't wash when it becomes dry
- Fixes #94942 placing ducts by hand on turf won't run time. Also
Plumbing machinery properly reconnects when un wrenching ducts in
circular connections
- All plumbing machinery now operates in the plumbing subsystem & map
loaded machines begin processing

**Refactor**
- Refactored sink frame into a wall frame item meaning it can now be
carried in hand and mounted on walls
- Refactored the sink attack chain to use `item_interaction()` instead
of `attackby()`
- All sinks are now wall mounted components meaning destroying the wall
they are attached to will cause it to deconstruct

## Changelog
🆑
qol: added examines & screen tips for wall frame items
qol: added examines & screen tips for washing items in sinks
fix: plumbing components inside shuttles reconnect to their machine
counterparts correctly
fix: plumbing iv drip has its red & blue connectors visible again
fix: sinks consume reagents when washing and won't wash when it becomes
dry
fix: map loaded plumbing machines begin processing
fix: placing stack of ducts by hand of ducts works again
fix; plumbing machinery properly reconnects when un wrenching ducts in
circular connections
refactor: sinks are now proper wall mounted components meaning
destroying their attached walls will cause it to get destroyed & sink
frames are wall frame items that can be carried in hand
/🆑
2026-01-26 15:00:11 +01:00
SmArtKar c74f104c89 Rewrites plasma rigging code to be much more flexible and dynamic, and cover more cases (#94861)
## About The Pull Request
Instead of being snowflake interactions on objects themselves, rigging
things with plasma or welding fuel is now handled on reagents' side via
``on_spark_act``, allowing each reagent to decide how they want to
handle exposure to electric currents or violent heating.
- Obviously plasma and welding fuel cause explosions, but former gains
additional power from electric current being passed through it (same
math as powercells), while latter doesn't explode unless in an enclosed
space, or a high enough current/temperature has been reached, and merely
creates a hotspot instead.
- Napalm and phlogiston create hotspots, or (try to) damage the holder
if they're enclosed
- Sorium, liquid dark matter, TATP, nitroglycerin and flash/smoke/sonic
powders trigger their usual detonation effects, albeit slightly weaker.
- Teslium creates a ZAP, with additional power for a BIG ZAP if it has
been triggered by electric current.
- RDX becomes spicier with temperature and current, similarly to how it
becomes more dangerous when mixed with LE or teslium.
- Gunpowder produces a delayed explosion effect (unless its hot or the
current is high enough, in which case its instant) and causes sparks as
the message claims it does (normal gunpowder explosions also do that)

Plasma and gunpowder rigged items can now be controlled using
stabilizing agent - in its presence, plasma will not explode unless the
used charge is higher than 0.2% of a standard cell's per unit of agent,
while gunpowder will instead spend 0.1 + (charge / 10% of a standard
cell's charge) units of agent to delay its detonation.

Smoke (powder) now produces a visible message and slightly damages lungs
of whoever it reacted inside of, if the container was a mob.
The numbers on plasma/welding fuel rigs should be ***roughly*** the
same. Also lighters can now be rigged in a fashion similar to welding
tools.

Also it turns out we broke light rigging at some point, so now it works
again.

## Why It's Good For The Game

This makes the system much more flexible and allows players to make more
creative IEDs, expanding upon the sandbox aspect of the game. Also I
have an upcoming project bringing IEDs (kind of, in a new form) back,
which is why I wrote this in the first place (but decided to atomize the
PRs).
As for smoke damage, it feels weird to not have any tells when someone
suddenly starts hacking up volumetric amounts of smoke, it makes sense
that they'd struggle a bit after coughing a few dozen cubic meters of
thick vape clouds.

## Changelog
🆑
add: Multiple new reagents such as napalm, sorium, TATP,
smoke/sonic/flash powders and other explosives can now be used to rig
cells or tools.
add: Plasma and gunpowder rigged items can now have controlled current
requirement/delay by adding some stabilizing agent alongside the main
reagent.
balance: Creating chemical smoke inside of a mob now makes them
violently cough it up, damaging their lungs a bit.
fix: Chemically-rigged lightbulbs now once again explode.
refactor: Refactored how power cells, welding tools, lightbulbs,
cigarettes (and now, lighters) handle being rigged with chemicals.
/🆑
2026-01-21 19:21:06 +00:00
Lucy bb744805a0 Make turrets only process when something "interesting" is in its range. (#94777)
## About The Pull Request

Port from https://github.com/Monkestation/Monkestation2.0/pull/10330, as
promised in https://github.com/tgstation/tgstation/pull/94757

This adds a proximity monitor to all turrets - they now track
"interesting" targets within the turret's range, and the turret will
only process if at least 1 thing is being tracked.

The proximity monitor's checks for what's "interesting" are slightly
less thorough than the turret's, and thus, it may still track something
the turret will ignore regardless - but that's still better than the
turret processing when nothing's nearby anyways.

This also makes a new processing subsystem, SSturrets, as turret
processing can be somewhat intensive in process, so like, let's not let
them hog the SSmachines tick (plus, I honestly believe that splitting
things into more specific processing subsystems is better for allowing
the MC to manage tick time with more granularity). SSturrets has the
same flags and wait as SSmachines.

## Why It's Good For The Game

Should improve performance quite a bit - mainly, turrets on space ruins
shouldn't waste tick time when there's nothing even near them.

## Changelog
🆑
refactor: Refactored turrets so they only process if something
potentially "interesting" is within its range.
/🆑
2026-01-20 20:01:48 -05:00