Commit Graph

5652 Commits

Author SHA1 Message Date
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
nevimer f16aa650fa fixes descending pt1 2026-03-03 23:54:23 -05: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 e9d964789b Swags out the roundstart report (#95149)
## About The Pull Request

The roundstart report has been dripped out with a logo and some
additional flavor

<img width="585" height="916" alt="image"
src="https://github.com/user-attachments/assets/d0dab027-24e4-4d4a-a5ad-59616b3bf33d"
/>

The flavor messages are just some randomly selected lore tidbits or
filler text

Other changes:

- Paper now updates to your writing implement immediately, rather than
on process ticks.
- Adds a config to hide the dynamic report for cutting down the length
of the roundstart report. Disabled by default
- Footnotes now requires `R_FUN` rather than `R_ADMIN`

## Why It's Good For The Game

Makes the command report look a ton more official while introducing some
fun worldbuilding.

## Changelog

🆑 Melbert
qol: Paper UI now updates immediately when you pick up or drop a writing
tool.
qol: The roundstart command report has had its style updated, and now
contains some bonus lore.
admin: Changes the perms needed to add command report footnotes to "Fun"
rather than "Admin"
admin: Adds a verb for changing the command report main contents
(Requiring "Fun")
config: Adds a config for hiding the dynamic report, disabled by default
(disabled meaning you still get the report)
/🆑
2026-02-20 20:54:36 -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
nevimer 4dc38c0ad6 Merge remote-tracking branch 'tgstation/master' into upstream-feb12-2026
# Conflicts:
#	code/game/objects/items/storage/belt.dm
#	code/modules/jobs/job_types/chief_engineer.dm
2026-02-12 23:54:07 -05:00
nevimer 00ccf0c6b5 Merge remote-tracking branch 'tgstation/master' into upstream-feb12-2026
# Conflicts:
#	.github/CODEOWNERS
#	.github/workflows/compile_changelogs.yml
#	.github/workflows/stale.yml
#	SQL/database_changelog.md
#	_maps/map_files/CatwalkStation/CatwalkStation_2023.dmm
#	code/__DEFINES/atom_hud.dm
#	code/__DEFINES/inventory.dm
#	code/__DEFINES/mobs.dm
#	code/__DEFINES/species_clothing_paths.dm
#	code/__DEFINES/subsystems.dm
#	code/__DEFINES/surgery.dm
#	code/__HELPERS/global_lists.dm
#	code/_globalvars/lists/maintenance_loot.dm
#	code/_globalvars/traits/_traits.dm
#	code/controllers/subsystem/minor_mapping.dm
#	code/controllers/subsystem/processing/quirks.dm
#	code/controllers/subsystem/shuttle.dm
#	code/datums/components/palette.dm
#	code/datums/components/surgery_initiator.dm
#	code/datums/diseases/advance/advance.dm
#	code/datums/hud.dm
#	code/datums/mood.dm
#	code/datums/mutations/chameleon.dm
#	code/datums/quirks/negative_quirks/nyctophobia.dm
#	code/datums/status_effects/debuffs/debuffs.dm
#	code/datums/status_effects/debuffs/drunk.dm
#	code/datums/status_effects/debuffs/slime/slime_leech.dm
#	code/datums/weather/weather.dm
#	code/game/data_huds.dm
#	code/game/objects/items.dm
#	code/game/objects/items/devices/scanners/health_analyzer.dm
#	code/game/objects/items/frog_statue.dm
#	code/game/objects/items/rcd/RLD.dm
#	code/game/objects/items/robot/items/hypo.dm
#	code/game/objects/items/stacks/medical.dm
#	code/game/objects/items/stacks/wrap.dm
#	code/game/objects/items/storage/garment.dm
#	code/game/objects/items/tools/medical/defib.dm
#	code/game/objects/items/weaponry.dm
#	code/game/objects/items/weaponry/melee/misc.dm
#	code/game/objects/structures/crates_lockers/closets/secure/security.dm
#	code/game/objects/structures/curtains.dm
#	code/game/objects/structures/dresser.dm
#	code/game/objects/structures/girders.dm
#	code/game/objects/structures/maintenance.dm
#	code/game/objects/structures/mirror.dm
#	code/modules/admin/greyscale_modify_menu.dm
#	code/modules/admin/verbs/light_debug.dm
#	code/modules/antagonists/ashwalker/ashwalker.dm
#	code/modules/antagonists/heretic/knowledge/starting_lore.dm
#	code/modules/antagonists/ninja/ninjaDrainAct.dm
#	code/modules/art/paintings.dm
#	code/modules/client/preferences.dm
#	code/modules/client/verbs/ooc.dm
#	code/modules/clothing/head/wig.dm
#	code/modules/events/disease_outbreak.dm
#	code/modules/holodeck/holo_effect.dm
#	code/modules/jobs/job_types/head_of_security.dm
#	code/modules/jobs/job_types/security_officer.dm
#	code/modules/library/skill_learning/generic_skillchips/point.dm
#	code/modules/mining/lavaland/ash_flora.dm
#	code/modules/mining/lavaland/mining_loot/megafauna/ash_drake.dm
#	code/modules/mob/dead/new_player/new_player.dm
#	code/modules/mob/living/basic/guardian/guardian.dm
#	code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm
#	code/modules/mob/living/carbon/carbon.dm
#	code/modules/mob/living/carbon/human/human.dm
#	code/modules/mob/living/carbon/human/human_defines.dm
#	code/modules/mob/living/carbon/life.dm
#	code/modules/mob/living/living.dm
#	code/modules/mob/living/living_defines.dm
#	code/modules/mob/mob.dm
#	code/modules/mob_spawn/ghost_roles/mining_roles.dm
#	code/modules/mod/mod_control.dm
#	code/modules/mod/modules/modules_general.dm
#	code/modules/modular_computers/computers/item/computer_ui.dm
#	code/modules/paperwork/paper.dm
#	code/modules/paperwork/paperbin.dm
#	code/modules/power/lighting/light.dm
#	code/modules/projectiles/guns/energy/kinetic_accelerator.dm
#	code/modules/projectiles/projectile.dm
#	code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm
#	code/modules/reagents/chemistry/reagents/food_reagents.dm
#	code/modules/reagents/chemistry/reagents/other_reagents.dm
#	code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
#	code/modules/research/xenobiology/crossbreeding/_clothing.dm
#	code/modules/research/xenobiology/crossbreeding/prismatic.dm
#	code/modules/surgery/advanced/brainwashing.dm
#	code/modules/surgery/advanced/lobotomy.dm
#	code/modules/surgery/amputation.dm
#	code/modules/surgery/blood_filter.dm
#	code/modules/surgery/bodyparts/_bodyparts.dm
#	code/modules/surgery/brain_surgery.dm
#	code/modules/surgery/cavity_implant.dm
#	code/modules/surgery/coronary_bypass.dm
#	code/modules/surgery/gastrectomy.dm
#	code/modules/surgery/healing.dm
#	code/modules/surgery/limb_augmentation.dm
#	code/modules/surgery/organ_manipulation.dm
#	code/modules/surgery/revival.dm
#	code/modules/surgery/sleeper_protocol.dm
#	code/modules/surgery/surgery_helpers.dm
#	code/modules/surgery/surgery_step.dm
#	code/modules/unit_tests/_unit_tests.dm
#	code/modules/unit_tests/designs.dm
#	code/modules/unit_tests/icon_state_worn.dm
#	code/modules/unit_tests/screenshots/screenshot_antag_icons_cultist.png
#	code/modules/unit_tests/screenshots/screenshot_antag_icons_headrevolutionary.png
#	code/modules/unit_tests/screenshots/screenshot_antag_icons_provocateur.png
#	code/modules/unit_tests/screenshots/screenshot_husk_body.png
#	code/modules/unit_tests/screenshots/screenshot_husk_body_missing_limbs.png
#	icons/map_icons/clothing/head/_head.dmi
#	icons/map_icons/clothing/shoes.dmi
#	icons/map_icons/items/_item.dmi
#	icons/mob/huds/hud.dmi
#	icons/mob/inhands/64x64_lefthand.dmi
#	icons/mob/inhands/64x64_righthand.dmi
#	icons/obj/machines/computer.dmi
#	tgui/packages/tgui/interfaces/OperatingComputer.jsx
#	tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferences/MainPage.tsx
#	tgui/packages/tgui/interfaces/PreferencesMenu/types.ts
#	tgui/packages/tgui/interfaces/SurgeryInitiator.tsx
#	tools/icon_cutter/check.py
2026-02-12 23:50:09 -05:00
LT3 7df523674a Remove rock the vote config entry [NO GBP] (#95136) 2026-02-13 02:12:39 +01: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
theOOZ 5464a0225b [NO GBP] Fixes queue'ing of roundstart ruleset (#94899)
## About The Pull Request

https://github.com/tgstation/tgstation/pull/94843 broke the queue'ing of
roundstart rulesets by handing the proc which processes this instances
while it expected typepaths.

## Why It's Good For The Game

Sorry!
2026-01-19 12:20:42 -06:00
Lucy beebdd2c52 Converts AI controller processing subsystems to use currentrun (#94905)
## About The Pull Request

this makes it so `SSai_controllers` and its subtypes use a `currentrun`
loop, instead of directly looping thru
`GLOB.ai_controllers_by_status[planning_status]`

## Why It's Good For The Game

most other processing subsystems do this, why shouldn't we?
it should ensure all ai controllers get to process, even if the server's
under load.

## Changelog

no player-facing changes, prolly
2026-01-18 19:35:30 -08:00
RikuTheKiller c7e4e90004 Adds a new antag, the Blood Worm (#93787)
## LTS Document

Check this document before making any significant future changes to
blood worms, please.

https://hackmd.io/@RikuTheKiller/H1AHQSKNZx

## About The Pull Request

THIS PR SHOULD ABSOLUTELY BE TM'D FIRST

Blood worms are a new progression antag. When the event runs, 2
candidates are picked from ghosts and spawned in as blood worm
hatchlings, which then have to grow up, do a couple objectives and take
over the station.

Hatchlings are weak outside of a host, while juveniles can stand their
own reasonably well. Adults have high offensive power and can only be
dealt with using the right gear or a lot of luck and robustness. They're
meant to be a moment of glory for achieving maximum progression and they
can bootstrap the next hatchlings by gathering corpses before cocooning.

Each growth stage requires 30 seconds in a cocoon, which can only be
created after consuming a lot of blood. There's a falloff curve on a
per-blood-type basis, meaning you can't drain the same person over and
over again to reach adulthood. The medbay freezer is a priority target
for the blood worms and can get one of them to the juvenile stage if
fully ransacked.

It takes 500 blood to mature from hatchling to juvenile, and 1500 blood
to mature from juvenile to adult. You can only get up to 1000 blood from
synthetic sources like monkeys, and consuming synthetic blood is 30%
less efficient. Blood worms can also examine living targets to see how
much blood a target has, and how much growth the blood worm would gain
for consuming that blood.

Blood worms spawn in vents and have night vision for maneuvering in
maintenance. Hatchlings can ventcrawl, while juveniles can move around
by breaking things. Optionally, you can take over a host with a lot of
access like the Captain to go basically anywhere, especially if nobody
knows you killed the captain.

Behind the scenes, host-taking kicks the host's original mind to a
backseat mob. This needs the most testing in practice, but it's
confirmed that it returns the host's mind back to their body, at least
in testing.

All mob, ability and action sprites are made by INFRARED_BARON. Legal
rights were transferred to me after I paid for the commission.

Note, I've been working on this massive PR for quite a while, so
documenting every small change is really hard! Apologies for anything
I've missed. There's a lot.

Final note, admins can spawn these by either:
A. Trigger the midround event via the dynamic-panel verb, under the
Rulesets tab.
B. Giving someone the Blood Worm antag datum via the Traitor Panel in
the Player Panel for the target player. This will transform their mob
into a valid Blood Worm, with all of the associated objectives and such.

### Active Abilities
1. Leech Blood (No Host) - Lets the blood worm drain blood from living
targets and reagent containers. Uses an aggressive grab to restrain
living targets until leeching is over, which takes around a second to
initiate. Causes oxyloss during the leeching. NPC monkeys can't escape
from this and it floors targets as well.
2. Spit Blood (Both) - Multi-function ability, lets the blood worm fire
ranged corrosive blood spit at targets, melt restraints on their hosts
by right-clicking, and as an adult, shoot a burst of blood spit at a
target by right-clicking. Note of the right-click abilities, shooting
bursts can't be done while in a host. (to avoid unfair stealth kills)
Shooting a burst has a much longer cooldown than shooting normally. All
spit types cost blood to use.
3. Invade Corpse (No Host) - Lets the blood worm take a host for
themselves, consuming all of the host's blood and in essence, "becoming"
the host. Any bloodloss inflicted on the host is taken as damage to the
blood worm, and the blood worm retains its weakness to fire even in this
state. Burn damage itself no longer has any extra damage, though.
4. Leave Host (Host) - Title, literally just leaves the host after a
delay. Notably works even while the host is moving, dead, incapacitated
or otherwise fucked up in any way, shape or form.
5. Inject Blood (Host) - Lets the blood worm heal its host. The potency
of this increases as the worm grows up, but so does the cooldown and
blood consumption. This works on organ damage, injuries, etc.
6. Mature (No Host) - Makes the blood worm enter a cocoon for 30
seconds, emerging as the next growth stage. Requires an increasing
amount of consumed blood / growth as the blood worm uses it.
7. Reproduce (No Host, Adult Only) - Makes the blood worm enter a cocoon
for 30 seconds, with 4 hatchlings emerging out of it, including the
original blood worm, now reverted back into a hatchling as well.
8. Revive Host (Host) - If the host is in a viable state to be revived,
revives them after an animation sequence plays out.

### Passive Abilities
1. Space Immunity - Blood worms are immune to the cold, low pressures
and a lack of oxygen. Only the immunity to a lack of oxygen carries on
to hosts from this.
2. Organ Insertion - Blood worms can insert organs into their hosts by
right-clicking on them with the organ in-hand. This mainly exists to
deal with hosts that lack organs, and avoids the gotcha where an adult
blood worm ends up gutting their host by hitting them too hard, as they
can simply fix it on the spot.
3. Life Support - Blood worm hosts don't need a heart, lungs or a liver
to survive. Lungs are useful for speaking, and a liver is necessary to
process reagents.
4. Regeneration - Blood worms slowly heal over time. This is nowhere
near enough to overcome bleeding or heat damage, since it's 0.3 hp/s for
a hatchling, 0.4 hp/s for a juvenile and 0.5 hp/s for an adult.
5. Night Vision - Blood worms can see in the dark. This doesn't extend
to hosts.
6. Ventcrawling - Hatchling blood worms can ventcrawl.
7. Doorcrawling - Hatchling and juvenile blood worms can slide under
doors. Doing so takes 3 seconds for a hatchling and 5 seconds for a
juvenile.
8. HUD - Blood worms can tell how much blood targets have at a glance,
via a blood HUD bar exclusive to them. They can also tell apart other
blood worm hosts from normal people via an antag HUD. There's also an
examine message they can use on living targets for even more info.

### Weaknesses
1. Heat and Fire - Blood worms quickly die to heat, their bodies are
flammable and their blood will burn up if their host's core temperature
is too high. The main counter to this is getting a host with
flame-resistant gear.
2. Bleeding - While in a host, bleeding wounds will directly damage the
blood worm itself. How much a host needs to bleed before the worm dies
depends on their growth stage. Blood worm hosts keep bleeding even while
dead, so just keep hitting them and they'll die. Blood worms
automatically leave their hosts when they hit 10% health or lower, and
their hosts bleed 50% faster than normal people.
3. Stuns - Blood worms have no way of dealing with a stunned host other
than getting out. They can deal with any restraints by melting them,
though.
4. Testing - Security can order a blood worm testing crate from cargo,
either for a 20 minute cooldown via the security cargo interface
console, or for 10000 credits via the supply console. It contains 4
single-use testers that hurt a bit when applied, but are instant to use
and 100% accurate. The stopgap is that they're really fucking expensive
and only work once per item.

### Screenshot
<img width="280" height="132" alt="image"
src="https://github.com/user-attachments/assets/00d22361-997e-4347-a0bf-aa240de40727"
/>

## Why It's Good For The Game

Antagonist variety, mainly. This is basically Cortical Borers 2:
Electric Boogaloo.

Currently, we lack any antagonists with mind control abilities. That
really sucks!

I've also gotten a lot of positive feedback about the antagonist while
working on it.

This antagonist also has great potential for roleplay, as they can take
over hosts, surprise attack people by getting out of a dead corpse, talk
to each other using Wormspeak, etc.

I think we're also itching for variety on "pest" antagonists. Right now
we just have spiders and xenos. Everybody knows these two, so why not
mix it up a bit?

And as for balance? Blood worms are relatively easy to dispatch when you
know their weaknesses, which are extremely clear. Bleeding for hosts,
fire for either one, lasers for the worms themselves. As long as you get
the host in crit and keep hitting, you've pretty much won, and they
can't keep spamming Inject Blood forever since they'll quickly run out
of blood to use.
## Changelog
🆑
add: Added a new heavy roundstart/midround antagonist, the Blood Worm.
Credit to INFRARED_BARON for the sprites!
fix: Removing traits based on a source no longer causes issues with
trait signals.
fix: High-priority effects no longer double-trigger due to subsystem
issues.
fix: Weighted averaging in reagent merging code has been band-aid fixed.
It's not the best, but it works.
/🆑
2026-01-14 23:30:35 -06:00
theOOZ fdd96d7d23 queued_rulesets list uses proc to unqueue (#94843)
## About The Pull Request

Makes unqueue'ing rulesets use a `unqueue_ruleset()` proc, just like
`queue_ruleset()`
Takes singletons instead of type paths.

## Why It's Good For The Game

Consistently uses these procs when adding or removing rulesets from the
queue. There was already a proc for adding, so having one for removing
suits. This PR removes any case of directly editing the
`queued_rulesets` list. This should make the code cleaner, among other
things.

## Changelog

🆑
code: Adding or removing rulesets from the queue list is done by procs
instead of directly editing the list.
/🆑
2026-01-15 03:44:38 +01:00
ArcaneMusic 81b99b85a1 Adds a fishing log file. (#94828) 2026-01-13 19:32:47 +01:00
John Willard b068c1e7c9 Fixes job changing swapping paycheck dep (#94792)
## About The Pull Request

Adding job access in the HoP's console (``add_trim_access_to_card``
proc) changes the paycheck department of EVERYONE of that job, because
we assign all players via one job datum using ``SStype_occupations``
(through ``get_job_type``), so everyone's bank account stores the same
job datum as everyone else of their job.

To fix this, we are simply going to update the job of the bank account
to the new one, rather than change the paycheck department. This will
keep it in-sync with the current system while fixing the bug.

## Why It's Good For The Game

WTAF.
2026-01-10 12:24:12 -06:00
Tad Hardesty f58c056f4a Slightly improve tabular layout of MC statpanel (#94747)
## About The Pull Request

* Add a distinct column at the start for the stat letter, and monospace
it, to solve "[Q]" and "[R]" being one pixel wider than
"[&nbsp;&nbsp;]".
* Vertically align cells to the top, so the name of a subsystem appears
next to the first line of its description, not in the middle.

Before:
<img width="558" height="351" alt="image"
src="https://github.com/user-attachments/assets/c688d94b-535b-421e-90c6-a3a870cb7a4e"
/>
<img width="504" height="114" alt="image"
src="https://github.com/user-attachments/assets/bcbef34f-f2ff-4987-8643-93bfe6994a8c"
/>

After:
<img width="558" height="351" alt="image"
src="https://github.com/user-attachments/assets/ecc862a6-a7cc-4188-b231-449c22fec1f4"
/>
<img width="558" height="109" alt="image"
src="https://github.com/user-attachments/assets/29a104a2-637e-4026-a386-e1e86397cc8e"
/>

## Why It's Good For The Game

Looks prettier, easier to navigate by eyeball.
2026-01-06 17:37:09 -05:00
Jacquerel ae46b029e3 Removes Big Hands quirk (#94759)
## About The Pull Request

This PR removes the quirk "Big Hands" from the game

## Why It's Good For The Game


https://superset.moth.fans/superset/dashboard/28/?native_filters_key=U_1PwGbC9S0Sdb6We7h4rZiXiq-2OqlJo28rmbtiCXl6s7Cbi_Nhw-uLWDvHMTrw
In the last quarter-year of played rounds, Light Drinker was assigned
35,600 times.
Big Hands was assigned 57 times.

Nobody uses this quirk.
It's boring.
It says nothing about your character.
We already have a better, more fun, and more-used quirk that makes you
bad at using guns (stormtrooper aim).

Sometimes it feels like we add negative quirks just because we can, and
this is one of those.

## Changelog

🆑
del: It's no longer considered quirky to have Big Hands.
/🆑
2026-01-06 17:36:09 -05:00
Bloop 83cd43da91 Extends atom_reskin to be more modular/adds support for greyscale reskins in the loadout menu (#94466)
Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com>
2026-01-05 09:02:23 +00:00
SmArtKar 4922e738d3 Fixes TTS filters (sometimes) not working (#94696)
## About The Pull Request

``speaker`` is the voice, not the atom itself

## Changelog
🆑
fix: Fixed TTS filters (sometimes) not working
/🆑
2026-01-03 22:52:47 -07:00
Bloop b0d3d6acc5 Stops the radioactive nebula from irradiating mirage holders and other abstract mapping objects (#94575) 2025-12-30 18:30:05 +01:00
SyncIt21 7c5ef1cfb8 Removes unused parameter times_fired from mob procs (#94590)
## About The Pull Request
What it says on the tin. `times_fired` is the most unused parameter in
all mob procs. I say most because there were just 2 cases where it was
used
- handling breathing
- handling heartbeat

Besides these 2 cases this parameter did nothing in every proc. Removing
it does 2 things
- Makes those procs more readable as it now has 1 less parameter that
was documented poorly and did nothing
- Makes those procs slightly faster as we are passing 1 less variable to
its parameter call stack

It can easily be substituted with `SSmobs.times_fired` which was its
original value anyways

## Changelog
🆑
code: removes an unused parameter `times_fired` from mob life procs.
Making them function slightly faster
/🆑
2025-12-26 09:51:33 -05:00
san7890 2c3513e998 Admins Can Now Always Recall Shuttles (#94486) 2025-12-26 19:32:37 +11:00
MrMelbert a9b0ecb7d0 Weather anomaly (#94509)
## About The Pull Request

A weather anomaly can spawn on the station, causing a sandstorm,
snowstorm, or rainstorm to affect the room (and nearby rooms). These
weathers range from "harmless" to "mildly damaging".

They last for around five minutes.
The weather doesn't start immediately, giving people time to neutralize
it before it causes damage.
Neutralizing the anomaly stops the weather. 
If they detonate, it just throw objects away from itself.

<img width="407" height="225" alt="image"
src="https://github.com/user-attachments/assets/2de1b797-2b17-442c-9023-11085b4849cf"
/>

<img width="991" height="674" alt="image"
src="https://github.com/user-attachments/assets/afe5a21d-9cf8-4e9d-95ec-adef6fd12a93"
/>

A rarer version of the anomaly can also occur, which brings a lightning
storm, which may damage the station itself.

Also, reactive weather armor. When you are hit, it summons a lightning
strike below nearby assailants.

## Why It's Good For The Game

With the added rain mechanics I wanted to use them, but it's kinda hard
to shoe them into the station because, "why is it raining on a space
station that makes no sense"

However, anomalies are weird, so this fits perfectly

## Changelog

🆑 Melbert
add: Weather anomalies, in four variants: Rain, snow, sand, and the rare
lightning storm.
add: Reactive Weather Armor
/🆑
2025-12-20 12:33:10 -05:00
SmArtKar 0dcf70d9ec Adds a warning for invalid dynamic config weights (#94517)
## About The Pull Request

Warns admins and clamps values for dynamic weights/pops to ensure that
invalid values don't get stored in the list
Should prevent errors like
https://github.com/tgstation-operations/server-config/commit/e3c44eebf3de8f6b99a7ddc18268e87b33d793cb
from slipping under our radar in the future

## Changelog
🆑
admin: Added a warning for invalid dynamic config weights
/🆑
2025-12-19 10:17:15 -05:00
SmArtKar 739bd4b76a Fixes runtimes caused by persistent scars trying to save bodyswapped people's scars (#94504)
## About The Pull Request

Original slot index is preserved upon mind transferring between bodies,
but original character isn't, so this could runtime if you bodyswapped,
lived until roundend and had persistent scars on.

## Changelog
🆑
fix: Fixed runtimes caused by persistent scars trying to save
bodyswapped people's scars
/🆑
2025-12-16 21:54:04 -05:00
nevimer 6e9f2ccfc0 Merge remote-tracking branch 'tgstation/master' into upstream-12-15
# Conflicts:
#	.github/workflows/compile_all_maps.yml
#	.github/workflows/run_integration_tests.yml
#	_maps/map_files/CatwalkStation/CatwalkStation_2023.dmm
#	code/_onclick/hud/credits.dm
#	code/controllers/subsystem/networks/id_access.dm
#	code/datums/diseases/advance/advance.dm
#	code/datums/diseases/advance/symptoms/heal.dm
#	code/game/machinery/doors/door.dm
#	code/game/objects/structures/crates_lockers/closets/secure/medical.dm
#	code/game/objects/structures/crates_lockers/closets/secure/security.dm
#	code/modules/antagonists/malf_ai/malf_ai_modules.dm
#	code/modules/jobs/job_types/_job.dm
#	code/modules/loadout/categories/accessories.dm
#	code/modules/loadout/loadout_helpers.dm
#	code/modules/loadout/loadout_items.dm
#	code/modules/loadout/loadout_preference.dm
#	code/modules/mob/living/silicon/robot/robot_defense.dm
#	code/modules/mod/mod_theme.dm
#	code/modules/projectiles/ammunition/energy/laser.dm
#	code/modules/reagents/reagent_containers/cups/drinks.dm
#	code/modules/shuttle/mobile_port/variants/supply.dm
#	code/modules/surgery/organs/internal/eyes/_eyes.dm
#	code/modules/unit_tests/screenshots/screenshot_antag_icons_heretic.png
#	icons/hud/screen_full.dmi
2025-12-15 18:12:29 -05:00
san7890 4f88c9f756 Cleanup + Logging for Readiness Bugs (#94462)
## About The Pull Request

On production, I sign up for rounds (and I know I pushed the button
because the auto-deadmin message comes up) but it doesn't inject me in
the game and fails without a warning. I have no idea why it's doing this
but I shifted some stuff around and added a few logs to hopefully stop
this strange consistent failure for me to start a shift.

I just cleaned up a lot of the code and turned the ready defines into
strings instead of a boolean (so I could log it more efficiently with
little overhead, as well as standardize it to a define without people
doing wacky shit everywhere). I don't think this will fix the issue but
it will definitely make some things more clear as to why I'm not joining
rounds without warning despite clicking ready.
## Why It's Good For The Game

Cleans the code up while trying to resolve a really puzzling bug I've
been having.
## Changelog
🆑
server: The ready/not ready states of new players are logged when a
shift starts.
/🆑
2025-12-14 21:25:58 -05:00
FalloutFalcon d25c6201f4 Standerdizing currency symbols Part 2 (#94259)
## About The Pull Request
Converts almost all non-constant, non-tgui usages of all variantions of
"credit" and "cr"

Everything seems in order, tested most the currencies.
<img width="905" height="119" alt="image"
src="https://github.com/user-attachments/assets/3fa005a7-a114-426c-9646-b81f68bc2dec"
/>
<img width="255" height="128" alt="image"
src="https://github.com/user-attachments/assets/14c83b54-4fd9-4bee-838f-5b1c03939d9a"
/>


## Why It's Good For The Game
Same justification as https://github.com/tgstation/tgstation/pull/94128
Just easier to mantain/adjust the grammer/names of our money
## Changelog
🆑
spellcheck: minor cleanup on some usecases of "credits"
/🆑
2025-12-13 21:00:19 -05:00
san7890 bbd0e070a3 Adds In-Game Link To Server Config (#94371)
## About The Pull Request

On the tin, just adds a link to
https://github.com/tgstation-operations/server-config to the game so
people are a little bit more aware of it.

Here's how it looks:

<img width="1386" height="275" alt="image"
src="https://github.com/user-attachments/assets/63d2d284-6d5f-4f41-ba80-abc33699f7c5"
/>

## Why It's Good For The Game

More visibility to a public resource, this wasn't feasible before the
present situation. It won't show up here unless the config variable is
set.
## Changelog
🆑
config: If you publicly host a copy of your server's config, you may now
link to the public URL in the 'CONFIGURL' setting in the server config.
It will show to players in the Escape Menu's Resources Carousel.
/🆑
2025-12-13 20:52:36 -05:00
LT3 701801355f Removes Rock The Vote config entry (#94408)
## About The Pull Request

Removes the RTV config entry, as RTV was removed in
https://github.com/tgstation/tgstation/pull/86788

## Why It's Good For The Game

Remove leftover useless config entry

## Changelog

🆑 LT3
admin: Removed ability to enable Rock The Vote because RTV is no longer
a thing
/🆑
2025-12-13 20:37:47 -05:00
san7890 d25647c250 log_world() the Round ID (#94429)
## About The Pull Request

Better correspondence in higher-level logging files (e.g. TGS's
DreamDaemonLog Diagnostic), also helpful in instances where Round ID is
not known (like if someone gives you a random log and the round ID has
been forgotten), pretty good to have it logged if we know it in all the
important stuff like dd.log.
## Why It's Good For The Game

Higher standard of information tracking without having to do infinite
amounts of UTC Timezone maths and what-not as it's becoming more common
for me to see stuff and then have to pull all sorts of other data in
order to make sure what I'm looking at is accurate to what I want (and
still having that degree of uncertainty is unideal).
## Changelog
🆑
server: Round ID is now output to `log_world()`, so it'll show up stuff
like world.log, dd.log, etc.
/🆑
2025-12-13 20:32:43 -05:00
Rockdtben 02271c6032 Provides two work arounds for uplink going off screen. (#94405)
## About The Pull Request
This provides a work around for issue: #92706

Which prevents user from using uplink.

YES -> A new verb called "Reset UI Positions". It puts them all to the
0,0 location which is top left of screen.
YES, too! -> Holding ALT and clicking the background of the window will
allow you to move it.

## Why It's Good For The Game

This provides ADMINs two ways to help antags that get their uplink page
stuck.
2025-12-12 13:34:04 -06:00
Alien 9175f53a2e Adds "Department Budget" access that lets you place orders with the shopping app, gives it to warden and cargo techs (#94288)
## About The Pull Request

The "NT Shopping Network" app now checks for if you have "Department
Budget" access instead of command access for letting you place orders
and not requests. All heads, cargo techs and the warden have it shift
start but it can be given to anyone (same as EVA access) and heads of
staff can add or remove it at their access consoles.
Also makes warden start with the app to hint that they have access to
the budget.

## Why It's Good For The Game

The access itself is good because letting heads choose who has access to
the department budget is obviously good.
Cargo techs get it cuz they already have access to it by having access
to the request consoles in cargo.
Warden gets it by default because HOS is usually busy
killing/arresting/patrolling while warden is the one actually managing
brig and the armory. If HOS really hates that warden has access to the
budget they can just remove it on their console.
2025-12-11 19:18:37 -06:00