* Refactor icemoon wolves into basic mobs and add taming + pack behavior (#79736)
## About The Pull Request
Ports icemoon wolves over to the basic mob framework with a bit of extra
stuff:
- Wolves call for help when attacked within a decently large radius.
Because you know, pack animals.
- Wolves can now be tamed with a slab of meat
- When tamed, wolves can be ridden like goliath mounts. Ride wolf, life
good. Pretend you're playing ARK and start shivering to death in thatch
huts for that High Roleplay experience.
- Tamed wolves have access to a bunch of pet commands (following, point
fetching, point attacking, play dead, etc) and will also defend their
owners vehemently if they're attacked.
You can probably tame multiple if you wanted to.
## Why It's Good For The Game
What part about riding wolves isn't entertaining? I don't really play
/tg/ that much so I can't argue too much about the balance implications
this might pose, but it's undoubtedly a stupid little gimmick and is
likely to be used by bored assistants and miners with too much time on
their hands.
Especially robust individuals will probably find a million things to do
with a basic mob capable of fetching, attacking on command and generally
being able to defend themselves decently well.
## Changelog
🆑 yooriss
refactor: Icemoon wolves now use the basic mob framework and should act
more intelligently, defending their pack.
add: Icemoon wolves can be tamed with slabs of meat and can be ridden as
mounts once friendly. Being rather large dogs, they also have access to
most of the pet commands you'd expect, such as fetching things, and
violently mauling people their owners point at.
/🆑
---------
Co-authored-by: san7890 <the@ san7890.com>
* Refactor icemoon wolves into basic mobs and add taming + pack behavior
---------
Co-authored-by: Ephemeralis <Ephemeralis@users.noreply.github.com>
Co-authored-by: san7890 <the@ san7890.com>
* More standardization for ghost notifications (READY) (#79596)
## About The Pull Request
I'm still not satisfied with how ghost notifications work. This gives
every notification with a source (99% of all notifications, in other
words) a link to jump/orbit. Currently, notifications with "play"
interactions would only get the interact link, so jumping to the source
was pretty annoying.
It removes posting the entire message in the alert tooltip, as some got
pretty lengthy and it didn't seem to fit. To replace this, they will
always use headers
After:



NOTIFY_JUMP and NOTIFY_ORBIT have been merged, since the only difference
seems to be whether it's a turf. The result shaves off some redundant
lines of code, since most-every usage of notify_ghosts uses
NOTIFY_ORBIT.
## Why It's Good For The Game
More standardization for the ghost notification system. Adds a few alert
headers that never had them. All in all, makes it easier for creators to
throw alerts at ghosts
## Changelog
🆑
qol: Nearly every ghost alert should now feature a "VIEW" button, even
those with click interaction.
del: Ghost alerts no longer show the entire message in the tooltip,
instead have been replaced with titles.
/🆑
* More standardization for ghost notifications (READY)
* Modular
* Update outpost_of_cogs.dm
---------
Co-authored-by: Jeremiah <42397676+jlsnow301@users.noreply.github.com>
Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com>
* Splits placeontop proc (#79702)
## About The Pull Request
I find the proc hard to read honestly. There's no reason we can't split
this into two functions - the secondary functionality is used only once,
in reader.dmm.
## Why It's Good For The Game
Code improvement
Glorious snake case
## Changelog
N/A nothing player facing
---------
Co-authored-by: san7890 <34697715+san7890@ users.noreply.github.com>
* Splits placeontop proc
* Update brass_spreader.dm
---------
Co-authored-by: Jeremiah <42397676+jlsnow301@users.noreply.github.com>
Co-authored-by: san7890 <34697715+san7890@ users.noreply.github.com>
Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com>
* Fixes tram electrocuting law abiding crosswalk users [NO GBP] (#79780)
## About The Pull Request
Fixes the tram_pos var to actually use the tram's position when
calculating the tram's velocity.
## Changelog
🆑 LT3
fix: Tram will no longer electrocute innocent, law abiding crew trying
to use the crosswalk when there's no tram in sight
/🆑
* Fixes tram electrocuting law abiding crosswalk users [NO GBP]
---------
Co-authored-by: lessthanthree <83487515+lessthnthree@users.noreply.github.com>
* Code compression for reagent holder. Lowers plumbing reaction chamber tick usage (#79686)
## About The Pull Request
More code improvements for reagent holder. As you can see it removes a
lot more code than it adds so code savings are significant. This does
not touch on any floating point arithmetic, all that is behind us, this
focuses on removing redundant procs and merging existing procs to
achieve the same functionality so if you do see any changes in reagent
related behaviour it's not intentional and should be reported as a bug
here.
The following code changes can be summarized into points.
**1. Removes procs `get_master_reagent_id()` &
`get_master_reagent_name()`**
Both of these procs have the exact same functionality as
`get_master_reagent()` with the only exception of returning a different
value. Instead we can just call `get_master_reagent()` directly and
infer the name & type of it ourselves rather than creating a wrapper
proc to do it for us, therefore reducing overall code
**2. Removes & Merges `remove_all_type()` proc into `remove_reagent()`**
The proc `remove_all_type()` is highly inefficient, it first uses a for
loop to look for the reagent to remove & then it again calls
`remove_reagent()` on the reagent once it has found it. We can just
embed this functionality directly into `remove_reagent()` by simply
adding an additional parameter `include_subtypes`. This way the
operation is faster, and we reduce the code to get the job done. Also
now `remove_reagent()` will return the total volume of reagents removed
rather that a simple TRUE/FALSE
**3. Removes & Merges `trans_id_to()` proc into `trans_to()`**
Both these procs have the same job of transferring either a single
reagent or all reagents. `trans_id_to()` is a scaled down version of
`trans_to()` because
- It does not have any `method` var. This means if you want to transfer
a single reagent to a mob/organ or any other object it does not have the
functionality to expose the target to that transferred reagent.
- It does not have a `multiplier` var to scale reagent volumes
- It does not have code to deal with organs or stop reactions i.e. it
does not have the `no_react` var.
We can overcome all these short comings by simply adding an extra var
`target_id` to specify what specific reagent to transfer therefore
attaining the same functionality while keeping the benefits of
`trans_to()` proc therefore reducing overall code
**4. Lowers plumbing reaction chamber tick usage for balancing ph.**
Rather than invoking a while loop to balance ph it's much easier for the
player to simply make the reaction chamber wait for e.g. add a reagent
that will never come. This will make the chamber wait therefore giving
the reaction chamber ample time to correctly balance the ph and then
remove that reagent from the list therefore getting correct ph levels.
No need to create code hacks when the player can do it themselves so
the while loop has been removed
## Changelog
🆑
code: removed redundant procs `get_master_reagent_id()` &
`get_master_reagent_name()`
code: merged `remove_all_type()` proc with `remove_reagent()` now this
proc can perform both functions. `remove_reagent()` now returns the
total volume of reagents removed rather than a simple TRUE/FALSE.
code: merged `trans_id_to()` proc with `trans_to()` now this proc can
perform both functions
refactor: plumbing reaction chamber will now use only a single tick to
balance ph of a solution making it less efficient but more faster. Just
make the reaction chamber wait for longer periods of time to accurately
balance ph
refactor: reagent holder code has been condensed. Report any bugs on
GitHub
/🆑
* Code compression for reagent holder. Lowers plumbing reaction chamber tick usage
* Modular update
* Update alcohol_reagents.dm
---------
Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com>
Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com>
* Orbit Poll respects Preferences + Asks for Permission to Unghost (#79712)
## About The Pull Request
Fixes#79676
Ticking either the player or admin "do not consider me for ghost roles"
excludes you from the pool of candidates in an orbit ghost poll.
You will now get a `tgui_alert()` asking you if you want to accept being
put into the orbit poll role's before you accept it, putting it in line
with every other ghost role in the game. If the player doesn't accept,
the proc is re-ran with someone else on the list.
## Why It's Good For The Game
We need both of these behaviors present to keep it standard with what
players expect with ghost roles, and it is annoying to be an admin/AFK
player who gets hotswapped into one of these roles while they're doing
stuff.
## Changelog
🆑
qol: You will no longer be added to the list for ghost-orbit role polls
if you have opted out of getting antag ghost roles in your preferences.
qol: You will get a tgui_alert to accept the ghost role if you were
selected via the orbit poll, instead of it just throwing you intot he
role.
/🆑
* Orbit Poll respects Preferences + Asks for Permission to Unghost
---------
Co-authored-by: san7890 <the@san7890.com>
* Fixes tram plate electrocution [NO GBP] (#79717)
## About The Pull Request
When tram electrocution was turned into a component instead of on the
turf, the bad luck omen stopped having a chance of electrocuting the
mob. Fixes the toast proc to check for the cursed trait, now also
applied by the omen.
Splits the toast probability into one value for a normal plate, and one
for a broken plate or people with omen. Narrows the window of a
potential shock with adjusted probability, no chance of electrocution on
green.
Adds a missing early return for when the tram isn't moving.
## Changelog
🆑 LT3
fix: Bad luck omen again raises your chance of getting shocked by the
tram plate
fix: Tram plate checks and energizes when the tram is moving
code: Omen component now applies the cursed trait
/🆑
* Fixes tram plate electrocution [NO GBP]
---------
Co-authored-by: lessthanthree <83487515+lessthnthree@users.noreply.github.com>
* Gunpoint now blocks bumps, adds examine text and can be broken by shoving (#79564)
## About The Pull Request
Lesser version of https://github.com/tgstation/tgstation/pull/75226
Changes a few things with bumping which could lead to cheesing a charged
shot if the shooter has an ally to bump the target. Also adds examine
text to know what's happening.
Also shoving now can be used to break gunpoint, since having immovable
mobs can be troublesome in some situations
## Why It's Good For The Game
Grabs from the target no longer counter gunpoint;
Accidental or cheesy bumps are removed;
Shoves and pulls can be used in a teamplay to break gunpoint
## Changelog
🆑
qol: Gunpoint: Examining the target will show who is holding them at
gunpoint
qol: Gunpoint: Examining the shooter will show who they are holding at
gunpoint
balance: Gunpoint: If the target tries to grab, they will trigger the
shot
balance: Gunpoint: If the target or the shooter are shoved, it will
cancel the gunpoint
balance: Gunpoint: If the target is pulled, it will cancel the gunpoint
balance: Both the target and the shooter can't be bumped anymore to
avoid cheesing charged shot or removing the gunpoint by just moving
around
fix: Clicking the alert button of the shooter will now correctly remove
gunpoint
/🆑
---------
Co-authored-by: Ghom <42542238+Ghommie@ users.noreply.github.com>
* Gunpoint now blocks bumps, adds examine text and can be broken by shoving
---------
Co-authored-by: larentoun <31931237+larentoun@users.noreply.github.com>
Co-authored-by: Ghom <42542238+Ghommie@ users.noreply.github.com>
* Lemon fixes ci (#79384)
## About The Pull Request
Sets up moveloops to better catch issues with duplicated loops
Letting people modify the timer var AND have it track what bucket we're
in was a bad idea.
So instead let's store the queued time separate. Also makes
allowed_to_move return true/false instead of flags
This fixed? the null loop issue locally, I honestly have no damn idea
why. I'm gonna be working on the rest of ci here, left trackers so if it
pops up between now and merge I'll know what the issue is.
---------
Co-authored-by: John Willard <53777086+JohnFulpWillard@ users.noreply.github.com>
Co-authored-by: Emmett Gaines <ninjanomnom@ gmail.com>
* Lemon fixes ci
---------
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
Co-authored-by: John Willard <53777086+JohnFulpWillard@ users.noreply.github.com>
Co-authored-by: Emmett Gaines <ninjanomnom@ gmail.com>
* Removes final remnants of 'targetted' (#79626)
## About The Pull Request
Finishing what https://github.com/tgstation/tgstation/pull/79513/
started, removes 'targetted' typo from code. Also updates the basic mob
guide with the new updated var names.
## Why It's Good For The Game
Typos bad. Accurate guides good.
## Changelog
🆑
code: gets rid of the rest of the instances of 'targetted' typo from
code
/🆑
* Removes final remnants of 'targetted'
---------
Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com>
* Basic Guardians/Holoparasites (#79473)
## About The Pull Request
Fixes#79485Fixes#77552
Converts Guardians (aka Holoparasites) into Basic Mobs.
Changes a bunch of their behaviours into actions or components which we
can reuse.
Replaces some verbs it would give to you and hide in the status panel
with action buttons that you may be able to find more quickly.
They _**should**_ work basically like they did before but a bit
smoother. It is not unlikely that I made some changes by accident or
just by changing framework though.
My one creative touch was adding random name suggestions.
The Wizard federation have a convention of naming their arcane spirit
guardians by combining a colour and a major arcana of the tarot. The
Syndicate of course won't truck with any of that mystical claptrap and
for their codenames use the much more sensible construction of a colour
and a gamepiece.
This lets you be randomly assigned such creative names as "Sparkling
Hermit", "Bloody Queen", "Blue World", or "Purple Diamond".
You can of course still ignore this entirely and type "The Brapmaster"
into the box if so desired.
I made _one_ other intentional change, which is to swap to Mothblocks'
nice leash component instead of instantly teleporting guardians back to
you when they are pulled out of the edge of their range. They should now
be "dragged" along behind you until they can't path, at which point they
will teleport. This should make the experience a bit less disorienting,
you have the recall button if you _want_ to instantly catch up.
This is unfortunately a bumper-sized PR because it did not seem
plausible to not do all of it at once, but I can make a project branch
for atomisation if people think this is too much of a pain in the ass to
review.
Other changes:
- Some refactoring to how the charge action works so I could
individually override "what you can hit" and "what happens when you hit"
instead of those being the same proc
- Lightning Guardian damage chain is now a component
- Explosive Guardian explosive trap is now a component
- Added even more arguments to the Healing Touch component to allow it
to heal tox/oxy damage and require a specific click modifier
- Life Link component which implements the Guardian behaviour of using
another mob as your health bar
- Moved some stuff about deciding what guardians look and are described
like into a theming datum
- Added a generic proc which can return whether your mob is meant to
apply some kind of damage multiplier to a certain damage type. It's not
perfect because I couldn't figure out how ot cram limb modifiers in
there, which is where most of it is on carbons. Oh well.
- Riders of vehicles now inherit all movement traits of those vehicles,
so riding a charging holoparasite will let you cross chasms. Also works
if you piggyback someone with wings, probably.
## Changelog
🆑
refactor: Guardians/Powerminers/Holoparasites now use the basic mob
framework. Please report any unexpected changes or behaviour.
qol: The verbs used to communicate with, recall, or banish your Guardian
are now action buttons.
balance: If (as a Guardian) your host moves slightly out of range you
will now be dragged back into range if possible, rather than being
instantly teleported to them.
balance: Protectors now have a shorter leash range rather than a longer
one, in order to more easily take advantage of their ability to drag
their charge out of danger.
balance: Ranged Guardians can now hold down the mouse button to fire
automatically.
balance: People riding vehicles or other mobs now inherit all of their
movement traits, so riding a flying mob (or vehicle, if we have any of
those) will allow you to cross chasms and lava safely.
/🆑
---------
Co-authored-by: san7890 <the@ san7890.com>
* Basic Guardians/Holoparasites
* Modular
---------
Co-authored-by: Jacquerel <hnevard@gmail.com>
Co-authored-by: san7890 <the@ san7890.com>
Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com>
* Emergency hotfix for engi crossbow [NO GBP] (#79606)
Hadnt added these commits when the PR got merged due to not expecting it
oops
## Why It's Good For The Game
See above, used to make my last pr actually function as intended.
## Changelog
🆑
fix: fixed engi crossbow being able to be used onehanded + ability to
craft with sci inducers
/🆑
---------
Co-authored-by: Jacquerel <hnevard@ gmail.com>
* Emergency hotfix for engi crossbow [NO GBP]
---------
Co-authored-by: KingkumaArt <69398298+KingkumaArt@users.noreply.github.com>
Co-authored-by: Jacquerel <hnevard@ gmail.com>
* Targeting Datums Renamed (and global) (#79513)
## About The Pull Request
[Implements the backend required to make targeting datums
global](6901ead12e)
It's inconsistent with the rest of basic ai for these to have a high
degree of state, plus like, such a waste yaknow?
[Implements
GET_TARGETING_STRATEGY](d79c29134d)
Regexes used:
new.*(/datum/targetting_datum[^,(]*)\(*\)* -> GET_TARGETING_STRATEGY($1)
Renamed all instances of targetting to targeting (also targetting datum
-> targeting strategy)
I've used GET_TARGETING_STRATEGY at the source where the keys are
actually used, rather then in the listing. This works out just fine.
## Why It's Good For The Game
Not a misspelled name through the whole codebase, very slightly less
memory load for basically no downside (slight cpu cost maybe but not a
significant one.
---------
Co-authored-by: John Willard <53777086+JohnFulpWillard@ users.noreply.github.com>
* Targeting Datums Renamed (and global)
* Update dogs.dm
* Modular
* Modular
* Modular
* Merge skew?
* Revert "Merge skew?"
This reverts commit 0889389ab5cb5c56655f1860d9173ba87efe9a22.
---------
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
Co-authored-by: John Willard <53777086+JohnFulpWillard@ users.noreply.github.com>
Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com>
* [NO GBP] Final precision rounding for reagent volumes (#79571)
## About The Pull Request
- Fixes#79566
This applies mostly to plumbing reaction chambers but to implement that
fix some rounding operations had to be carried over to `holder.dm`(which
will benefit everything in general)
I'm pulling out all the stops here. Rather than checking "are we close
enough" plumbing reaction chambers will now check if we and i quote
"absolutely insanely precisely there". This means volumes like 49.9999
should become 50 period.
Note this is a high probability & not a definite fix. i.e. now
theoretically 100% of the time you should not get this problem but if it
still happens then as of now i have no solution and have to go back to
the drawing board on this one but i am very confident this should be the
end of all plumbing related problems i.e. at least problems with volumes
not getting rounded to whole numbers
## Changelog
🆑
fix: plumbing factories should not rarely/randomly brick at volumes like
0.9999(when in fact it should have been 1)
/🆑
* [NO GBP] Final precision rounding for reagent volumes
---------
Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com>
* Automatic fire for mobs (#79502)
This adds a component you can slap onto mobs with ranged attacks which
lets them fire repeatedly with the mouse held down.
I applied it to a couple of existing mobs, to be honest we don't
currently have any which _need_ this but I will add it to the Ranged
Holoparasite (which really does need it) depending on which PR gets
merged first.
* Automatic fire for mobs
---------
Co-authored-by: Jacquerel <hnevard@gmail.com>
* Adds engi improvised weapon - rebar crossbow + Engi Exclusive Tot Shop Variant (#78777)
<!-- 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

Engi now has access to a Half Life 2 Inspired rebar crossbow! Made of
rods, wire, and an inducer, it shoots sharpened iron rods at a high
velocity. High damage and good embed chance, but requires you to reload
every shot which requires you to stand still for three seconds to pull
the string back. You can also Use a wrench on it to force it to store
more rods (read: more than one), but risks it exploding and shooting you
instead.
The syndicate variant, avaliable to traitor engis, can fire three rounds
before needing a reload, and features a scope and better armor piercing
ammpo, but costs 10TC. I see it as a sidegrade to the revolver - quieter
and has much more widespread ammuniton, but holds less ammo and doesnt
have the same burst stopping power. And, to those concerned about the
balance of a non-traitor with this item - the AP ammo can only be made
by the traitor who bought it, and anyone else has to use normal ammo.
GUN STAT JUNK
Normal one has 60% embed chance and does 40 damage (against unarmored
targetd), but requires you to wait at least 3 seconds not moving to pull
the string back. Good alpha strike but not sustainable in a long fight.
Its akin to a pipegun.
Lacks any AP qualities besides piercing a jumpsuit, because any wound
chance it has is due to a bare skin bonus. Generally not a great weapon
to fight sec with.
Syndie version is generally the above but better. Takes less to pull the
string back, slightly higher damage, better fire rate, etc. Doesnt fare
well against any armor thats equivalent to sec gear or better due to
most having low (relatively) AP and wound chance, but good bare wound
bonus.
STATS TLDR: Its good against unarmored chumps and greyshirts but anyone
in armor that protects against bullets will kick your teeth in.
Also, Ammo is crafted from an iron rod. I wanted to have it just fire
rods as is, but theyre stacked items which you cant define projectiles
or ammo from.
## Why It's Good For The Game
I've always felt engi, for as big of a department as it is, is lacking
in the "fun weapons" area. Sci has mechs and xenobio, med has chem nades
and syringe guns, and cargo has anything the QM will buy - but other
than the flamer and shocked doors, engi doesnt have much. Thats why I
made this pr. it was originally just a traitor item, as they lacked many
traitor items in their shop, but I felt like a worse, bootleg version
would suit them.
## Changelog
<!-- If your PR modifies aspects of the game that can be concretely
observed by players or admins you should add a changelog. If your change
does NOT meet this description, remove this section. Be sure to properly
mark your PRs to prevent unnecessary GBP loss. You can read up on GBP
and it's effects on PRs in the tgstation guides for contributors. Please
note that maintainers freely reserve the right to remove and add tags
should they deem it appropriate. You can attempt to finagle the system
all you want, but it's best to shoot for clear communication right off
the bat. -->
🆑
add: Enginenering rebar crossbows + tot kit
add: Added a bunch of ammos and crafting junk to make the ammo exist
image: added icond for all the above
/🆑
<!-- 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>
Co-authored-by: Jacquerel <hnevard@ gmail.com>
* Adds engi improvised weapon - rebar crossbow + Engi Exclusive Tot Shop Variant
---------
Co-authored-by: KingkumaArt <69398298+KingkumaArt@users.noreply.github.com>
Co-authored-by: MrMelbert <51863163+MrMelbert@ users.noreply.github.com>
Co-authored-by: Jacquerel <hnevard@ gmail.com>
* You can fish out of hydroponics trays (#79443)
## About The Pull Request
Adds a fishing spot to hydroponics trays.
Chances
- 33% nothing
- 33% grass
- 20% random seed (discludes rarer seeds, such as gatfruit and most
mutations)
- 10% grass seeds
- 1% strange seed
- 1% axolotl
- 1% frog
Lightly inspired by something (I think) is possible on Goon, but
obviously entirely new code.
## Why It's Good For The Game
Mostly just for laughs, they're basins of water so surely you can get
something out of it.
## Changelog
🆑 Melbert
add: Fishers can now try their luck at fishing out of hydroponics
basins.
/🆑
* You can fish out of hydroponics trays
---------
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
* Re-adds rounding tweaks for reagent volumes & plumbing reaction chamber tweaks (#79478)
## About The Pull Request
- Closes#79464
This takes the important fixes mentioned in the above PR and adds them
here. The above PR implemented the fixes by reverting a bunch of reagent
PR's but in the process of doing so it has brought back really
inefficient code & even some bugs that were previously fixed.
Rather than reviewing them & bringing back those changes which is time
consuming this PR extracts only those important rounding operations
required for the fix leaving all other optimizations intact
Mentioned @ CliffracerX in the changelog so they can get their GBP
Also plumbing reaction chamber is more active in taking in reagents.
That is if a reagent is not available in the pipe net rather than
waiting for it to become available it will simply skip over it & look
for other listed reagents thus saving time
- Fixes#31206
## Changelog
SyncIt21, CliffracerX
🆑
fix: reagent volumes should be consistent & non breaking across plumbing
& chemistry as a whole
fix: plumbing reaction chambers are more proactive. Will attempt to take
in reagents more frequently
/🆑
* Re-adds rounding tweaks for reagent volumes & plumbing reaction chamber tweaks
---------
Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com>
* Basic Shades (#79469)
## About The Pull Request
Makes shades into basic mobs. As they are solely player-controller and
have no AI, this was a very simple conversion.
Things of note:
- I've made shades use the same "theme" system as constructs, to
determine their drops and coloration - as opposed to these things being
manually set by the type of soulstone they're held in.
- I've reorganized files slightly, putting both constructs and shades in
a new "cult" basic mob folder.
That's more or less it. As I said, shades are simple.
## Why It's Good For The Game
Basic-izes another mob and cleans up the code a little. Removes the last
cult-related simplemob, too.
## Changelog
🆑
refactor: Shades now use the basic mob framework. Please report any
bugs.
/🆑
* Basic Shades
---------
Co-authored-by: lizardqueenlexi <105025397+lizardqueenlexi@users.noreply.github.com>
* Allows possessed blades to be possessed again [NO GBP] (#79447)
## About The Pull Request
An oversight- unregister was blocking future attempts to garner spirits
Converts some of the messages to balloon alerts
## Why It's Good For The Game
Fixes#79444
## Changelog
🆑
fix: Possessed blades can attempt to channel spirits again
/🆑
* Allows possessed blades to be possessed again [NO GBP]
---------
Co-authored-by: Jeremiah <42397676+jlsnow301@users.noreply.github.com>
* fixes signal circuit not working | refactors name of timer cooldown macros to be inherent, also docs them (#79367)
## About The Pull Request
Title
## Why It's Good For The Game
Less headache in the future for a macro thats not really obvious in what
it does
## Changelog
🆑
fix: signals in circuits now actually function
/🆑
* fixes signal circuit not working | refactors name of timer cooldown macros to be inherent, also docs them
---------
Co-authored-by: Zephyr <12817816+ZephyrTFA@users.noreply.github.com>
* Dehardcodes microwave cleaning, allows spray cleaner to work on dense objects such as windows (#79354)
## About The Pull Request
- Dehardcodes microwave cleaning
- Instead of hard istyping for a rag, soap, or space cleaner, we just
use `wash`.
- Gets rid of a redundant signal
- `COMSIG_ATOM_WASHED`: not only was it misleading (only sent to items),
but it was pointless because `COMSIG_COMPONENT_CLEAN_ACT` is the same
signal.
- Improves microwave attackby code, splitting tool stuff into tool-procs
- Allows spray cleaner to work on dense objects such as windows
- Clicking on a dense object or mob adjacent to you with spray cleaner
will spawn the puff cloud on the target, rather than on your own
position.
- This will skip the moveloop and just clean everything on the target
turf alone.
- This means you can spray down a bloody window with a spray bottle, as
janitor gods intended.
- It also means you can fill the spray with other stuff to spray onto
dense objects directly, which might be worth noting. Especially for
stuff like Napalm.
Fixes#79261
## Why It's Good For The Game
Opens up the sandbox to allow more objects to clean microwaves + better
code.
## Changelog
🆑 Melbert
qol: Clicking on an adjacent dense object (or mob) with Spray Cleaner
will now spritz it rather than doing nothing. This means you can use
Spray Cleaner to clean bloodied windows, as the janitor gods intended.
It also means you can fill a spray bottle with Napalm, I guess.
refactor: Any cleaning object can now clean a microwave.
/🆑
* Dehardcodes microwave cleaning, allows spray cleaner to work on dense objects such as windows
---------
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
* Plumbing IV Drip has full control over its transfer rate (#79373)
The problem is plumbing iv drip has the
`/datum/component/plumbing/iv_drip` component attached to it. We gave
this component full control over the mob we are trying to inject into
with this statement over here
c356f2f735/code/datums/components/plumbing/IV_drip.dm (L28)
Remember this component is inherited from `/datum/component/plumbing`
which has it's own **"process"** proc.
c356f2f735/code/datums/components/plumbing/_plumbing.dm (L74)
It was this proc that was injecting reagents into the mob at a rate of
`MACHINE_REAGENT_TRANSFER`(10 units) per second.
This process proc was conflicting with the base plumbing machinery
process proc
Why is why our transfer rate controls never worked. Now the plumbing
machinery only draws reagents from the plumbing network into it's own
internal container(not the mob) at an rate of
`MACHINE_REAGENT_TRANSFER`(10 units) per second leaving the injection &
draining rate alone and in full control of the player as intended.
Also since plumbing iv drip inherited from `/obj/machinery/iv_drip` and
not from the base type for all plumbing machinery
`/obj/machinery/plumbing` it did not override the `/obj/plunger_act()`
proc so the plunger did not work on it. That's fixed now too
Also took the opportunity to move plumbing vat to plumbing module folder
cause it belongs there
* Plumbing IV Drip has full control over its transfer rate
---------
Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com>
* Basic Constructs: Wraith (#79235)
## About The Pull Request
Converts wraith constructs to basic mobs. The last of the "mainline"
constructs, though there's still one to go after this.
Wraiths are pretty much the same as they've always been - speedy
constructs that pack a bit of a punch, built around doing hit-and-run
tactics with their ability to ethereal jaunt. Notably, I've converted
their ability to recharge their jaunts with attacks into a new
component, `recharging_attacks`. This can be placed on any basic mob to
let them recharge a cooldown action by landing hits, which could
possibly be useful in the future.
NPC wraiths are pretty straightforward, with a twist - they will always
chase down and beat to death the lowest-hp mob they can see. Happening
upon one of these while wounded will end very badly! While I originally
wanted them to be more flighty and use hit-and-run tactics, I couldn't
figure out a way to do this that didn't look kind of silly and make them
less effective overall.
In addition to the wraiths, I've done some much-needed cleanup to basic
constructs as a whole, improving some things and covering some things I
missed along the way.
- Ectoplasm drop types from constructs is now properly based on their
theme. I _believe_ I've done this in a way that will pass unit tests
this time, but we'll see if my local tests were being honest with me.
- Player-controlled constructs now attack faster. I didn't realize that
being basic mobs capped them to attacking once every 2 seconds, which is
a gigantic nerf over the simple animal version. I cut this to just 1
second, which should be much closer to how it originally was.
- Artificers actually seek out and heal the most damaged ally they can
find, instead of the least damaged. Turns out the sort was doing the
exact opposite order from what I thought, which became much more obvious
when using the same targeting behavior on wraiths.
- I put the PR number in the juggernaut update script, which I somehow
missed on that one.
- Removed the extraneous "noncult" construct subtypes that didn't do
anything. The Artificer one, which does something, is still around.
## Why It's Good For The Game
For the same reasons as the previous three. 5 more simple animals gone,
and only one construct to go until I can nuke simple constructs from the
codebase entirely. Other than that, the new component could possibly
come in handy in future designs, and the NPC behavior should hopefully
be a little scary - even if just a little.
## Changelog
🆑
refactor: Wraith constructs have been converted to the basic mob
framework. NPC wraiths are now extra cruel and will attack the
lowest-health mob they can see at any given time. Make sure this isn't
you! Please report any bugs.
fix: Artificers and juggernauts no longer attack significantly more
slowly than intended.
/🆑
* Basic Constructs: Wraith
* Update defcon2.dmm
---------
Co-authored-by: lizardqueenlexi <105025397+lizardqueenlexi@users.noreply.github.com>
Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com>
* Basic Pirate NPCs (#79284)
## About The Pull Request
Converts hostile pirate NPCs to basic mobs - specifically, a subtype of
trooper. As their behavior is not meaningfully distinct from other
troopers, this conversion mostly just sticks them on the existing AI
behavior while keeping the rest the same.
Pirates do have one new thing going for them, though, to differentiate
them from other troopers. They use the new **plundering attacks**
component, which means that every time they land a melee attack, they
steal money from the bank account of whoever they hit. This requires the
target to be wearing an ID with a linked bank account, so it's not the
hardest thing in the world to hide your money from them - but it's still
something to be wary of! If killed, any mob with this component will
drop everything they've stolen in a convenient holochip.
## Why It's Good For The Game
Takes down 5 more simplemobs, and (I think) converts the last remaining
trooper-type enemy to be a basic trooper. (It's possible there's more
I've forgotten that could use the same AI, though.)
The money-stealing behavior is mostly good because I think it's funny,
but it also makes the pirates something a little distinct from "yet
another mob that runs at you and punches you until you die". They still
do that, but now there's a little twist! This can be placed on other
mobs too, if we want to make any other sorts of thieves or brigands.
## Changelog
🆑
refactor: Pirate NPCs now use the basic mob framework. They'll be a
little smarter in combat, and if you're wearing your ID they'll siphon
your bank account with every melee attack! Beware! Please report any
bugs.
/🆑
* Basic Pirate NPCs
* Modular paths
---------
Co-authored-by: lizardqueenlexi <105025397+lizardqueenlexi@users.noreply.github.com>
Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com>
* Converts traders to basic mobs (#79187)
## About The Pull Request
This PR converts the two trader mobs into basic mobs, these being the
basic debug trader that buys ectoplasm and sells ghost burgers, and Mr
Bones, who buys empty milk cartons and bones, and sells bone relate
paraphernalia.
Traders now use dynamic appearance generation. The old sprites still
exist as hallucinations, and as shop signs.
Trader UI is now summoned via `COMSIG_ATOM_ATTACK_HAND`, which properly
cancels the attack chain, so there is no longer need to put it on
Interact.
I kept most of the original behaviour, but moved them off into a
component. I have also cached all the images generated for the radials,
I hope I have not overengineered it. I have also created a new datum,
which stores the trader's wares, needs, and speech patterns.
Admins can put the component along with the trader data on any living
mobs with an AI controller, turning them into traders. Keep in mind that
most AI has random idle movement, meaning they have a chance to walk
off, closing your trader radial.

The trader AI consists of the following, first, when a trader sees
someone, they will deploy their shop, if one does not already exists.
The shop consists of a chair, and a holographic sign. If you attack
them, they will chase you with their weapons, and then return to their
chair when victorious. If the chair is somehow destroyed, they will
create a new shop when they see a new potential customer.

Mr Bones uses a variant of the AI, where they will run at you, and
deploy their shop when they reach you. I call this the jumpscare
variant. Below you can see me getting actually jumpscared because Mr
Bones has stepped on a yelling frog when I opened the maintenance door.

I have also made an element that toggles an ai controlled combat mode
when it gains a target, and when it loses it. I am using it to make
Traders unable to trade while they are trying to kill a robber. To aid
this, I a have made
`/datum/ai_controller/proc/sig_remove_from_blackboard` send the
`COMSIG_AI_BLACKBOARD_KEY_CLEARED` signal, in case the trader kills a
mob that deletes itself on death. This means I could remove a signup
`/datum/component/appearance_on_aggro` was doing towards Qdeleting.
Below you can see Mr Bones shooting me with candy corn.


Traders actually only shoot you until you are conscious, so I survived
here in crit. Most mobs don't have crit state, so they just die, so I am
sticking by this voice line.
Thank you @ CoiledLamb for help with the sale sign!
## Why It's Good For The Game
Two more mobs off the list. The AI and Componentized behaviours allows
us to set up new kind of traders.
## Changelog
🆑
refactor: Traders are basic mobs now. Please alert us of any strange
behaviours!
code: If there is only one option, radial lists will autopick it. This
behaviour can be turned off via a new argument.
/🆑
* Converts traders to basic mobs
---------
Co-authored-by: Profakos <profakos@gmail.com>
* Fixes invisibility exploit (#79337)
## About The Pull Request
Adds a short cooldown timer (1s) to the toggle seethrough ability to
give it time to stop animating
## Why It's Good For The Game
Fixes#79161
## Changelog
🆑
fix: Fixed an invisibility exploit on large mobs. Probably better this
way
/🆑
---------
Co-authored-by: Jacquerel <hnevard@ gmail.com>
* Fixes invisibility exploit
---------
Co-authored-by: Jeremiah <42397676+jlsnow301@users.noreply.github.com>
Co-authored-by: Jacquerel <hnevard@ gmail.com>
* Light-Eaten objects can no longer emit light after being turned off and then back on (#79240)
## About The Pull Request
#67676 described a bug where PDAs can apparently emit a small amount of
light after being affected by the light eater. As it turns out, the bug
is even worse than that. It doesn't work for just PDAs, it works for
basically any light source that can be turned off and on. Even
flashlights. In the following pictures, a flashlight has been
light-eaten and then turned off and on again:

Observe how the nightmare jaunt is available, as it should be. However,
one step closer to the flashlight:

The nightmare jaunt can no longer be used, because the flashlight is
still emitting light.
This PR just fixes that behavior. Light-eaten objects will now be
totally dark again, even after being power cycled. Closes#67676.
## Why It's Good For The Game
Bugs bad.
## Changelog
🆑
fix: Light-Eaten objects can no longer emit light after being turned off
and then back on.
code: Flashlights now use light_on instead of defining their own
variable. Please report buggy behavior.
/🆑
* Light-Eaten objects can no longer emit light after being turned off and then back on
* updatepaths
---------
Co-authored-by: GPeckman <21979502+GPeckman@users.noreply.github.com>
Co-authored-by: lessthanthree <83487515+lessthnthree@users.noreply.github.com>
* Ground sinking sanity checks and doc cleanup (#79214)
## About The Pull Request
The asynchronous sinking component of garden gnomes did not check if the
gnome still existed, when the sinking timer ran out, which caused null
exception runtimes. I have added sanity checks to this. In addition, the
sinking used do_after, but failing the do_after had no effect on
anything, and infact, made the mob sink even faster into the ground, so
I have added an early return, and a call for unsinking.
Also tweaked proc names and documentation.
Funny story: the only reason I have found out about this bug is because
sometimes garden gnomes spawn on a downstream map, and they cause a CI
failure when the nuke cinematic unit test explodes them. 😔
## Why It's Good For The Game
Runtimes bad. Also if an action has a do_after call, it should probably
fail if it the timer fails.
## Changelog
🆑
fix: Gnomes no longer runtime if they explode while sinking into the
ground
/🆑
* Ground sinking sanity checks and doc cleanup
---------
Co-authored-by: Profakos <profakos@gmail.com>
* Adds support to the wet_floor component to avoid displaying its overlay, makes ice turfs no longer receive said wet overlay (#79275)
## About The Pull Request
The title says it all, really.
I always thought ice looked a bit silly, and always wondered why. Today,
I found out it was because of the `wet_floor` component adding an
overlay that suddenly made a turf that should look continuous, tiled,
which in turn gave some very ugly visuals. Ice already looks slippery,
you can tell that it's ice, and the overlay that was added to it just
didn't really help telegraph that any better than the sprite itself
already does.
That's why I added support to make it so it would be possible to force
the overlay to just not be applied to the turf that's affected by the
component, to make it all look a bit better overall.
I added it to the ice turfs as a proof of concept, although I guess it
could also be used on other turfs that are always "wet", like the
bananium floors, but I didn't really care enough to touch that yet, and
I guess the bananium floors can use it a bit better than ice did.
I did notice in this PR that the smoothing of ice seemed to potentially
be broken, but that's something to look into at a later time.
## Why It's Good For The Game
Look at this ice and how much smoother it looks like now:

## Changelog
🆑 GoldenAlpharex
code: Added support to the wet_floor component to make it so the wet
overlay could not be applied to certain turfs if desired.
fix: Ice turfs no longer look tiled, and instead look smooth when placed
next to one-another.
/🆑
* Adds support to the wet_floor component to avoid displaying its overlay, makes ice turfs no longer receive said wet overlay
---------
Co-authored-by: GoldenAlpharex <58045821+GoldenAlpharex@users.noreply.github.com>
* Improves the deployable component (#79199)
## About The Pull Request
The deployable component had a few random things I noticed when I tried
actually using it that kinda sucked so I'm:
Making the examine message more generic, we did NOT need to make it that
complicated.
Letting anything with hands deploy stuff, because mobs other than humans
can hold things.
Giving the option to let something be deployed more than once.
Letting direction setting be optional.
Tweaking the check for if something can be placed somewhere to be a bit
better.
## Why It's Good For The Game
I want to use the deployable component for stuff but I made it awful.
## Changelog
🆑
code: the deployable component has been tweaked and improved with some
new options to it
/🆑
---------
Co-authored-by: Jacquerel <hnevard@ gmail.com>
* Improves the deployable component
* Modular
---------
Co-authored-by: Paxilmaniac <82386923+Paxilmaniac@users.noreply.github.com>
Co-authored-by: Jacquerel <hnevard@ gmail.com>
Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com>
* Cuts the number of `apply_damage` copypaste procs from 3(.5) to 1, fixing a few bugs along the way
* Update _species.dm
* Update damage_procs.dm
* Modular adjustments
* Update mutant_species.dm
* Update mutant_species.dm
---------
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com>
* Scatter laser shells now use the scatter laser beam, and makes them significantly easier to make. Projectiles can now have damage falloff. (#78927)
## About The Pull Request
Allows for damage falloff to apply to more than just shotgun pellets.
Now any projectile can have a damage falloff defined.
Scatter Laser shells no longer use the minigun beams to determine their
damage. Instead they use the actually defined scatter laser beams. Those
beams do 7.5 damage per pellet, times by 6 pellets.
Scatter laser beams now have damage falloff, a separately defined
(positive) wounding power from normal beams, and wound falloff.
Scatter laser shells can be printed from security protolathes once you
have weapon tech.
Scatter laser shells _may_ be damaged by EMPs based on severity. The
result is that it fires a practically useless volley of laser fire. They
cause a honk sound when they hit, so you know when you've shot one of
these.
## Why It's Good For The Game
Well, we want shotguns universally to not be defined by their damage
output (especially extreme damage output) but by niche.
What does the scatter laser shell currently occupy as a niche?
The single highest damage output of any projectile weapon in direct
damage. The thing we don't want of shotguns, and it is reigning champion
of all guns.
Okay, that's a bit misleading, because obviously it is competing with
the likes of .50 BMG which does 70 damage outright and dismembers limbs,
potentially doing upwards of 90 damage if it does, and also hard stuns
people. Obviously _that_ is technically a stronger bullet.
But not for raw damage, because the scatter laser does 90 damage out the
gate, barring any potential wounding that might occur which increases
the damage multiplicatively. No gimmicks, no extra procs, nothing. It's
just 15 force lasers (with no damage dropoff) split between 6 beams.
And the reason for this is because this shell has been nerfed once prior
by making it not fire 6 normal laser shots into someone. That was 120
damage at the time, 120 to 90 was...I guess a nerf during the taser era.
Depends on how you viewed it. Buckshot was doing like 80 at the time,
believe me it was a wild period. But anyway, when we did the whole
damage rearrangement over the course of the laser few years, every other
shell got touched except this one for some reason. Even pulse slugs lost
10 damage while this was still sitting on 90 force point blank.
So what is the new niche? Well, it's laser buckshot. That's not a niche
but crew don't get buckshot, so this is their buckshot. It wounds real
good. Real goddamn good. And its is a laser. It fits the aesthetic,
obviously.
Okay, thanks.
## Changelog
🆑
balance: Scatter laser shells actually utilize the _real_ scatter laser
beam. This comes with damage changes. And wounding power.
feature: EMPs can potentially damage scatter laser shells.
refactor: All projectiles can now have damage falloff defined. Yay.
balance: Scatter laser shells can be printed when weapons technology is
researched.
/🆑
---------
Co-authored-by: Jacquerel <hnevard@ gmail.com>
* Scatter laser shells now use the scatter laser beam, and makes them significantly easier to make. Projectiles can now have damage falloff.
* Modular
---------
Co-authored-by: necromanceranne <40847847+necromanceranne@users.noreply.github.com>
Co-authored-by: Jacquerel <hnevard@ gmail.com>
Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com>
* Pollution no longer happens when the subsystem is offline
* Removes the code for bonfire pollution that wasn't done modularly
* Modularizes bonfire pollution, makes the default bonfire not produce pollution
* Player-made campfires produce pollution
* Aquariums now have an internal feed storage. Fish catalogs as 25cr goodies. (#78958)
## About The Pull Request
Added a reagent holder to aquarium tanks and some code to enable the
fish to be automatically fed at selectable intervals of 1 minute to 7
(default 3). The holder can be accessed and filled by opening the
control panel, and emptied with a plunger if necessary. Simple plumbing
compatibility has been added as well, in case you think the 6 units of
capacity of the reagent holder (enough to feed a fish 60 times) are not
enough. The preset fishing tank starts with enough feed to keep its
contents alive for 30 minutes.
Beside that, I've fixed a small oversight with the fish analyzer goodie
pack. It should cost 150, not 500.
The fish catalog is now a goodie pack you can get as a goodie for dirt
cheap (25 creds) and a subtype of `book/manual`, so there's a slim
chance you may find it at the library or somewhere else.
Fixed a small oversight inside the fish catalog.
Mapped in a single aquarium kit for each station map, in the service
hallway/storage room where the techfab and cargo consoles are also
found.
Aquarium kits are now compatible with slapcrafting.
## Why It's Good For The Game
Aquariums require too much maintainance for a gimmick, and it's quite
awful to see the fish inside preset aquariums die 5 minutes into the
round. Also, you cannot get fish catalogs anywhere but from the aquarium
kit crate, which costs 1k credits, though its pertinence with fishing
goes beyond aquarium stuff.
Lastiy, I think it's good to give the crew a free aquarium kit. The
price of the supply pack is a bit out of reach for many, service could
use a bit of fisciculture too (I may make it a service pack later, so
that it can be ordered through the service console).
## Changelog
🆑
add: Aquariums now have a small internal reagent holder, accessible when
the panel is open and used to automatically feed the fishes at
selectable intervals, also compatible with plumbing.
add: Fish catalogs can now be bought as a goodie pack, for 25 cr, or
rarely found at the library or maints.
fix: Fixed the prices of fish analyzers. It's supposed to be 150 cr, not
500.
map: Added an aquarium kit to each station, found in the room where the
service techfab and order console also are.
qol: Aquarium kits are now compatible with slapcrafting (crafted by
hitting them with the required material without opening the menu).
balance: Moved the aquarium kit and fish supply packs from the "General"
section to "Service" and "Livestock" respectively, meaning they can be
ordered for free from the service orders console.
/🆑
* Aquariums now have an internal feed storage. Fish catalogs as 25cr goodies.
* UpdatePaths
---------
Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com>
* Fixes crafting menu not detecting ingredients properly (#79141)
## About The Pull Request
1. Fixes#79089
This fix applies for the above issue and all crafting recipes that
require some sort of reagent container containing reagents. It now adds
the container & the reagents inside of it to the list of available
ingredients & not just the reagents which was previously the case.
2. Fixes#79159
Other crafting ingredients in general were not being detected if it was
not a stack type. That's fixed now too
## Changelog
🆑
fix: items that require reagent containers & the reagents inside it for
crafting(e.g. molotov) now crafts properly.
fix: most crafting recipes should work now
/🆑
* Fixes crafting menu not detecting ingredients properly
---------
Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com>
* Adds a subtle ghost poll (#79105)
## About The Pull Request
This makes a new ghost poll system which doesn't give TGUI popups -
instead, users are prompted to follow the POI and one of the orbiters is
chosen. The old system remains in place, so you can still prompt if you
want to.
This gives two things:
1. A deadchat notification:

2. A screen alert:

## Why It's Good For The Game
As stated in #76507, popups are pretty annoying. This is halfway between
a screen alert with no time limit and an event with more important
pings. This is better because:
1. Less popup fatigue
2. You can SEE how many you're competing with
4. DRY
## Changelog
🆑
add: Adds a subtle ghost poll. This pings in dead chat and gives a
screen alert, but no TGUI popup. Orbit the point of interest to be
selected for the role.
refactor: A number of ghost spawns now feature this alert. Write an
issue report if anything breaks.
/🆑
---------
Co-authored-by: MrMelbert <51863163+MrMelbert@ users.noreply.github.com>
* Adds a subtle ghost poll
---------
Co-authored-by: Jeremiah <42397676+jlsnow301@users.noreply.github.com>
Co-authored-by: MrMelbert <51863163+MrMelbert@ users.noreply.github.com>