Commit Graph
482 Commits
Author SHA1 Message Date
TimandGitHub f95b377e74 Books now make paper sound when opened (#96411)
## About The Pull Request
Uses the existing paper sounds so that when a book is opened, it makes a
small noise instead of just being silent.

## Why It's Good For The Game
Sound is good.

## Changelog
🆑
sound: Books now make paper sound when opened
/🆑
2026-06-10 14:59:23 +02:00
LT3andGitHub 95905028c1 Janitors have perfect aim throwing things into disposal units (#96188) 2026-05-27 23:51:09 -04:00
MrMelbertandGitHub ea0859d5fe Bane refactor (now uses damage multipliers) (#96003) 2026-05-16 11:41:29 +10:00
_0StevenandGitHub e34504c5e3 Fixes two books creation bugs: trimming and newlines. (#95704)
## About The Pull Request

### Trimming

So as per #89165, paper below 5000 characters was getting cut off
despite being below the cap.
This seems to have been happening because of the following code:

https://github.com/tgstation/tgstation/blob/d8774f4c4176f09463457f04905570923b27b3de/code/modules/library/book_info.dm#L44-L50
Paper uses the raw text for its count and handles pen
color/font/boldness/such tgui-side, but books first expand that html
dm-side AND then encode it, significantly increasing the amount of
characters before trimming occurs.
This, obviously, leads to characters getting cut off!

Buuuuuuuut not trimming it at all isn't perfect. We know paper *should*
trim it, but we also know that's not gonna be all paper. There's gonna
be paper where it's inexplicably past the 5000 characters cap.

So, instead we use a second more lenient book limit, right now defined
as 2x the paper limit, which should stop the worst cases without
breaking for the best cases.

### Newlines

Second bit! Paper stores each writing attempt as a separate thing, but
turning them into books collapses these:

https://github.com/tgstation/tgstation/blob/d8774f4c4176f09463457f04905570923b27b3de/code/modules/library/book_info.dm#L46-L48
This, however, doesn't account for the part where paper tgui inserts
newlines between these inputs:

https://github.com/tgstation/tgstation/blob/d8774f4c4176f09463457f04905570923b27b3de/tgui/packages/tgui/interfaces/PaperSheet/Preview.tsx#L317-L318
Which book tgui doesn't! Cause it's just one big glob of text, not
separate entries.
Which in turn means paper written with multiple entries just... has all
of these put on the same line, which sucks.

So we make the paper entries collapsing actually add newlines the same
way, fixing our issue.

### Nitpicks

...We also change the `to_raw_html(...)` proc to re-use the same
`<font>` tag. Regrettably, we can't use the exact same setup as
paperwork uses on its tgui side because it uses `style` which would get
sanitized out, but there's no reason for us to double the amount of
characters behind the scenes by using multiple layered `<font>` tags for
no reason.

***Ideally*** I feel books and paper should just use the same tgui
systems, but I sure as hell wouldn't know how to do that without
breaking everything including old books, with how fickle paperwork code
already is.
## Why It's Good For The Game

Fixes #89165.
fix jank 👍
It *really* sucks when you make a book below the 5000 character cap, but
it somehow hits the character cap and gets trimmed anyway. I feel the
books using static ui data should avoid this being horrible.
## Changelog
🆑
fix: Books no longer get trimmed below the paper length limit.
fix: Books made using paperwork created with multiple inputs no longer
put all that text on the same line.
/🆑
2026-04-17 13:04:32 +02:00
MrMelbertandGitHub 4eadf5caf7 The big tooltype_act de-cargo-cult-ing (#95408)
## About The Pull Request

Removes a lot of cargo cult copypasta with
`default_deconstruction_screwdriver`, `default_deconstruction_crowbar`,
and to a lesser extent `default_pry_open` and
`default_change_direction_wrench`

ALL you gotta do now if you want your machine to have an openable panel
or be deconstructible with a crowbar is this
```dm
/obj/machinery/dish_drive/screwdriver_act(mob/living/user, obj/item/tool)
	return default_deconstruction_screwdriver(user, tool)

/obj/machinery/dish_drive/crowbar_act(mob/living/user, obj/item/tool)
	return default_deconstruction_crowbar(user, tool)
```

`default_deconstruction_screwdriver` no longer directly sets
`icon_state`, requiring the user pass in the open and closed icon
states. Now, it just calls `update_appearance`, and everything that once
passed the icon state now uses `base_icon_state` and
`update_icon_state`.

## Why It's Good For The Game

Many of these procs were terribly overcomplicated and difficult to work
with for what should be a relatively simple action

Streamlining it makes it easier for coders to understand and work with

## Changelog

🆑 Melbert
refactor: A majority of machines had their screwdriver/crowbar/wrench
interactions rewritten, report any oddities like being unable to open a
machine's panel or deconstruct a machine
/🆑
2026-04-14 19:46:24 -04:00
MrMelbertandGitHub ee08406e4a Fixes me destroying the IDC in the last commit (#95695) 2026-04-10 00:53:59 +02:00
ed54499828 [MDB Ignore] Medical larp: Adds the IDC-27 as an analog to the SDSM-35 for viruses (#95465)
## About The Pull Request

Continues the work of #94761 by adding an analog for virus references

It contains a majority of viruses - including some that are
not-quite-viruses like parrot possession
Some are excluded, some are combined into others

It also contains all advanced virus symptoms

<img width="859" height="509" alt="image"
src="https://github.com/user-attachments/assets/c73f56c0-5a11-4643-9a97-1e2a06ade0c1"
/>

Other changes

- Refactored the SDSM to have use a generic "PaginatedBook" component
for reuse
- Adjusted flavor of all of the diseases
- Flu / Spanish Flu and Cold / Cold 9 now properly act as antibodies for
one another as implied by cure text

## Why It's Good For The Game

Refer to #94761 : De-wikification and larp. This one is a reference to
the IDC-11.

## Changelog

🆑 Melbert
refactor: Refactored the SDSM-35 to allow for new books of similar
styles, report any oddities with it.
fix: Fixes the broken image(s) in the SDSM-35. 
add: Adds the IDC-27 in Medbay, the CMO's office, Virology, and possibly
the Library. It's a reference book to all viruses you may experience,
similar to the SDSM-35.
add: Several diseases/viruses received minor flavor adjustments,
primarily to cure text, agent, description, and form.
add: Getting cured of the Flu provides immunity to Spanish Flu (and visa
versa) as implied in cure text.
add: Getting cured of a Cold provides immunity to Cold-9 (and visa
versa) as implied in cure text.
/🆑

---------

Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com>
2026-04-07 07:51:30 +02:00
John WillardandGitHub 1d4081e6c0 Barcode scanner now lets you check books out (#95431)
## About The Pull Request

The barcode scanner has a check-in mode, but to checkout you have to
scroll through a (potentially) large list of books. This aims to fix
that by letting you skip the UI using the same item you use to check-in.



https://github.com/user-attachments/assets/916b743e-d974-4e7d-a9f2-a407562c5123


Also limits library book borrowing time to 2 hours, cause the UI looked
really weird with it uncapped (also any round that goes more than 2
hours you should bring your books back)

## Why It's Good For The Game

Better UX I think.
2026-03-24 12:11:28 -05:00
LemonInTheDarkandGitHub 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
MrMelbertandGitHub 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
86cb91e653 Fix Kommand reset not updating action icon (#95107)
## About The Pull Request

Fix Kommand reset not updating action icon.

## Why It's Good For The Game

Fixes the Kommand icon staying the set color even after being reset.

## Changelog

🆑
fix: The Kommand action icon will now properly reflect your pointer
colour after being reset.
/🆑

Co-authored-by: Jordan Dominion <Cyberboss@users.noreply.github.com>
2026-02-14 07:22:44 +01:00
MrMelbertandGitHub 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
SmArtKarandGitHub 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
FalloutFalconandGitHub 8f1a925afa More abstract types (#95064) 2026-02-03 23:25:31 +01:00
MrMelbertandGitHub 45b23412f8 [MDB Ignore] Medical larp: Adds the SDSM-35 (an in game brain trauma reference) (#94761)
## About The Pull Request

Medbay, the CMO, the Psychologist, (possibly) the Library, and some
maint rooms across all maps now have multiple copies of the SDSM-35

This exists as an in game ability to reference what brain traumas do. No
special bells or whistles, not even a search bar - it's a book after
all.

<img width="819" height="589" alt="image"
src="https://github.com/user-attachments/assets/ace867b9-a0f0-4302-99f9-46ed4d6fe377"
/>

<img width="802" height="546" alt="image"
src="https://github.com/user-attachments/assets/c96941d3-8da8-48f7-859b-93953fe01473"
/>

## Why It's Good For The Game

De-wikification: Rather than needing to pull up the wiki to figure out
what the brain trauma is doing, you can refer to the in game book and
cross reference the patient's behavior.

Medial larp: It's a reference to the DSM-5. If that wasn't obvious. 

## Changelog

🆑 Melbert
add: You can now find the SDMS-35 in Medbay, the CMO's office, the
Psychologist's office, and possibly the Library. Quite simply, it's a
reference book for all the brain trauma's you may experience.
/🆑
2026-01-08 19:47:04 -07:00
Tad HardestyandGitHub ddc7bfa4c4 Use evil CSS tricks to fix wiki books looking awful (#94738)
## About The Pull Request

The [MediaWiki "printable" version of pages][p] was at some point
deprecated in favor of standard print stylesheets, making wiki books
look rather ugly, even uglier than if they weren't using the parameter.
However, there seems to be no way to command an iframe to opt in to or
simulate the print stylesheet. What we really want is to suppress the
sidebar and header. Therefore: position the iframe off of the page to
the left and top by the size of the elements we want to hide.

Hiding the left sidebar seems fully clean. However, hiding the top
header also hides the first bit of the scrollbar, which is a little
odd-looking.

Also, fix wiki books not giving book nerd moodlets.

[p]: https://wiki.tgstation13.org/Guide_to_drinks?printable=yes

Before:
<img width="984" height="790" alt="SS13 wiki book before"
src="https://github.com/user-attachments/assets/1eb6e961-bc35-418b-a015-868d7269e2f5"
/>

After:
<img width="985" height="752" alt="SS13 wiki book after"
src="https://github.com/user-attachments/assets/39a63ad3-bc99-4c71-a5e7-ff06ae1b6852"
/>

## Why It's Good For The Game

Less offensively ugly UI.

## Changelog
🆑
fix: Wiki books such as "Barman Recipes" and "Space Law" no longer have
terrible formatting.
fix: Wiki books now properly give book nerd moodlets.
/🆑
2026-01-06 17:37:29 -05:00
John WillardandGitHub 41f34c2a86 Adds tgui color picker (#94313)
## About The Pull Request

Ports https://github.com/Monkestation/Monkestation2.0/pull/1231 which is
a port of https://github.com/BeeStation/BeeStation-Hornet/pull/9417
which is a port of https://github.com/omgovich/react-colorful/
Also a port of
https://github.com/effigy-se/effigy/blob/main/tgui/packages/tgui/interfaces/effigy/ColorPickerModal.tsx
for hex color presets

Admin stuff got excluded (pref-like picker, filterrific, get-variables)



https://github.com/user-attachments/assets/7069bef9-81cd-4636-bf68-cbad227ef09e


## Why It's Good For The Game

It's one of the only input areas that still doesn't use TGUI, leaving
darkmode players flashbanged every single time a color selection UI is
opened. This is also just visually great and I think a big upgrade from
byond's.

## Changelog

🆑 omgovich, itsmeow, Absolucy, JohnFulpWillard, jlsnow301, TealSeer,
lessthnthree
add: Color selection panels now use TGUI (If you have TGUI enabled in
settings).
/🆑
2025-12-21 16:18:34 -08:00
MrMelbertandGitHub bfdb237612 Spooky Scary Supreme Surgery (Rework) (#93697) 2025-12-19 18:42:58 +01:00
GhomandGitHub 0b0c5ea91e Unit test material checks are now performed on all crafting recipes by default. All stack recipes now transfer mats to the results (#92620)
## About The Pull Request
Extends the part of the crafting unit test that ensures consistency
between the total mats of the components of a recipe (or rather, the
result of said recipe) and a generic instance of the same type as its
result, previously only implemented on food recipes.

## Why It's Good For The Game
This ensures a degree of consistency with the material composition of
various objects in the game. I couldn't do it in the original PR as that
one was too big already and it took months to get it merged, and have
the relative bugs fixed.

Currently a WIP as I slowly deal with the unit test reports.

## Changelog

🆑
refactor: Follow-up to the crafting/material refactor from months ago.
All objects crafted with stacks now inherit their mat composition (not
necessarily the effects and color) by default, while previously only a
few things like chair, sinks and toilets did. Report any object looking
or behaving weirdly as a result.
fix: The material composition of ammo boxes is no longer a 1/10 of what
it's supposed to be. It was a shitty hack to make it harder to recycle
empty ammo boxes. Instead, they lose materials as they're emptied now.
/🆑
2025-12-02 18:29:01 -05:00
Joshua KidderandGitHub 7a3ad79506 All camelCase (Brute|Burn|Fire|Tox|Oxy|Organ|Stamina)(Loss) procs now use snake_case. UNDERSCORES RULE! (#94111)
## About The Pull Request
It's just a partial cleanup of
anti-[STYLE](https://github.com/tgstation/tgstation/blob/master/.github/guides/STYLE.md)
code from /tg/'s ancient history. I compiled & tested with my helpful
assistant and damage is still working.

<img width="1920" height="1040" alt="image"
src="https://github.com/user-attachments/assets/26dabc17-088f-4008-b299-3ff4c27142c3"
/>


I'll upload the .cs script I used to do it shortly.

## Why It's Good For The Game
Just minor code cleanup.

Script used is located at https://metek.tech/camelTo-Snake.7z

EDIT 11/23/25: Updated the script to use multithreading and sequential
scan so it works a hell of a lot faster
```
/*
//
Copyright 2025 Joshua 'Joan Metekillot' Kidder

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
//
*/
using System.Text.RegularExpressions;
class Program
{
    static async Task Main(string[] args)
    {
        var readFile = new FileStreamOptions
        {
            Access = FileAccess.Read,
            Share = FileShare.ReadWrite,
            Options = FileOptions.Asynchronous | FileOptions.SequentialScan
        };
        FileStreamOptions writeFile = new FileStreamOptions
        {
            Share = FileShare.ReadWrite,
            Access = FileAccess.ReadWrite,
            Mode = FileMode.Truncate,
            Options = FileOptions.Asynchronous
        };
        RegexOptions regexOptions = RegexOptions.Multiline | RegexOptions.Compiled;
        Dictionary<string, int> changedProcs = new();
        string regexPattern = @"(?<=\P{L})([a-z]+)([A-Z]{1,2}[a-z]+)*(Brute|Burn|Fire|Tox|Oxy|Organ|Stamina)(Loss)([A-Z]{1,2}[a-z]+)*";
        Regex camelCaseProcRegex = new(regexPattern, regexOptions);

        string snakeify(Match matchingRegex)
        {
            var vals =
            matchingRegex.Groups.Cast<Group>().SelectMany(_ => _.Captures).Select(_ => _.Value).ToArray();
            var newVal = string.Join("_", vals.Skip(1).ToArray()).ToLower();
            string logString = $"{vals[0]} => {newVal}";
            if (changedProcs.TryGetValue(logString, out int value))
            {
                changedProcs[logString] = value + 1;
            }
            else
            {
                changedProcs.Add(logString, 1);
            }
            return newVal;
        }
        var dmFiles = Directory.EnumerateFiles(".", "*.dm", SearchOption.AllDirectories).ToAsyncEnumerable<string>();

        // uses default ParallelOptions
        // https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.paralleloptions?view=net-10.0#main
        await Parallel.ForEachAsync(dmFiles, async (filePath, UnusedCancellationToken) =>
        {
            var reader = new StreamReader(filePath, readFile);
            string oldContent = await reader.ReadToEndAsync();
            string newContent = camelCaseProcRegex.Replace(oldContent, new MatchEvaluator((Func<Match, string>)snakeify));
            if (oldContent != newContent)
            {
                var writer = new StreamWriter(filePath, writeFile);
                await writer.WriteAsync(newContent);
                await writer.DisposeAsync();
            }
            reader.Dispose();
        });
        var logToList = changedProcs.Cast<KeyValuePair<string, int>>().ToList();
        foreach (var pair in logToList)
        {
            Console.WriteLine($"{pair.Key}: {pair.Value} locations");
        }
    }
}

```

## Changelog
🆑 Bisar
code: All (Brute|Burn|Fire|Tox|Oxy|Organ|Stamina)(Loss) procs now use
snake_case, in-line with the STYLE guide. Underscores rule!
/🆑
2025-11-27 15:50:23 -05:00
necromanceranneandGitHub 03da670d45 Adds backflipping, because flipping wasn't annoying enough (#93655)
## About The Pull Request

Adds backflipping, which has a lower probability of failing.

## Why It's Good For The Game

Expression of emotion is a key component to communication. 

Or perhaps you just want to deteriorate your acrobatics implant faster.

## Changelog
🆑
qol: You can now backflip.
/🆑
2025-11-11 19:27:25 -08:00
Leland KembleandGitHub 348789fa8d The Renamening- upgrades UNIQUE_RENAME and moves a lot of renaming implementations under it (#93115)
## About The Pull Request

Moves a lot of the unique renaming implementations described in #82664
to the functions given by the `obj_flag` `UNIQUE_RENAME`.
`UNIQUE_RENAME` has been given new properties to account for
non-standard renaming, these being the `RENAME_NO_DESC` flag that
prevents changing the description, the `nameformat()` and `descformat()`
procs that, when modified, allow for applying naming formats(i.e. "Body
Bag - [input]"), as well as other post-renaming handling such as
changing the name of the output plant of a renamed seed, the
`rename_checks()` proc that allows for unique naming prevention(such as
a locked personal closet), and the `rename_reset()` proc to clean up
other possible renamed variables potentially changed in `nameformat()`
and `descformat()`.

This also adds `/datum/element/tool_renaming` to crayons, which will let
them rename anything that has `UNIQUE_RENAME`. I looked through
everything with that flag, and I didn't see anything that I don't think
should be renameable by a crayon(except things that shouldn't be
renamable with pens), so it shouldn't fuck anything up.

## Why It's Good For The Game

moves all of the non-honorable mentions in #82664 to the same renaming
system, and also moves all of the honorable mentions save for:

- plaques, as they only get renamed once and wouldn't benefit from
`UNIQUE_RENAME` imo
- books, because they're far more than just renaming, and are persistent
- paintings, because they're persistent
- photos, because they're not normal renaming and they're persistent
- endoskeletons, because they're done with a multitool in UI
- cardboard IDs, because they're far more than just renaming

Additionally, this fixes:

- Implanter renaming didn't work because a ! was missing
- Clown borg picket sign renaming didn't work because they didn't use
the correct arguments

This'll make it easier to make renameable objects in the future, as
well.

## Changelog
🆑

fix: fixes implanter renaming not working
fix: fixes clownborg picket sign renaming not working
code: brought most unique renaming implementations under UNIQUE_RENAME

/🆑
2025-10-17 01:56:09 +02:00
MrMelbertandGitHub 750ca9d2ec Two as anything greps (and some other cleanup) (#92974) 2025-09-20 13:44:28 -04:00
GhomandGitHub 76b933fd4b Underwater basketweaving recipes are hidden unless you've the skillchip (#92979)
## About The Pull Request
The recipes are locked behind a particular skillchip anyway. We might as
well just use the framework for learnable recipes instead of relying on
a particular trait with no other use to it. This also prevents these
recipes from showing in the menu even if the requirements aren't met.

## Why It's Good For The Game
See above.

## Changelog

🆑
refactor: Underwater basketweaving refactored so it doesn't show in the
crafting menu unless you've the skillchip active.
/🆑
2025-09-15 16:41:01 -07:00
necromanceranneandGitHub 7e3563ab2c Fixes a runtime in Syndicate Tome bibble smack code (#92952)
## About The Pull Request

fixes https://github.com/tgstation/tgstation/issues/92951

## Why It's Good For The Game

This was still using outdated args. 

## Changelog
🆑
fix: Syndicate Tomes once again can be used to beat the shit out of
people.
/🆑
2025-09-13 00:36:54 +02:00
MrMelbertandGitHub 7c0973ccf4 Refactors names and voices / potted plants no longer conceal voice (just appearance) / honorifics show on examine (#92781)
## About The Pull Request

Closes #92778
Closes #86829

<img width="347" height="39" alt="image"
src="https://github.com/user-attachments/assets/c50bd1ff-8c00-47a7-a31a-617fae2adc5b"
/>

1. Splits `TRAIT_UNKNOWN` into `TRAIT_UNKNOWN_APPEARANCE` and
`TRAIT_UNKNOWN_VOICE`

2. Renames some stuff like `getvoice` and `getspecialvoice`

3. Gets rid some crummy signals around `get_visible_name` and
`get_voice`

4. Heads now apply the disfigured trait when relevant (rather than
snowflake checking for damage amount)

5. Ling voice refactored into using special voice (it was only used by a
viro symptom anyways; I don't anticipate this overlap being problematic)

6. Mask voice changer refactored into a trait

## Why It's Good For The Game

Potted plants shouldn't have magical voice concealing powers -
especially not over radio, but not over in person either. It's a damn
plant

So I addressed this by refactoring our face and voice system. Overall
things should be a lot cleaner and easier to use.

## Changelog

🆑 Melbert
refactor: Refactored a lot of code relating to human face and voice, ie,
what shows up in examine and in say. Report anything odd when examining
people, with ID cards, when talking over radio, or when disguised
refcator: Refactored how you get disfigured when your head's super
damaged
refactor: Refactored ling mimic voice and traitor voice changer
del: Potted plants no longer hide voice. They still hide appearance,
though
qol: Honorifics now show in examine / in world, rather than only when
speaking.
/🆑
2025-09-12 17:11:06 +02:00
SmArtKarandGitHub fa6964c581 Fixes newspapers not lighting on fire from lighters (#92641)
## About The Pull Request

Closes #92636
Actually two bugs in one, also fixes books printing the same message
thinking that you're trying to vandalize them.

## Changelog
🆑
fix: Fixed newspapers not lighting on fire from lighters
/🆑
2025-08-21 02:38:44 +02:00
_0StevenandGitHub 69bd91b2f4 Fixes newscaster channels having a random chance of breaking upon creation of a new channel, refactors how channels are tracked in the first place (#92371)
## About The Pull Request

So in a recent round I noticed the newscaster UI was acting kind of
funky, where two channels seemed to overlap and weirdly pick between the
two in unpredictable ways. Looking into it, it seemed that somehow the
channels had managed to get their unique IDs to overlap-
Oh.

https://github.com/tgstation/tgstation/blob/5d3353e7af2b88ab9379d5fb567b24afd8776acd/code/game/machinery/newscaster/newscaster_data.dm#L109-L131
I see.

...I think that code speaks for itself, in how this could've gone wrong.

Anyhow, in this pr we entirely ditch this system, and instead make it
use an incremental and thus guaranteed to be unique ID.
This fixes our issues.

While we're here, we also remove the unused `channel_IDs` list, and
replace it with the associative lists `network_channels_by_id` and
`network_channels_by_name`. This allows us to also stop iterating over
every network channel until we find the one with the right name or ID.
We also rename some confusing, wrong, or non-standard vars while we're
here.
2025-08-12 16:22:35 -05:00
ArturlangandGitHub 0bc42d6940 Fixes the issue of usr pointing to admins by making Trigger pass down clicker (#92354)
## About The Pull Request
Fixes the issue of usr pointing to admins by making Trigger pass down
clicker, as usr is fucky and can be passed down by other unrelated
procs. Fun.
Added the clicker arg to all usages of Trigger as well
Also changes isobserver check in antagonist ui_act code that prevents
observers from clicking UI's instead to check if the ui.user is
owner.current
## Why It's Good For The Game
Fixes admins giving heretic to people opening the heretic UI for the
admin instead
2025-08-05 22:58:40 -05:00
Y0SH1M4S73RandGitHub fa573fa539 Adds the self-surgery skillchip as a fairly rare black market item (#91606)
## About The Pull Request

This PR adds a skillchip that allows the user to perform normal
surgeries on themselves, albeit with a 1.5x speed penalty and a flat 33%
increase to the probability of screwing up each step. You can find this
skillchip occasionally on the black market. It is also contraband, and
can be detected by n-spect scanners.

## Why It's Good For The Game

Provides a risky alternate means of obtaining surgical intervention,
such as if you either can't trust anybody else to do surgery on you or
can't be trusted to have certain surgeries done on you.

## Changelog

🆑
add: The Centcom Department of Import Control has become aware of the
use of highly-illegal and medically dubious self-surgery skillchips
aboard company stations. We suspect they are being sold to the station
through the black market.
/🆑
2025-07-05 17:43:54 +10:00
096c032402 Adds a new halloween species: Spirits (#90711)
## About The Pull Request

Adds 2 new species: Spirits and Ghosts

Spirits are available roundstart during Halloween, Wabbajack and
Xenobio's black slime extract
Ghosts are available through Magic mirrors

They fly around, and don't have legs and instead float around. They also
can't get legs implanted onto themselves.

They also do have organs, so they are affected by flashbangs, they do
get hungry, they do need oxygen to survive (they don't take damage in
space but they do suffocate & get slowdown), and can process chems.
Gibbing a ghost gives ectoplasm, an ingredient for ghost burgers.

Chaplains also got a buff here, null rod-type weapons' bane is now
against Spirit mobs, rather than hardcoded revenants. This means it now
includes Spirits/Ghosts, but also Soulscythes & Cult shades.

Also re-adds https://github.com/tgstation/tgstation/pull/81630 which was
reverted in https://github.com/tgstation/tgstation/pull/86506 which I
assume was accidental.

### The difference between Spirits and Ghosts

Ghosts have an innate ability to become incorporeal, which allows them
to phase through walls and stuff. Using this will immediately make them
drop any non-ghost limb/organ (not implants cause I thought it would be
funny). This ability is not available if they have holy water in their
system, and like revenants they also can't walk over blessed tiles with
it. They are also invisible to cameras while using this (not the obscura
though).

Sprites taken from observers directly, if anyone wants to make custom
sprites for them feel free. If anyone wants to make this obtainable
somehow in-game as well I wouldn't be opposed, halloween is just where I
thought it would fit most.

This also adds a lot of fixes that I encountered trying to add this,
from systems that have been neglected throughout the years.


https://github.com/user-attachments/assets/e368d710-80a0-4c63-b271-1abe3dd41a5e

## Why It's Good For The Game

We haven't gotten a new halloween species in a long time and thought it
would be fun if you can play as an actual ghost, the soul that remains
after a person passes, so Halloween feels more haunted. It's overall
made in just good fun, with a bonus that Ghosts are a cool species to
play with as well for Wizards & maybe Chaplains in the future (Dead sect
when?)

## Changelog

🆑
add: Added a new halloween species: Spirits, a species without legs and
instead floats.
add: Added a new magic mirror species: Ghosts, like spirits but with the
ability to become incorporeal, traversing through solid wall.
fix: Mobs unable to use storage items now can't use storage items.
fix: Mobs unable to use items can now not open airlocks & closets
fix: Mobs unable to pick items up can no longer pick items up and
immediately drop, moving one tile at a time.
fix: Mobs with intentional missing limbs (Alien larva) no longer show
their limbs as missing on examine (again)
fix: Golems' pref page had a missing icon, it now has one.
/🆑

---------

Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com>
2025-06-22 10:02:06 +02:00
GhomandGitHub aef17e5378 Mild acrobatics skillchip buff. Added item descriptions to other chips (#91439)
## About The Pull Request
There is no way to repair the acrobatics skillchip, and the allowed
usages only prevent it from taking damage, not the user. This PR ups
that amount to 5 and makes it repair 1% of its integrity every 2
seconds.

Also assigns a `desc` to other chips that were using the generic one,
which is really not in the slightest helpful, especially if you're
buying the skillchip from a vending machine.

## Why It's Good For The Game
Better acrobatics skillchip (It's just flipping and spinning, there's
little mechanical advantage to that), and more descriptive chips.

## Changelog

🆑
balance: Buffed the acrobatics skillchip (the one that disables spinning
and flipping cooldowns). Gave new item descriptions to skillchips that
were missing one.
/🆑
2025-06-09 16:36:26 +01:00
GhomandGitHub 14fb86e3e8 Mutation code cleanup, mutations now have sources to avoid concurrency problems. (#91346)
## About The Pull Request
This PR aims to clean or bring up to date portions of code about dna,
the dna console and mutations. This includes taking care of or removing
some of the awful choices like the pratically useless
`datum/mutation/human` pathing, or the class variable, in favor of using
sources to avoid potential issues with extraneous sources of a mutation.

The files changed are over a hundred just because I removed the
`datum/mutation/human` path, but the actual bulk of the code is mainly
shared between the datum/dna.dm, _mutations.dm and dna_console.dm.

## Why It's Good For The Game
Mutation shitcode is hurting my future plans for infusions a little.
Also it's a much needed refactor. Drafted 'till I'm sure it works
without issues.

## Changelog

🆑
refactor: Refactored mutation code backend. Report any issue.
/🆑
2025-06-08 13:57:10 +02:00
3804b5fe43 Refactors book attackby into item interaction procs, adding screentips, minor qol (#91273)
## About The Pull Request

This mostly just refactors the book `attackby(...)` proc into
`item_interaction(...)`, with some side-effects and screentips.
Notable ones follow here:

We move carving away from combat mode, and instead based it on whether
our tool is a pure writing utensil, a pure carving tool, or both at once
like the captain's fountain pen. If it's a pure tool, both left click
and right click are its respective primary action. If it's both,
however, left click is vandalizing and right click is carving.
This tries to ensure the expected primary interaction is always
left-click, without blocking anything if it could do both.

We move the barcode scanner interaction to the barcode scanner instead.
There's no good reason for this to stay on the book itself.

We add `can_vandalize(...)` as a proc and move all checks in there, so
we can call it after every tgui input. We don't replace the
`to_chat(...)` calls here with balloon alerts because the additional
clarifying info is needed, and it keeps the 'soulful' blind message.

We add `get_attack_self_context(...)` as a proc for getting screentips
on hovering over it in your active hand, because both the bible subtype
and the syndicate bible _bible subtype_ want different screentips there
in different situations, and so while it's clunky it's much less clunky
than the alternatives I considered.

Making it use actual storage datums avoids subtypes needing to make
manual changes to it in the `carve_out(...)` proc, and is just good for
organization.

This doesn't add screentips to most bible-specific interactions, as I
deemed them outside of the scope of this pr.
Those are better off done atomized into another pr.
## Why It's Good For The Game

less attackby, more item interaction
screentips good

I think having the carving interaction on combat mode is unintuitive,
especially when that's the only interaction it can do.
This ensures the expected primary interaction is always left-click.
## Changelog
🆑
refactor: Refactored the book interaction chain. Please report any
issues.
fix: You can no longer vandalize carved out books if you carve it after
opening the input menu but before entering anything.
qol: Added screentips to book interactions.
qol: Added screentips to barcode scanner interactions.
qol: Carving out books no longer uses combat mode, instead using
left-click by default and right-click if your tool can also write.
Screentips account for this.
/🆑

---------

Co-authored-by: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com>
2025-06-08 09:19:15 +02:00
7b04440de1 Re-adds the Dragoon tomb ruin & Spear (#90781)
## About The Pull Request

It was removed in https://github.com/tgstation/tgstation/pull/27799
because the spear was broken and the Flans' AI sucked with not-great
sprites and was all just one big reference. Original addition:
https://github.com/tgstation/tgstation/pull/22270

This re-adds it, updates the map (now using airless turfs) with extra
ambiance, using ash whelps (lavaland variation of ice whelps) instead of
Flans, re-adds the spear, and adds armor as well this time around.

The spear gives you a jump ability to crash down upon a player below
you, rather than teleporting to wherever you throw the spear at. You
can't attack while mid-air, you can go through tables but not
walls/doors, and you also can't un-dualwield or drop the spear mid-jump.
Landing on a mob deals double damage to them (36 to unarmored people),
while landing on objects deals 150 damage to them (taken from savannah's
jump ability, which was in turn taken from hulk's punching)
It's also got some extra throw force (24 compared to default spear's 20)

The armor has basic security-level armor but covers your whole body.
Does not include space protection, and can be worn by Ian.

Video demonstration


https://github.com/user-attachments/assets/a77c3a0d-17d2-4e8d-88b6-cdbca8b1f2c3

New sprites demonstration

https://github.com/user-attachments/assets/0e465351-5484-406f-8adc-ffa1ac180daf

Armor demonstration

https://github.com/user-attachments/assets/abdfcac6-65bf-443c-bde2-27d157ee3a80

Map

![436285657-104a555f-60dc-46f0-8283-a92db2ca5352](https://github.com/user-attachments/assets/a1677c9a-7157-4562-9703-5ad44c923e8d)

With the changes in https://github.com/tgstation/tgstation/pull/90771 I
had to mess with ash whelp abilities a bit, I decided to make them use
cold fire instead of hardcoding blue color on top of the fire sprites,
and it now acts accordingly too


https://github.com/user-attachments/assets/cfca0d70-d13d-4c73-996d-2d4a7519866d

The jump was taken from Savannah Ivanov, and Goof's bunny jumping.

##### Code bounty by Ezel/Improvedname

## Why It's Good For The Game

This Re-implements a old spear that got removed for its buggyness/bad
mapping and on the authors request as well not wanting to deal with it.

Re-introduces the SkyBulge as a space ruin, referencing Dragoons from
Final Fantasy. this just like any normal spear, but using the savannah
jump mechanic, this allows you to close distances with the spear
avoiding ranged projectiles in the jump, and if you directly land on
your target you will do double the damage.

##### -Ezel/Improvedname

## Changelog

🆑 Ezel/Improvedname, Toriate, JohnFulpWillard
add: Re-added the Dragoon Tomb lair, now has a Skybulge spear and
Drachen armor.
balance: Ice whelps now spit out cold fire.
/🆑

---------

Co-authored-by: Jacquerel <hnevard@gmail.com>
2025-05-30 11:36:38 +10:00
MrMelbertandGitHub 5261efb67f Re-refactors batons / Refactors attack chain force modifiers (#90809)
## About The Pull Request

Melee attack chain now has a list passed along with it,
`attack_modifiers`, which you can stick force modifiers to change the
resulting attack

This is basically a soft implementation of damage packets until a more
definitive pr, but one that only applies to item attack chain, and not
unarmed attacks.

This change was done to facilitate a baton refactor - batons no longer
hack together their own attack chain, and are now integrated straight
into the real attack chain. This refactor itself was done because batons
don't send any attack signals, which has been annoying in the past (for
swing combat).

## Changelog

🆑 Melbert
refactor: Batons have been refactored again. Baton stuns now properly
count as an attack, when before it was a nothing. Report any oddities,
particularly in regards to harmbatonning vs normal batonning.
refactor: The method of adjusting item damage mid-attack has been
refactored - some affected items include the Nullblade and knives.
Report any strange happenings with damage numbers.
refactor: A few objects have been moved to the new interaction chain -
records consoles, mawed crucible, alien weeds and space vines, hedges,
restaurant portals, and some mobs - to name a few.
fix: Spears only deal bonus damage against secure lockers, not all
closet types (including crates)
/🆑
2025-05-19 13:32:12 +10:00
John WillardandGitHub 138a61cba0 Chaplains can deaconize one person, everyone else loses bible perms (#90686) 2025-05-04 16:49:36 +02:00
GhomandGitHub 339616ae78 You can now interact with held mobs beside wearing them (feat: "minor" melee attack chain cleanup) (#90080)
## About The Pull Request
People can now pet held mothroaches and pugs if they want to, or use
items on them, hopefully without causing many issues. After all, it only
took about a couple dozen lines of code to make...

...Oh, did the 527 files changed or the 850~ lines added/removed perhaps
catch your eye? Made you wonder if I accidentally pushed the wrong
branch? or skewed something up big time? Well, nuh uh. I just happen to
be fed up with the melee attack chain still using stringized params
instead of an array/list. It was frankly revolting to see how I'd have
had to otherwise call `list2params` for what I'm trying to accomplish
here, and make this PR another tessera to the immense stupidity of our
attack chain procs calling `params2list` over and over and over instead
of just using that one call instance from `ClickOn` as an argument. It's
2025, honey, wake up!

I also tried to replace some of those single letter vars/args but there
are just way too many of them.

## Why It's Good For The Game
Improving old code. And I want to be able to pet mobroaches while
holding them too.

## Changelog

🆑
qol: You can now interact with held mobs in more ways beside wearing
them.
/🆑
2025-04-23 20:18:26 +00:00
MrMelbertandGitHub 283084786b Burning paper (and similar) is now two way (you can hold a paper to your cigarette to burn it) (#90307)
## About The Pull Request

1. Burning paper (and similar) is now two way - rather than
necessitating you touch the paper with the burning thing, you can now
touch the burning thing with the paper

2. You can now light a cigarette on a lit candle

3. Candles no longer craft into flashlight eyes

## Why It's Good For The Game

1. Burning money with a cigarette larp 

2. Cool Frenchman larp

3. ??? I noticed you can't light a candle with a candle because it tried
to craft flashlight eyes.

## Changelog

🆑 Melbert
qol: Burning paper (and similar) is now two way. Rather than needing to
click on the paper with a burning item, you can now click on a burning
item with the paper. This means you can burn paper on your lit cigarette
like a badass.
qol: You can now light cigarettes on candles. 
del: Flares and candles can no longer craft into flashlight eyes, I
guess.
/🆑
2025-04-02 22:16:34 +01:00
SmArtKarandGitHub cf131db497 Cleans up mood and mood-related code (#90162)
## About The Pull Request

One of my upcoming PRs affects a significant chunk of the codebase so
I'm cleaning up messes that I've found along the way.
This PR adds wrappers for adjusting sanity/checking if a mob already has
a certain moodlet, fixes an oversight where attempting to set sanity
over passed maximum would abort the change outright (instead of actually
capping it out), moved jolly and depression processing into quirks
themselves (instead of having dedicated traits for them used solely by
said quirks and nothing else that are constantly checked for by mood
datums), and rewrote how blessings return their results to move omen's
deletion on blessing effect from constantly checking mood for a blessing
moodlet to a comsig.

## Why It's Good For The Game

Less jank handling of certain mechanics, we ***really*** shouldn't be
checking for blessings every time mood of all things is updated.

## Changelog
🆑
fix: Adjusting sanity over the allowed maximum will no longer completely
halt the change, and instead actually cap it at the maximum value.
code: Cleaned up mood and mood-adjacent code.
/🆑
2025-03-24 13:53:03 +01:00
MrMelbertandGitHub 0f22994886 Mappers can disable bookshelf randomization, Non-adult shelves can no longer random into adult books (#90165)
## About The Pull Request

1. Mappers can disable bookshelf randomization


2. Bookshelves which are not explicitly marked as "adult bookshelves"
can no longer randomly load "adult" books


3. Random books can no longer random into "adult" books

## Why It's Good For The Game

1. If a mapper is placing a bookshelf with the express attention only x
type books will be in that bookshelf, they can guarantee that by
changing `category_prob`.

2. If the intention behind bookshelves are that "you have to go out of
your way to find the adult category to read an adult book", we probably
shouldn't add flat 25% chance for all bookshelves to be unmarked adult
bookshelves?

3. Similar logic - if you get a random book in the mail and crack it
open and it's an adult book, you can't really say you were "asking" for
it

## Changelog

🆑 Melbert
qol: Mappers can now disable bookshelf randomization
qol: Random books found via mail or in maint will no longer random into
books from the "adult" section
qol: Bookshelf randomization will now exclude adult books unless marked
as adult
/🆑
2025-03-23 23:45:08 +01:00
52678d41b5 Everyone is kung fu fighting: Refactors martial arts / You can have multiple martial arts and swap between them (#89840)
## About The Pull Request

Refactors martial arts off the mind. Don't worry the martial arts you
learn still transfer with mindswap

Instead, they are just tracked on a list on the mob, and they also
independently track the datum that created them

This fixes a lot of jank with martial arts, like say, having your krav
maga gloves transfer across slime clones or something...

But it also opens an opportunity: As we track all martial arts
available, I added a verb (ic tab) that lets you swap between the ones
you know


![image](https://github.com/user-attachments/assets/6db1fc14-2859-444b-88ed-773962602f85)

(Some don't let you swap like that one brain trauma)

## Why It's Good For The Game

Aforementioned fixes a lot of jank

Recently martial arts have just been up and disappearing and this was
entirely spurred on by that bug

Probably fixes #84710 (haven't checked) 
Probably fixes #89247
Probably fixes #89948
Probably fixes #90067

## Changelog

🆑 Melbert
refactor: Refactored martial arts, if you notice any oddities like
managing to know two martial arts at once or having your powers
disappear, report it!
add: If you know multiple martial arts, such as krav maga from gloves
and cqc from a book, you can now swap between them at will via a button
in the IC tab!
/🆑

---------

Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
2025-03-16 03:16:49 +00:00
itsmeowandGitHub cc335e7e9e IconForge: rust-g Spritesheet Generation (#89478)
## About The Pull Request

Replaces the asset subsystem's spritesheet generator with a rust-based
implementation (https://github.com/tgstation/rust-g/pull/160).

This is a rough port of
https://github.com/BeeStation/BeeStation-Hornet/pull/10404, but it
includes fixes for some cases I didn't catch that apply on TG.

(FWIW we've been using this system on prod for over a year and
encountered no major issues.)

### TG MAINTAINER NOTE


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

### Batched Spritesheets

`/datum/asset/spritesheet_batched`: A version of the spritesheet system
that collects a list of `/datum/universal_icon`s and sends them off to
rustg asynchronously, and the generation also runs on another thread, so
the game doesn't block during realize_spritesheet. The rust generation
is about 10x faster when it comes to actual icon generation, but the
biggest perk of the batched spritesheets is the caching system.

This PR notably does not convert a few things to the new spritesheet
generator.

- Species and antagonist icons in the preferences view because they use
getFlatIcon ~~which can't be converted to universal icons~~.
- Yes, this is still a *massive* cost to init, unfortunately. On Bee, I
actually enabled the 'legacy' cache on prod and development, which you
can see in my PR. That's why I added the 'clear cache' verb and the
`unregister()` procs, because it can force a regeneration at runtime. I
decided not to port this, since I think it would be detrimental to the
large amount of contributors here.
- It is *technically* possible to port parts of this to the uni_icon
system by making a uni_icon version of getFlatIcon. However, some
overlays use runtime-generated icons which are ~~completely unparseable
to IconForge, since they're stored in the RSC and don't exist as files
anywhere~~. This is most noticeable with things like hair (which blend
additively with the hair mask on the server, thus making them invisible
to `get_flat_uni_icon`). It also doesn't help that species and antag
icons will still need to generate a bunch of dummies and delete them to
even verify cache validity.
- It is actually possible to write the RSC icons to the filesystem
(using fcopy) and reference them in IconForge. However, I'm going to
wait on doing this until I port my GAGS implementation because it
requires GAGS to exist on the filesystem as well.

#### Caching

IconForge generates a cache based on the set of icons used, all
transform operations applied, and the source DMIs of each icon used
within the spritesheet. It can compare the hashes and invalidate the
cache automatically if any of these change. This means we can enable
caching on development, and have absolutely no downsides, because if
anything changes, the cache invalidates itself.

The caching has a mean cost of ~5ms and saves a lot of time compared to
generating the spritesheet, even with rust's faster generation. The main
downside is that the cache still requires building the list of icons and
their transforms, then json encoding it to send to rustg.

Here's an abbreviated example of a cache JSON. All of these need to
match for the cache to be valid. `input_hash` contains the transform
definitions for all the sprites in the spritesheet, so if the input to
iconforge changes, that hash catches it. The `sizes` and `sprites` are
loaded into DM.

```json
{
	"input_hash": "99f1bc67d590e000",
	"dmi_hashes": {
		"icons/ui/achievements/achievements.dmi": "771200c75da11c62"
	},
	"sizes": [
		"76x76"
	],
	"sprites": {
		"achievement-rustascend": {
			"size_id": "76x76",
			"position": 1
		}
	},
	"rustg_version": "3.6.0",
	"dm_version": 1
}
```

### Universal Icons

Universal icons are just a collection of DMI, Icon State, and any icon
transformation procs you apply (blends, crops, scales). They can be
convered to DM icons via `to_icon()`. I've included an implementation of
GAGS that produces universal icons, allowing GAGS items to be converted
into them. IconForge can read universal icons and add them to
spritesheets. It's basically just a wrapper that reimplements BYOND icon
procs.

### Other Stuff

Converts some uses of md5asfile within legacy spritesheets to use
rustg_hash_file instead, improving the performance of their generation.

Fixes lizard body markings not showing in previews, and re-adds eyes to
the ethereal color preview. This is a side effect of IconForge having
*much* better error handling than DM icon procs. Invalid stuff that gets
passed around will error instead of silently doing nothing.

Changes the CSS used in legacy spritesheet generation to split
`background: url(...) no-repeat` into separate props. This is necessary
for WebView2, as IE treats these properties differently - adding
`background-color` to an icon object (as seen in the R&D console) won't
work if you don't split these out.

Deletes unused spritesheets and their associated icons (condiments
spritesheet, old PDA spritesheet)

## Why It's Good For The Game

If you press "Character Setup", the 10-13sec of lag is now approximately
0.5-2 seconds.

Tracy profile showing the time spent on get_asset_datum. I pressed the
preferences button during init on both branches. Do note that this was
ran with a smart cache HIT, so no generation occurred.


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

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


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

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


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

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

**Before**


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

**After**


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

## Changelog

🆑
fix: Fixed lizard body markings and ethereal feature previews in the
preference menu missing some overlays.
refactor: Optimized spritesheet asset generation greatly using rustg
IconForge, greatly reducing post-initialization lag as well as reducing
init times and saving server computation.
config: Added 'smart' asset caching, for batched rustg IconForge
spritesheets. It is persistent and suitable for use on local, with
automatic invalidation.
add: Added admin verbs - Debug -> Clear Smart/Legacy Asset Cache for
spritesheets.
fix: Fixed R&D console icons breaking on WebView2/516
/🆑
2025-03-03 14:58:27 +01:00
Penelope HazeandGitHub 4c2a76ede3 Fix a large number of typos (#89254)
Fixes a very large number of typos. A few of these fixes also extend to
variable names, but only the really egregious ones like "concious".
2025-01-28 22:16:16 +01:00
Penelope HazeandGitHub 8196190aa1 Removes a a at at be be of of and and have have (#89155)
## About The Pull Request
I just had to one-up https://github.com/tgstation/tgstation/pull/89127.

## Why It's Good For The Game
Removes a a at at be be of of and and have have

## Changelog
N/A
2025-01-22 08:09:57 +11:00
SmArtKarandGitHub 7ddc30783a Adds better attack animations and alternate attack modes (#88418)
## About The Pull Request

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

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

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

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

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

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

Additionally, also fixes an issue where attack verbs for you and
everyone else may differ.
2024-12-17 12:35:52 -06:00
GhomandGitHub ee96509686 fixing runtime errors when removing a brain with skillchips. (#88178)
## About The Pull Request
The organs code changes bundled with the organ fishing PR have broken a
few things, while unveiling a bunch of other problems that flew under
the radar. This concern the first category actually. Anyway, I've also
included a unit test to ensure this won't be an inssue in the future.

## Why It's Good For The Game
Fixing some errors.
2024-12-03 18:10:46 -06:00
13705da08d fixes a few issues with the chipped quirk (#87764)
<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may
not be viewable. -->
<!-- You can view Contributing.MD for a detailed description of the pull
request process. -->

## About The Pull Request

<!-- Describe The Pull Request. Please be sure every change is
documented or this can delay review and even discourage maintainers from
merging your PR! --> the text displayed when this quirk's gained would
include the skillchip's typepath rather than its name. this fixes that.
also fixes an issue with how the callback timer was being handled, which
would lead to a runtime whenever the quirk was removed (since addtimer
returns the id and not the callback itself). also fixes the scratch
effect never actually working because an organ slot was being provided
to `get_organ_by_type` rather than the type. also fixes the itchy effect
not going away after the skillchip is removed (it gets added again if
the skillchip is reimplanted).

## Why It's Good For The Game

<!-- Argue for the merits of your changes and how they benefit the game,
especially if they are controversial and/or far reaching. If you can't
actually explain WHY what you are doing will improve the game, then it
probably isn't good for the game in the first place. --> fixes a few
issues with the chipped quirk

## Changelog

<!-- If your PR modifies aspects of the game that can be concretely
observed by players or admins you should add a changelog. If your change
does NOT meet this description, remove this section. Be sure to properly
mark your PRs to prevent unnecessary GBP loss. You can read up on GBP
and its effects on PRs in the tgstation guides for contributors. Please
note that maintainers freely reserve the right to remove and add tags
should they deem it appropriate. You can attempt to finagle the system
all you want, but it's best to shoot for clear communication right off
the bat. -->

🆑
fix: fixes the chipped quirk displaying the skill chip's typepath rather
than its name
fix: fixes chipped quirk's itchy effect not working
fix: the chipped quirk's itchy effect now goes away when the skillchip
is removed
/🆑

<!-- Both 🆑's are required for the changelog to work! You can put
your name to the right of the first 🆑 if you want to overwrite your
GitHub username as author ingame. -->
<!-- You can use multiple of the same prefix (they're only used for the
icon ingame) and delete the unneeded ones. Despite some of the tags,
changelogs should generally represent how a player might be affected by
the changes rather than a summary of the PR's contents. -->

---------

Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
2024-11-23 12:27:02 +01:00
MrMelbertandGitHub d3bc3e8cb4 Being drunk or having a broken arm hurts accuracy with ranged weapons. Also cleans up a fair bit of hand handling to be more readable (#87904)
## About The Pull Request

1. Having a broken arm will affect your accuracy when firing a weapon
with that arm, even potentially causing damage to you if it's a weapon
with recoil. This effect is not applied under the effects of a
painkiller.

2. The sister effect of this (punching someone with a broken arm) now
also has an interact with painkillers (it can no longer block your
attack).

3. Being drunk heavily affects ranged weapon accuracy, unless you're the
bartender

4. A lot of hand handling cleanup, using new macros to make it a lot
more readable at a glance

## Why It's Good For The Game

We have this system for modifying firearm accuracy but we don't really
use it commonly, and I feel like it slots in well with a lot of places

For broken arms, it adds some more depth to the wound system, in the
same way that trying to punch someone with a broken arm causes pain. (I
actually want to expand this to melee weapon accuracy and attacking with
melee weapons in general, but that's for a later time)

For drunkenness, it just adds to the drunk shenanigans. It also slightly
reduces the effectiveness of drinks as combat healing chemicals, such as
quadsec - makes it a bit more of a trade off.

## Changelog

🆑 Melbert
balance: Having a broken arm affects your accuracy with ranged weapons
fired with that arm. Utilizing a painkiller will nullify this effect,
however.
balance: Painkillers will prevent your punches from being cancelled due
to having a broken arm. You'll still take damage, though.
balance: Being drunk now affects your accuracy with ranged weapon. The
bartender is immune to this effect via their skillchip.
code: A lot of code involving left and right hand handling has been
cleaned up, easier to read. Report any oddities, like left and rights
being flipped
/🆑
2024-11-19 19:31:06 +01:00
GoatandGitHub 7ac524151d Makes curator inventory update when buttons are pressed. (#87841)
## About The Pull Request
Adds two calls for `update_static_data_for_all_viewers()` so the UI will
update when a player switches pages or removes an item in the inventory
screen.
## Why It's Good For The Game
Responsive UI good. When I click button UI should respond accordingly. 
fix #82733 
## Changelog
🆑 Goat
qol: Curator console's inventory screen will now update when you change
pages or remove items.
/🆑
2024-11-12 17:22:23 +01:00