Fixes https://github.com/tgstation/tgstation/issues/76481
TLDR /mob/living/carbon/human/species subtypes were NOT updating their
bodytypes on spawn due to absurd and wacky carbon bodypart creation code
that meant try_attach_limb() never got called (What the FUCK?)
This PR introduces a whole bunch of Coroner and Morbid related content.
Firstly, Morbid is now a mind trait, and specifically, coroners start
with it.
Coroners also have a liver trait that allows them to heal toxins (very
slowly) from eating pickles and drinking pickle juice. They also
can...drink formaldehyde. I guess. Dissections is thirsty work.
Coroners gain a whole set of special tools specifically for use in any
surgeries marked as interests of the Morbid. This is determined by the
``surgery_flag`` called ``SURGERY_MORBID_CURIOSITY``. Currently, these
surgeries are included;
dissections, autospies, revival surgery, plastic surgery, organ/feature
manipulations, amputations
To fit the theme, TRAIT_MORBID also applies the reduction to eye
snatchers.
While using their special tools, and the surgery is a morbid curiosity,
the coroner/anyone who is morbid gains a 30% speed boost! This stacks
with the dissection speed boost. Otherwise, the tools are just regular
tools with a special name (though the scalpel is better at killing
undead, because, you know, you're watching over the dead).
The coroner's special medkit, which is the only one you can get in a
round, can fit their autopsy scanners and tools. Anything that comes
standard with their kit can go back into it.
Anyone who is morbid can safely retrieve the secrets of the elephant
graveyard. The serrated shovel, notably, is a much better tool and
notably better at killing organics, but not inorganics (like the dead).
(Gives roboticists secure morgue access during skeleton crew pop totals)
## About The Pull Request
Title.
## Why It's Good For The Game
Seriously this shit pisses me off, why are ORGAN_SYNTHETIC and
ORGAN_ROBOTIC two different things?
## Changelog
not applicable unless i fucked up
---------
Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com>
## About The Pull Request
Alright, let's get real, handling food tastes with the species datum is
hacky at best - This is a continuation of my nuking of the species
datum, which currently handles way too much of human mobs' behaviors.
While moving that to the tongue isn't exactly a perfect solution, it
allows for more interesting behavior than the species datum, especially
now that I added getter procs to get foodtypes liked/disliked by the mob
and such.
## Why It's Good For The Game
Makes tongue transplants more appealing and emergent, since they fully
control tastes and not just taste sensitivity which is pretty much
cosmetic.
## Changelog
🆑
refactor: Liking/disliking food is now handled by the tongue organ, not
the species. Also, having a failing tongue means you can't taste food
properly!
add: You can read peoples' tongues now, if you have the entrail reading
skillchip.
/🆑
---------
Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com>
## About The Pull Request
Title.
I saw a comment on psyker code complaining about these species traits
(which admittedly, they suck) and heeded the call to turn all of this
crap into something defined almost entirely by the head bodypart.
## Why It's Good For The Game
Potential to simplify species code further in the future, by delegating
more visuals to bodyparts, which is where most of them should be
handled.
## Changelog
Should not be player facing, unless I fucked up.
---------
Co-authored-by: Time-Green <timkoster1@hotmail.com>
## About The Pull Request
Fixes#75197
Adds a global list of gun types banned from being added to turrets. Adds
dueling pistols to the banned list as they can freely round remove
people when in turrets without the usual restrictions.
## Why It's Good For The Game
Instakill turrets are an undesirable outcome.
## Changelog
🆑
fix: Dueling pistols can no longer be fitted in turrets to instantly
kill people.
/🆑
A flag that lets you use an interactive TGUI screen while laying down.
Adds this flag to the PDA.
You're relaxing on a bed or something and it's annoying having to stand
up just to reply to a PDA message and then lay back down. We know how to
text without dropping the PDA on our face. (Usually)
The flag can be applied to anything else you should be able to interact
with while laying down.
## About The Pull Request
https://github.com/tgstation/tgstation/blob/0426f7ddbaa91439c7278189101f5db9c7f2ed95/code/game/objects/items/stacks/stack.dm#L449
Ok, but can we not?
This PR refactors sheet crafting to generalize all the cases that were
previously locked behind grille/window type checks and such. In their
stead there are bitflags that can be set to achieve certain behaviors.
All the behavior from before should be preserved, but now it can be
extended to other items. E.g. if you want a railing that can be crafted
underneath directional windows, or an item that behaves like a grille
does--it's just a matter of setting the right obj_flags for it now.
This makes it very simple and painless to add new recipes that use
directional crafting! It's all modular now.
<details><summary>Details</summary>
---
### What I've done:
-Eliminated all the type checks, instead it will now be handled by
object flags and recipe vars, making for a much more configurable
system.
-Added two new obj_flags: `BLOCKS_CONSTRUCTION_DIR` and
`IGNORE_DENSITY`.
-Additionally, I renamed the existing flag `NO_BUILD` to
`BLOCKS_CONSTRUCTION`.
-Changes the proc `valid_window_location` to `valid_build_direction`,
and makes it work for things other than windows.
-Removed a deprecated `window_checks` var from the stack_recipe datum.
-Added three more vars to the stack_recipe datum: `check_direction` and
`check_density`, `is_fulltile`
-Decoupled `on_solid_ground` from the object density check. Now you can
set those separately, allowing you to make recipes that forbid/allow
building things over other things while in space.
---
### What the new flags do:
`BLOCKS_CONSTRUCTION` works as before---prevents objects from being
built on the object. I felt that the previous name was not descriptive
enough, you should know exactly what it does just from looking at the
name.
_example: dna scanner_
`BLOCKS_CONSTRUCTION_DIR` -- setting this on an object will prevent
objects from being built on it when their directions are the same.
_example: directional windows, windoors, railings_
`IGNORE_DENSITY` -- setting this on an object will cause its density to
be ignored when performing the construction density check. This could
have other potential uses as well in the future.
_example: grilles, directional windows, tables_
These three flags cover all the bases for the types of items that are
currently craftable, so there is no more need for any type checking or
weird snowflake window checks. Simply set the appropriate flag and it'll
work as you would expect.
---
### What the recipe vars do:
`check_direction` tells the recipe to check if there's something in that
direction with the `BLOCKS_CONSTRUCTION_DIR` flag set.
`check_density` tells the recipe to run the density check when set. This
is true by default. There are very few items in the game that currently
have this set to false--namely grilles. Setting this to false will make
it so that the object can be constructed regardless of what is in that
tile (unless `one_per_turf` is also set, which will make it so that you
can't craft the same thing twice in the same turf).
`is_fulltile` is used for fulltile windows, but it doesn't necessarily
have to be--you can give this to any recipe and it will adopt the same
properties as that of the fulltile window. Basically they have a special
case where they shouldn't be able to be built over directional
constructions, where normally things would be able to be. Setting this
makes check_direction true as well.
---
### In summary:
Sheet crafting still works just as it did before. But the backend of it
has gotten a glow up and will be able to more easily support new
behaviors.
</details>
## Why It's Good For The Game
This makes the crafting system much more flexible to add recipes to, and
will prevent bad code practices of stacking more conditionals down the
line whenever someone wants to add an item that behaves like grilles or
directional windows in how they are constructed.
It had to be done. Those window checks were a mess.
## Changelog
🆑
qol: added fifty stack versions of remaining glass sheet stacks for ease
of debugging
refactor: refactored sheet crafting to better support directional
constructions that aren't windows
/🆑
---------
Co-authored-by: san7890 <the@san7890.com>
## About The Pull Request
Title.
Also, to make bodypart code slightly nicer, I retooled some variables to
be part of a new bitfield called bodypart_flags.
## Why It's Good For The Game
We've been trying to move away from the species datum for limb stuff
precisely because of funny shenanigans like this, no?
## Changelog
🆑
refactor: Implanted foreign limbs will no longer be wiped by species
change.
/🆑
## About The Pull Request
### How things work
As things currently stand, when a mob breaths several things happen
(simplified to focus on the stupid)
We assert the existance of all possible breathable gases, and pull
partial pressures for them
Then we walk through all possible interactions lungs could have with
these gases, one by one, and see if they're happening or not
As we go we are forced to cleanup potential alerts caused by the
previous breath, even if those effects never actually happen
At the end we clear out all the unused gas ids, and handle the
temperature of the breath.
### What sucks
There's I'd say 3 different types of gas reactions.
- You can "need" a gas to survive. o2, n2 and plasma all fall into this
category
- A gas can do something to you while it's in your system. This applies
to most gas types
- Variation on the previous, some gases do cleanup when they're not in
your system, or when there isn't much of them in the first place
The main headache here is that second one, constantly cleaning up
potential side effects sucks, and fixing it would require a lot of dummy
variables
There's other suckage too.
Needing to constantly check for a gas type even if it isn't there is
stupid, and leads to wasted time It's also really annoying to do
subtypes in this system.
There is what amounts to a hook proc you can override, but you can't
override the reaction to a gas type.
It also just like, sucks to add new gases. one mega proc smells real
stupid.
### Improvements
In the interest of speed:
- I'd like to build a system that doesn't require manually checking for
gas
- Reacting to gas "disappearing" should be promoted by the system,
instead of being hacky.
- I would like to avoid needing to assert the existence of all possible
gases, as this is slow on both the assert and the garbage collect.
In the interest of dev ergonomics:
- It should be easy to define a new gas reaction
- It should be easy for subtypes to implement their own gas reactions.
The current method of vars on the lung is all tangled up and not really
undoable as of now, but I'd like to not require it
- It should be possible to fully override how a gas is handled
### What I've Done
Lungs have 3 lists of proc paths stored on them
Each list handles a different way the lung might want to interact with a
gas.
There's a list for always processing on a gas (we use this for stuff
that's breathed), a list for handling a gas in our breath, and a list
for reacting to a gas previously being in our breath, but not any more.
Lungs fill out these lists using a helper proc during Initialize()
Then, when it comes time to breath, we loop over the gas in the breath
and react to it.
We also keep track of the previous list of partial pressures, which we
calculate for free here, and use that to figure out when to call the
loss reactions.
This proc pattern allows for overrides, easy reactions to removals,
lower indentation code and early returns, and better organization of
signal handlers
It's also significantly faster. Ballpark 4x faster
### Misc
Removes support for breathing co2, and dying from n2 poisoning.
They were both unused, and I think it's cringe to clutter these procs
even further
Added "do we even have oxyloss" checks to most cases of passive
breathing.
This is a significant save, since redundant adjustoxy's are decently
expensive at the volume of calls we have here.
Fixes a bug with breathing out if no gas is passed in, assigning a var
to another var doesn't perform a copy
Rewrote breathe_gas_volume() slightly to insert gas into an immutable
mix stored on the lung, rather then one passed in
This avoids passing of a gas_mixture around just to fill a hole.
I may change my mind on this, since it would be nice to have support for
temperature changing from a hot/cold breath.
Not gonna be done off bodytemp tho lord no.
Uses merge() instead of a hard coded version to move the gas ids over.
This is slightly slower with lower gas counts but supports more things
in future and is also just easier to read.
## Why It's Good For The Game
Faster, easier to work with and read (imo)
Profiles:
[breath_results_old.txt](https://github.com/tgstation/tgstation/files/11068247/breath_results_old.txt)
[breath_results_pre_master.txt](https://github.com/tgstation/tgstation/files/11068248/breath_results_new.txt)
[breath_results_new.txt](https://github.com/tgstation/tgstation/files/11068349/breath_results_new.txt)
(These profiles were initially missing #73026. Merging this brings the
savings from 16% to 12%. Life is pain)
---------
Co-authored-by: san7890 <the@san7890.com>
## About The Pull Request
Things like pens weren't giving any feedback messages when you put them
on someone else, and I ran into this while working on another PR so I've
dealt with that
Renames `worn_dangerous` to `show_visible_message` as it was only used
to confirm if there would be visible messages or not
The `DANGEROUS_OBJECT` clothing flag is a trait now, so it can be put on
non-clothing items too
Removing non-clothing items from someone has been unchanged.
## Why It's Good For The Game
People should be able to identify that someone is putting something on
them, and recognize what that is if they pay attention.
This means that a player cannot reverse pickpocket a grenade onto
someone else without giving any indication of doing so
## Changelog
🆑
balance: Putting a non-clothing item onto someone else creates a visible
message the same way a clothing item would.
/🆑
## About The Pull Request
Code changes:
- Fixes#73946 , Ice Slipping not going forever as intended
- Detailed in the issue report. Ice slide slip was replaced from a stun
to a knockdown, but it relied on it being a stun to function. I replaced
it back with an immobilize and incapacitate, reduced to 1 second to
prevent cheese.
- Refactors noslip mechanics
- Changes noslip and noslip_ice from a clothing flag to a clothing
trait, as the trait already existed and was used by MODsuits. Also added
noslip_slide, which prevents all sliding from slips like lube.
- Refactors magboots
- Refactored and modernized magboot code. Mostly cleanup, like using
base icon state, updating appearance, etc.
- Fixes speed potioned magboots not maintaining the speed boost after a
toggle
- Adds a helper for adding or removing clothing traits from existing,
(potentially) worn items.
- `TRAIT_NEGATE_GRAVITY` now always updates gravity on signal, no longer
requiring a manual call after.
Balance change:
- Magboots now prevent sliding on permafrost (outside icebox).
- This is mainly to give them more of a purpose on Icebox.
- Magboot snow prevent sliding on ice (or lube). You will still slip.
- Slipping over ice or lube will knock you down as before, but will not
send you across the room.
- See https://tgstation13.org/phpBB/viewtopic.php?t=33217.
## Why It's Good For The Game
Magboots justification:
This makes Magboots much less of a "noob trab" for engineers
fire-fighting in the Supermatter room. Most engineers believe themselves
to be completely save to the Supermatter's pull with magboots, however
"wet ice" will still send you flying into the crystal.
I think it is an inconsistency, seeing as it protects you from other
forms of forced movement like gravitational pulls. However making them
pure no-slip seemed a bit too far to me, so the knockdown still occurs.
## Changelog
🆑 Melbert
balance: Magboots will now protect you from sliding on ice. It will not
stop the slip, though.
fix: "Ice sliding" (from patches of permafrost ice) will now correctly
slide you until you reach a non-ice patch.
fix: Speed potioned magboots maintain their speed booster after toggling
them
refactor: Refactored magboots.
refactor: Refactored noslip mechanics.
/🆑
## About The Pull Request
I had thought I took care of this edge case but I was mistaken.
## Why It's Good For The Game
Fixes the edge case of a removed lung preventing oxyloss damage in
carbon mobs. Big derp.
---
Also took care of the case of mobs without lungs being injected with
oxyloss healing chems by adding a `mob_respiration_type` var.
This essentially just makes it so that plasmamen without lungs can no
longer be healed by salbutanol etc. They are currently the only mob with
a different respiration type than the default, so this particular bug
only affected them. In the future this will be important as chems that
target other respiration types are added.
The `mob_respiration_type` var also allows for simple mobs to have their
own respiration types defined. By default everything is
`RESPIRATION_OXYGEN,` so there is no difference from how it was before
unless you specify a different type for that particular mob.
## Changelog
🆑
fix: hotfix for lungless oxyloss immunity
fix: hotfix for mobs being able to circumvent reagent respiration_type
requirements by removing their lungs
/🆑
## About The Pull Request
Fixes#73276
This is a followup PR from my series of biotype updates. Changed oxyloss
to default to ignoring biotype requirements. Fixes a bug in lung code
that was preventing mobs from suffocating under certain conditions.
~~Now biotype requirements for oxyloss are respected only when `forced`
is set to `FALSE`, which I have done for all applicable reagents. This
is more of a temporary fix for until the damage system gets a refactor
to better accommodate biotypes. @Time-Green and @LemonInTheDark would
know what I mean, we were just talking about this. There is a problem
with `MOB_ORGANIC` being the deafult and this is the ugly workaround.~~
Edit: I felt that oxyloss (which should be renamed to something else at
this point) should have its own flag to check what type of respiration
the mob's lungs can do. Because you can have organic mobs that breathe
different gases. It gets messy when you try to use the same flag for
everything.
So I refactored oxyloss to use a new lung flag, `respiration_type`,
which is automatically set based on the `safe_min_oxygen`,
`safe_min_plasma` etc variables within the lung code. This will allow
for individual lung types to dynamically determine whether they can take
oxyloss from reagents, or any other sources that pass the
`respiration_type` in the `adjustOxyLoss` proc.
## Why It's Good For The Game
Plasmamen can't breathe without plasma anymore. Humans can't breathe
without oxygen anymore. Etc.
Adds better handling for dealing with the 'oxyloss' damage type,
allowing it to be applied based on the type of gas being breathed by the
specific lung. The argumentless default is to apply it regardless of
respiration_type e.g. it behaves exactly as it did before.
## Changelog
🆑
fix: fixes oxyloss not being applied when there is a partial pressure of
0 (no more being able to breathe in space)
code: fixes any lingering damage-application issues related to non
MOB_ORGANIC biotypes
refactor: refactored lungs to have a respiration_type flag which is then
used by adjustOxyloss/setOxyloss to determine whether to take 'oxygen'
damage.
/🆑
## About The Pull Request
Fixes#55151 is fixed it seems and can be closed.
Edit: OK, the carpet bug issue I'm not able to reproduce, I'll chalk it
up to late night brain. but feel free to merge this anyway for the
missing bitfields if you'd like. I'll leave it open.
---
</details>
## Why It's Good For The Game
Adds missing bitfield vars for turf_flags, which allows it to show up in
the vars which leads to less confusion.
## Changelog
🆑
fix: adds some messing bitfield defines for turf_flags
/🆑
## About The Pull Request
Mechs had the ability to short circuit, but lacked the logic to display
and repair that.
Resolves#72835
## Why It's Good For The Game
## Changelog
🆑
fix: NanoTrasen Engineering has identified and resolved an issue with
MechOS that prevented diagnostics for internal shorting
/🆑
Signed-off-by: GitHub <noreply@github.com>
* Makes only station areas part of Statioj
* Makes only subtypes of /area/station be part of the station
* Removes Icemoon and Shuttles as a check for Anomaly placers as they aren't needed anymore, not being part of shuttles.
* Removes a ton of uses of NO_ALERTS where it is no longer needed.
* Removes overlay queuing, saves 6/7 seconds of initialize. Lightly modifies stat tracking macros
So we have this overlay queuing system right? It's build with the assumption
that the "add to overlay list" operation is real expensive, and is
thus useful to queue removals or additions.
It turns out that it just isn't, at least during init. In my testing the
operation of queuing took LONGER then the actual overlay add/remove did.
That's ignoring the cost of the subsystem's work.
I've also modified part of the stat tracking macro, since it took a good
bit of cpu time, and didn't seem to well, do anything. So far as I can
tell it always evaluates to 1
* Replaces `being_shocked` and `shocked_1` with `TRAIT_BEING_SHOCKED`, removing a flag_1, taking us away from the possibility of hitting the flag limit.
* Optimizes away /obj/Initialize
We were spending like 0.15 seconds just checking for blueprints, obj
flags and network ids
All these things can just be applied where they're wanted, saves time
Oh and I replaced object flags with an emag injector. I'll give it a
sprite and name later I promise
* Requires a GenerateTag() call to set DF_USE_TAG, rather then doing a check in atom New
This is technically harder to use, but I don't really want people using
tags, and it saves 0.15 seconds
* Moves generatetag to /datum
* I am dumb
* Saves 0.5 seconds, makes init emissive blockers actually work
Ok so background. If an overlay is added with add_overlay, and not
"managed" somehow, it will effectively never be removed, because
nothing's tracking it.
Update_overlays uses the managed_overlays list/var (one of those) to do
this.
I'm gonna piggyback off this to make emissive overlays actually like,
respect overlay updates.
Oh and uh, I've saved maybe 0.5 seconds by caching the new emissive, and
not using add_overlay. There's a chance this will lead to overlay
corruption, but since we never readd the flattened, I think we'll be
safe
* Fixes plane not being set right, changes color logic too, since alpha will override past color sets
* Makes it actually work. also makes rand posters update appearance to clear away the overlay, since it shows on right click and looks bad
* Fixes blockers showing as emissives. It turns out alpha sets override the color list we use. Not sure why we pretend to support them
* Makes the injector support traits, adds an amazing sprite
* Cleans up organ code, removing the EXTERNAL_ORGAN flag, as it can just simply use the external organ subtype instead
Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com>
Currently, storage works as a subtype of /datum/component, utilizing GetComponent() and signals to operate. While this is a pretty good idea in theory, the execution was pretty trash, and we end up with alot of GetComponent() snowflake code (something that shouldn't even need to be used frankly), and a heaping load of scattered procs that lead into one another, and procs that don't get utilized properly.
Instead, this PR adds atom_storage and proc/create_storage(. . .) to every atom, allowing for the possibility of storage on quite frankly anything. Not only does this entirely remove the need for signals, but it heavily squashes down the number of needed procs in total (removing snowflake signal procs that just lead to one another), reducing overall proc overhead and improving performance.
ever see the tram take 10 milliseconds per movement to move 2100 objects? now you have
https://user-images.githubusercontent.com/15794172/166198184-8bab93bd-f584-4269-9ed1-6aee746f8f3c.mp4
About The Pull Request
fixes#66887
done for the code bounty posted by @MMMiracles to optimize the tram so that it can be sped up. the tram is now twice as fast, firing every tick instead of every 2 ticks. and is now around 10x cheaper to move. also adds support for multiz trams, as in trams that span multiple z levels.
the tram on master takes around 10-15 milliseconds per movement with nothing on it other than its starting contents. why is this? because the tram is the canary in the coal mines when it comes to movement code, which is normally expensive as fuck. the tram does way more work than it needs to, and even finds new ways to slow the game down. I'll walk you through a few of the dumber things the tram currently does and how i fixed them.
the tram, at absolute minimum, has to move 55 separate industrial_lift platforms once per movement. this means that the tram has to unregister its entered/exited signals 55 times when "the tram" as a singular object is only entering 5 new turfs and exiting 5 old turfs every movement, this means that each of the 55 platforms calculates their own destination turfs and checks their contents every movement. The biggest single optimization in this pr was that I made the tram into a single 5x11 multitile object and made it only do entering/exiting checks on the 5 new and 5 old turfs in each movement.
way too many of the default tram contents are expensive to move for something that has to move a lot. fun fact, did you know that the walls on the tram have opacity? do you know what opacity does for movables? it makes them recalculate static lighting every time they move. did you know that the tram, this entire time, was taking JUST as much time spamming SSlighting updates as it was spending time in SStramprocess? well it is! now it doesnt do that, the walls are transparent. also, every window and every grille on the tram had the atmos_sensitive element applied to them which then added connect_loc to them, causing them to update signals every movement. that is also dumb and i got rid of that with snowflake overrides. Now we must take care to not add things that sneakily register to Moved() or the moved signal to the roundstart tram, because that is dumb, and the relative utility of simulating objects that should normally shatter due to heat and conduct heat from the atmosphere is far less than the cost of moving them, for this one object.
all tram contents physically Entered() and Exited() their destination and old turfs every movement, even though because they are on a tram they literally do not interact with the turf, the tram does. also, any objects that use connect_loc or connect_loc behalf that are on the same point on the tram also interact with each other because of this. now all contents of the tram act as if theyre being abstract_move()'d to their destination so that (almost) nothing thats in the destination turf or the exit turf can react to the event of "something laying on the tram is moving over you". the rare things that DO need to know what is physically entering or exiting their turf regardless of whether theyre interacting with the ground can register to the abstract entered and exited signals which are now always sent.
many of the things hooked into Moved(), whether it be overrides of Moved() itself, or handlers for the moved signal, add up to a LOT of processing time. especially for humans. now ive gotten rid of a lot of it, mostly for the tram but also for normal movement. i made footsteps (a significant portion of human movement cost) not do any work if the human themselves didnt do the movement. i optimized has_gravity() a fair amount, and then realized that since everything on the tram isnt changing momentum, i didnt actually need to check gravity for the purposes of drifting (newtonian_move() was taking a significant portion of the cost of movement at some points along the development process). so now it simply doesnt call newtonian_move() for movements that dont represent a change in momentum (by default all movements do).
also i put effort into 1. better organizing tram/lift code so that most of it is inside of a dedicated modules folder instead of scattered around 5 generic folders and 2. moved a lot of behavior from lift platforms themselves into their lift_master_datum since ideally the platforms would just handle moving themselves, while any behavior involving the entire lift such as "move to destination" and "blow up" would be handled by the lift_master_datum.
also
https://user-images.githubusercontent.com/15794172/166220129-ff2ea344-442f-4e3e-94f0-ec58ab438563.mp4
multiz tram (this just adds the capability to map it like this, no tram does this)
Actual Performance Differences
to benchmark this, i added a world.Profile(PROFILER_START) and world.Profile(PROFILER_START) to the tram moving, so that it generates a profiler output of all tram movement without any unrelated procs being recorded (except for world.Profile() overhead). this made it a lot easier to quantify what was slowing down both the tram and movement in general. and i did 3 types of tests on both master and my branch.
also i should note that i sped up the "master" tram test to move once per tick as well, simply because the normal movement speed seems unbearably slow now. so all recorded videos are done at twice the speed of the real tram on master. this doesnt affect the main thing i was trying to measure: cost for each movement.
the first test was the base tram, containing only my player mob and the movables starting on the tram roundstart. on master, this takes around 13 milliseconds or so on my computer (which is pretty close to what it takes on the servers), on this branch, it takes between 0.9-1.3 milliseconds.
ALSO in these benchmarks youll see that tram/proc/travel() will vary significantly between the master and optimized branches. this is 100% because there are 55 times more platforms moving on master compared to the master branch, and thus 55x more calls to this proc. every test was recorded with the exact same amount of distance moved
here are the master and optimized benchmark text files:
master
master base tram.txt
https://user-images.githubusercontent.com/15794172/166210149-f118683d-6f6d-4dfb-b9e4-14f17b26aad8.mp4
also this shows the increased SSlighting usage resulting from the tram on master spamming updates, which doesnt happen on the optimized branch
optimized
optimization base tram.txt
https://user-images.githubusercontent.com/15794172/166206280-cd849aaa-ed3b-4e2f-b741-b8a5726091a9.mp4
the second test is meant to benchmark the best case scaling cost of moving objects, where nothing extra is registered to movement besides the bare minimum stuff on the /atom/movable level. Each of the open tiles of the tram had 1 bluespace rped filled with parts dumped onto it, to the point that the tram in total was moving 2100 objects. the vast majority of these objects did nothing special in movement so they serve as a good base case. only slightly off due to the rped's registering to movement.
on master, this test takes over 100 milliseconds per movement
master 2000 obj's.txt
https://user-images.githubusercontent.com/15794172/166210560-f4de620d-7dc6-4dbd-8b61-4a48149af707.mp4
when optimized, about 10 milliseconds per movement
https://user-images.githubusercontent.com/15794172/166208654-bc10086b-bbfc-49fa-9987-d7558109cc1d.mp4
optimization 2000 obj's.txt
the third test is 300 humans spawned onto the tram, meant to test all the shit added on to movement cost for humans/carbons. in retrospect this test is actually way too biased in favor of my optimizations since the humans are all in only 3 tiles, so all 100 humans on a tile are reacting to the other 99 humans movements, which wouldnt be as bad if they were distributed across 20 tiles like in the second test. so dont read into this one too hard.
on master, this test takes 200 milliseconds
master 300 catgirls.txt
when optimized, this takes about 13-14 milliseconds.
optimization 300 catgirls on ram ranch.txt
Why It's Good For The Game
the tram is literally 10x cheaper to move. and the code is better organized.
currently on master the tram is as fast as running speed, meaning it has no real relative utility compared to just running the tracks (except for the added safety of not having to risk being ran over by the tram). now the tram of which we have an entire map based around can be used to its full potential.
also, has some fixes to things on the tram reacting to movement. for example on master if you are standing on a tram tile that contains a banana and the TRAM moves, you will slip if the banana was in that spot before you (not if you were there first however). this is because the banana has no concept of relative movement, you and it are in the same reference frame but the banana, which failed highschool physics, believes you to have moved onto it and thus subjected you to the humiliation of an unjust slipping. now since tram contents that dont register to abstract entered/exited cannot know about other tram contents on the same tile during a movement, this cannot happen.
also, you no longer make footstep sounds when the tram moves you over a floor
TODO
mainly opened it now so i can create a stopping point and attend to my other now staling prs, we're at a state of functionality far enough to start testmerging it anyways.
add a better way for admins to be notified of the tram overloading the server if someone purposefully stuffs it with as much shit as they can, and for admins to clear said shit.
automatically slow down the tram if SStramprocess takes over like, 10 milliseconds complete. the tram still cant really check tick and yield without introducing logic holes, so making sure it doesnt take half of the tick every tick is important
go over my code to catch dumb shit i forgot about, there always is for these kinds of refactors because im very messy
remove the area based forced_gravity optimization its not worth figuring out why it doesnt work
fix the inevitable merge conflict with master lol
create an icon for the tram_tunnel area type i made so that objects on the tram dont have to enter and exit areas twice in a cross-station traversal
add an easy way to vv tram lethality for mobs/things being hit by it. its an easy target in another thing i already wanted to do: a reinforced concept of shared variables from any particular tram platform and the entire tram itself. admins should be able to slow down the tram by vv'ing one platform and have it apply to the entire tram for example.
Changelog
cl
balance: the tram is now twice as fast, pray it doesnt get any faster (it cant without raising world fps)
performance: the tram is now about 10 times cheaper to move for the server
add: mappers can now create trams with multiple z levels
code: industrial_lift's now have more of their behavior pertaining to "the entire lift" being handled by their lift_master_datum as opposed to belonging to a random platform on the lift.
/cl
* New illiterate quirk that makes a person unable to read or write. This applies to books, PDAs, paper, computers, and other electronics.
* New brain trauma dyslexia that makes you illiterate until fixed.
* Ashlizards are now illiterate as a default starting trait. The mining shuttle computer has been updated to compensate illiterate mobs randomly smashing buttons that causes a shuttle launch.
Co-authored-by: Kylerace <kylerlumpkin1@gmail.com>
* organizing flora file and icon states, & flags
Changes the typepath for a lot of flora, and adds new paths depending on the amount of icon states the flora had, for better modularization on mappers. Also adds flags to the flora depending on what type it was, instead of 3 bools
* Getting ready to attempt to modularize flora
Moving most vars and procs from ash flora into the normal flora type path, as a general preparation to add more here
* Weighted products & Region Messages
Rewrites flora code so a flora's produced items can be initialized with a weighted list. Also has some improvements, relating to item stacks.
Adds an option via variables to separate 3 messages into 3 possible regions, or the old method where the message changes when the value is exactly the same as the low or high harvest value
* organizing + documentation on procs
* Documentation, Organization & Modularization
(DOMing) yeah, I dom
Gives variables for tools that can harvest flora, a blacklist of them, and modularizes variables a bit.
Retypes the stump to be a subtype of a tree, which just deletes after being harvested
* Adds the ability to uproot flora with a shovel
* added eswords to the list of things that can cut
* ausbush junk
* code review appreciation + changing drag_slowdown
* more code review appreciation
* kirbyplants ComponentInitialize() -> Initialize()
* forgot glob.
* i wanna go to bed so im pushing this
* It compiles but doesn't work yet
* It works!
* I WANT TO DIE
* Appease linters
* some CI fixes
* Address reviews + oversight
* Limb grower fix
* more icon fixes
* forgot to hit save
* I'm a dumbass
* Removes bodypart parent from unit test
* Fixes monkeys and CI
* Grammar pass
* I hate zombie code so much
* General code cleanup
* THE SHITCODERS ARE COMING FOR MY VARS
* THE UNIT TESTS ARE COMING FOR MY SHITCODE
* Reviews + skirts
* Removes an unused DMI
* Why didn't I do this in the first place?
* HAIR REFACTOR
* Haha whoops
* How did I miss this
* Admin spawned creatures now have their features
* Optimize me harder
* minor fix i need to push to merge master
* Fixes hair (maybe) and a runtime
* Maybe fixes mirrors
* Attempts to fix women
* Fixes hair on dismembered heads and a grammar change
* Caps lock did me dirty
* address reviews
* icon failures fix + missed reviews
* Fixes: Facehuggers and Regenerate_limb
* Fixes ethereal color pref appearance
* How the fuck did this not break everything else horribly?
* JESUS FUCKING CHRIST IM A MORON
* Fixes compile
* I'm not high I swear
* Im a dipshiiiit
* grumble grumble
* Fixes a visual bug with digitigrade legs. Adds \improper to roundstart species names. Added two new clothing-related helper procs. Renamed a couple procs to be more accurate. Adds SHOULD_CALL_PARENT(TRUE) to examine_more. Addresses reviews.
* Forgot this little readability thing.
* Updates CODEOWNERS
* Me when I forget how github works
* mapload me harder
* Last second fixes
Simple little PR that adds bitflag defs for the flags_inv var on /obj/item, so editing it in VV shows you the values as a toggle instead of the raw number.
Adds the foundational system for contextual screentips, which will show you what you can do with objects/items, including through context, such as what you are holding.
Provides several helper elements for most use cases, and applies it to a handful of common objects in order to show the full breadth of the system.
Changes screentips preference from on/off to on/off/only with context. Players who originally had it on off will have it migrated to only with context, though can re-disable it.
Alt of #64105 and #64126 (I'm sorry Novva, I should have said something earlier)
I main janitor. As a janitor main, my greatest joy in life is slipping people who ignore my signs
I've seen some people complain about janitor borgs, so I decided to look into em
Unfortunately, not only is the janitor borg just a straight upgrade to janitors, it has absolutely no reason to use most of its kit
We give it standard cleaning supplies, and hell even bespoke tools to deal with leaving slippery tiles everywhere, but we also just let them clean anything they can walk over
This seems a bit too much to me, even for borgs. Also it's like, really boring
So what if we made their movement based cleaning cost something? How about we make it suck water from their bucket. Use the same pattern as mop code, make it twice as expensive though. Give it a slowdown, some sound cues, and an action button to trigger it all
Implements the Modernizing radiation design document ( https://hackmd.io/@tgstation/rJNIyeBHt ) and replaces the current radiation sources with the new system, as well as replacing/removing a bunch of old consumers of radiation that either had no reason to exist, or could be replaced by something else.
Diverges from the doc in that items radiation don't go up like explained. I was going to, but items get irradiated so easily that it just feels pretty lame. Items still get irradiated, but it's mostly just so that radiation sources look cooler (wow, lots of stuff around going green), and for things like the geiger counter.
Instead of the complicated radiation_wave system, radiation now just checks everything between the radiation source and the potential target, losing power along the way based on the radiation insulation of whats in between. If this reaches too low a point (specified by radiation_pulse consumers), then the radiation will not pass. Otherwise, will roll a chance to irradiate. Uranium structures allow a delay before irradiating, so stay away!
Adds 2 new elements, one for slowing down pulling of dangerous objects (dispenser tanks and canisters), and one for preventing hostile attacking of elements in a typecache.
Also updates the obj_flags bitfield 'cause I thought I was gonna use that, but I didn't.
Adds these elements to spiders and space carp (from space dragon)
fixes#60197
woke up today with a ridiculous idea of semi-automatic compile time loop unrolling, wasnt worth the complexity in the least but it made the basis of this PR which i then continued work on. makes area_sensitive_contents into a more general system of important_recursive_contents where we can define reasonable uses to replace recursive contents iteration of the type found in get_hearers_in_view() as long as everything that uses it isnt something incredibly common to the point that it noticeably increases memory usage.
* optimizes some internals of signal and component code
* comment and a better var name
* gets rid of DF_SIGNAL_ENABLED and all referencing code because its dumb
* gets rid of NONE | CallAsync(stuff)
* fixes conflicts
* puts NONE back in
Moves eyestabbing off from an item flag that is checked on every item attack to an element.
Kills /obj/item/proc/eyestab, and makes the new element the sole owner.