diff --git a/.github/guides/VISUALS.md b/.github/guides/VISUALS.md
index 82ee0c6b5d6..9c385ee8765 100644
--- a/.github/guides/VISUALS.md
+++ b/.github/guides/VISUALS.md
@@ -4,10 +4,10 @@ Welcome to a breakdown of visuals and visual effects in our codebase, and in BYO
I will be describing all of the existing systems we use, alongside explaining and providing references to BYOND's ref for each tool.
-Note, I will not be covering things that are trivial to understand, and which we don't mess with much.
+Note, I will not be covering things that are trivial to understand, and which we don't mess with much.
For a complete list of byond ref stuff relevant to this topic, see [here](https://www.byond.com/docs/ref/#/atom/var/appearance).
-This is to some extent a collation of the BYOND ref, alongside a description of how we actually use these tools.
+This is to some extent a collation of the BYOND ref, alongside a description of how we actually use these tools.
My hope is after reading this you'll be able to understand and implement different visual effects in our codebase.
Also please see the ref entry on the [renderer](https://www.byond.com/docs/ref/#/{notes}/renderer).
@@ -53,10 +53,10 @@ You'll find links to the relevant reference entries at the heading of each entry
## Appearances in BYOND
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/appearance)
+- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/appearance)
Everything that is displayed on the map has an appearance variable that describes exactly how it should be rendered.
-To be clear, it doesn't contain EVERYTHING, [plane masters](#planes) exist separately and so do many other factors.
+To be clear, it doesn't contain EVERYTHING, [plane masters](#planes) exist separately and so do many other factors.
But it sets out a sort of recipe of everything that could effect rendering.
Appearances have a few quirks that can be helpful or frustrating depending on what you're trying to do.
@@ -65,25 +65,27 @@ To start off with, appearances are static. You can't directly edit an appearance
The way to edit them most of the time is to just modify the corresponding variable on the thing the appearance represents.
-This doesn't mean it's impossible to modify them directly however. While appearances are static,
+This doesn't mean it's impossible to modify them directly however. While appearances are static,
their cousins mutable appearances [(Ref Entry)](https://www.byond.com/docs/ref/info.html#/mutable_appearance) **are**.
-What we can do is create a new mutable appearance, set its appearance to be a copy of the static one (remember all appearance variables are static),
+What we can do is create a new mutable appearance, set its appearance to be a copy of the static one (remember all appearance variables are static),
edit it, and then set the desired thing's appearance var to the appearance var of the mutable.
Somewhat like this
```byond
-// NOTE: we do not actually have access to a raw appearance type, so we will often
+// NOTE: we do not actually have access to a raw appearance type, so we will often
// Lie to the compiler, and pretend we are using a mutable appearance
// This lets us access vars as expected. Be careful with it tho
-/proc/mutate_icon_state(mutable_appearance/thing)
+/proc/mutate_icon_state(mutable_appearance/thing)
var/mutable_appearance/temporary_lad = new()
temporary_lad.appearance = thing
temporary_lad.icon_state += "haha_owned"
return temporary_lad.appearance
```
+> **Note:** More then being static, appearances are unique. Only one copy of each set of appearance vars exists, and when you modify any of those vars, the corrosponding appearance variable changes its value to whatever matches the new hash. That's why appearance vars can induce inconsistent cost on modification.
+
> **Warning:** BYOND has been observed to have issues with appearance corruption, it's something to be weary of when "realizing" appearances in this manner.
## Overlays
@@ -91,7 +93,7 @@ Somewhat like this
- [Table of Contents](#table-of-contents)
- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/overlays) (Also see [rendering](https://www.byond.com/docs/ref/#/{notes}/renderer))
-Overlays are a list of static [appearances](#appearances-in-byond) that we render on top of ourselves.
+Overlays are a list of static [appearances](#appearances-in-byond) that we render on top of ourselves.
Said appearances can be edited via the realizing method mentioned above.
Their rendering order is determined by [layer](#layers) and [plane](#planes), but conflicts are resolved based off order of appearance inside the list.
@@ -104,67 +106,67 @@ It's not significant, but it is there, and something to be aware of.
### Our Implementation
-We use overlays as our primary method of overlaying visuals.
+We use overlays as our primary method of overlaying visuals.
However, since overlays are COPIES of a thing's appearance, ensuring that they can be cleared is semi troublesome.
To solve this problem, we manage most overlays using `update_overlays()`.
-This proc is called whenever an atom's appearance is updated with `update_appearance()`
-(essentially just a way to tell an object to rerender anything static about it, like icon state or name),
+This proc is called whenever an atom's appearance is updated with `update_appearance()`
+(essentially just a way to tell an object to rerender anything static about it, like icon state or name),
which will often call `update_icon()`.
`update_icon()` handles querying the object for its desired icon, and also manages its overlays, by calling `update_overlays()`.
-Said proc returns a list of things to turn into static appearances, which are then passed into `add_overlay()`,
+Said proc returns a list of things to turn into static appearances, which are then passed into `add_overlay()`,
which makes them static with `build_appearance_list()` before queuing an overlay compile.
-This list of static appearances is then queued inside a list called `managed_overlays` on `/atom`.
+This list of static appearances is then queued inside a list called `managed_overlays` on `/atom`.
This is so we can clear old overlays out before running an update.
-We actually compile queued overlay builds once every tick using a dedicated subsystem.
+We actually compile queued overlay builds once every tick using a dedicated subsystem.
This is done to avoid adding/removing/adding again to the overlays list in cases like humans where it's mutated a lot.
-You can bypass this managed overlays system if you'd like, using `add_overlay()` and `cut_overlay()`,
+You can bypass this managed overlays system if you'd like, using `add_overlay()` and `cut_overlay()`,
but this is semi dangerous because you don't by default have a way to "clear" the overlay.
Be careful of this.
## Visual Contents
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/vis_contents)
+- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/vis_contents)
The `vis_contents` list allows you to essentially say "Hey, render this thing ON me".
-The definition of "ON" varies significantly with the `vis_flags` value of the *thing* being relayed.
-See the ref [here](https://www.byond.com/docs/ref/#/atom/var/vis_flags).
+The definition of "ON" varies significantly with the `vis_flags` value of the *thing* being relayed.
+See the ref [here](https://www.byond.com/docs/ref/#/atom/var/vis_flags).
Some flags of interest:
-- `VIS_INHERIT_ID`: This allows you to link the object DIRECTLY to the thing it's drawn on,
+- `VIS_INHERIT_ID`: This allows you to link the object DIRECTLY to the thing it's drawn on,
so clicking on the `vis_contents`'d object is just like clicking on the thing
-- `VIS_INHERIT_PLANE`: We will discuss [planes](#planes) more in future, but we use them to both effect rendering order and apply effects as a group.
-This flag changes the plane of any `vis_contents`'d object (while displayed on the source object) to the source's.
+- `VIS_INHERIT_PLANE`: We will discuss [planes](#planes) more in future, but we use them to both effect rendering order and apply effects as a group.
+This flag changes the plane of any `vis_contents`'d object (while displayed on the source object) to the source's.
This is occasionally useful, but should be used with care as it breaks any effects that rely on plane.
-Anything inside a `vis_contents` list will have its loc stored in its `vis_locs` variable.
+Anything inside a `vis_contents` list will have its loc stored in its `vis_locs` variable.
We very rarely use this, primarily just for clearing references from `vis_contents`.
-`vis_contents`, unlike `overlays` is a reference, not a copy. So you can update a `vis_contents`'d thing and have it mirror properly.
+`vis_contents`, unlike `overlays` is a reference, not a copy. So you can update a `vis_contents`'d thing and have it mirror properly.
This is how we do multiz by the by, with uh, some more hell discussed under [multiz](#multiz).
-To pay for this additional behavior however, vis_contents has additional cost in maptick.
-Because it's not a copy, we need to constantly check if it's changed at all, which leads to cost scaling with player count.
+To pay for this additional behavior however, vis_contents has additional cost in maptick.
+Because it's not a copy, we need to constantly check if it's changed at all, which leads to cost scaling with player count.
Careful how much you use it.
## Images
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/image)
+- [Reference Entry](https://www.byond.com/docs/ref/#/image)
Images are technically parents of [mutable appearances](#appearances-in-byond).
We don't often use them, mostly because we can accomplish their behavior with just MAs.
-Images exist both to be used in overlays, and to display things to only select clients on the map.
+Images exist both to be used in overlays, and to display things to only select clients on the map.
See [/client/var/images](#client-images)
> Note: the inheritance between the two is essentially for engine convenience. Don't rely on it.
@@ -172,7 +174,7 @@ See [/client/var/images](#client-images)
## Client Images
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/client/var/images)
+- [Reference Entry](https://www.byond.com/docs/ref/#/client/var/images)
`/client/var/images` is a list of image objects to display to JUST that particular client.
@@ -180,35 +182,35 @@ The image objects are displayed at their loc variable, and can be shown to more
### Our Implementation
-We use client images in a few ways. Often they will be used just as intended, to modify the view of just one user.
+We use client images in a few ways. Often they will be used just as intended, to modify the view of just one user.
Think tray scanner or technically ai static.
-However, we often want to show a set of images to the same GROUP of people, but in a limited manner.
+However, we often want to show a set of images to the same GROUP of people, but in a limited manner.
For this, we use the `/datum/atom_hud` (hereafter hud) system.
This is different from `/datum/hud`, which I will discuss later.
-HUDs are datums that represent categories of images to display to users.
+HUDs are datums that represent categories of images to display to users.
They are most often global, but can be created on an atom to atom bases in rare cases.
They store a list of images to display (sorted by source z level to reduce lag) and a list of clients to display to.
-We then mirror this group of images into/out of the client's images list, based on what HUDs they're able to see.
+We then mirror this group of images into/out of the client's images list, based on what HUDs they're able to see.
This is the pattern we use for things like the medihud, or robot trails.
## View
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/client/var/view)
+- [Reference Entry](https://www.byond.com/docs/ref/#/client/var/view)
-`/client/var/view` is actually a pretty simple topic,
-but I'm gonna take this chance to discuss the other things we do to manage pixel sizing and such since there isn't a better place for it,
+`/client/var/view` is actually a pretty simple topic,
+but I'm gonna take this chance to discuss the other things we do to manage pixel sizing and such since there isn't a better place for it,
and they're handled in the same place by us.
Alright then, view. This is pretty simple, but it basically just lets us define the tile bound we want to show to our client.
This can either be a number for an X by X square, or a string in the form "XxY" for more control.
-We use `/datum/view_data` to manage and track view changes, so zoom effects can work without canceling or being canceled by anything else.
+We use `/datum/view_data` to manage and track view changes, so zoom effects can work without canceling or being canceled by anything else.
### Client Rendering Modes
@@ -218,29 +220,29 @@ Clients get some choice in literally how they want the game to be rendered to th
The two I'm gonna discuss here are `zoom`, and `zoom-mode` mode, both of which are skin params (basically just variables that live on the client)
-`zoom` decides how the client wants to display the turfs shown to it.
-It can have two types of values.
-If it's equal to 0 it will stretch the tiles sent to the client to fix the size of the map-window.
-Otherwise, any other numbers will lead to pixels being scaled by some multiple.
+`zoom` decides how the client wants to display the turfs shown to it.
+It can have two types of values.
+If it's equal to 0 it will stretch the tiles sent to the client to fix the size of the map-window.
+Otherwise, any other numbers will lead to pixels being scaled by some multiple.
This effect can only really result in nice clean edges if you pass in whole numbers which is why most of the constant scaling we give players are whole numbers.
-`zoom-mode` controls how a pixel will be up-scaled, if it needs to be.
-See the ref for more details, but `normal` is gonna have the sharpest output, `distort` uses nearest neighbor,
+`zoom-mode` controls how a pixel will be up-scaled, if it needs to be.
+See the ref for more details, but `normal` is gonna have the sharpest output, `distort` uses nearest neighbor,
which causes some blur, and `blur` uses bilinear sampling, which causes a LOT of blur.
## Eye
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/client/var/eye)
+- [Reference Entry](https://www.byond.com/docs/ref/#/client/var/eye)
-`/client/var/eye` is the atom or mob at which our view should be centered.
+`/client/var/eye` is the atom or mob at which our view should be centered.
Any screen objects we display will show "off" this, as will our actual well eye position.
-It is by default `/client/var/mob` but it can be modified.
+It is by default `/client/var/mob` but it can be modified.
This is how we accomplish ai eyes and ventcrawling, alongside most other effects that involve a player getting "into" something.
## Client Screen
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/{notes}/HUD)
+- [Reference Entry](https://www.byond.com/docs/ref/#/{notes}/HUD)
Similar to client images but not *quite* the same, we can also insert objects onto our client's literal screen
@@ -256,21 +258,21 @@ The classic `screen_loc` format looks something like this (keeping in mind it co
The pixel offsets can be discarded as optional, but crucially the x and y values do not NEED to be absolute.
-We can use cardinal keywords like `NORTH` to anchor screen objects to the view size of the client (a topic that will be discussed soon).
-You can also use directional keywords like `TOP` to anchor to the actual visible map-window, which prevents any accidental out of bounds.
-Oh yeah you can use absolute offsets to position screen objects out of the view range, which will cause the map-window to forcefully expand,
+We can use cardinal keywords like `NORTH` to anchor screen objects to the view size of the client (a topic that will be discussed soon).
+You can also use directional keywords like `TOP` to anchor to the actual visible map-window, which prevents any accidental out of bounds.
+Oh yeah you can use absolute offsets to position screen objects out of the view range, which will cause the map-window to forcefully expand,
exposing the parts of the map byond uses to ahead of time render border things so moving is smooth.
### Secondary Maps
While we're here, this is a bit of a side topic but you can have more then one map-window on a client's screen at once.
-This gets into dmf fuckery but you can use [window ids](https://www.byond.com/docs/ref/#/{skin}/param/id) to tell a screen object to render to a secondary map.
+This gets into dmf fuckery but you can use [window ids](https://www.byond.com/docs/ref/#/{skin}/param/id) to tell a screen object to render to a secondary map.
Useful for creating popup windows and such.
## Blend Mode
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/blend_mode)
+- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/blend_mode)
`/atom/var/blend_mode` defines how an atom well, renders onto the map.
@@ -280,7 +282,7 @@ This is how we do lighting effects, since the lighting [plane](#planes) can be u
## Appearance Flags
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/appearance_flags)
+- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/appearance_flags)
`/atom/var/appearance_flags` is a catch all for toggles that apply to visual elements of an atom.
I won't go over all of them, but I will discuss a few.
@@ -293,8 +295,8 @@ Flags of interest:
## Gliding
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/{notes}/gliding)
-
+- [Reference Entry](https://www.byond.com/docs/ref/#/{notes}/gliding)
+
You may have noticed that moving between tiles is smooth, or at least as close as we can get it.
Moving at 0.2 or 10 tiles per second will be smooth. This is because we have control over the speed at which atoms animate between moves.
@@ -306,37 +308,37 @@ This is done using `/atom/movable/proc/set_glide_size`, which will inform anythi
Glide size is often set in the context of some rate of movement. Either the movement delay of a mob, set in `/client/Move()`, or the delay of a movement subsystem.
We use defines to turn delays into pixels per tick.
-Client moves will be limited by `DELAY_TO_GLIDE_SIZE` which will allow at most 32 pixels a tick.
-Subsystems and other niche uses use `MOVEMENT_ADJUSTED_GLIDE_SIZE`.
-We will also occasionally use glide size as a way to force a transition between different movement types, like space-drift into normal walking.
+Client moves will be limited by `DELAY_TO_GLIDE_SIZE` which will allow at most 32 pixels a tick.
+Subsystems and other niche uses use `MOVEMENT_ADJUSTED_GLIDE_SIZE`.
+We will also occasionally use glide size as a way to force a transition between different movement types, like space-drift into normal walking.
There's extra cruft here.
-> Something you should know: Our gliding system attempts to account for time dilation when setting move rates.
+> Something you should know: Our gliding system attempts to account for time dilation when setting move rates.
This is done in a very simplistic way however, so a spike in td will lead to jumping around as glide rate is outpaced by mob movement rate.
-On that note, it is VERY important that glide rate is the same or near the same as actual move rate.
-Otherwise you will get strange jumping and jitter.
+On that note, it is VERY important that glide rate is the same or near the same as actual move rate.
+Otherwise you will get strange jumping and jitter.
This can also lead to stupid shit where people somehow manage to intentionally shorten a movement delay to jump around. Dumb.
Related to the above, we are not always able to maintain sync between glide rate and mob move rate.
-This is because mob move rate is a function of the initial move delay and a bunch of slowdown/speedup modifiers.
-In order to maintain sync we would need to issue a move command the MOMENT a delay is up, and if delays are not cleanly divisible by our tick rate (0.5 deciseconds) this is impossible.
+This is because mob move rate is a function of the initial move delay and a bunch of slowdown/speedup modifiers.
+In order to maintain sync we would need to issue a move command the MOMENT a delay is up, and if delays are not cleanly divisible by our tick rate (0.5 deciseconds) this is impossible.
This is why you'll sometime see a stutter in your step when slowed
Just so you know, client movement works off `/client/var/move_delay` which sets the next time an input will be accepted. It's typically glide rate, but is in some cases just 1 tick.
## Sight
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/mob/var/sight)
+- [Reference Entry](https://www.byond.com/docs/ref/#/mob/var/sight)
`/mob/var/sight` is a set of bitflags that *mostly* set what HAS to render on your screen. Be that mobs, turfs, etc.
That said, there is some nuance here so I'ma get into that.
-- `SEE_INFRA`: I'll get into this later, but infrared is essentially a copy of BYOND darkness, it's not something we currently use.
-- `SEE_BLACKNESS`: This relates heavily to [planes](#planes), essentially typically the "blackness" (that darkness that masks things that you can't see)
-is rendered separately, out of our control as "users".
+- `SEE_INFRA`: I'll get into this later, but infrared is essentially a copy of BYOND darkness, it's not something we currently use.
+- `SEE_BLACKNESS`: This relates heavily to [planes](#planes), essentially typically the "blackness" (that darkness that masks things that you can't see)
+is rendered separately, out of our control as "users".
However, if the `SEE_BLACKNESS` flag is set, it will instead render on plane 0, the default BYOND plane.
-This allows us to capture it, and say, blur it, or redraw it elsewhere. This is in theory very powerful, but not possible with the 'side_map' [map format](https://www.byond.com/docs/ref/#/world/var/map_format)
+This allows us to capture it, and say, blur it, or redraw it elsewhere. This is in theory very powerful, but not possible with the 'side_map' [map format](https://www.byond.com/docs/ref/#/world/var/map_format)
## BYOND Lighting
@@ -346,14 +348,14 @@ Alongside OUR lighting implementation, which is discussed in with color matrixes
It's very basic. Essentially, a tile is either "lit" or it's not.
-If a tile is not lit, and it matches some other preconditions, it and all its contents will be hidden from the user,
+If a tile is not lit, and it matches some other preconditions, it and all its contents will be hidden from the user,
sort of like if there was a wall between them. This hiding uses BYOND darkness, and is thus controllable.
I'll use this section to discuss all the little bits that contribute to this behavior
### Luminosity
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/luminosity)
+- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/luminosity)
`/atom/var/luminosity` is a variable that lets us inject light into BYOND's lighting system.
It's real simple, just a range of tiles that will be lit, respecting sight-lines and such of course.
@@ -363,16 +365,16 @@ You can actually force it to use a particular mob's sight to avoid aspects of th
### See in Dark
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/mob/var/see_in_dark)
+- [Reference Entry](https://www.byond.com/docs/ref/#/mob/var/see_in_dark)
This is why when you stand in darkness you can see yourself, and why you can see a line of objects appear when you use mesons (horrible effect btw).
It's quite simple, but worth describing.
### Infrared
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/mob/var/see_infrared)
+- [Reference Entry](https://www.byond.com/docs/ref/#/mob/var/see_infrared)
-Infrared vision can be thought of as a hidden copy of standard BYOND darkness.
+Infrared vision can be thought of as a hidden copy of standard BYOND darkness.
It's not something we actually use, but I think you should know about it, because the whole thing is real confusing without context.
## Invisibility
@@ -388,16 +390,16 @@ It's also used to hide some more then ghost invisible things, like some timers a
## Layers
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/layer)
+- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/layer)
-`/atom/var/layer` is the first bit of logic that decides the order in which things on the map render.
-Rendering order depends a LOT on the [map format](https://www.byond.com/docs/ref/#/world/var/map_format),
-which I will not get into in this document because it is not yet relevant.
-All you really need to know is for our current format,
-the objects that appear first in something's contents will draw first, and render lowest.
-Think of it like stacking little paper cutouts.
+`/atom/var/layer` is the first bit of logic that decides the order in which things on the map render.
+Rendering order depends a LOT on the [map format](https://www.byond.com/docs/ref/#/world/var/map_format),
+which I will not get into in this document because it is not yet relevant.
+All you really need to know is for our current format,
+the objects that appear first in something's contents will draw first, and render lowest.
+Think of it like stacking little paper cutouts.
-Layer has a bit more nuance then just being lowest to highest, tho it's not a lot.
+Layer has a bit more nuance then just being lowest to highest, tho it's not a lot.
There are a few snowflake layers that can be used to accomplish niche goals, alongside floating layers, which are essentially just any layer that is negative.
Floating layers will float "up" the chain of things they're being drawn onto, until they find a real layer. They'll then offset off of that.
@@ -406,7 +408,7 @@ This allows us to keep relative layer differences while not needing to make all
## Planes
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/plane)
+- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/plane)
Allllright `/atom/var/plane`s. Let's talk about em.
@@ -415,16 +417,16 @@ Higher planes will (**normally**) render over lower ones. Very clearcut.
Similarly to [layers](#layers), planes also support "floating" with `FLOAT_PLANE`. See above for an explanation of that.
-However, they can be used for more complex and... fun things too!
+However, they can be used for more complex and... fun things too!
If a client has an atom with the `PLANE_MASTER` [appearance flag](#appearance-flags) in their [screen](#client-screen),
then rather then being all rendered normally, anything in the client's view is instead first rendered onto the plane master.
-This is VERY powerful, because it lets us [hide](https://www.byond.com/docs/ref/#/atom/var/alpha), [color](#color),
+This is VERY powerful, because it lets us [hide](https://www.byond.com/docs/ref/#/atom/var/alpha), [color](#color),
and [distort](#filters) whole classes of objects, among other things.
I cannot emphasize enough how useful this is. It does have some downsides however.
Because planes are tied to both grouping and rendering order, there are some effects that require splitting a plane into bits.
-It's also possible for some effects, especially things relating to [map format](https://www.byond.com/docs/ref/#/world/var/map_format),
+It's also possible for some effects, especially things relating to [map format](https://www.byond.com/docs/ref/#/world/var/map_format),
to just be straight up impossible, or conflict with each other.
It's dumb, but it's what we've got brother so we're gonna use it like it's a free ticket to the bahamas.
@@ -432,15 +434,15 @@ We have a system that allows for arbitrary grouping of plane masters for the pur
called `/atom/movable/plane_master_controller`.
This is somewhat outmoded by our use of [render relays](#render-targetsource), but it's still valid and occasionally useful.
-> Something you should know: Plane masters effect ONLY the map their screen_loc is on.
+> Something you should know: Plane masters effect ONLY the map their screen_loc is on.
For this reason, we are forced to generate whole copies of the set of plane masters with the proper screen_loc to make subviews look right
-> Warning: Planes have some restrictions on valid values. They NEED to be whole integers, and they NEED to have an absolute value of `10000`.
+> Warning: Planes have some restrictions on valid values. They NEED to be whole integers, and they NEED to have an absolute value of `10000`.
This is to support `FLOAT_PLANE`, which lives out at the very edge of the 32 bit int range.
## Render Target/Source
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/render_target)
+- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/render_target)
Render targets are a way of rendering one thing onto another. Not like vis_contents but in a literal sense ONTO.
The target object is given a `/atom/var/render_target` value, and anything that wishes to "take" it sets its `/atom/var/render_source` var to match.
@@ -475,8 +477,8 @@ This meant the turf below looked as if it was offset, and everything was good.
Except not, for 2 reasons. One more annoying then the other.
- 1: It looked like dog doo-doo. This pattern destroyed the old planes of everything vis_contents'd, so effects/lighting/dropshadows broke bad.
-- 2: I alluded to this earlier, but it totally breaks the `side_map` [map format](https://www.byond.com/docs/ref/#/world/var/map_format)
-which I need for a massive resprite I'm helping with. This is because `side_map` changes how rendering order works,
+- 2: I alluded to this earlier, but it totally breaks the `side_map` [map format](https://www.byond.com/docs/ref/#/world/var/map_format)
+which I need for a massive resprite I'm helping with. This is because `side_map` changes how rendering order works,
going off "distance" from the front of the frame.
The issue here is it of course needs a way to group things that are even allowed to overlap, so it uses plane.
So when you squish everything down onto one plane, this of course breaks horribly and fucks you.
@@ -491,7 +493,7 @@ to the openspace plane master one level up. More then doable.
SECOND problem. How do we get everything below to "land" on the right plane?
The answer to this is depressing but still true. We manually offset every single object on the map's plane based off its "z layer".
-This includes any `overlays` or `vis_contents` with a unique plane value.
+This includes any `overlays` or `vis_contents` with a unique plane value.
Mostly we require anything that sets the plane var to pass in a source of context, like a turf or something that can be used to derive a turf.
There are a few edge cases where we need to work in explicitly offsets, but those are much rarer.
@@ -500,18 +502,18 @@ This is stupid, but it's makable, and what we do.
## Mouse Opacity
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/mouse_opacity)
+- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/mouse_opacity)
`/atom/var/mouse_opacity` tells clients how to treat mousing over the atom in question.
A value of 0 means it is completely ignored, no matter what.
A value of 1 means it is transparent/opaque based off the alpha of the icon at any particular part.
-A value of 2 means it will count as opaque across ALL of the icon-state. All 32x32 (or whatever) of it.
+A value of 2 means it will count as opaque across ALL of the icon-state. All 32x32 (or whatever) of it.
-We will on occasion use mouse opacity to expand hitboxes, but more often this is done with [vis_contents](#visual-contents),
+We will on occasion use mouse opacity to expand hitboxes, but more often this is done with [vis_contents](#visual-contents),
or just low alpha pixels on the sprite.
-> Note: Mouse opacity will only matter if the atom is being rendered on its own. [Overlays](#overlays)(and [images](#images))
+> Note: Mouse opacity will only matter if the atom is being rendered on its own. [Overlays](#overlays)(and [images](#images))
will NOT work as expected with this.
However, you can still have totally transparent overlays. If you render them onto a [plane master](#planes) with the desired mouse opacity value
it will work as expected. This is because as a step of the rendering pipeline the overlay is rendered ONTO the plane master, and then the plane
@@ -519,10 +521,10 @@ master's effects are applied.
## Filters
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/{notes}/filters)
+- [Reference Entry](https://www.byond.com/docs/ref/#/{notes}/filters)
Filters are a general purpose system for applying a limited set of shaders to a render.
-These shaders run on the client's machine. This has upsides and downsides.
+These shaders run on the client's machine. This has upsides and downsides.
Upside: Very cheap for the server. Downside: Potentially quite laggy for the client.
Take care with these
@@ -544,7 +546,7 @@ It'll let you add and tweak *most* of the filters in BYOND.
## Particles
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/{notes}/particles)
+- [Reference Entry](https://www.byond.com/docs/ref/#/{notes}/particles)
Particles are a system that allows you to attach "generators" to atoms on the world, and have them spit out little visual effects.
This is done by creating a subtype of the `/particles` type, and giving it the values you want.
@@ -558,7 +560,7 @@ It'll let you add and tweak the particles attached to that atom.
## Pixel Offsets
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/pixel_x)
+- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/pixel_x)
This is a real simple idea and I normally wouldn't mention it, but I have something else I wanna discuss related to it, so I'ma take this chance.
@@ -571,7 +573,7 @@ There are two "types" of each direction offset. There's the "real" offset (x/y)
Real offsets will change both the visual position (IE: where it renders) and also the positional position (IE: where the renderer thinks they are).
Fake offsets only effect visual position.
-This doesn't really matter for our current map format, but for anything that takes position into account when layering, like `side_map` or `isometric_map`
+This doesn't really matter for our current map format, but for anything that takes position into account when layering, like `side_map` or `isometric_map`
it matters a whole ton. It's kinda a hard idea to get across, but I hope you have at least some idea.
## Map Formats
@@ -585,10 +587,10 @@ There are 4 types currently. Only 2 that are interesting to us, and one that's n
Most of them involve changing how layering works, from the standard [layers](#layers) and [planes](#planes) method.
There's a bit more detail here, not gonna go into it, stuff like [underlays](https://www.byond.com/docs/ref/#/atom/var/underlays) drawing under things. See [Understanding The Renderer](https://www.byond.com/docs/ref/#/{notes}/renderer)
-> There is very technically more nuance here.
+> There is very technically more nuance here.
> In default rendering modes, byond will conflict break by using the thing that is highest in the contents list of its location. Or lowest. Don't remember.
-### [`TOPDOWN_MAP`](https://www.byond.com/docs/ref/#/{notes}/topdown)
+### [`TOPDOWN_MAP`](https://www.byond.com/docs/ref/#/{notes}/topdown)
This is the default rendering format. What we used to use. It tells byond to render going off [plane](#planes) first, then [layer](#layers). There's a few edgecases involving big icons, but it's small peanuts.
@@ -604,7 +606,7 @@ The idea is the closer to the front of the screen something is, the higher its l
`pixel_y` + `y` tell the engine where something "is".
`/atom/var/bound_width`, `/atom/var/bound_height` and `/atom/var/bound_x/y` describe how big it is, which lets us in theory control what it tries to layer "against".
-I'm not bothering with reference links because they are entirely unrelated.
+I'm not bothering with reference links because they are entirely unrelated.
An issue that will crop up with this map format is needing to manage the "visual" (how/where it renders) and physical (where it is in game) aspects of position and size.
Physical position tells the renderer how to layer things. Visual position and a combination of physical bounds (manually set) and visual bounds (inferred from other aspects of it. Sprite width/height, physical bounds, transforms, filters, etc) tell it what the sprite might be rendering OVER.
@@ -645,28 +647,28 @@ One more thing. Big icons are fucked
From the byond reference
>If you use an icon wider than one tile, the "footprint" of the isometric icon (the actual map tiles it takes up) will always be a square. That is, if your normal tile size is 64 and you want to show a 128x128 icon, the icon is two tiles wide and so it will take up a 2×2-tile area on the map. The height of a big icon is irrelevant--any excess height beyond width/2 is used to show vertical features. To draw this icon properly, other tiles on that same ground will be moved behind it in the drawing order.
-> One important warning about using big icons in isometric mode is that you should only do this with dense atoms. If part of a big mob icon covers the same tile as a tall building for instance, the tall building is moved back and it could be partially covered by other turfs that are actually behind it. A mob walking onto a very large non-dense turf icon would experience similar irregularities.
+> One important warning about using big icons in isometric mode is that you should only do this with dense atoms. If part of a big mob icon covers the same tile as a tall building for instance, the tall building is moved back and it could be partially covered by other turfs that are actually behind it. A mob walking onto a very large non-dense turf icon would experience similar irregularities.
These can cause very annoying flickering. In fact, MUCH of how rendering works causes flickering. This is because we don't decide on a pixel by pixel case, the engine groups sprites up into a sort of rendering stack, unable to split them up.
-This combined with us being unable to modify bounds means that if one bit of the view is conflicting.
+This combined with us being unable to modify bounds means that if one bit of the view is conflicting.
If A wants to be above B and below C, but B wants to be below A and above C, we'll be unable to resolve the rendering properly, leading to flickering depending on other aspects of the layering.
This can just sort of spread. Very hard to debug.
-### [`ISOMETRIC_MAP`](https://www.byond.com/docs/ref/#/{notes}/isometric)
-
+### [`ISOMETRIC_MAP`](https://www.byond.com/docs/ref/#/{notes}/isometric)
+
Isometric mode, renders everything well, isometrically, biased to the north east. This gives the possibility for fake 3d, assuming you get things drawn properly.
It will render things in the foreground "last", after things in the background. This is the right way of thinking about it, it's not rendering things above or below, but in a layering order.
This is interesting mostly in the context of understanding [side map](#side_map-check-the-main-page-too), but we did actually run an isometric station for april fools once.
It was really cursed and flickered like crazy (which causes client lag). Fun as hell though.
-The mode essentially overrides the layer/plane layering discussed before, and inserts new rules.
-I wish I knew what those rules EXACTLY are, but I'm betting they're similar to [side map's](#side_map-check-the-main-page-too), and lummy's actually told me those.
+The mode essentially overrides the layer/plane layering discussed before, and inserts new rules.
+I wish I knew what those rules EXACTLY are, but I'm betting they're similar to [side map's](#side_map-check-the-main-page-too), and lummy's actually told me those.
Yes this is all rather poorly documented.
Similar to sidemap, we take physical position into account when deciding layering. In addition to its height positioning, we also account for width.
-So both `pixel_y` and `pixel_x` can effect layering. `pixel_z` handles strictly visual y, and `pixel_w` handles x.
+So both `pixel_y` and `pixel_x` can effect layering. `pixel_z` handles strictly visual y, and `pixel_w` handles x.
This has similar big icon problems to [sidemap](#side_map-check-the-main-page-too).
@@ -677,14 +679,14 @@ it would be automatically broken down into smaller icon states, which you would
## Color
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/color)
+- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/color)
`/atom/var/color` is another one like [pixel offsets](#pixel-offsets) where its most common use is really uninteresting, but it has an interesting
edge case I think is fun to discuss/important to know.
So let's get the base case out of the way shall we?
-At base, you can set an atom's color to some `rrggbbaa` string (see [here](https://www.byond.com/docs/ref/#/{{appendix}}/html-colors)). This will shade every pixel on that atom to said color, and override its [`/atom/var/alpha`](https://www.byond.com/docs/ref/#/atom/var/alpha) value.
+At base, you can set an atom's color to some `rrggbbaa` string (see [here](https://www.byond.com/docs/ref/#/{{appendix}}/html-colors)). This will shade every pixel on that atom to said color, and override its [`/atom/var/alpha`](https://www.byond.com/docs/ref/#/atom/var/alpha) value.
See [appearance flags](#appearance-flags) for how this effect can carry into overlays and such.
That's the boring stuff, now the fun shit.
@@ -703,7 +705,7 @@ It'll help visualize this process quite well. Play around with it, it's fun.
## Transform
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/transform)
+- [Reference Entry](https://www.byond.com/docs/ref/#/atom/var/transform)
`/atom/var/transform` allows you to shift, contort, rotate and scale atoms visually.
This is done using a matrix, similarly to color matrixes. You will likely never need to use it manually however, since there are
@@ -730,17 +732,17 @@ and forget to update this file.
## Animate()
- [Table of Contents](#table-of-contents)
-- [Reference Entry](https://www.byond.com/docs/ref/#/proc/animate)
+- [Reference Entry](https://www.byond.com/docs/ref/#/proc/animate)
The animate proc allows us to VISUALLY transition between different values on an appearance on clients, while in actuality
setting the values instantly on the servers.
This is quite powerful, and lets us do many things, like slow fades, shakes, hell even parallax using matrixes.
-It doesn't support everything, and it can be quite temperamental especially if you use things like the flag that makes it work in
+It doesn't support everything, and it can be quite temperamental especially if you use things like the flag that makes it work in
parallel. It's got a lot of nuance to it, but it's real useful. Works on filters and their variables too, which is AGGRESSIVELY useful.
-Lets you give radiation glow a warm pulse, that sort of thing.
+Lets you give radiation glow a warm pulse, that sort of thing.
## GAGS
- [Table of Contents](#table-of-contents)
diff --git a/_maps/deathmatch/ragin_mages.dmm b/_maps/deathmatch/ragin_mages.dmm
new file mode 100644
index 00000000000..37939643b72
--- /dev/null
+++ b/_maps/deathmatch/ragin_mages.dmm
@@ -0,0 +1,1880 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"ay" = (
+/obj/structure/railing/corner/end{
+ dir = 4
+ },
+/obj/machinery/door/airlock/wood,
+/obj/structure/railing/corner/end/flip{
+ dir = 4
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"aT" = (
+/obj/item/cardboard_cutout/adaptive{
+ pixel_y = 14;
+ pixel_x = 8
+ },
+/obj/effect/decal/cleanable/cobweb,
+/obj/effect/decal/cleanable/dirt/dust,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"bb" = (
+/obj/structure/chair/wood/wings{
+ dir = 8
+ },
+/obj/effect/light_emitter{
+ set_cap = 2;
+ light_color = "#DEEFFF";
+ set_luminosity = 4
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"bg" = (
+/obj/effect/spawner/random/entertainment/arcade,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"bv" = (
+/obj/machinery/power/shuttle_engine/propulsion,
+/turf/open/floor/plating/airless,
+/area/deathmatch/teleport)
+"co" = (
+/obj/structure/table/reinforced,
+/obj/item/paper_bin/carbon{
+ pixel_y = 12;
+ pixel_x = 7
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"ct" = (
+/obj/structure/flora/bush/grassy/style_random,
+/mob/living/simple_animal/pet/gondola{
+ name = "Jommy";
+ faction = list("gondola", "Wizard")
+ },
+/turf/open/floor/grass,
+/area/deathmatch/teleport)
+"cU" = (
+/obj/structure/chair/wood/wings{
+ dir = 1
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"dj" = (
+/obj/machinery/door/airlock/wood,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"ds" = (
+/turf/open/floor/carpet/purple,
+/area/deathmatch/teleport)
+"ez" = (
+/obj/structure/closet/crate,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"fH" = (
+/obj/effect/turf_decal/tile/bar/opposingcorners,
+/obj/machinery/griddle,
+/obj/item/food/burger/spell{
+ pixel_y = 11;
+ pixel_x = -3
+ },
+/obj/item/stack/medical/ointment{
+ pixel_y = -2;
+ pixel_x = 9
+ },
+/turf/open/floor/iron,
+/area/deathmatch/teleport)
+"fI" = (
+/turf/open/lava,
+/area/deathmatch/teleport)
+"gn" = (
+/obj/effect/spawner/structure/window/reinforced,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"gr" = (
+/obj/effect/turf_decal/tile/bar/opposingcorners,
+/obj/structure/chair/wood,
+/turf/open/floor/iron,
+/area/deathmatch/teleport)
+"hg" = (
+/obj/structure/railing/corner/end/flip{
+ dir = 8
+ },
+/obj/machinery/door/airlock/wood,
+/obj/structure/railing/corner/end{
+ dir = 8
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"hk" = (
+/obj/item/kirbyplants/organic/plant10{
+ pixel_y = 21;
+ pixel_x = -7
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"hK" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/light_emitter{
+ set_cap = 2;
+ light_color = "#DEEFFF";
+ set_luminosity = 4
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"ig" = (
+/obj/structure/table/wood,
+/obj/item/stack/medical/bruise_pack{
+ pixel_x = -12
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"iz" = (
+/obj/structure/chair/comfy/brown{
+ dir = 1
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"iL" = (
+/obj/effect/light_emitter{
+ set_cap = 2;
+ light_color = "#DEEFFF";
+ set_luminosity = 4
+ },
+/turf/open/floor/carpet/red,
+/area/deathmatch/teleport)
+"iQ" = (
+/obj/structure/table,
+/obj/structure/bedsheetbin{
+ pixel_y = 4;
+ pixel_x = 3
+ },
+/turf/open/floor/plastic,
+/area/deathmatch/teleport)
+"iZ" = (
+/obj/effect/turf_decal/tile/bar/opposingcorners,
+/obj/structure/sink/directional/west,
+/turf/open/floor/iron,
+/area/deathmatch/teleport)
+"jb" = (
+/obj/machinery/door/airlock/wood,
+/obj/structure/railing/corner/end/flip,
+/obj/structure/railing/corner/end,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"jg" = (
+/obj/effect/turf_decal/tile/bar/opposingcorners,
+/obj/effect/landmark/deathmatch_player_spawn,
+/turf/open/floor/iron,
+/area/deathmatch/teleport)
+"jm" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/structure/mystery_box/wands,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"js" = (
+/obj/effect/turf_decal/tile/bar/opposingcorners,
+/turf/open/floor/iron,
+/area/deathmatch/teleport)
+"jM" = (
+/obj/structure/table/reinforced,
+/obj/effect/decal/cleanable/dirt/dust,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"jV" = (
+/obj/effect/turf_decal/tile/bar/opposingcorners,
+/obj/machinery/door/airlock/wood,
+/turf/open/floor/iron,
+/area/deathmatch/teleport)
+"kl" = (
+/obj/structure/flora/bush/grassy/style_random,
+/obj/machinery/light/floor,
+/obj/effect/light_emitter{
+ set_cap = 2;
+ light_color = "#DEEFFF";
+ set_luminosity = 4
+ },
+/turf/open/floor/grass,
+/area/deathmatch/teleport)
+"li" = (
+/obj/structure/table,
+/obj/item/extinguisher{
+ pixel_x = 7;
+ pixel_y = -6
+ },
+/obj/item/clothing/suit/wizrobe/red{
+ pixel_y = 3;
+ pixel_x = -6
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"lM" = (
+/obj/structure/bed{
+ dir = 1
+ },
+/obj/item/bedsheet/wiz{
+ dir = 1
+ },
+/obj/effect/light_emitter{
+ set_cap = 2;
+ light_color = "#DEEFFF";
+ set_luminosity = 4
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"lO" = (
+/obj/structure/closet/crate,
+/obj/effect/decal/cleanable/dirt/dust,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"mu" = (
+/obj/effect/turf_decal/stripes,
+/obj/structure/railing{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/deathmatch/teleport)
+"mV" = (
+/obj/structure/railing{
+ dir = 4
+ },
+/obj/structure/railing{
+ dir = 8
+ },
+/obj/structure/mystery_box/tdome,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"nk" = (
+/obj/item/gun/magic/wand/death,
+/obj/structure/window/reinforced/plasma/spawner/directional/east,
+/obj/structure/window/reinforced/plasma/spawner/directional/north,
+/obj/structure/window/reinforced/plasma/spawner/directional/west,
+/turf/open/floor/grass,
+/area/deathmatch/teleport)
+"nx" = (
+/obj/effect/landmark/deathmatch_player_spawn,
+/turf/open/floor/carpet/red,
+/area/deathmatch/teleport)
+"nQ" = (
+/obj/machinery/door/airlock/wood,
+/turf/open/floor/plastic,
+/area/deathmatch/teleport)
+"on" = (
+/obj/structure/table/wood,
+/turf/open/floor/carpet/red,
+/area/deathmatch/teleport)
+"oP" = (
+/obj/structure/destructible/cult/item_dispenser/archives/library,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"pe" = (
+/obj/item/kirbyplants/organic/plant10{
+ pixel_y = 21;
+ pixel_x = -7
+ },
+/turf/open/floor/carpet/red,
+/area/deathmatch/teleport)
+"ph" = (
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"pv" = (
+/obj/effect/light_emitter{
+ set_cap = 2;
+ light_color = "#DEEFFF";
+ set_luminosity = 4
+ },
+/turf/open/floor/iron,
+/area/deathmatch/teleport)
+"pL" = (
+/obj/effect/turf_decal/stripes{
+ dir = 1
+ },
+/obj/structure/mystery_box/wands,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"pV" = (
+/obj/structure/flora/bush/flowers_br/style_random,
+/turf/open/floor/grass,
+/area/deathmatch/teleport)
+"qx" = (
+/obj/effect/light_emitter{
+ set_cap = 2;
+ light_color = "#DEEFFF";
+ set_luminosity = 4
+ },
+/turf/open/floor/carpet/purple,
+/area/deathmatch/teleport)
+"qY" = (
+/obj/structure/closet/crate/bin,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"rj" = (
+/obj/machinery/door/window/right/directional/east,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"rD" = (
+/obj/structure/railing{
+ dir = 4
+ },
+/obj/structure/railing{
+ dir = 8
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"sf" = (
+/obj/structure/mirror/directional/east,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"tL" = (
+/obj/structure/flora/bush/fullgrass/style_random,
+/mob/living/simple_animal/hostile/ooze/gelatinous{
+ name = "Jimmy";
+ faction = list("slime", "Wizard")
+ },
+/turf/open/floor/grass,
+/area/deathmatch/teleport)
+"ue" = (
+/obj/effect/turf_decal/tile/bar/opposingcorners,
+/obj/item/food/burger/yellow{
+ pixel_x = -11;
+ pixel_y = 8
+ },
+/obj/item/food/burger/red{
+ pixel_y = 13;
+ pixel_x = 6
+ },
+/obj/item/food/burger/purple{
+ pixel_y = 3
+ },
+/obj/structure/table/reinforced,
+/turf/open/floor/iron,
+/area/deathmatch/teleport)
+"ui" = (
+/obj/effect/turf_decal/stripes,
+/turf/open/floor/iron,
+/area/deathmatch/teleport)
+"uz" = (
+/turf/open/floor/iron,
+/area/deathmatch/teleport)
+"uR" = (
+/obj/item/clothing/shoes/sandal/magic{
+ pixel_y = 16
+ },
+/obj/effect/light_emitter{
+ set_cap = 2;
+ light_color = "#DEEFFF";
+ set_luminosity = 4
+ },
+/turf/open/floor/plastic,
+/area/deathmatch/teleport)
+"vh" = (
+/obj/structure/mystery_box/wands,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"vv" = (
+/obj/vehicle/ridden/scooter/skateboard{
+ dir = 4
+ },
+/obj/effect/decal/cleanable/dirt/dust,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"vR" = (
+/obj/structure/bookcase/random,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"wd" = (
+/obj/effect/turf_decal/tile/bar/opposingcorners,
+/obj/structure/mystery_box/wands,
+/turf/open/floor/iron,
+/area/deathmatch/teleport)
+"wl" = (
+/obj/item/kirbyplants/organic/plant10{
+ pixel_y = 1;
+ pixel_x = -6
+ },
+/turf/open/floor/carpet/purple,
+/area/deathmatch/teleport)
+"wL" = (
+/obj/effect/turf_decal/tile/bar/opposingcorners,
+/obj/machinery/gibber/autogibber,
+/turf/open/floor/iron,
+/area/deathmatch/teleport)
+"xk" = (
+/obj/structure/sink/directional/south,
+/obj/structure/mirror/directional/north{
+ pixel_y = 36
+ },
+/turf/open/floor/plastic,
+/area/deathmatch/teleport)
+"xs" = (
+/obj/structure/flora/bush/grassy/style_random,
+/turf/open/floor/grass,
+/area/deathmatch/teleport)
+"yA" = (
+/obj/structure/chair/wood/wings,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"zN" = (
+/obj/structure/mystery_box/wands,
+/obj/structure/sign/poster/contraband/the_big_gas_giant_truth/directional/north,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"zO" = (
+/obj/structure/closet,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"Au" = (
+/obj/structure/railing{
+ dir = 4
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"AD" = (
+/obj/structure/sign/departments/restroom/directional/west,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"Bm" = (
+/obj/effect/landmark/deathmatch_player_spawn,
+/turf/open/floor/plastic,
+/area/deathmatch/teleport)
+"Cb" = (
+/obj/effect/turf_decal/tile/bar/opposingcorners,
+/obj/structure/table/wood,
+/turf/open/floor/iron,
+/area/deathmatch/teleport)
+"Cj" = (
+/obj/structure/table,
+/obj/item/clothing/ears/earmuffs{
+ pixel_y = 14;
+ pixel_x = 4
+ },
+/obj/item/toy/gun{
+ pixel_y = 2;
+ pixel_x = -3
+ },
+/obj/item/clothing/head/wizard/red{
+ pixel_x = 6;
+ pixel_y = -10
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"Cq" = (
+/turf/open/floor/carpet/red,
+/area/deathmatch/teleport)
+"CM" = (
+/obj/structure/railing/corner,
+/obj/structure/railing/corner{
+ dir = 8
+ },
+/obj/structure/railing/corner{
+ dir = 4
+ },
+/obj/structure/railing/corner{
+ dir = 1
+ },
+/obj/effect/light_emitter{
+ set_cap = 2;
+ light_color = "#DEEFFF";
+ set_luminosity = 4
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"DK" = (
+/obj/structure/railing{
+ dir = 8
+ },
+/obj/structure/railing{
+ dir = 8
+ },
+/obj/structure/railing{
+ dir = 4
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"DW" = (
+/obj/machinery/computer,
+/turf/open/floor/carpet/red,
+/area/deathmatch/teleport)
+"Eh" = (
+/obj/effect/light_emitter{
+ set_cap = 2;
+ light_color = "#DEEFFF";
+ set_luminosity = 4
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"Fb" = (
+/obj/effect/turf_decal/stripes{
+ dir = 1
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"Fm" = (
+/obj/structure/chair/comfy/black{
+ dir = 1
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"Fv" = (
+/obj/structure/chair/wood/wings{
+ dir = 4
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"Fx" = (
+/obj/item/target,
+/obj/structure/sign/flag/nanotrasen/directional/north,
+/turf/open/floor/iron,
+/area/deathmatch/teleport)
+"FL" = (
+/turf/open/floor/plastic,
+/area/deathmatch/teleport)
+"Ge" = (
+/obj/item/flashlight/flare{
+ pixel_x = -5;
+ pixel_y = -12
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"Gv" = (
+/obj/item/kirbyplants/organic/plant10{
+ pixel_y = 2;
+ pixel_x = 5
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"GC" = (
+/obj/effect/spawner/structure/window,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"GZ" = (
+/obj/structure/curtain,
+/obj/machinery/shower/directional/north,
+/obj/item/soap/syndie,
+/turf/open/floor/noslip,
+/area/deathmatch/teleport)
+"Hf" = (
+/obj/item/kirbyplants/organic/plant10{
+ pixel_y = 1;
+ pixel_x = -6
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"Hs" = (
+/turf/template_noop,
+/area/template_noop)
+"HM" = (
+/obj/structure/rack,
+/obj/item/knife/ritual{
+ pixel_y = 5
+ },
+/obj/item/staff{
+ pixel_x = -4;
+ pixel_y = 4
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"HP" = (
+/obj/structure/chair/comfy/black{
+ dir = 1
+ },
+/turf/open/floor/carpet/red,
+/area/deathmatch/teleport)
+"HS" = (
+/obj/structure/table/wood/fancy,
+/turf/open/floor/plastic,
+/area/deathmatch/teleport)
+"IE" = (
+/obj/structure/table/wood,
+/obj/item/clothing/suit/wizrobe/black{
+ pixel_y = 3;
+ pixel_x = -1
+ },
+/obj/item/clothing/head/wizard/black{
+ pixel_y = 13;
+ pixel_x = 6
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"IM" = (
+/obj/item/kirbyplants/organic/plant10{
+ pixel_y = 2;
+ pixel_x = 5
+ },
+/turf/open/floor/carpet/purple,
+/area/deathmatch/teleport)
+"Jm" = (
+/turf/closed/wall/mineral/wood,
+/area/deathmatch/teleport)
+"Jo" = (
+/obj/structure/toilet{
+ dir = 4
+ },
+/turf/open/floor/plastic,
+/area/deathmatch/teleport)
+"Kr" = (
+/obj/effect/landmark/deathmatch_player_spawn,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"KW" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"Le" = (
+/obj/structure/filingcabinet,
+/obj/effect/decal/cleanable/dirt/dust,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"Mg" = (
+/obj/machinery/computer,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"Nl" = (
+/obj/machinery/power/shuttle_engine/heater{
+ resistance_flags = 3
+ },
+/obj/structure/window/reinforced/spawner/directional/north{
+ resistance_flags = 3
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"Nm" = (
+/obj/item/kirbyplants/organic/plant10{
+ pixel_y = 21;
+ pixel_x = 6
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"Nt" = (
+/obj/item/target{
+ pixel_y = 11
+ },
+/obj/effect/turf_decal/stripes,
+/turf/open/floor/iron,
+/area/deathmatch/teleport)
+"NW" = (
+/obj/structure/railing{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes{
+ dir = 1
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"Ok" = (
+/obj/machinery/vending/cigarette,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"OD" = (
+/obj/structure/filingcabinet,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"OK" = (
+/obj/item/kirbyplants/organic/plant10{
+ pixel_y = 21;
+ pixel_x = 6
+ },
+/turf/open/floor/carpet/red,
+/area/deathmatch/teleport)
+"PD" = (
+/obj/structure/table/wood,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"Qj" = (
+/obj/structure/dresser,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"QH" = (
+/obj/structure/table,
+/obj/item/clothing/head/wizard{
+ pixel_y = 14;
+ pixel_x = 4
+ },
+/turf/open/floor/plastic,
+/area/deathmatch/teleport)
+"QT" = (
+/obj/structure/mystery_box/wands,
+/turf/open/floor/plastic,
+/area/deathmatch/teleport)
+"RB" = (
+/obj/machinery/vending/snack,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"RI" = (
+/obj/effect/decal/cleanable/cobweb,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"RT" = (
+/obj/machinery/power/shuttle_engine/heater{
+ resistance_flags = 3
+ },
+/obj/structure/window/reinforced/spawner/directional/north{
+ resistance_flags = 3
+ },
+/turf/open/lava,
+/area/deathmatch/teleport)
+"Sa" = (
+/turf/open/floor/grass,
+/area/deathmatch/teleport)
+"SK" = (
+/obj/structure/flora/bush/fullgrass/style_random,
+/turf/open/floor/grass,
+/area/deathmatch/teleport)
+"Th" = (
+/obj/effect/turf_decal/tile/bar/opposingcorners,
+/obj/structure/table/reinforced,
+/obj/item/food/burger/rat{
+ pixel_y = 9;
+ pixel_x = -2
+ },
+/obj/item/food/bun{
+ pixel_x = 8;
+ pixel_y = 2
+ },
+/obj/effect/light_emitter{
+ set_cap = 2;
+ light_color = "#DEEFFF";
+ set_luminosity = 4
+ },
+/turf/open/floor/iron,
+/area/deathmatch/teleport)
+"Vk" = (
+/obj/machinery/door/window/left/directional/east,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"VM" = (
+/obj/structure/table/wood/poker,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"Wl" = (
+/obj/structure/railing{
+ dir = 4
+ },
+/obj/effect/light_emitter{
+ set_cap = 2;
+ light_color = "#DEEFFF";
+ set_luminosity = 4
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"WX" = (
+/obj/machinery/vending/magivend,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"Xv" = (
+/obj/structure/railing{
+ layer = 3.1
+ },
+/obj/structure/railing{
+ layer = 3.1;
+ dir = 1
+ },
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"YP" = (
+/obj/structure/closet/crate/coffin,
+/obj/effect/decal/cleanable/cobweb/cobweb2,
+/obj/effect/decal/cleanable/dirt/dust,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"YS" = (
+/obj/effect/decal/cleanable/cobweb,
+/obj/effect/decal/cleanable/dirt/dust,
+/turf/open/floor/engine/cult,
+/area/deathmatch/teleport)
+"Zo" = (
+/obj/structure/flora/bush/flowers_pp/style_random,
+/turf/open/floor/grass,
+/area/deathmatch/teleport)
+"ZS" = (
+/obj/structure/railing/corner/end/flip,
+/turf/open/floor/iron,
+/area/deathmatch/teleport)
+
+(1,1,1) = {"
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+"}
+(2,1,1) = {"
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+"}
+(3,1,1) = {"
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+"}
+(4,1,1) = {"
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+"}
+(5,1,1) = {"
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Jm
+Jm
+Jm
+Jm
+Jm
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+"}
+(6,1,1) = {"
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Jm
+Jm
+vR
+lM
+Qj
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Hs
+Hs
+Hs
+Hs
+"}
+(7,1,1) = {"
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Jm
+Jm
+vR
+ph
+ph
+ph
+Jm
+QT
+Jo
+HS
+iQ
+GZ
+Jm
+Fx
+uz
+ui
+Fb
+ph
+ph
+ph
+ph
+RT
+bv
+Hs
+Hs
+Hs
+"}
+(8,1,1) = {"
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+gn
+PD
+iz
+ph
+ph
+ph
+dj
+FL
+FL
+Bm
+QH
+uR
+Jm
+Fx
+pv
+Nt
+Fb
+Kr
+ph
+Eh
+ph
+RT
+bv
+Hs
+Hs
+Hs
+"}
+(9,1,1) = {"
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+gn
+ig
+ph
+Kr
+qY
+Jm
+Jm
+Jm
+Jm
+xk
+FL
+FL
+Jm
+Fx
+ZS
+mu
+NW
+Wl
+Au
+Vk
+rj
+RT
+bv
+Hs
+Hs
+Hs
+"}
+(10,1,1) = {"
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Jm
+HM
+ph
+Eh
+Jm
+Jm
+qx
+wl
+Jm
+Jm
+nQ
+Jm
+Jm
+dj
+Jm
+Jm
+pL
+ph
+ph
+ph
+Gv
+Jm
+Hs
+Hs
+Hs
+Hs
+"}
+(11,1,1) = {"
+Hs
+Hs
+Hs
+gn
+gn
+gn
+Jm
+zN
+ph
+ph
+Jm
+WX
+ds
+ds
+Hf
+Jm
+ph
+AD
+Eh
+ph
+vR
+Jm
+Jm
+Cj
+li
+ph
+Jm
+Jm
+Hs
+Hs
+Hs
+Hs
+"}
+(12,1,1) = {"
+Hs
+Hs
+gn
+gn
+IE
+PD
+Jm
+oP
+ph
+ph
+dj
+ph
+ds
+ds
+ph
+dj
+ph
+ph
+ph
+ph
+ph
+vR
+Jm
+Jm
+Jm
+ay
+Jm
+Hs
+Hs
+Hs
+Hs
+Hs
+"}
+(13,1,1) = {"
+Hs
+Hs
+gn
+Mg
+Fm
+Hf
+Jm
+Jm
+sf
+Gv
+Jm
+vR
+ds
+ds
+ph
+Jm
+Jm
+Jm
+Jm
+Nm
+ph
+ph
+vR
+Jm
+fI
+Xv
+Jm
+Jm
+Hs
+Hs
+Hs
+Hs
+"}
+(14,1,1) = {"
+Hs
+Hs
+gn
+Mg
+ph
+ph
+vh
+Jm
+Jm
+Jm
+Jm
+vR
+ds
+ds
+ph
+Jm
+xs
+tL
+Jm
+Jm
+ph
+ph
+vR
+Jm
+fI
+Xv
+fI
+Jm
+Jm
+Hs
+Hs
+Hs
+"}
+(15,1,1) = {"
+Hs
+Hs
+gn
+on
+Cq
+Cq
+Cq
+Cq
+Cq
+Cq
+Cq
+Cq
+ds
+ds
+Cq
+GC
+Zo
+Sa
+xs
+Jm
+OK
+Cq
+Cq
+Jm
+fI
+Xv
+fI
+fI
+RT
+bv
+Hs
+Hs
+"}
+(16,1,1) = {"
+Hs
+Hs
+gn
+DW
+HP
+iL
+nx
+Cq
+Cq
+Cq
+iL
+Cq
+ds
+ds
+Cq
+GC
+Sa
+kl
+nk
+Jm
+nx
+iL
+Cq
+jb
+DK
+CM
+rD
+mV
+Nl
+bv
+Hs
+Hs
+"}
+(17,1,1) = {"
+Hs
+Hs
+gn
+on
+Cq
+Cq
+Cq
+Cq
+Cq
+Cq
+Cq
+Cq
+ds
+ds
+Cq
+GC
+Sa
+pV
+SK
+Jm
+pe
+Cq
+Cq
+Jm
+fI
+Xv
+fI
+fI
+RT
+bv
+Hs
+Hs
+"}
+(18,1,1) = {"
+Hs
+Hs
+gn
+Mg
+ph
+ph
+Ok
+Jm
+Jm
+Jm
+Jm
+vR
+ds
+ds
+ph
+Jm
+SK
+ct
+Jm
+Jm
+ph
+ph
+vR
+Jm
+fI
+Xv
+fI
+Jm
+Jm
+Hs
+Hs
+Hs
+"}
+(19,1,1) = {"
+Hs
+Hs
+gn
+Mg
+Fm
+Gv
+Jm
+Jm
+PD
+vh
+Jm
+vR
+ds
+ds
+ph
+Jm
+Jm
+Jm
+Jm
+hk
+ph
+ph
+vR
+Jm
+fI
+Xv
+Jm
+Jm
+Hs
+Hs
+Hs
+Hs
+"}
+(20,1,1) = {"
+Hs
+Hs
+gn
+gn
+PD
+PD
+Jm
+PD
+ph
+ph
+dj
+ph
+ds
+ds
+ph
+dj
+ph
+ph
+ph
+ph
+ph
+vR
+Jm
+Jm
+Jm
+hg
+Jm
+Hs
+Hs
+Hs
+Hs
+Hs
+"}
+(21,1,1) = {"
+Hs
+Hs
+Hs
+gn
+gn
+gn
+Jm
+PD
+ph
+ph
+Jm
+RB
+ds
+ds
+Gv
+Jm
+ph
+ph
+Eh
+ph
+vh
+Jm
+Jm
+YS
+KW
+Ge
+Jm
+Jm
+Hs
+Hs
+Hs
+Hs
+"}
+(22,1,1) = {"
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Jm
+PD
+ph
+Eh
+Jm
+Jm
+qx
+IM
+Jm
+Jm
+jV
+Jm
+Jm
+dj
+Jm
+Jm
+RI
+ph
+vR
+ph
+lO
+Jm
+Hs
+Hs
+Hs
+Hs
+"}
+(23,1,1) = {"
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+gn
+zO
+ph
+Kr
+ph
+Jm
+Jm
+Jm
+Jm
+wL
+js
+fH
+Jm
+aT
+ph
+KW
+ph
+hK
+vR
+KW
+ez
+RT
+bv
+Hs
+Hs
+Hs
+"}
+(24,1,1) = {"
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+gn
+bg
+ph
+ph
+Fv
+ph
+dj
+js
+js
+jg
+js
+Th
+Jm
+jm
+Eh
+vR
+KW
+Kr
+KW
+Eh
+vv
+RT
+bv
+Hs
+Hs
+Hs
+"}
+(25,1,1) = {"
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Jm
+Jm
+ph
+yA
+VM
+cU
+Jm
+wd
+gr
+Cb
+iZ
+ue
+Jm
+YP
+KW
+KW
+ph
+Le
+OD
+co
+jM
+RT
+bv
+Hs
+Hs
+Hs
+"}
+(26,1,1) = {"
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Jm
+Jm
+ph
+bb
+Gv
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Jm
+Hs
+Hs
+Hs
+Hs
+"}
+(27,1,1) = {"
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Jm
+Jm
+Jm
+Jm
+Jm
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+"}
+(28,1,1) = {"
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+"}
+(29,1,1) = {"
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+"}
+(30,1,1) = {"
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+"}
+(31,1,1) = {"
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+"}
+(32,1,1) = {"
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+Hs
+"}
diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm
index eec9705fcf4..ba86d17dc61 100644
--- a/_maps/map_files/Birdshot/birdshot.dmm
+++ b/_maps/map_files/Birdshot/birdshot.dmm
@@ -254,19 +254,6 @@
/obj/structure/table,
/turf/open/floor/iron,
/area/station/maintenance/starboard/aft)
-"agb" = (
-/obj/effect/turf_decal/tile/green{
- dir = 8
- },
-/obj/effect/turf_decal/tile/blue{
- dir = 4
- },
-/obj/structure/chair/office/light{
- dir = 8
- },
-/obj/effect/landmark/start/virologist,
-/turf/open/floor/iron/white,
-/area/station/medical/virology)
"agy" = (
/obj/effect/turf_decal/stripes/line,
/obj/machinery/atmospherics/components/tank/oxygen{
@@ -2799,12 +2786,6 @@
},
/turf/open/floor/circuit/green,
/area/station/science/robotics/mechbay)
-"boT" = (
-/obj/effect/turf_decal/bot,
-/obj/machinery/light/cold/dim/directional/west,
-/obj/machinery/vending/wardrobe/engi_wardrobe,
-/turf/open/floor/iron,
-/area/station/engineering/main)
"boW" = (
/obj/structure/table/glass,
/obj/machinery/status_display/ai/directional/south,
@@ -10013,6 +9994,22 @@
/obj/effect/turf_decal/siding/wood,
/turf/open/floor/wood/tile,
/area/station/science/lower)
+"erJ" = (
+/obj/effect/turf_decal/siding/wood{
+ dir = 1
+ },
+/obj/structure/table/greyscale,
+/obj/item/folder/yellow{
+ pixel_x = 4;
+ pixel_y = 4
+ },
+/obj/item/clothing/glasses/meson,
+/obj/item/grenade/chem_grenade/smart_metal_foam{
+ pixel_x = -8;
+ pixel_y = 14
+ },
+/turf/open/floor/iron/grimy,
+/area/station/engineering/main)
"erK" = (
/obj/structure/cable,
/obj/effect/turf_decal/siding/thinplating_new,
@@ -11507,6 +11504,14 @@
/obj/effect/turf_decal/tile/neutral,
/turf/open/floor/iron,
/area/station/hallway/primary/fore)
+"eWf" = (
+/obj/structure/closet/cardboard,
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 8
+ },
+/obj/item/airlock_painter,
+/turf/open/floor/iron/grimy,
+/area/station/engineering/main)
"eWj" = (
/obj/machinery/atmospherics/components/unary/thermomachine/heater/on{
dir = 4;
@@ -11986,6 +11991,17 @@
/obj/machinery/light_switch/directional/west,
/turf/open/floor/iron/cafeteria,
/area/station/service/cafeteria)
+"fhX" = (
+/obj/structure/table/greyscale,
+/obj/item/lightreplacer{
+ pixel_y = 7
+ },
+/obj/item/lightreplacer{
+ pixel_y = 2;
+ pixel_x = -2
+ },
+/turf/open/floor/iron/grimy,
+/area/station/engineering/main)
"fib" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -19298,13 +19314,6 @@
},
/turf/open/floor/wood,
/area/station/engineering/main)
-"hGt" = (
-/obj/effect/turf_decal/tile/blue{
- dir = 1
- },
-/obj/effect/landmark/start/virologist,
-/turf/open/floor/iron/white,
-/area/station/medical/medbay/aft)
"hGE" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment,
@@ -24920,16 +24929,6 @@
},
/turf/open/floor/iron/dark/small,
/area/station/ai_monitored/security/armory)
-"jBA" = (
-/obj/structure/cable,
-/obj/machinery/power/smes/full,
-/obj/machinery/camera/directional/north{
- c_tag = "AI Chamber - SMES";
- network = list("aicore")
- },
-/obj/machinery/flasher/directional/north,
-/turf/open/floor/circuit/red,
-/area/station/ai_monitored/turret_protected/ai)
"jBD" = (
/obj/structure/table/wood,
/obj/effect/mapping_helpers/broken_floor,
@@ -25638,10 +25637,6 @@
"jKU" = (
/turf/closed/wall,
/area/station/engineering/atmos/storage/gas)
-"jLi" = (
-/obj/effect/landmark/start/virologist,
-/turf/open/floor/iron/showroomfloor,
-/area/station/medical/virology)
"jLl" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -25705,6 +25700,13 @@
/obj/machinery/light/small/directional/west,
/turf/open/floor/iron/smooth_large,
/area/station/cargo/warehouse)
+"jMq" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/landmark/start/virologist,
+/turf/open/floor/iron/white/small,
+/area/station/medical/virology)
"jMy" = (
/obj/machinery/atmospherics/components/binary/pump/on{
dir = 8;
@@ -26989,12 +26991,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central/fore)
-"kiQ" = (
-/obj/structure/cable,
-/obj/machinery/power/smes/full,
-/obj/machinery/status_display/ai/directional/north,
-/turf/open/floor/iron/smooth,
-/area/station/ai_monitored/turret_protected/aisat/equipment)
"kjg" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -28885,6 +28881,13 @@
/obj/effect/turf_decal/trimline/blue/warning,
/turf/open/floor/iron/white,
/area/station/medical/treatment_center)
+"kNk" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/effect/landmark/start/virologist,
+/turf/open/floor/iron/white,
+/area/station/medical/medbay/aft)
"kNn" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -31141,18 +31144,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/medbay/lobby)
-"lwl" = (
-/obj/effect/gibspawner/human,
-/obj/structure/table/optable{
- desc = "A cold, hard place for your final rest.";
- name = "Morgue Slab"
- },
-/mob/living/carbon/human/species/monkey/humand_legged{
- name = "Charles";
- real_name = "Charles"
- },
-/turf/open/floor/iron/white/diagonal,
-/area/station/maintenance/department/science/xenobiology)
"lwn" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/door/airlock/hatch,
@@ -33039,14 +33030,6 @@
},
/turf/open/floor/iron,
/area/station/cargo/storage)
-"lWK" = (
-/obj/structure/closet/cardboard,
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 8
- },
-/obj/item/airlock_painter,
-/turf/open/floor/iron/grimy,
-/area/station/engineering/main)
"lWQ" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/ticket_machine/directional/north,
@@ -35262,13 +35245,6 @@
/obj/machinery/atmospherics/pipe/smart/simple/dark/hidden,
/turf/open/floor/iron/grimy,
/area/station/tcommsat/server)
-"mIa" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/landmark/start/virologist,
-/turf/open/floor/iron/white/small,
-/area/station/medical/virology)
"mIg" = (
/obj/machinery/light/small/directional/west,
/turf/open/floor/catwalk_floor/iron_dark,
@@ -36955,6 +36931,12 @@
/obj/effect/mapping_helpers/airlock/access/all/security/general,
/turf/open/floor/iron/textured_half,
/area/station/security)
+"nki" = (
+/obj/effect/turf_decal/bot,
+/obj/machinery/light/cold/dim/directional/west,
+/obj/machinery/vending/wardrobe/engi_wardrobe,
+/turf/open/floor/iron,
+/area/station/engineering/main)
"nkl" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -56939,6 +56921,19 @@
"sSB" = (
/turf/open/floor/catwalk_floor,
/area/station/engineering/break_room)
+"sSF" = (
+/obj/effect/turf_decal/tile/green{
+ dir = 8
+ },
+/obj/effect/turf_decal/tile/blue{
+ dir = 4
+ },
+/obj/structure/chair/office/light{
+ dir = 8
+ },
+/obj/effect/landmark/start/virologist,
+/turf/open/floor/iron/white,
+/area/station/medical/virology)
"sSK" = (
/obj/structure/disposalpipe/segment{
dir = 5
@@ -60129,6 +60124,18 @@
/obj/structure/cable,
/turf/open/floor/catwalk_floor/iron_dark,
/area/station/cargo/bitrunning/den)
+"tQd" = (
+/obj/effect/gibspawner/human,
+/obj/structure/table/optable{
+ desc = "A cold, hard place for your final rest.";
+ name = "Morgue Slab"
+ },
+/mob/living/carbon/human/species/monkey/humand_legged{
+ name = "Charles";
+ real_name = "Charles"
+ },
+/turf/open/floor/iron/white/diagonal,
+/area/station/maintenance/department/science/xenobiology)
"tQx" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/reagent_dispensers/fueltank,
@@ -67782,6 +67789,16 @@
/obj/item/kirbyplants/random,
/turf/open/floor/iron/cafeteria,
/area/station/service/cafeteria)
+"vVd" = (
+/obj/structure/cable,
+/obj/machinery/power/smes/full,
+/obj/machinery/camera/directional/north{
+ c_tag = "AI Chamber - SMES";
+ network = list("aicore")
+ },
+/obj/machinery/flasher/directional/north,
+/turf/open/floor/circuit/red,
+/area/station/ai_monitored/turret_protected/ai)
"vVo" = (
/obj/machinery/light/cold/directional/south,
/obj/structure/table/reinforced,
@@ -68883,17 +68900,6 @@
},
/turf/open/space/basic,
/area/station/engineering/atmos/space_catwalk)
-"wlW" = (
-/obj/structure/table/greyscale,
-/obj/item/lightreplacer{
- pixel_y = 7
- },
-/obj/item/lightreplacer{
- pixel_y = 2;
- pixel_x = -2
- },
-/turf/open/floor/iron/grimy,
-/area/station/engineering/main)
"wmd" = (
/obj/machinery/atmospherics/pipe/smart/simple/cyan/visible,
/obj/machinery/atmospherics/pipe/smart/simple/cyan/visible/layer2{
@@ -68968,6 +68974,10 @@
},
/turf/open/floor/iron/white,
/area/station/security/medical)
+"wmT" = (
+/obj/effect/landmark/start/virologist,
+/turf/open/floor/iron/showroomfloor,
+/area/station/medical/virology)
"wmV" = (
/obj/structure/cable,
/turf/open/floor/plating,
@@ -74884,22 +74894,6 @@
},
/turf/open/floor/plating,
/area/station/service/abandoned_gambling_den/gaming)
-"xMU" = (
-/obj/effect/turf_decal/siding/wood{
- dir = 1
- },
-/obj/structure/table/greyscale,
-/obj/item/folder/yellow{
- pixel_x = 4;
- pixel_y = 4
- },
-/obj/item/clothing/glasses/meson,
-/obj/item/grenade/chem_grenade/smart_metal_foam{
- pixel_x = -8;
- pixel_y = 14
- },
-/turf/open/floor/iron/grimy,
-/area/station/engineering/main)
"xMY" = (
/turf/closed/wall/r_wall,
/area/station/command/teleporter)
@@ -75496,6 +75490,12 @@
/obj/effect/landmark/start/paramedic,
/turf/open/floor/iron/white,
/area/station/medical/medbay/lobby)
+"xTL" = (
+/obj/structure/cable,
+/obj/machinery/power/smes/full,
+/obj/machinery/status_display/ai/directional/north,
+/turf/open/floor/iron/smooth,
+/area/station/ai_monitored/turret_protected/aisat/equipment)
"xTM" = (
/obj/machinery/atmospherics/pipe/smart/simple/yellow/visible{
dir = 6
@@ -91992,7 +91992,7 @@ dgV
sHH
rQi
rPV
-boT
+nki
uOk
nmH
sHO
@@ -92257,7 +92257,7 @@ dgm
wIu
oHO
sDo
-wlW
+fhX
lsd
jJu
kya
@@ -92768,11 +92768,11 @@ rmM
btV
lMl
ayR
-xMU
+erJ
vDg
euP
all
-lWK
+eWf
eIx
kWg
bNq
@@ -103045,7 +103045,7 @@ aJq
yjV
fpY
uTA
-jBA
+vVd
xTV
dua
gnA
@@ -104086,7 +104086,7 @@ wct
hJp
wct
gOm
-kiQ
+xTL
eFe
eYk
xvT
@@ -106247,7 +106247,7 @@ tRc
tRc
tRc
tRc
-hGt
+kNk
dHT
sSQ
sSQ
@@ -107022,7 +107022,7 @@ bUv
cSk
gLb
nlS
-mIa
+jMq
gpM
sSQ
hrF
@@ -108560,12 +108560,12 @@ jrk
gIF
wYA
bpS
-jLi
+wmT
nYk
vVP
xAA
hgf
-agb
+sSF
uGj
wgL
oiA
@@ -113421,7 +113421,7 @@ dDB
blb
dDB
ldq
-lwl
+tQd
vXn
ldq
ldq
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index d97755766cb..3d1f3a212d7 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -1144,14 +1144,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/engineering/gravity_generator)
-"anU" = (
-/obj/structure/sign/warning/secure_area/directional/south,
-/obj/effect/turf_decal/trimline/purple/filled/line{
- dir = 10
- },
-/obj/item/kirbyplants/organic/plant10,
-/turf/open/floor/iron/white,
-/area/station/science/research)
"anV" = (
/obj/effect/landmark/start/hangover/closet,
/obj/structure/closet/firecloset,
@@ -1415,20 +1407,6 @@
/obj/item/pillow/random,
/turf/open/floor/wood,
/area/station/commons/dorms)
-"aqU" = (
-/obj/machinery/light/directional/west,
-/obj/effect/turf_decal/trimline/brown/filled/line{
- dir = 4
- },
-/obj/effect/turf_decal/bot/left,
-/obj/structure/sign/nanotrasen{
- pixel_x = -32
- },
-/obj/machinery/modular_computer/preset/cargochat/science{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/science/research)
"aqW" = (
/obj/structure/table/reinforced,
/obj/machinery/newscaster/directional/north,
@@ -2379,18 +2357,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/service/chapel/funeral)
-"aCA" = (
-/obj/effect/turf_decal/trimline/brown/filled/line{
- dir = 4
- },
-/obj/structure/table,
-/obj/machinery/fax{
- fax_name = "Research Division";
- name = "Research Division Fax Machine";
- pixel_x = 1
- },
-/turf/open/floor/iron,
-/area/station/science/research)
"aCJ" = (
/obj/structure/cable,
/obj/effect/decal/cleanable/dirt,
@@ -2570,6 +2536,14 @@
/obj/structure/grille/broken,
/turf/open/space,
/area/space/nearstation)
+"aFp" = (
+/obj/structure/sign/warning/secure_area/directional/south,
+/obj/effect/turf_decal/trimline/purple/filled/line{
+ dir = 10
+ },
+/obj/item/kirbyplants/organic/plant10,
+/turf/open/floor/iron/white,
+/area/station/science/research)
"aFv" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -2914,14 +2888,6 @@
/obj/effect/turf_decal/trimline/blue/filled/line,
/turf/open/floor/iron/white,
/area/station/medical/medbay/lobby)
-"aJj" = (
-/obj/machinery/airalarm/directional/west,
-/obj/effect/turf_decal/trimline/brown/filled/line{
- dir = 4
- },
-/obj/machinery/recharge_station,
-/turf/open/floor/iron,
-/area/station/science/research)
"aJu" = (
/obj/structure/cable,
/obj/machinery/power/smes/engineering,
@@ -3773,6 +3739,15 @@
},
/turf/open/space/basic,
/area/space/nearstation)
+"aUZ" = (
+/obj/machinery/airalarm/directional/north,
+/obj/structure/table,
+/obj/machinery/fax{
+ fax_name = "Service Hallway";
+ name = "Service Fax Machine"
+ },
+/turf/open/floor/iron/checker,
+/area/station/hallway/secondary/service)
"aVo" = (
/obj/machinery/computer/security/hos{
dir = 1
@@ -6501,9 +6476,6 @@
},
/turf/open/floor/plating,
/area/station/security/prison)
-"bDx" = (
-/turf/open/floor/iron,
-/area/station/security/office)
"bDy" = (
/obj/machinery/camera/directional/north{
c_tag = "Chapel - Confessional";
@@ -7066,13 +7038,6 @@
/obj/effect/turf_decal/tile/yellow/opposingcorners,
/turf/open/floor/iron,
/area/station/engineering/atmos/project)
-"bJi" = (
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
- dir = 1
- },
-/obj/effect/landmark/event_spawn,
-/turf/open/floor/iron/dark,
-/area/station/hallway/secondary/service)
"bJs" = (
/obj/structure/table/reinforced,
/obj/item/stack/sheet/iron{
@@ -8840,16 +8805,6 @@
"cfu" = (
/turf/open/floor/circuit/green,
/area/station/ai_monitored/turret_protected/ai_upload)
-"cfx" = (
-/obj/structure/plaque/static_plaque/golden{
- pixel_y = -32
- },
-/obj/structure/reagent_dispensers/water_cooler,
-/obj/effect/turf_decal/tile/red/half/contrasted{
- dir = 4
- },
-/turf/open/floor/iron,
-/area/station/security/office)
"cfy" = (
/obj/effect/turf_decal/stripes/line,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
@@ -8988,6 +8943,13 @@
/obj/effect/turf_decal/tile/red/fourcorners,
/turf/open/floor/iron,
/area/station/security/checkpoint/engineering)
+"chv" = (
+/obj/structure/cable,
+/obj/machinery/power/smes/full,
+/obj/effect/turf_decal/bot,
+/obj/item/radio/intercom/directional/west,
+/turf/open/floor/iron,
+/area/station/engineering/gravity_generator)
"chF" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -9329,6 +9291,16 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/visible,
/turf/open/floor/iron/dark/corner,
/area/station/maintenance/disposal/incinerator)
+"clB" = (
+/obj/structure/table/glass,
+/obj/machinery/computer/records/medical/laptop,
+/obj/item/toy/figure/virologist,
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 1
+ },
+/obj/structure/cable,
+/turf/open/floor/iron/white,
+/area/station/medical/virology)
"clE" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/door/airlock/maintenance_hatch{
@@ -10586,12 +10558,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/service/chapel/storage)
-"cBB" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/cable,
-/turf/open/floor/iron/dark,
-/area/station/hallway/secondary/service)
"cBC" = (
/obj/structure/table/reinforced,
/obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible{
@@ -11264,16 +11230,6 @@
},
/turf/open/floor/iron/white/corner,
/area/station/hallway/secondary/exit/departure_lounge)
-"cJQ" = (
-/obj/structure/disposalpipe/segment,
-/obj/effect/turf_decal/tile/neutral/half/contrasted{
- dir = 8
- },
-/obj/structure/window/reinforced/spawner/directional/north,
-/obj/item/kirbyplants/random,
-/obj/effect/turf_decal/bot,
-/turf/open/floor/iron,
-/area/station/medical/storage)
"cJX" = (
/obj/structure/table/reinforced,
/obj/machinery/status_display/evac/directional/west,
@@ -12168,13 +12124,6 @@
},
/turf/open/floor/plating,
/area/station/maintenance/central)
-"cVD" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/cable,
-/obj/item/radio/intercom/directional/north,
-/turf/open/floor/iron/dark,
-/area/station/hallway/secondary/service)
"cVN" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable,
@@ -17175,6 +17124,17 @@
},
/turf/open/floor/iron,
/area/station/command/heads_quarters/qm)
+"ekF" = (
+/obj/structure/sign/poster/official/random/directional/south,
+/obj/machinery/light/directional/south,
+/obj/structure/window/reinforced/spawner/directional/west,
+/obj/structure/disposalpipe/trunk{
+ dir = 4
+ },
+/obj/machinery/disposal/bin,
+/obj/effect/turf_decal/bot,
+/turf/open/floor/iron,
+/area/station/engineering/storage_shared)
"ekM" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/cobweb/cobweb2,
@@ -18240,6 +18200,15 @@
},
/turf/open/floor/iron/white,
/area/station/medical/treatment_center)
+"eyl" = (
+/obj/machinery/firealarm/directional/east,
+/obj/effect/turf_decal/trimline/purple/filled/corner{
+ dir = 8
+ },
+/obj/machinery/airalarm/directional/south,
+/obj/machinery/photocopier,
+/turf/open/floor/iron/white,
+/area/station/science/research)
"eyr" = (
/obj/item/kirbyplants/random,
/obj/machinery/power/apc/auto_name/directional/north,
@@ -18981,28 +18950,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/service/abandoned_gambling_den/gaming)
-"eIu" = (
-/obj/structure/table/reinforced,
-/obj/machinery/door/firedoor,
-/obj/machinery/door/poddoor/preopen{
- id = "hopblast";
- name = "HoP Blast Door"
- },
-/obj/machinery/door/window/brigdoor/left/directional/east{
- name = "Access Desk";
- req_access = list("hop")
- },
-/obj/machinery/door/window/right/directional/west{
- name = "Access Queue"
- },
-/obj/effect/turf_decal/stripes/line{
- dir = 8
- },
-/obj/structure/desk_bell{
- pixel_x = 7
- },
-/turf/open/floor/iron,
-/area/station/command/heads_quarters/hop)
"eIy" = (
/obj/structure/disposalpipe/segment{
dir = 5
@@ -20757,6 +20704,13 @@
},
/turf/open/floor/wood/large,
/area/station/service/theater)
+"fes" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/iron,
+/area/station/security/office)
"fez" = (
/obj/effect/landmark/start/hangover,
/obj/effect/turf_decal/siding/wood/corner,
@@ -22781,6 +22735,18 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/service/abandoned_gambling_den)
+"fEV" = (
+/obj/structure/sign/poster/official/moth_epi/directional/west,
+/obj/effect/turf_decal/bot,
+/obj/structure/disposalpipe/trunk{
+ dir = 1
+ },
+/obj/machinery/disposal/bin,
+/obj/effect/turf_decal/tile/neutral/half/contrasted{
+ dir = 8
+ },
+/turf/open/floor/iron,
+/area/station/medical/storage)
"fFb" = (
/obj/structure/table,
/obj/effect/spawner/random/entertainment/drugs{
@@ -24068,6 +24034,13 @@
},
/turf/open/floor/iron,
/area/station/engineering/atmos)
+"fWB" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/item/radio/intercom/directional/north,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/service)
"fWH" = (
/obj/effect/turf_decal/trimline/blue/filled/corner,
/turf/open/floor/iron/white,
@@ -24546,6 +24519,14 @@
},
/turf/open/floor/iron,
/area/station/service/hydroponics)
+"gch" = (
+/obj/structure/table,
+/obj/item/clipboard,
+/obj/item/stack/package_wrap,
+/obj/item/hand_labeler,
+/obj/effect/turf_decal/bot,
+/turf/open/floor/iron/checker,
+/area/station/hallway/secondary/service)
"gci" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/poddoor/shutters/window/preopen{
@@ -26257,6 +26238,12 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/grimy,
/area/station/command/heads_quarters/hop)
+"guZ" = (
+/obj/machinery/light/small/directional/west,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/photobooth/security,
+/turf/open/floor/iron/dark,
+/area/station/security/execution/transfer)
"gvf" = (
/obj/structure/window/reinforced/spawner/directional/north,
/obj/structure/lattice,
@@ -27861,18 +27848,6 @@
/obj/effect/turf_decal/tile/brown/half/contrasted,
/turf/open/floor/iron,
/area/station/security/prison)
-"gPH" = (
-/obj/structure/sign/poster/official/moth_epi/directional/west,
-/obj/effect/turf_decal/bot,
-/obj/structure/disposalpipe/trunk{
- dir = 1
- },
-/obj/machinery/disposal/bin,
-/obj/effect/turf_decal/tile/neutral/half/contrasted{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/medical/storage)
"gPO" = (
/obj/structure/table/reinforced,
/obj/item/flashlight/lamp/green,
@@ -29294,11 +29269,6 @@
/obj/effect/turf_decal/tile/yellow/fourcorners,
/turf/open/floor/iron,
/area/station/medical/pharmacy)
-"hjH" = (
-/obj/item/radio/intercom/directional/north,
-/obj/machinery/photocopier,
-/turf/open/floor/iron/checker,
-/area/station/hallway/secondary/service)
"hjJ" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/cable,
@@ -29398,14 +29368,6 @@
dir = 1
},
/area/station/science/ordnance/storage)
-"hkZ" = (
-/obj/structure/sign/warning/secure_area/directional/south,
-/obj/effect/turf_decal/trimline/purple/filled/line{
- dir = 6
- },
-/obj/item/kirbyplants/organic/plant10,
-/turf/open/floor/iron/white,
-/area/station/science/research)
"hlj" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/holopad,
@@ -30815,6 +30777,16 @@
/obj/effect/mapping_helpers/airlock/access/all/service/kitchen,
/turf/open/floor/iron/freezer,
/area/station/service/kitchen/coldroom)
+"hFQ" = (
+/obj/structure/disposalpipe/segment,
+/obj/effect/turf_decal/tile/neutral/half/contrasted{
+ dir = 8
+ },
+/obj/structure/window/reinforced/spawner/directional/north,
+/obj/item/kirbyplants/random,
+/obj/effect/turf_decal/bot,
+/turf/open/floor/iron,
+/area/station/medical/storage)
"hFS" = (
/obj/structure/cable,
/obj/effect/turf_decal/stripes/line{
@@ -31546,6 +31518,18 @@
},
/turf/open/floor/iron,
/area/station/maintenance/department/security)
+"hPH" = (
+/obj/structure/chair/office/light{
+ dir = 8
+ },
+/obj/effect/landmark/start/virologist,
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 4
+ },
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/neutral/full,
+/turf/open/floor/iron/large,
+/area/station/medical/virology)
"hPJ" = (
/obj/machinery/atmospherics/pipe/smart/manifold/purple/visible{
dir = 8
@@ -31696,15 +31680,6 @@
/obj/effect/turf_decal/tile/dark_blue/fourcorners,
/turf/open/floor/iron,
/area/station/commons/dorms/laundry)
-"hRU" = (
-/obj/effect/turf_decal/bot,
-/obj/structure/extinguisher_cabinet/directional/south,
-/obj/machinery/light/small/directional/south,
-/obj/machinery/modular_computer/preset/cargochat/service{
- dir = 1
- },
-/turf/open/floor/iron/checker,
-/area/station/hallway/secondary/service)
"hRV" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -32081,6 +32056,28 @@
/obj/effect/turf_decal/bot,
/turf/open/floor/iron,
/area/station/engineering/atmos/hfr_room)
+"hWA" = (
+/obj/structure/table/reinforced,
+/obj/machinery/door/firedoor,
+/obj/machinery/door/poddoor/preopen{
+ id = "hopblast";
+ name = "HoP Blast Door"
+ },
+/obj/machinery/door/window/brigdoor/left/directional/east{
+ name = "Access Desk";
+ req_access = list("hop")
+ },
+/obj/machinery/door/window/right/directional/west{
+ name = "Access Queue"
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/obj/structure/desk_bell{
+ pixel_x = 7
+ },
+/turf/open/floor/iron,
+/area/station/command/heads_quarters/hop)
"hWF" = (
/obj/structure/disposalpipe/segment,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -32231,16 +32228,6 @@
/obj/machinery/airalarm/directional/south,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/morgue)
-"hYh" = (
-/obj/machinery/newscaster/directional/east,
-/obj/machinery/airalarm/directional/south,
-/obj/structure/tank_holder/extinguisher,
-/obj/machinery/camera/directional/south{
- c_tag = "Library - Art Gallery";
- name = "library camera"
- },
-/turf/open/floor/wood/tile,
-/area/station/service/library/artgallery)
"hYn" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -35456,15 +35443,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron,
/area/station/engineering/atmos)
-"iOp" = (
-/obj/machinery/light_switch/directional/north,
-/obj/structure/cable,
-/obj/effect/turf_decal/loading_area{
- dir = 8
- },
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron/textured,
-/area/station/medical/storage)
"iOu" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -36996,18 +36974,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/engineering/supermatter/room)
-"jgG" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/cable,
-/obj/machinery/firealarm/directional/north,
-/obj/machinery/camera/directional/north{
- c_tag = "Service - Service Hall";
- dir = 9;
- name = "service camera"
- },
-/turf/open/floor/iron/dark,
-/area/station/hallway/secondary/service)
"jgN" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -41333,6 +41299,15 @@
/obj/effect/landmark/start/hangover,
/turf/open/floor/iron,
/area/station/hallway/primary/fore)
+"kix" = (
+/obj/effect/turf_decal/bot,
+/obj/structure/extinguisher_cabinet/directional/south,
+/obj/machinery/light/small/directional/south,
+/obj/machinery/modular_computer/preset/cargochat/service{
+ dir = 1
+ },
+/turf/open/floor/iron/checker,
+/area/station/hallway/secondary/service)
"kiz" = (
/obj/structure/sign/poster/random/directional/east,
/obj/structure/table,
@@ -41914,6 +41889,16 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/iron/grimy,
/area/station/tcommsat/computer)
+"kqI" = (
+/obj/structure/plaque/static_plaque/golden{
+ pixel_y = -32
+ },
+/obj/structure/reagent_dispensers/water_cooler,
+/obj/effect/turf_decal/tile/red/half/contrasted{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/security/office)
"kqJ" = (
/obj/effect/turf_decal/tile/brown/anticorner/contrasted{
dir = 1
@@ -43511,6 +43496,13 @@
},
/turf/open/floor/iron/dark,
/area/station/engineering/transit_tube)
+"kNB" = (
+/obj/structure/table/wood,
+/obj/item/papercutter,
+/obj/item/paper/fluff/ids_for_dummies,
+/obj/item/radio/intercom/directional/east,
+/turf/open/floor/wood,
+/area/station/command/heads_quarters/hop)
"kNC" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -44615,6 +44607,15 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/maintenance/department/eva/abandoned)
+"lcl" = (
+/obj/machinery/light_switch/directional/north,
+/obj/structure/cable,
+/obj/effect/turf_decal/loading_area{
+ dir = 8
+ },
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/iron/textured,
+/area/station/medical/storage)
"lcm" = (
/turf/open/floor/wood,
/area/station/security/detectives_office/private_investigators_office)
@@ -46459,20 +46460,6 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/wood,
/area/station/service/theater)
-"lAe" = (
-/obj/machinery/light/directional/south,
-/obj/machinery/camera/directional/south{
- c_tag = "Security - Office Aft"
- },
-/obj/machinery/computer/security/telescreen/entertainment/directional/south,
-/obj/machinery/modular_computer/preset/cargochat/security{
- dir = 1
- },
-/obj/effect/turf_decal/trimline/brown/filled/line{
- dir = 9
- },
-/turf/open/floor/iron/dark,
-/area/station/security/office)
"lAg" = (
/obj/structure/table/wood,
/obj/item/folder/red,
@@ -48436,6 +48423,42 @@
/obj/machinery/light/directional/south,
/turf/open/floor/iron,
/area/station/hallway/secondary/entry)
+"lZC" = (
+/obj/structure/table/wood,
+/obj/machinery/computer/records/medical/laptop,
+/obj/machinery/light_switch/directional/west{
+ pixel_x = -38;
+ pixel_y = 8
+ },
+/obj/machinery/button/flasher{
+ id = "hopflash";
+ pixel_x = -38;
+ pixel_y = -7;
+ req_access = list("kitchen")
+ },
+/obj/machinery/button/ticket_machine{
+ pixel_y = 22;
+ pixel_x = -6
+ },
+/obj/machinery/button/door/directional/west{
+ id = "hopblast";
+ name = "Lockdown Blast Doors";
+ pixel_y = 6;
+ req_access = list("hop")
+ },
+/obj/machinery/button/door/directional/west{
+ id = "hopline";
+ name = "Queue Shutters Control";
+ pixel_y = -6;
+ req_access = list("hop")
+ },
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/button/photobooth{
+ pixel_y = 22;
+ pixel_x = 6
+ },
+/turf/open/floor/iron/dark,
+/area/station/command/heads_quarters/hop)
"lZF" = (
/obj/machinery/power/shieldwallgen/xenobiologyaccess,
/obj/structure/cable,
@@ -48451,6 +48474,12 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/dark/textured_large,
/area/station/science/xenobiology)
+"lZV" = (
+/obj/structure/chair/office/light,
+/obj/effect/landmark/start/virologist,
+/obj/effect/turf_decal/trimline/green/filled/warning,
+/turf/open/floor/iron/white,
+/area/station/medical/virology)
"lZX" = (
/obj/structure/cable,
/obj/machinery/power/apc/auto_name/directional/south,
@@ -49251,42 +49280,6 @@
"mlE" = (
/turf/closed/wall/r_wall,
/area/station/ai_monitored/command/storage/eva)
-"mlM" = (
-/obj/structure/table/wood,
-/obj/machinery/computer/records/medical/laptop,
-/obj/machinery/light_switch/directional/west{
- pixel_x = -38;
- pixel_y = 8
- },
-/obj/machinery/button/flasher{
- id = "hopflash";
- pixel_x = -38;
- pixel_y = -7;
- req_access = list("kitchen")
- },
-/obj/machinery/button/ticket_machine{
- pixel_y = 22;
- pixel_x = -6
- },
-/obj/machinery/button/door/directional/west{
- id = "hopblast";
- name = "Lockdown Blast Doors";
- pixel_y = 6;
- req_access = list("hop")
- },
-/obj/machinery/button/door/directional/west{
- id = "hopline";
- name = "Queue Shutters Control";
- pixel_y = -6;
- req_access = list("hop")
- },
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/obj/machinery/button/photobooth{
- pixel_y = 22;
- pixel_x = 6
- },
-/turf/open/floor/iron/dark,
-/area/station/command/heads_quarters/hop)
"mlW" = (
/obj/structure/sign/nanotrasen{
pixel_y = 32
@@ -49700,6 +49693,16 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/fore)
+"msL" = (
+/obj/machinery/newscaster/directional/east,
+/obj/machinery/airalarm/directional/south,
+/obj/structure/tank_holder/extinguisher,
+/obj/machinery/camera/directional/south{
+ c_tag = "Library - Art Gallery";
+ name = "library camera"
+ },
+/turf/open/floor/wood/tile,
+/area/station/service/library/artgallery)
"msR" = (
/obj/effect/turf_decal/tile/red/opposingcorners{
dir = 1
@@ -49789,6 +49792,23 @@
/obj/effect/turf_decal/tile/yellow/fourcorners,
/turf/open/floor/iron,
/area/station/engineering/storage)
+"mtD" = (
+/obj/machinery/requests_console/directional/north{
+ department = "Medbay";
+ name = "Medbay Requests Console"
+ },
+/obj/effect/mapping_helpers/requests_console/assistance,
+/obj/structure/cable,
+/obj/effect/turf_decal/bot,
+/obj/machinery/camera/directional/north{
+ c_tag = "Medbay - Storage";
+ name = "medbay camera";
+ network = list("ss13","medbay")
+ },
+/obj/machinery/modular_computer/preset/cargochat/medical,
+/obj/effect/turf_decal/trimline/brown/filled/end,
+/turf/open/floor/iron,
+/area/station/medical/storage)
"mtO" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/turf_decal/tile/yellow{
@@ -51035,14 +51055,6 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
/area/station/hallway/secondary/construction)
-"mIg" = (
-/obj/structure/chair/office/light,
-/obj/effect/turf_decal/trimline/green/filled/line{
- dir = 10
- },
-/obj/effect/landmark/start/virologist,
-/turf/open/floor/iron/white,
-/area/station/medical/virology)
"mIs" = (
/turf/closed/wall,
/area/station/command/gateway)
@@ -51748,6 +51760,18 @@
},
/turf/open/floor/iron,
/area/station/service/abandoned_gambling_den/gaming)
+"mRl" = (
+/obj/effect/turf_decal/trimline/brown/filled/line{
+ dir = 4
+ },
+/obj/structure/table,
+/obj/machinery/fax{
+ fax_name = "Research Division";
+ name = "Research Division Fax Machine";
+ pixel_x = 1
+ },
+/turf/open/floor/iron,
+/area/station/science/research)
"mRs" = (
/obj/structure/cable,
/obj/effect/landmark/start/depsec/science,
@@ -52028,12 +52052,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/commons/locker)
-"mVX" = (
-/obj/machinery/power/smes/full,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron/dark/telecomms,
-/area/station/tcommsat/server)
"mVY" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -54518,6 +54536,20 @@
/obj/effect/turf_decal/tile/blue,
/turf/open/floor/iron,
/area/station/service/hydroponics)
+"nFf" = (
+/obj/structure/disposalpipe/segment{
+ dir = 10
+ },
+/obj/effect/turf_decal/delivery,
+/obj/effect/turf_decal/tile/neutral/anticorner/contrasted{
+ dir = 1
+ },
+/obj/machinery/door/window/left/directional/east{
+ name = "Medical Delivery";
+ req_access = list("medical")
+ },
+/turf/open/floor/iron/textured,
+/area/station/medical/storage)
"nFr" = (
/obj/structure/cable,
/obj/effect/turf_decal/stripes/line{
@@ -58034,13 +58066,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central/fore)
-"oBa" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/item/kirbyplants/random,
-/turf/open/floor/iron,
-/area/station/engineering/storage_shared)
"oBd" = (
/obj/machinery/newscaster/directional/east,
/obj/effect/turf_decal/trimline/blue/filled/corner{
@@ -58184,16 +58209,6 @@
},
/turf/open/floor/iron/dark/textured_half,
/area/station/service/janitor)
-"oDw" = (
-/obj/structure/table/glass,
-/obj/machinery/computer/records/medical/laptop,
-/obj/item/toy/figure/virologist,
-/obj/effect/turf_decal/trimline/green/filled/line{
- dir = 1
- },
-/obj/structure/cable,
-/turf/open/floor/iron/white,
-/area/station/medical/virology)
"oDx" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/security{
@@ -58717,6 +58732,21 @@
},
/turf/open/floor/wood,
/area/station/service/electronic_marketing_den)
+"oLD" = (
+/obj/machinery/camera/directional/north{
+ c_tag = "Science - Central Access";
+ dir = 9;
+ name = "science camera";
+ network = list("ss13","rd")
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/item/radio/intercom/directional/north,
+/obj/effect/turf_decal/trimline/purple/filled/corner{
+ dir = 4
+ },
+/turf/open/floor/iron/white,
+/area/station/science/research)
"oLL" = (
/obj/structure/cable,
/obj/effect/turf_decal/delivery,
@@ -59051,21 +59081,6 @@
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/science/lobby)
-"oPF" = (
-/obj/machinery/camera/directional/north{
- c_tag = "Science - Central Access";
- dir = 9;
- name = "science camera";
- network = list("ss13","rd")
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/item/radio/intercom/directional/north,
-/obj/effect/turf_decal/trimline/purple/filled/corner{
- dir = 4
- },
-/turf/open/floor/iron/white,
-/area/station/science/research)
"oPL" = (
/obj/machinery/door/window/right/directional/east{
name = "Danger: Conveyor Access";
@@ -59159,6 +59174,20 @@
/obj/machinery/light/small/dim/directional/north,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"oRf" = (
+/obj/machinery/light/directional/south,
+/obj/machinery/camera/directional/south{
+ c_tag = "Security - Office Aft"
+ },
+/obj/machinery/computer/security/telescreen/entertainment/directional/south,
+/obj/machinery/modular_computer/preset/cargochat/security{
+ dir = 1
+ },
+/obj/effect/turf_decal/trimline/brown/filled/line{
+ dir = 9
+ },
+/turf/open/floor/iron/dark,
+/area/station/security/office)
"oRh" = (
/obj/machinery/status_display/evac/directional/east,
/obj/structure/chair{
@@ -59182,11 +59211,6 @@
/obj/machinery/light/small/directional/south,
/turf/open/floor/plating,
/area/station/commons/fitness/recreation)
-"oRq" = (
-/obj/structure/cable,
-/mob/living/basic/slime,
-/turf/open/floor/circuit/green,
-/area/station/science/xenobiology)
"oRs" = (
/obj/structure/disposalpipe/segment,
/obj/effect/decal/cleanable/dirt,
@@ -59452,23 +59476,6 @@
},
/turf/open/floor/iron/dark,
/area/station/service/abandoned_gambling_den)
-"oUf" = (
-/obj/machinery/requests_console/directional/north{
- department = "Medbay";
- name = "Medbay Requests Console"
- },
-/obj/effect/mapping_helpers/requests_console/assistance,
-/obj/structure/cable,
-/obj/effect/turf_decal/bot,
-/obj/machinery/camera/directional/north{
- c_tag = "Medbay - Storage";
- name = "medbay camera";
- network = list("ss13","medbay")
- },
-/obj/machinery/modular_computer/preset/cargochat/medical,
-/obj/effect/turf_decal/trimline/brown/filled/end,
-/turf/open/floor/iron,
-/area/station/medical/storage)
"oUh" = (
/obj/machinery/atmospherics/pipe/smart/manifold/cyan/visible{
dir = 1
@@ -59670,15 +59677,6 @@
dir = 8
},
/area/station/engineering/atmos/project)
-"oXX" = (
-/obj/machinery/disposal/bin,
-/obj/effect/decal/cleanable/dirt,
-/obj/structure/disposalpipe/trunk{
- dir = 1
- },
-/obj/effect/turf_decal/bot,
-/turf/open/floor/iron/checker,
-/area/station/hallway/secondary/service)
"oYe" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -59814,13 +59812,6 @@
},
/turf/open/floor/wood,
/area/station/security/detectives_office/private_investigators_office)
-"paD" = (
-/obj/structure/table/wood,
-/obj/item/papercutter,
-/obj/item/paper/fluff/ids_for_dummies,
-/obj/item/radio/intercom/directional/east,
-/turf/open/floor/wood,
-/area/station/command/heads_quarters/hop)
"paQ" = (
/obj/effect/turf_decal/trimline/purple/filled/line,
/turf/open/floor/iron/white,
@@ -61082,6 +61073,16 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/security/detectives_office/private_investigators_office)
+"pqo" = (
+/obj/machinery/flasher/directional/east{
+ id = "hopflash";
+ pixel_x = 0;
+ pixel_y = 26
+ },
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/obj/machinery/photobooth,
+/turf/open/floor/iron/dark,
+/area/station/hallway/primary/central/fore)
"pqp" = (
/obj/structure/sign/warning/secure_area/directional/north,
/obj/structure/table,
@@ -62130,6 +62131,14 @@
/obj/effect/mapping_helpers/airlock/access/all/engineering/general,
/turf/open/floor/iron,
/area/station/engineering/atmos)
+"pDb" = (
+/obj/structure/chair/office/light,
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 10
+ },
+/obj/effect/landmark/start/virologist,
+/turf/open/floor/iron/white,
+/area/station/medical/virology)
"pDf" = (
/obj/machinery/computer/camera_advanced/xenobio{
dir = 1
@@ -63115,16 +63124,6 @@
/obj/structure/barricade/wooden,
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
-"pOu" = (
-/obj/machinery/power/smes/full,
-/obj/machinery/status_display/ai/directional/north,
-/obj/structure/cable,
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/obj/machinery/light/small/directional/north,
-/turf/open/floor/plating,
-/area/station/ai_monitored/turret_protected/aisat_interior)
"pOz" = (
/obj/structure/cable,
/obj/machinery/modular_computer/preset/id{
@@ -63339,6 +63338,15 @@
},
/turf/open/floor/iron/white,
/area/station/medical/chemistry)
+"pQo" = (
+/obj/machinery/modular_computer/preset/cargochat/engineering{
+ dir = 1
+ },
+/obj/effect/turf_decal/trimline/brown/filled/end{
+ dir = 1
+ },
+/turf/open/floor/iron,
+/area/station/engineering/storage_shared)
"pQx" = (
/obj/structure/lattice,
/obj/structure/window/reinforced/spawner/directional/north,
@@ -63904,6 +63912,18 @@
},
/turf/open/floor/iron,
/area/station/cargo/storage)
+"pWB" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/obj/machinery/firealarm/directional/north,
+/obj/machinery/camera/directional/north{
+ c_tag = "Service - Service Hall";
+ dir = 9;
+ name = "service camera"
+ },
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/service)
"pWG" = (
/obj/structure/table/wood,
/obj/item/radio/intercom/directional/west,
@@ -65072,6 +65092,12 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/carpet/green,
/area/station/service/library)
+"qlY" = (
+/obj/machinery/power/smes/full,
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron/dark/telecomms,
+/area/station/tcommsat/server)
"qmd" = (
/obj/effect/turf_decal/trimline/purple/filled/corner{
dir = 8
@@ -65539,6 +65565,13 @@
},
/turf/open/floor/iron,
/area/station/hallway/secondary/entry)
+"qsv" = (
+/obj/effect/turf_decal/bot,
+/obj/structure/table,
+/obj/item/paper_bin,
+/obj/item/pen,
+/turf/open/floor/iron/checker,
+/area/station/hallway/secondary/service)
"qsw" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/table/wood,
@@ -65986,12 +66019,6 @@
},
/turf/open/floor/iron,
/area/station/engineering/main)
-"qyK" = (
-/obj/machinery/light/small/directional/west,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/obj/machinery/photobooth/security,
-/turf/open/floor/iron/dark,
-/area/station/security/execution/transfer)
"qyX" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -67033,16 +67060,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/security/courtroom)
-"qLa" = (
-/obj/machinery/flasher/directional/east{
- id = "hopflash";
- pixel_x = 0;
- pixel_y = 26
- },
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/obj/machinery/photobooth,
-/turf/open/floor/iron/dark,
-/area/station/hallway/primary/central/fore)
"qLg" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -67591,6 +67608,12 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/iron/grimy,
/area/station/service/library)
+"qSC" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 8
+ },
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/service)
"qSG" = (
/obj/machinery/portable_atmospherics/canister/anesthetic_mix,
/obj/machinery/light/small/blacklight/directional/north,
@@ -67714,15 +67737,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron,
/area/station/maintenance/disposal/incinerator)
-"qUL" = (
-/obj/machinery/modular_computer/preset/cargochat/engineering{
- dir = 1
- },
-/obj/effect/turf_decal/trimline/brown/filled/end{
- dir = 1
- },
-/turf/open/floor/iron,
-/area/station/engineering/storage_shared)
"qUM" = (
/obj/structure/sign/nanotrasen,
/turf/closed/wall/r_wall,
@@ -68509,6 +68523,16 @@
/obj/effect/turf_decal/delivery,
/turf/open/floor/iron,
/area/station/engineering/main)
+"rgH" = (
+/obj/machinery/power/smes/full,
+/obj/machinery/status_display/ai/directional/north,
+/obj/structure/cable,
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/obj/machinery/light/small/directional/north,
+/turf/open/floor/plating,
+/area/station/ai_monitored/turret_protected/aisat_interior)
"rgK" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -68862,6 +68886,12 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/security/detectives_office)
+"rky" = (
+/obj/effect/turf_decal/bot,
+/obj/machinery/holopad,
+/obj/effect/landmark/start/hangover,
+/turf/open/floor/iron/checker,
+/area/station/hallway/secondary/service)
"rkC" = (
/obj/structure/chair/office{
dir = 8
@@ -69268,15 +69298,6 @@
},
/turf/open/floor/iron,
/area/station/maintenance/port)
-"roh" = (
-/obj/machinery/firealarm/directional/east,
-/obj/effect/turf_decal/trimline/purple/filled/corner{
- dir = 8
- },
-/obj/machinery/airalarm/directional/south,
-/obj/machinery/photocopier,
-/turf/open/floor/iron/white,
-/area/station/science/research)
"rol" = (
/obj/structure/chair/sofa/bench{
dir = 8
@@ -70698,18 +70719,6 @@
/obj/effect/turf_decal/tile/yellow/fourcorners,
/turf/open/floor/iron,
/area/station/engineering/main)
-"rIO" = (
-/obj/structure/chair/office/light{
- dir = 8
- },
-/obj/effect/landmark/start/virologist,
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
- dir = 4
- },
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/neutral/full,
-/turf/open/floor/iron/large,
-/area/station/medical/virology)
"rIP" = (
/obj/structure/lattice/catwalk,
/obj/structure/sign/warning/secure_area/directional/east,
@@ -72406,16 +72415,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/pharmacy)
-"sbZ" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/status_display/evac/directional/north,
-/obj/structure/disposalpipe/segment{
- dir = 10
- },
-/turf/open/floor/iron/dark,
-/area/station/hallway/secondary/service)
"sca" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -72437,6 +72436,20 @@
},
/turf/open/floor/iron,
/area/station/maintenance/port/fore)
+"scp" = (
+/obj/machinery/light/directional/west,
+/obj/effect/turf_decal/trimline/brown/filled/line{
+ dir = 4
+ },
+/obj/effect/turf_decal/bot/left,
+/obj/structure/sign/nanotrasen{
+ pixel_x = -32
+ },
+/obj/machinery/modular_computer/preset/cargochat/science{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/science/research)
"scs" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
@@ -72451,15 +72464,6 @@
/obj/effect/turf_decal/delivery,
/turf/open/floor/iron/dark,
/area/station/science/ordnance/storage)
-"scJ" = (
-/obj/machinery/airalarm/directional/north,
-/obj/structure/table,
-/obj/machinery/fax{
- fax_name = "Service Hallway";
- name = "Service Fax Machine"
- },
-/turf/open/floor/iron/checker,
-/area/station/hallway/secondary/service)
"scR" = (
/obj/machinery/airalarm/directional/south,
/turf/open/floor/iron/white,
@@ -72766,14 +72770,6 @@
},
/turf/open/floor/iron,
/area/station/security/brig)
-"sgG" = (
-/obj/structure/table,
-/obj/item/clipboard,
-/obj/item/stack/package_wrap,
-/obj/item/hand_labeler,
-/obj/effect/turf_decal/bot,
-/turf/open/floor/iron/checker,
-/area/station/hallway/secondary/service)
"sgI" = (
/obj/docking_port/stationary/escape_pod{
dir = 4
@@ -74667,13 +74663,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/plating,
/area/station/ai_monitored/turret_protected/ai_upload)
-"sGp" = (
-/obj/effect/turf_decal/tile/red{
- dir = 8
- },
-/obj/item/kirbyplants/random,
-/turf/open/floor/iron,
-/area/station/security/office)
"sGx" = (
/obj/structure/cable,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
@@ -75579,6 +75568,11 @@
"sRd" = (
/turf/closed/wall/r_wall,
/area/station/security/evidence)
+"sRs" = (
+/obj/item/radio/intercom/directional/north,
+/obj/machinery/photocopier,
+/turf/open/floor/iron/checker,
+/area/station/hallway/secondary/service)
"sRt" = (
/obj/structure/rack,
/obj/effect/spawner/random/maintenance,
@@ -76129,12 +76123,6 @@
},
/turf/open/floor/iron,
/area/station/science/lab)
-"sYe" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 8
- },
-/turf/open/floor/iron/dark,
-/area/station/hallway/secondary/service)
"sYf" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -76513,6 +76501,19 @@
/obj/effect/turf_decal/tile/red,
/turf/open/floor/iron,
/area/station/security/execution/transfer)
+"tdm" = (
+/obj/machinery/power/smes/full,
+/obj/structure/sign/warning/electric_shock/directional/north,
+/obj/machinery/camera/directional/north{
+ c_tag = "AI Chamber - Fore";
+ name = "motion-sensitive ai camera";
+ network = list("aichamber")
+ },
+/obj/structure/cable,
+/obj/effect/turf_decal/stripes/line,
+/obj/machinery/light/small/directional/north,
+/turf/open/floor/iron/dark,
+/area/station/ai_monitored/turret_protected/ai)
"tdt" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -77297,33 +77298,6 @@
/obj/machinery/light/small/dim/directional/north,
/turf/open/floor/iron/dark,
/area/station/maintenance/department/science)
-"tpV" = (
-/obj/structure/disposalpipe/segment{
- dir = 10
- },
-/obj/effect/turf_decal/delivery,
-/obj/effect/turf_decal/tile/neutral/anticorner/contrasted{
- dir = 1
- },
-/obj/machinery/door/window/left/directional/east{
- name = "Medical Delivery";
- req_access = list("medical")
- },
-/turf/open/floor/iron/textured,
-/area/station/medical/storage)
-"tpX" = (
-/obj/machinery/power/smes/full,
-/obj/structure/sign/warning/electric_shock/directional/north,
-/obj/machinery/camera/directional/north{
- c_tag = "AI Chamber - Fore";
- name = "motion-sensitive ai camera";
- network = list("aichamber")
- },
-/obj/structure/cable,
-/obj/effect/turf_decal/stripes/line,
-/obj/machinery/light/small/directional/north,
-/turf/open/floor/iron/dark,
-/area/station/ai_monitored/turret_protected/ai)
"tpZ" = (
/turf/closed/wall,
/area/station/maintenance/starboard/fore)
@@ -78607,6 +78581,12 @@
/obj/structure/sign/poster/official/random/directional/west,
/turf/open/floor/wood,
/area/station/maintenance/port/fore)
+"tFu" = (
+/obj/structure/cable,
+/obj/machinery/firealarm/directional/east,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/iron,
+/area/station/engineering/storage_shared)
"tFG" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
@@ -80201,6 +80181,14 @@
},
/turf/open/floor/iron,
/area/station/hallway/secondary/command)
+"tYN" = (
+/obj/machinery/airalarm/directional/west,
+/obj/effect/turf_decal/trimline/brown/filled/line{
+ dir = 4
+ },
+/obj/machinery/recharge_station,
+/turf/open/floor/iron,
+/area/station/science/research)
"tYP" = (
/obj/structure/chair/office/light,
/obj/structure/cable,
@@ -80366,6 +80354,12 @@
},
/turf/open/floor/iron,
/area/station/medical/abandoned)
+"ubJ" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/cable,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/service)
"ubK" = (
/obj/machinery/computer/operating,
/obj/effect/turf_decal/tile/neutral/fourcorners,
@@ -83002,12 +82996,6 @@
/obj/effect/turf_decal/tile/neutral,
/turf/open/floor/iron,
/area/station/hallway/secondary/exit)
-"uJl" = (
-/obj/effect/turf_decal/bot,
-/obj/machinery/holopad,
-/obj/effect/landmark/start/hangover,
-/turf/open/floor/iron/checker,
-/area/station/hallway/secondary/service)
"uJm" = (
/obj/effect/turf_decal/tile/neutral,
/turf/open/floor/iron,
@@ -83323,6 +83311,15 @@
/obj/effect/turf_decal/bot,
/turf/open/floor/iron,
/area/station/cargo/miningoffice)
+"uMT" = (
+/obj/machinery/disposal/bin,
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/disposalpipe/trunk{
+ dir = 1
+ },
+/obj/effect/turf_decal/bot,
+/turf/open/floor/iron/checker,
+/area/station/hallway/secondary/service)
"uMV" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -84272,13 +84269,6 @@
},
/turf/open/floor/iron,
/area/station/commons/fitness/recreation)
-"uZc" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron,
-/area/station/security/office)
"uZe" = (
/obj/machinery/door/window/brigdoor/left/directional/south{
name = "Coroner's Office";
@@ -85106,13 +85096,6 @@
},
/turf/open/floor/iron,
/area/station/maintenance/port/aft)
-"vke" = (
-/obj/structure/cable,
-/obj/machinery/power/smes/full,
-/obj/effect/turf_decal/bot,
-/obj/item/radio/intercom/directional/west,
-/turf/open/floor/iron,
-/area/station/engineering/gravity_generator)
"vkg" = (
/obj/effect/turf_decal/stripes/line{
dir = 8
@@ -85207,6 +85190,11 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/wood/large,
/area/station/service/barber)
+"vlS" = (
+/obj/structure/cable,
+/mob/living/basic/slime,
+/turf/open/floor/circuit/green,
+/area/station/science/xenobiology)
"vlY" = (
/obj/machinery/door/firedoor,
/obj/effect/turf_decal/stripes/line{
@@ -86959,6 +86947,9 @@
},
/turf/open/floor/iron,
/area/station/engineering/atmos)
+"vHq" = (
+/turf/open/floor/iron,
+/area/station/security/office)
"vHu" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -88645,13 +88636,6 @@
/obj/item/flashlight/lamp,
/turf/open/floor/wood,
/area/station/hallway/secondary/service)
-"wgz" = (
-/obj/effect/turf_decal/bot,
-/obj/structure/table,
-/obj/item/paper_bin,
-/obj/item/pen,
-/turf/open/floor/iron/checker,
-/area/station/hallway/secondary/service)
"wgC" = (
/obj/machinery/door/poddoor/shutters/radiation/preopen{
id = "engsm";
@@ -88999,17 +88983,6 @@
},
/turf/open/floor/iron/dark,
/area/station/command/bridge)
-"wkV" = (
-/obj/structure/sign/poster/official/random/directional/south,
-/obj/machinery/light/directional/south,
-/obj/structure/window/reinforced/spawner/directional/west,
-/obj/structure/disposalpipe/trunk{
- dir = 4
- },
-/obj/machinery/disposal/bin,
-/obj/effect/turf_decal/bot,
-/turf/open/floor/iron,
-/area/station/engineering/storage_shared)
"wlc" = (
/obj/structure/table/reinforced,
/obj/item/gun/energy/laser/carbine/practice{
@@ -90941,6 +90914,13 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/science/auxlab/firing_range)
+"wGm" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/item/kirbyplants/random,
+/turf/open/floor/iron,
+/area/station/engineering/storage_shared)
"wGs" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 4
@@ -91438,12 +91418,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/station/hallway/secondary/entry)
-"wOz" = (
-/obj/structure/chair/office/light,
-/obj/effect/landmark/start/virologist,
-/obj/effect/turf_decal/trimline/green/filled/warning,
-/turf/open/floor/iron/white,
-/area/station/medical/virology)
"wOP" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 9
@@ -91631,12 +91605,6 @@
/obj/structure/window/reinforced/spawner/directional/north,
/turf/open/floor/iron/grimy,
/area/station/command/heads_quarters/captain)
-"wRJ" = (
-/obj/structure/cable,
-/obj/machinery/firealarm/directional/east,
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/iron,
-/area/station/engineering/storage_shared)
"wRL" = (
/obj/effect/spawner/random/structure/crate,
/obj/machinery/light/small/broken/directional/west,
@@ -92877,6 +92845,16 @@
/obj/effect/turf_decal/trimline/neutral/warning,
/turf/open/floor/iron/dark/textured_half,
/area/station/medical/morgue)
+"xiu" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/status_display/evac/directional/north,
+/obj/structure/disposalpipe/segment{
+ dir = 10
+ },
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/service)
"xiB" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -93088,6 +93066,13 @@
/obj/effect/landmark/start/hangover,
/turf/open/floor/iron/dark,
/area/station/hallway/primary/central/fore)
+"xlf" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 1
+ },
+/obj/effect/landmark/event_spawn,
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/service)
"xls" = (
/obj/structure/table/reinforced,
/obj/item/storage/toolbox/mechanical,
@@ -93522,6 +93507,14 @@
},
/turf/open/floor/iron/dark,
/area/station/command/bridge)
+"xrS" = (
+/obj/structure/sign/warning/secure_area/directional/south,
+/obj/effect/turf_decal/trimline/purple/filled/line{
+ dir = 6
+ },
+/obj/item/kirbyplants/organic/plant10,
+/turf/open/floor/iron/white,
+/area/station/science/research)
"xsb" = (
/obj/item/kirbyplants/random,
/obj/effect/turf_decal/stripes/line{
@@ -95800,6 +95793,13 @@
/obj/machinery/duct,
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
+"xUs" = (
+/obj/effect/turf_decal/tile/red{
+ dir = 8
+ },
+/obj/item/kirbyplants/random,
+/turf/open/floor/iron,
+/area/station/security/office)
"xUv" = (
/obj/machinery/firealarm/directional/west,
/obj/structure/cable,
@@ -103565,7 +103565,7 @@ btH
btH
btH
bPC
-pOu
+rgH
bTq
jYp
vgi
@@ -105352,7 +105352,7 @@ alK
qPm
btH
btH
-tpX
+tdm
kXJ
bEl
xMy
@@ -117181,7 +117181,7 @@ xqR
qzc
kUx
kTV
-vke
+chv
dQl
oIE
fFu
@@ -118512,7 +118512,7 @@ pWL
jjm
rUl
rTW
-oRq
+vlS
rTW
oVW
oUe
@@ -120054,7 +120054,7 @@ kSA
jjm
nkj
rTW
-oRq
+vlS
rTW
oVW
fmi
@@ -120517,7 +120517,7 @@ fXF
jgZ
mrd
rDL
-qUL
+pQo
uCa
wkj
bqP
@@ -120774,7 +120774,7 @@ fXF
suH
ikV
gIk
-wkV
+ekF
leE
bfq
iFn
@@ -120815,7 +120815,7 @@ uKY
gcr
mQO
rTW
-oRq
+vlS
rTW
iWX
csO
@@ -121031,7 +121031,7 @@ nmi
xvf
oQJ
xJJ
-oBa
+wGm
uCa
aTz
ygM
@@ -121544,7 +121544,7 @@ wiZ
fXF
xkz
hwe
-wRJ
+tFu
vpV
uCa
gQk
@@ -126730,7 +126730,7 @@ nIa
hSf
ffb
cMn
-hkZ
+xrS
sIX
sIX
cLR
@@ -128272,15 +128272,15 @@ txc
pZM
ffb
dqP
-anU
+aFp
sIX
sIX
xbJ
sIX
sIX
-aCA
-aqU
-aJj
+mRl
+scp
+tYN
dNN
qMB
wtS
@@ -129304,7 +129304,7 @@ ikZ
oRh
oHq
wNV
-roh
+eyl
dNN
uMV
sEF
@@ -129563,7 +129563,7 @@ dNN
dNN
dNN
dNN
-oPF
+oLD
dCx
aJT
fDF
@@ -131407,7 +131407,7 @@ tgT
rZl
wjV
jpN
-mIg
+pDb
rJG
gqm
qYo
@@ -131910,8 +131910,8 @@ bMV
wjP
aaa
uUx
-oDw
-rIO
+clB
+hPH
qJA
gKl
ecC
@@ -131921,7 +131921,7 @@ gqm
jyT
wjV
sFR
-wOz
+lZV
fLV
gqm
qYo
@@ -132094,7 +132094,7 @@ fxs
lAg
kPM
pRS
-qLa
+pqo
nLS
xld
uqZ
@@ -132352,7 +132352,7 @@ rgW
vze
pRS
pRS
-eIu
+hWA
iaL
pRS
iaL
@@ -132608,7 +132608,7 @@ sEm
dEA
nxd
pRS
-mlM
+lZC
eGs
ykB
jpe
@@ -133078,7 +133078,7 @@ sid
sBG
sLz
vRB
-sgG
+gch
xMe
kVP
bSp
@@ -133334,8 +133334,8 @@ cnL
kfa
pPI
kVP
-sbZ
-oXX
+xiu
+uMT
jVP
kVP
pET
@@ -133591,8 +133591,8 @@ vdZ
qPp
pXt
kVP
-cVD
-uJl
+fWB
+rky
iXO
kVP
pgN
@@ -133848,8 +133848,8 @@ vBt
tyK
kVP
kVP
-jgG
-wgz
+pWB
+qsv
gMB
kVP
kVP
@@ -133893,7 +133893,7 @@ wmp
rgW
mGw
pRS
-paD
+kNB
lAv
nAz
jce
@@ -134105,11 +134105,11 @@ kVP
kVP
kVP
dUH
-cBB
-bJi
+ubJ
+xlf
giz
kVr
-hRU
+kix
kVP
sGS
qOT
@@ -135134,7 +135134,7 @@ mqV
kVP
giz
giz
-sYe
+qSC
lJJ
maV
ptC
@@ -135391,7 +135391,7 @@ kVP
kVP
vat
kVP
-hjH
+sRs
hUh
kVP
cAV
@@ -135648,7 +135648,7 @@ pOD
tWU
sSH
kVP
-scJ
+aUZ
qPX
kVP
aVE
@@ -136510,9 +136510,9 @@ umA
veM
veM
ako
-tpV
-cJQ
-gPH
+nFf
+hFQ
+fEV
uQF
ibh
cYk
@@ -136767,7 +136767,7 @@ oCo
fiU
jRJ
ako
-iOp
+lcl
dNc
dNc
dNc
@@ -137024,7 +137024,7 @@ euF
oCo
sJG
ako
-oUf
+mtD
rjO
oOI
oOI
@@ -137495,7 +137495,7 @@ ilI
ilI
ilI
hup
-mVX
+qlY
cMD
ilI
ilI
@@ -144471,7 +144471,7 @@ lsJ
ffP
gBi
tqy
-hYh
+msL
qMf
oci
bqS
@@ -149040,7 +149040,7 @@ nzR
gKp
gDP
rTG
-sGp
+xUs
ozu
dql
pWH
@@ -149554,8 +149554,8 @@ ieg
eIl
ieg
ieg
-uZc
-bDx
+fes
+vHq
dql
eBE
gIV
@@ -149800,7 +149800,7 @@ ouc
qWZ
iCo
krO
-qyK
+guZ
lET
gBA
xtf
@@ -149812,7 +149812,7 @@ bdx
lpI
iIb
tXW
-cfx
+kqI
vgK
wdC
lTt
@@ -150069,7 +150069,7 @@ sKp
tXJ
bkN
gCV
-lAe
+oRf
vgK
ljX
tLx
diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
index e66eb438644..de038813256 100644
--- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm
+++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm
@@ -1853,6 +1853,16 @@
/obj/structure/extinguisher_cabinet/directional/south,
/turf/open/floor/iron/white,
/area/station/science/robotics/lab)
+"aEK" = (
+/obj/machinery/atmospherics/components/binary/pump/off,
+/obj/machinery/airlock_sensor/incinerator_ordmix{
+ pixel_x = 24
+ },
+/obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden{
+ dir = 4
+ },
+/turf/open/floor/engine,
+/area/station/science/ordnance)
"aEM" = (
/obj/structure/sign/departments/cargo,
/turf/closed/wall/r_wall,
@@ -4336,6 +4346,10 @@
},
/turf/open/floor/iron/dark,
/area/station/service/hydroponics)
+"bqX" = (
+/obj/machinery/air_sensor/ordnance_burn_chamber,
+/turf/open/floor/engine/vacuum,
+/area/station/science/ordnance)
"bqY" = (
/obj/structure/closet,
/obj/effect/spawner/random/maintenance/two,
@@ -6204,6 +6218,14 @@
/obj/effect/landmark/blobstart,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
+"bPA" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 9
+ },
+/obj/effect/landmark/start/virologist,
+/obj/structure/chair/stool/directional/east,
+/turf/open/floor/iron/dark,
+/area/station/medical/virology)
"bPE" = (
/obj/structure/table,
/obj/item/radio/intercom/directional/east,
@@ -8226,6 +8248,10 @@
/obj/machinery/light/small/directional/west,
/turf/open/floor/wood,
/area/station/commons/vacant_room/office)
+"cuB" = (
+/obj/machinery/atmospherics/components/unary/outlet_injector/monitored/ordnance_burn_chamber_input,
+/turf/open/floor/engine/vacuum,
+/area/station/science/ordnance)
"cuJ" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 4
@@ -9893,13 +9919,6 @@
initial_gas_mix = "ICEMOON_ATMOS"
},
/area/icemoon/underground/explored)
-"cSm" = (
-/obj/machinery/mineral/processing_unit/gulag{
- dir = 1
- },
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/plating,
-/area/mine/laborcamp)
"cSu" = (
/obj/structure/disposalpipe/segment{
dir = 10
@@ -12647,12 +12666,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply,
/turf/open/floor/iron/dark,
/area/station/medical/virology)
-"dJk" = (
-/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/incinerator_ordmix{
- dir = 8
- },
-/turf/open/floor/engine,
-/area/station/science/ordnance)
"dJx" = (
/obj/structure/cable,
/obj/effect/spawner/structure/window/reinforced,
@@ -14910,6 +14923,10 @@
"evb" = (
/turf/open/floor/iron,
/area/station/service/janitor)
+"evc" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on,
+/turf/open/floor/engine/vacuum,
+/area/station/science/ordnance)
"evk" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -16606,14 +16623,16 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/white,
/area/station/medical/medbay/central)
+"eYz" = (
+/obj/machinery/mineral/processing_unit/gulag{
+ dir = 1
+ },
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/mine/laborcamp)
"eYC" = (
/turf/open/floor/iron/smooth,
/area/mine/laborcamp/security)
-"eYH" = (
-/obj/machinery/power/smes/full,
-/obj/structure/cable,
-/turf/open/floor/circuit,
-/area/station/ai_monitored/turret_protected/ai)
"eYL" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/closed/wall,
@@ -17645,6 +17664,11 @@
},
/turf/open/floor/carpet,
/area/station/service/theater)
+"fqM" = (
+/obj/machinery/power/smes/full,
+/obj/structure/cable,
+/turf/open/floor/circuit,
+/area/station/ai_monitored/turret_protected/ai)
"fqQ" = (
/obj/effect/turf_decal/stripes/corner{
dir = 1
@@ -18366,6 +18390,10 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/station/medical/medbay/lobby)
+"fCS" = (
+/obj/machinery/door/poddoor/incinerator_ordmix,
+/turf/open/floor/engine/vacuum,
+/area/station/science/ordnance)
"fCW" = (
/obj/structure/extinguisher_cabinet/directional/east,
/turf/open/floor/iron/dark/textured,
@@ -19319,10 +19347,6 @@
/obj/structure/sign/warning/electric_shock/directional/east,
/turf/open/floor/iron,
/area/station/hallway/primary/central)
-"fSG" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/closed/wall/r_wall,
-/area/station/science/ordnance)
"fTb" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -20969,10 +20993,6 @@
},
/turf/open/floor/iron,
/area/station/security/prison/visit)
-"grY" = (
-/obj/structure/gulag_vent/ice,
-/turf/open/misc/asteroid/snow/icemoon,
-/area/icemoon/underground/explored)
"gsk" = (
/obj/structure/reflector/single/anchored{
dir = 5
@@ -22771,10 +22791,6 @@
/obj/structure/cable,
/turf/open/floor/iron/dark,
/area/station/security/interrogation)
-"gWZ" = (
-/obj/machinery/atmospherics/components/unary/outlet_injector/monitored/ordnance_burn_chamber_input,
-/turf/open/floor/engine/vacuum,
-/area/station/science/ordnance)
"gXe" = (
/obj/effect/turf_decal/siding/white{
dir = 4
@@ -24054,13 +24070,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/plating,
/area/station/maintenance/port/aft)
-"hrZ" = (
-/obj/structure/chair/office/light{
- dir = 4
- },
-/obj/effect/landmark/start/virologist,
-/turf/open/floor/iron/white,
-/area/station/medical/virology)
"hsh" = (
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/plating,
@@ -25146,16 +25155,6 @@
/obj/machinery/airalarm/directional/north,
/turf/open/floor/iron,
/area/station/service/janitor)
-"hKj" = (
-/obj/machinery/atmospherics/components/binary/pump/off,
-/obj/machinery/airlock_sensor/incinerator_ordmix{
- pixel_x = 24
- },
-/obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden{
- dir = 4
- },
-/turf/open/floor/engine,
-/area/station/science/ordnance)
"hKr" = (
/obj/structure/table/glass,
/obj/item/book/manual/wiki/infections{
@@ -26040,10 +26039,6 @@
},
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
-"iao" = (
-/obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible,
-/turf/closed/wall/r_wall,
-/area/station/science/ordnance)
"iar" = (
/obj/structure/cable,
/obj/machinery/door/poddoor/preopen{
@@ -26927,10 +26922,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/chemistry)
-"inb" = (
-/obj/machinery/door/poddoor/incinerator_ordmix,
-/turf/open/floor/engine/vacuum,
-/area/station/science/ordnance)
"inh" = (
/obj/structure/stairs/west,
/obj/structure/railing,
@@ -27488,6 +27479,9 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
+"iwq" = (
+/turf/open/floor/engine/vacuum,
+/area/station/science/ordnance)
"iwx" = (
/obj/machinery/door/airlock/maintenance{
name = "Xenobiology Maintenance"
@@ -27661,15 +27655,6 @@
/obj/effect/spawner/structure/window/reinforced/tinted,
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
-"izc" = (
-/obj/machinery/atmospherics/components/binary/pump/on{
- dir = 1
- },
-/obj/machinery/atmospherics/pipe/layer_manifold/scrubbers/hidden{
- dir = 8
- },
-/turf/open/floor/engine,
-/area/station/science/ordnance)
"izn" = (
/obj/effect/spawner/random/decoration/generic,
/turf/open/floor/plating,
@@ -27903,6 +27888,10 @@
dir = 4
},
/area/station/science/explab)
+"iCe" = (
+/obj/machinery/atmospherics/pipe/smart/simple/dark/visible,
+/turf/closed/wall/r_wall,
+/area/station/science/ordnance)
"iCg" = (
/obj/effect/turf_decal/stripes/corner{
dir = 1
@@ -32830,9 +32819,6 @@
dir = 4
},
/area/station/maintenance/port/fore)
-"keV" = (
-/turf/open/floor/engine/vacuum,
-/area/station/science/ordnance)
"keX" = (
/obj/structure/table,
/obj/item/stack/cable_coil{
@@ -36520,6 +36506,15 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/catwalk_floor/iron_smooth,
/area/station/maintenance/port/fore)
+"lgP" = (
+/obj/machinery/atmospherics/components/binary/pump/on{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/layer_manifold/scrubbers/hidden{
+ dir = 8
+ },
+/turf/open/floor/engine,
+/area/station/science/ordnance)
"lgW" = (
/obj/machinery/meter/monitored/distro_loop,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/visible,
@@ -41332,14 +41327,6 @@
/obj/structure/cable,
/turf/open/floor/wood/parquet,
/area/station/service/bar/atrium)
-"mIC" = (
-/obj/machinery/door/airlock/research/glass/incinerator/ordmix_exterior{
- name = "Burn Chamber Exterior Airlock"
- },
-/obj/effect/mapping_helpers/airlock/locked,
-/obj/effect/mapping_helpers/airlock/access/all/science/ordnance,
-/turf/open/floor/engine/vacuum,
-/area/station/science/ordnance)
"mIE" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable,
@@ -42191,10 +42178,6 @@
},
/turf/open/floor/plating,
/area/station/hallway/secondary/entry)
-"mYd" = (
-/obj/machinery/air_sensor/ordnance_burn_chamber,
-/turf/open/floor/engine/vacuum,
-/area/station/science/ordnance)
"mYh" = (
/turf/open/floor/iron/dark,
/area/station/ai_monitored/turret_protected/ai)
@@ -44390,10 +44373,6 @@
},
/turf/open/floor/plating,
/area/station/maintenance/aft/greater)
-"nBV" = (
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on,
-/turf/open/floor/engine/vacuum,
-/area/station/science/ordnance)
"nCa" = (
/obj/structure/rack,
/obj/item/pickaxe,
@@ -45211,14 +45190,6 @@
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/plating,
/area/mine/mechbay)
-"nNB" = (
-/obj/effect/turf_decal/trimline/green/filled/line{
- dir = 9
- },
-/obj/effect/landmark/start/virologist,
-/obj/structure/chair/stool/directional/east,
-/turf/open/floor/iron/dark,
-/area/station/medical/virology)
"nNM" = (
/obj/machinery/door/airlock/maintenance,
/obj/effect/mapping_helpers/airlock/abandoned,
@@ -46008,6 +45979,10 @@
},
/turf/open/floor/iron/white,
/area/station/science/xenobiology)
+"ocd" = (
+/obj/machinery/igniter/incinerator_ordmix,
+/turf/open/floor/engine/vacuum,
+/area/station/science/ordnance)
"ocf" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -47731,23 +47706,6 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/maintenance/solars/starboard/fore)
-"oCs" = (
-/obj/structure/table,
-/obj/item/toy/figure/virologist{
- pixel_x = -8;
- pixel_y = 7
- },
-/obj/item/radio/headset/headset_med{
- pixel_x = -3;
- pixel_y = -2
- },
-/obj/item/book/manual/wiki/infections{
- pixel_x = 10;
- pixel_y = 2
- },
-/obj/effect/turf_decal/tile/green/full,
-/turf/open/floor/iron/dark/smooth_large,
-/area/station/medical/virology)
"oCv" = (
/obj/item/chair/plastic{
pixel_y = 10
@@ -56730,6 +56688,14 @@
/obj/effect/mapping_helpers/airlock/access/all/supply/mining,
/turf/open/floor/iron/dark/textured_half,
/area/mine/mechbay)
+"rmG" = (
+/obj/machinery/door/airlock/research/glass/incinerator/ordmix_exterior{
+ name = "Burn Chamber Exterior Airlock"
+ },
+/obj/effect/mapping_helpers/airlock/locked,
+/obj/effect/mapping_helpers/airlock/access/all/science/ordnance,
+/turf/open/floor/engine/vacuum,
+/area/station/science/ordnance)
"rmM" = (
/obj/machinery/disposal/bin,
/obj/structure/disposalpipe/trunk{
@@ -56873,6 +56839,10 @@
/obj/machinery/newscaster/directional/south,
/turf/open/floor/iron,
/area/station/science/explab)
+"roW" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/closed/wall/r_wall,
+/area/station/science/ordnance)
"roX" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/cable,
@@ -57449,6 +57419,12 @@
/obj/item/kirbyplants/random,
/turf/open/floor/wood,
/area/station/hallway/secondary/service)
+"ryX" = (
+/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/incinerator_ordmix{
+ dir = 8
+ },
+/turf/open/floor/engine,
+/area/station/science/ordnance)
"rza" = (
/obj/structure/disposalpipe/segment,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -60232,6 +60208,17 @@
dir = 8
},
/area/station/service/chapel)
+"sqH" = (
+/obj/machinery/door/airlock/research/glass/incinerator/ordmix_interior{
+ name = "Burn Chamber Interior Airlock"
+ },
+/obj/effect/mapping_helpers/airlock/locked,
+/obj/machinery/airlock_controller/incinerator_ordmix{
+ pixel_x = 24
+ },
+/obj/effect/mapping_helpers/airlock/access/all/science/ordnance,
+/turf/open/floor/engine,
+/area/station/science/ordnance)
"sqN" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -60385,6 +60372,10 @@
/obj/structure/sign/warning/secure_area,
/turf/closed/wall/r_wall,
/area/station/engineering/storage/tech)
+"ssu" = (
+/obj/structure/gulag_vent/ice,
+/turf/open/misc/asteroid/snow/icemoon,
+/area/icemoon/underground/explored)
"ssv" = (
/obj/effect/turf_decal/tile/neutral/fourcorners,
/obj/effect/turf_decal/siding/thinplating_new/corner,
@@ -61126,10 +61117,6 @@
/obj/structure/cable/multilayer/multiz,
/turf/open/floor/plating,
/area/station/maintenance/starboard/lesser)
-"sDA" = (
-/obj/machinery/igniter/incinerator_ordmix,
-/turf/open/floor/engine/vacuum,
-/area/station/science/ordnance)
"sDQ" = (
/obj/item/radio/intercom/prison/directional/north,
/obj/effect/turf_decal/tile/red/half/contrasted{
@@ -63973,6 +63960,13 @@
/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
/turf/open/floor/plating,
/area/station/commons/storage/mining)
+"tAr" = (
+/obj/structure/chair/office/light{
+ dir = 4
+ },
+/obj/effect/landmark/start/virologist,
+/turf/open/floor/iron/white,
+/area/station/medical/virology)
"tAx" = (
/obj/effect/turf_decal/trimline/blue/filled/warning,
/obj/structure/disposalpipe/segment,
@@ -66822,6 +66816,23 @@
},
/turf/open/floor/iron,
/area/station/hallway/secondary/exit/departure_lounge)
+"uvz" = (
+/obj/structure/table,
+/obj/item/toy/figure/virologist{
+ pixel_x = -8;
+ pixel_y = 7
+ },
+/obj/item/radio/headset/headset_med{
+ pixel_x = -3;
+ pixel_y = -2
+ },
+/obj/item/book/manual/wiki/infections{
+ pixel_x = 10;
+ pixel_y = 2
+ },
+/obj/effect/turf_decal/tile/green/full,
+/turf/open/floor/iron/dark/smooth_large,
+/area/station/medical/virology)
"uvM" = (
/obj/effect/spawner/structure/window/hollow/reinforced/middle,
/turf/open/floor/plating,
@@ -73904,10 +73915,6 @@
"wHc" = (
/turf/closed/wall/r_wall,
/area/station/command/heads_quarters/rd)
-"wHd" = (
-/obj/machinery/atmospherics/pipe/smart/simple/dark/visible,
-/turf/closed/wall/r_wall,
-/area/station/science/ordnance)
"wHe" = (
/obj/structure/cable,
/turf/open/floor/iron/dark/textured,
@@ -74039,6 +74046,10 @@
/obj/effect/landmark/start/depsec/medical,
/turf/open/floor/iron/dark/smooth_large,
/area/station/security/checkpoint/medical)
+"wKh" = (
+/obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible,
+/turf/closed/wall/r_wall,
+/area/station/science/ordnance)
"wKm" = (
/obj/effect/turf_decal/tile/neutral/diagonal_edge,
/obj/structure/disposalpipe/segment{
@@ -74374,17 +74385,6 @@
},
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
-"wPC" = (
-/obj/machinery/door/airlock/research/glass/incinerator/ordmix_interior{
- name = "Burn Chamber Interior Airlock"
- },
-/obj/effect/mapping_helpers/airlock/locked,
-/obj/machinery/airlock_controller/incinerator_ordmix{
- pixel_x = 24
- },
-/obj/effect/mapping_helpers/airlock/access/all/science/ordnance,
-/turf/open/floor/engine,
-/area/station/science/ordnance)
"wPD" = (
/obj/machinery/door/airlock/security/glass{
name = "Evidence Storage"
@@ -116641,7 +116641,7 @@ dhq
dhq
iDt
iDt
-grY
+ssu
iDt
dLN
rbT
@@ -116905,7 +116905,7 @@ rbT
lLN
vRO
ggV
-cSm
+eYz
tGP
tGP
iRp
@@ -183834,7 +183834,7 @@ cDb
vEJ
wGX
oQY
-hrZ
+tAr
wsF
jUB
jUB
@@ -184605,7 +184605,7 @@ uCe
xKe
dRz
pwn
-oCs
+uvz
aru
rqY
tAg
@@ -184863,7 +184863,7 @@ lzX
dRz
jUB
cAM
-nNB
+bPA
qkB
vqH
xDb
@@ -193606,8 +193606,8 @@ uIf
uIf
uIf
uIf
-fSG
-fSG
+roW
+roW
bId
gcy
jJG
@@ -193859,12 +193859,12 @@ thA
thA
rcY
iDt
-inb
-keV
-gWZ
-wHd
-izc
-wHd
+fCS
+iwq
+cuB
+iCe
+lgP
+iCe
vcH
gnq
xEF
@@ -194116,12 +194116,12 @@ thA
thA
rcY
iDt
-inb
-sDA
-mYd
-mIC
-dJk
-wPC
+fCS
+ocd
+bqX
+rmG
+ryX
+sqH
qSk
sbd
rEh
@@ -194373,12 +194373,12 @@ thA
thA
rcY
iDt
-inb
-keV
-nBV
-iao
-hKj
-iao
+fCS
+iwq
+evc
+wKh
+aEK
+wKh
odf
sbd
jaY
@@ -248686,7 +248686,7 @@ mlp
lEg
cvh
uBi
-eYH
+fqM
jIZ
oFx
iHp
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 2d414269001..d86c0c5d24d 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -945,8 +945,6 @@
/area/station/command/heads_quarters/hos)
"atf" = (
/obj/structure/table/glass,
-/obj/item/clothing/gloves/latex,
-/obj/item/surgical_drapes,
/obj/machinery/power/apc/auto_name/directional/north,
/obj/structure/cable,
/obj/effect/turf_decal/tile/blue/fourcorners,
@@ -4592,6 +4590,14 @@
/obj/machinery/light/floor,
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
+"bEv" = (
+/obj/machinery/door/airlock/research/glass/incinerator/ordmix_exterior{
+ name = "Burn Chamber Exterior Airlock"
+ },
+/obj/effect/mapping_helpers/airlock/locked,
+/obj/effect/mapping_helpers/airlock/access/all/science/ordnance,
+/turf/open/floor/engine/vacuum,
+/area/station/science/ordnance)
"bEA" = (
/obj/structure/cable,
/obj/machinery/camera/directional/south{
@@ -5043,12 +5049,6 @@
/area/station/security/execution/education)
"bMS" = (
/obj/structure/table/glass,
-/obj/item/scalpel{
- pixel_y = 12
- },
-/obj/item/circular_saw,
-/obj/item/blood_filter,
-/obj/item/bonesetter,
/obj/machinery/button/door/directional/south{
id = "main_surgery";
name = "privacy shutters control"
@@ -6019,6 +6019,10 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
+"cgP" = (
+/obj/machinery/air_sensor/ordnance_burn_chamber,
+/turf/open/floor/engine/vacuum,
+/area/station/science/ordnance)
"cha" = (
/obj/machinery/door/airlock/research/glass{
name = "Ordnance Lab"
@@ -7640,6 +7644,12 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/command/heads_quarters/cmo)
+"cOT" = (
+/obj/machinery/atmospherics/components/unary/outlet_injector/monitored/ordnance_burn_chamber_input{
+ dir = 1
+ },
+/turf/open/floor/engine/vacuum,
+/area/station/science/ordnance)
"cOX" = (
/obj/structure/sign/warning/radiation/rad_area/directional/north,
/obj/effect/turf_decal/stripes/line{
@@ -8844,10 +8854,6 @@
/obj/effect/turf_decal/bot_white,
/turf/open/floor/iron,
/area/station/cargo/storage)
-"dke" = (
-/obj/machinery/air_sensor/ordnance_burn_chamber,
-/turf/open/floor/engine/vacuum,
-/area/station/science/ordnance)
"dkx" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/white,
@@ -9484,12 +9490,10 @@
/area/station/hallway/secondary/exit/departure_lounge)
"dyq" = (
/obj/structure/table/glass,
-/obj/item/retractor,
-/obj/item/hemostat,
-/obj/item/cautery,
/obj/effect/turf_decal/tile/blue/fourcorners,
/obj/machinery/status_display/evac/directional/west,
/obj/machinery/digital_clock/directional/south,
+/obj/item/surgery_tray/full,
/turf/open/floor/iron/white,
/area/station/medical/surgery/theatre)
"dyr" = (
@@ -9705,6 +9709,14 @@
},
/turf/open/floor/iron,
/area/station/engineering/gravity_generator)
+"dEF" = (
+/obj/machinery/atmospherics/components/binary/pump/on,
+/obj/machinery/light/small/directional/east,
+/obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden{
+ dir = 4
+ },
+/turf/open/floor/engine,
+/area/station/science/ordnance)
"dEH" = (
/obj/effect/landmark/generic_maintenance_landmark,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
@@ -10810,6 +10822,9 @@
},
/turf/open/floor/iron/dark,
/area/station/security/execution/education)
+"dXU" = (
+/turf/open/floor/engine/vacuum,
+/area/station/science/ordnance)
"dYa" = (
/obj/effect/turf_decal/tile/blue/fourcorners,
/turf/open/floor/iron,
@@ -13278,6 +13293,10 @@
/obj/effect/turf_decal/trimline/blue/filled/line,
/turf/open/floor/iron/white,
/area/station/medical/cryo)
+"eRn" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/closed/wall/r_wall,
+/area/station/science/ordnance)
"eRR" = (
/obj/structure/table,
/obj/item/screwdriver{
@@ -14227,8 +14246,6 @@
/area/station/medical/medbay/central)
"fiK" = (
/obj/structure/table/glass,
-/obj/item/clothing/gloves/latex,
-/obj/item/surgical_drapes,
/obj/machinery/airalarm/directional/south,
/obj/effect/turf_decal/tile/blue/fourcorners,
/turf/open/floor/iron/white,
@@ -14672,11 +14689,9 @@
/area/station/ai_monitored/aisat/exterior)
"fpg" = (
/obj/structure/table/glass,
-/obj/item/retractor,
-/obj/item/hemostat,
-/obj/item/cautery,
/obj/effect/turf_decal/tile/blue/fourcorners,
/obj/machinery/status_display/evac/directional/west,
+/obj/item/surgery_tray/full,
/turf/open/floor/iron/white,
/area/station/medical/surgery/theatre)
"fpj" = (
@@ -14720,9 +14735,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/plating,
/area/station/maintenance/disposal)
-"fpM" = (
-/turf/open/floor/engine/vacuum,
-/area/station/science/ordnance)
"fqB" = (
/obj/effect/turf_decal/tile/neutral/fourcorners,
/obj/structure/cable,
@@ -15524,6 +15536,14 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/wood,
/area/station/command/heads_quarters/qm)
+"fIn" = (
+/obj/structure/chair/office/light{
+ dir = 8
+ },
+/obj/effect/landmark/start/virologist,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron/white,
+/area/station/medical/virology)
"fIo" = (
/obj/effect/turf_decal/bot_white,
/obj/effect/turf_decal/tile/neutral/fourcorners,
@@ -16727,6 +16747,18 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
+"gil" = (
+/obj/machinery/atmospherics/components/binary/pump{
+ dir = 1
+ },
+/obj/machinery/airlock_sensor/incinerator_ordmix{
+ pixel_x = -24
+ },
+/obj/machinery/atmospherics/pipe/layer_manifold/scrubbers/hidden{
+ dir = 4
+ },
+/turf/open/floor/engine,
+/area/station/science/ordnance)
"gip" = (
/obj/structure/table/wood,
/obj/machinery/fax{
@@ -20018,10 +20050,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/carpet,
/area/station/service/chapel)
-"hsY" = (
-/obj/machinery/igniter/incinerator_ordmix,
-/turf/open/floor/engine/vacuum,
-/area/station/science/ordnance)
"hsZ" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/turf/open/floor/wood,
@@ -20097,12 +20125,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/carpet,
/area/station/command/heads_quarters/hop)
-"htN" = (
-/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/incinerator_ordmix{
- dir = 8
- },
-/turf/open/floor/engine,
-/area/station/science/ordnance)
"htO" = (
/obj/structure/chair/office{
dir = 1
@@ -24264,18 +24286,6 @@
"iOr" = (
/turf/closed/wall/r_wall,
/area/station/security/prison/garden)
-"iOt" = (
-/obj/structure/table/glass,
-/obj/machinery/reagentgrinder{
- pixel_y = 8
- },
-/obj/item/toy/figure/virologist{
- pixel_x = -8
- },
-/obj/effect/turf_decal/tile/green/half/contrasted,
-/obj/machinery/light/small/directional/south,
-/turf/open/floor/iron/white,
-/area/station/medical/virology)
"iOD" = (
/obj/machinery/atmospherics/components/binary/tank_compressor{
dir = 8
@@ -25985,14 +25995,6 @@
/obj/effect/spawner/random/maintenance,
/turf/open/floor/iron,
/area/station/cargo/warehouse)
-"jrJ" = (
-/obj/machinery/atmospherics/components/binary/pump/on,
-/obj/machinery/light/small/directional/east,
-/obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden{
- dir = 4
- },
-/turf/open/floor/engine,
-/area/station/science/ordnance)
"jrL" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -28457,6 +28459,10 @@
/obj/effect/turf_decal/tile/green/half/contrasted,
/turf/open/floor/iron/white,
/area/station/medical/virology)
+"kgC" = (
+/obj/machinery/door/poddoor/incinerator_ordmix,
+/turf/open/floor/engine/vacuum,
+/area/station/science/ordnance)
"kgV" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -39126,6 +39132,12 @@
/obj/machinery/bookbinder,
/turf/open/floor/wood,
/area/station/service/library)
+"nZL" = (
+/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/incinerator_ordmix{
+ dir = 8
+ },
+/turf/open/floor/engine,
+/area/station/science/ordnance)
"nZQ" = (
/obj/machinery/airalarm/directional/north,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -39464,6 +39476,12 @@
/obj/effect/mapping_helpers/airlock/access/all/service/hydroponics,
/turf/open/floor/iron,
/area/station/service/hydroponics)
+"oet" = (
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
+ dir = 1
+ },
+/turf/open/floor/engine/vacuum,
+/area/station/science/ordnance)
"oew" = (
/turf/open/floor/iron,
/area/station/commons/fitness/recreation)
@@ -41350,14 +41368,6 @@
/obj/structure/marker_beacon/olive,
/turf/open/space/basic,
/area/space/nearstation)
-"oPY" = (
-/obj/structure/chair/office/light{
- dir = 8
- },
-/obj/effect/landmark/start/virologist,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron/white,
-/area/station/medical/virology)
"oPZ" = (
/obj/structure/grille,
/turf/open/floor/plating,
@@ -44763,12 +44773,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
-"qaW" = (
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
- dir = 1
- },
-/turf/open/floor/engine/vacuum,
-/area/station/science/ordnance)
"qbr" = (
/obj/structure/bed/medical{
dir = 4
@@ -48563,6 +48567,10 @@
},
/turf/open/floor/iron,
/area/station/ai_monitored/command/storage/eva)
+"rtj" = (
+/obj/machinery/igniter/incinerator_ordmix,
+/turf/open/floor/engine/vacuum,
+/area/station/science/ordnance)
"rtD" = (
/obj/effect/turf_decal/tile/purple,
/obj/machinery/light/directional/east,
@@ -49818,6 +49826,16 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
/area/station/security/prison/garden)
+"rOS" = (
+/obj/structure/cable,
+/obj/structure/chair/office/light,
+/obj/effect/landmark/start/virologist,
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/iron/white,
+/area/station/medical/virology)
"rOY" = (
/obj/structure/mirror/directional/east,
/obj/machinery/shower/directional/west,
@@ -50751,6 +50769,17 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating/airless,
/area/space/nearstation)
+"sft" = (
+/obj/machinery/power/smes/full,
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/flasher/directional/north{
+ id = "AI";
+ pixel_x = -22
+ },
+/obj/machinery/light/small/directional/north,
+/turf/open/floor/iron/dark,
+/area/station/ai_monitored/turret_protected/ai)
"sfu" = (
/obj/machinery/atmospherics/pipe/bridge_pipe/orange/hidden,
/turf/open/floor/iron/stairs/left{
@@ -51700,16 +51729,6 @@
/obj/machinery/duct,
/turf/open/floor/plating,
/area/station/maintenance/fore)
-"syT" = (
-/obj/structure/cable,
-/obj/structure/chair/office/light,
-/obj/effect/landmark/start/virologist,
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 1
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron/white,
-/area/station/medical/virology)
"syV" = (
/obj/effect/turf_decal/arrows/white{
color = "#0000FF";
@@ -53434,10 +53453,6 @@
/obj/structure/bookcase/random/nonfiction,
/turf/open/floor/wood,
/area/station/service/library)
-"tcd" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/closed/wall/r_wall,
-/area/station/science/ordnance)
"tck" = (
/obj/structure/extinguisher_cabinet/directional/north,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -54101,12 +54116,6 @@
/obj/effect/turf_decal/tile/red,
/turf/open/floor/iron,
/area/station/hallway/primary/fore)
-"tnR" = (
-/obj/machinery/atmospherics/components/unary/outlet_injector/monitored/ordnance_burn_chamber_input{
- dir = 1
- },
-/turf/open/floor/engine/vacuum,
-/area/station/science/ordnance)
"tot" = (
/obj/structure/table/wood,
/obj/item/paper_bin{
@@ -55501,12 +55510,6 @@
/area/station/medical/virology)
"tOT" = (
/obj/structure/table/glass,
-/obj/item/scalpel{
- pixel_y = 12
- },
-/obj/item/circular_saw,
-/obj/item/blood_filter,
-/obj/item/bonesetter,
/obj/machinery/button/door/directional/north{
id = "main_surgery";
name = "privacy shutters control"
@@ -55897,17 +55900,6 @@
/obj/structure/table/wood,
/turf/open/floor/carpet,
/area/station/service/chapel/funeral)
-"tVC" = (
-/obj/machinery/power/smes/full,
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/flasher/directional/north{
- id = "AI";
- pixel_x = -22
- },
-/obj/machinery/light/small/directional/north,
-/turf/open/floor/iron/dark,
-/area/station/ai_monitored/turret_protected/ai)
"tVG" = (
/obj/machinery/atmospherics/components/unary/portables_connector/visible,
/obj/machinery/firealarm/directional/north,
@@ -58665,6 +58657,18 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
/area/station/maintenance/port)
+"uTy" = (
+/obj/structure/table/glass,
+/obj/machinery/reagentgrinder{
+ pixel_y = 8
+ },
+/obj/item/toy/figure/virologist{
+ pixel_x = -8
+ },
+/obj/effect/turf_decal/tile/green/half/contrasted,
+/obj/machinery/light/small/directional/south,
+/turf/open/floor/iron/white,
+/area/station/medical/virology)
"uTF" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/security/glass{
@@ -61184,18 +61188,6 @@
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/science/xenobiology)
-"vJs" = (
-/obj/machinery/atmospherics/components/binary/pump{
- dir = 1
- },
-/obj/machinery/airlock_sensor/incinerator_ordmix{
- pixel_x = -24
- },
-/obj/machinery/atmospherics/pipe/layer_manifold/scrubbers/hidden{
- dir = 4
- },
-/turf/open/floor/engine,
-/area/station/science/ordnance)
"vJy" = (
/obj/structure/rack,
/obj/item/stack/sheet/cardboard,
@@ -61218,14 +61210,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/port)
-"vJN" = (
-/obj/machinery/door/airlock/research/glass/incinerator/ordmix_exterior{
- name = "Burn Chamber Exterior Airlock"
- },
-/obj/effect/mapping_helpers/airlock/locked,
-/obj/effect/mapping_helpers/airlock/access/all/science/ordnance,
-/turf/open/floor/engine/vacuum,
-/area/station/science/ordnance)
"vJX" = (
/obj/structure/cable,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
@@ -61426,10 +61410,6 @@
},
/turf/open/space,
/area/space/nearstation)
-"vOe" = (
-/obj/machinery/door/poddoor/incinerator_ordmix,
-/turf/open/floor/engine/vacuum,
-/area/station/science/ordnance)
"vOh" = (
/obj/effect/turf_decal/stripes/end,
/turf/open/floor/plating/airless,
@@ -82761,8 +82741,8 @@ xjH
pIU
dno
uKy
-oPY
-iOt
+fIn
+uTy
xjH
nzQ
vol
@@ -83539,7 +83519,7 @@ pWX
eYE
hcR
gqV
-syT
+rOS
vUH
rUE
suP
@@ -99736,7 +99716,7 @@ fhi
uEo
fiS
gyQ
-tcd
+eRn
gyQ
gyQ
gyQ
@@ -99993,11 +99973,11 @@ fhi
xEU
iqx
xYZ
-vJs
+gil
xYZ
-qaW
-fpM
-vOe
+oet
+dXU
+kgC
lMJ
uGg
nFa
@@ -100250,11 +100230,11 @@ fhi
fhi
twy
nJA
-htN
-vJN
-dke
-hsY
-vOe
+nZL
+bEv
+cgP
+rtj
+kgC
lMJ
uGg
nFa
@@ -100507,11 +100487,11 @@ jvo
aHH
iYE
dTN
-jrJ
+dEF
dTN
-tnR
-fpM
-vOe
+cOT
+dXU
+kgC
lMJ
uGg
wpn
@@ -123304,7 +123284,7 @@ qyc
jZC
pan
mbS
-tVC
+sft
mCL
aWO
aYz
diff --git a/_maps/map_files/Mining/Lavaland.dmm b/_maps/map_files/Mining/Lavaland.dmm
index 6a1d703aea4..7cf30212586 100644
--- a/_maps/map_files/Mining/Lavaland.dmm
+++ b/_maps/map_files/Mining/Lavaland.dmm
@@ -125,6 +125,14 @@
},
/turf/open/floor/iron/checker,
/area/mine/laborcamp)
+"aQ" = (
+/obj/machinery/door/airlock/maintenance{
+ name = "Mining Station Maintenance"
+ },
+/obj/structure/cable,
+/obj/effect/mapping_helpers/airlock/access/all/engineering/general,
+/turf/open/floor/plating,
+/area/mine/maintenance/service)
"aV" = (
/obj/structure/marker_beacon/teal,
/obj/effect/turf_decal/sand/plating/volcanic,
@@ -870,10 +878,6 @@
},
/turf/open/floor/plating/lavaland_atmos,
/area/lavaland/surface/outdoors)
-"fP" = (
-/obj/structure/gulag_vent,
-/turf/open/misc/asteroid/basalt/lava_land_surface,
-/area/lavaland/surface/outdoors)
"fQ" = (
/turf/open/genturf,
/area/lavaland/surface/outdoors/unexplored/danger)
@@ -2834,12 +2838,6 @@
/obj/effect/spawner/random/trash/mess,
/turf/open/floor/iron/white,
/area/mine/laborcamp/production)
-"ps" = (
-/obj/structure/cable,
-/obj/machinery/power/smes/full,
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/plating,
-/area/mine/maintenance/service)
"pu" = (
/obj/item/chair/stool{
pixel_x = -2;
@@ -3416,15 +3414,6 @@
dir = 4
},
/area/mine/cafeteria)
-"tg" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/door/airlock/maintenance{
- name = "Mining Station Maintenance"
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/mapping_helpers/airlock/access/all/engineering/atmos,
-/turf/open/floor/plating,
-/area/mine/maintenance/service)
"ti" = (
/obj/structure/table,
/obj/effect/turf_decal/trimline/blue/filled/line{
@@ -3670,14 +3659,6 @@
/obj/effect/turf_decal/trimline/blue/filled/line,
/turf/open/floor/iron/white/smooth_corner,
/area/mine/medical)
-"vc" = (
-/obj/machinery/door/airlock/maintenance{
- name = "Mining Station Maintenance"
- },
-/obj/structure/cable,
-/obj/effect/mapping_helpers/airlock/access/all/engineering/general,
-/turf/open/floor/plating,
-/area/mine/maintenance/service)
"vd" = (
/obj/structure/railing/corner{
dir = 1
@@ -4107,16 +4088,6 @@
/obj/effect/turf_decal/sand/plating/volcanic,
/turf/open/floor/plating/lavaland_atmos,
/area/mine/maintenance/service/disposals)
-"xI" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/door/airlock/maintenance{
- name = "Mining Station Maintenance"
- },
-/obj/structure/cable,
-/obj/effect/mapping_helpers/airlock/access/all/engineering/tcoms,
-/turf/open/floor/plating,
-/area/mine/maintenance/service/comms)
"xJ" = (
/obj/machinery/vending/coffee,
/obj/effect/turf_decal/tile/blue/fourcorners,
@@ -4164,6 +4135,10 @@
dir = 1
},
/area/mine/storage/public)
+"xX" = (
+/obj/structure/gulag_vent,
+/turf/open/misc/asteroid/basalt/lava_land_surface,
+/area/lavaland/surface/outdoors)
"yc" = (
/obj/docking_port/stationary{
dir = 2;
@@ -4490,6 +4465,14 @@
/obj/structure/lattice/catwalk,
/turf/open/misc/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"Af" = (
+/obj/machinery/mineral/processing_unit/gulag{
+ dir = 1;
+ input_dir = 8;
+ output_dir = 4
+ },
+/turf/open/floor/plating,
+/area/mine/laborcamp/production)
"Ai" = (
/obj/structure/stone_tile/cracked{
dir = 1
@@ -4957,11 +4940,6 @@
/obj/effect/turf_decal/sand/plating/volcanic,
/turf/open/floor/plating/lavaland_atmos,
/area/lavaland/surface/outdoors)
-"Ee" = (
-/obj/machinery/power/smes/full,
-/obj/structure/cable,
-/turf/open/floor/plating,
-/area/mine/maintenance/labor)
"Eg" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/disposalpipe/segment,
@@ -5083,6 +5061,15 @@
/obj/machinery/power/apc/auto_name/directional/east,
/turf/open/floor/plating,
/area/mine/maintenance/service)
+"EV" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/door/airlock/maintenance{
+ name = "Mining Station Maintenance"
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/mapping_helpers/airlock/access/all/engineering/atmos,
+/turf/open/floor/plating,
+/area/mine/maintenance/service)
"EX" = (
/obj/structure/disposalpipe/segment{
dir = 5
@@ -5118,6 +5105,16 @@
"Ff" = (
/turf/open/floor/glass/reinforced,
/area/mine/lounge)
+"Fk" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/door/airlock/maintenance{
+ name = "Mining Station Maintenance"
+ },
+/obj/structure/cable,
+/obj/effect/mapping_helpers/airlock/access/all/engineering/tcoms,
+/turf/open/floor/plating,
+/area/mine/maintenance/service/comms)
"Fn" = (
/obj/structure/stone_tile/cracked{
dir = 4
@@ -6022,12 +6019,24 @@
/obj/machinery/camera/autoname/directional/north,
/turf/open/floor/iron,
/area/mine/lounge)
+"KK" = (
+/obj/machinery/power/smes/full,
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/mine/maintenance/labor)
"KL" = (
/obj/effect/turf_decal/tile/bar/opposingcorners{
dir = 1
},
/turf/open/floor/iron/checker,
/area/mine/cafeteria)
+"KT" = (
+/obj/machinery/door/airlock/maintenance{
+ name = "Mining Station Maintenance"
+ },
+/obj/effect/mapping_helpers/airlock/access/any/engineering/maintenance,
+/turf/open/floor/plating,
+/area/mine/maintenance/service)
"KV" = (
/obj/structure/table,
/obj/machinery/light/directional/east,
@@ -6253,14 +6262,6 @@
},
/turf/open/floor/plating/lavaland_atmos,
/area/lavaland/surface/outdoors)
-"LT" = (
-/obj/machinery/mineral/processing_unit/gulag{
- dir = 1;
- input_dir = 8;
- output_dir = 4
- },
-/turf/open/floor/plating,
-/area/mine/laborcamp/production)
"LY" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 8
@@ -7476,13 +7477,6 @@
},
/turf/open/floor/iron/dark/smooth_edge,
/area/mine/laborcamp/security)
-"TV" = (
-/obj/machinery/door/airlock/maintenance{
- name = "Mining Station Maintenance"
- },
-/obj/effect/mapping_helpers/airlock/access/any/engineering/maintenance,
-/turf/open/floor/plating,
-/area/mine/maintenance/service)
"TW" = (
/obj/machinery/door/airlock/maintenance{
name = "Mining Station Storage"
@@ -8043,6 +8037,12 @@
dir = 4
},
/area/mine/production)
+"Xk" = (
+/obj/structure/cable,
+/obj/machinery/power/smes/full,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/mine/maintenance/service)
"Xp" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -22573,7 +22573,7 @@ uU
uU
uU
pU
-fP
+xX
pU
ff
Gf
@@ -24377,7 +24377,7 @@ Hd
Nb
NR
Kv
-LT
+Af
ff
gm
mN
@@ -28238,7 +28238,7 @@ Zt
Zt
Zt
Zt
-Ee
+KK
ve
RD
RD
@@ -37975,7 +37975,7 @@ ni
rZ
ni
ON
-TV
+KT
xD
xD
xD
@@ -38485,12 +38485,12 @@ Ue
AA
gB
ON
-ps
+Xk
gq
ER
-vc
+aQ
YR
-xI
+Fk
DF
Kn
xD
@@ -39514,7 +39514,7 @@ ON
ON
ON
ON
-tg
+EV
ON
ON
ON
diff --git a/_maps/map_files/NorthStar/north_star.dmm b/_maps/map_files/NorthStar/north_star.dmm
index 2e62e13527d..e87b973338c 100644
--- a/_maps/map_files/NorthStar/north_star.dmm
+++ b/_maps/map_files/NorthStar/north_star.dmm
@@ -800,16 +800,6 @@
/obj/structure/table,
/turf/open/floor/iron/dark,
/area/station/commons/storage/primary)
-"ajz" = (
-/obj/structure/railing/corner,
-/obj/structure/chair{
- dir = 4
- },
-/obj/effect/turf_decal/trimline/red/filled/corner,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/duct,
-/turf/open/floor/iron/dark/textured,
-/area/station/commons/fitness)
"ajB" = (
/obj/effect/spawner/random/trash/mopbucket,
/obj/effect/spawner/random/trash/soap,
@@ -7955,6 +7945,12 @@
/obj/structure/sign/poster/official/cleanliness/directional/east,
/turf/open/floor/iron/dark/smooth_large,
/area/station/hallway/secondary/entry)
+"bWZ" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/duct,
+/obj/machinery/camera/autoname/directional/north,
+/turf/open/floor/iron/dark/textured,
+/area/station/commons/fitness)
"bXd" = (
/obj/effect/turf_decal/trimline/purple/line,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -12179,14 +12175,6 @@
},
/turf/open/floor/iron/dark,
/area/station/hallway/secondary/service)
-"daa" = (
-/obj/machinery/camera/motion/directional/north{
- c_tag = "Minisat North"
- },
-/obj/machinery/power/smes/full,
-/obj/structure/cable,
-/turf/open/floor/circuit,
-/area/station/ai_monitored/turret_protected/aisat/service)
"dab" = (
/obj/effect/spawner/random/trash/garbage{
spawn_scatter_radius = 1
@@ -23327,6 +23315,14 @@
},
/turf/open/floor/pod/light,
/area/station/maintenance/floor3/starboard/fore)
+"gbO" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/green/opposingcorners,
+/obj/effect/landmark/start/virologist,
+/turf/open/floor/iron/white,
+/area/station/medical/virology)
"gbR" = (
/obj/structure/flora/bush/sparsegrass/style_random,
/obj/structure/flora/bush/sunny/style_random,
@@ -24752,12 +24748,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/plastic,
/area/station/security/prison/shower)
-"gvV" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/duct,
-/obj/machinery/camera/autoname/directional/north,
-/turf/open/floor/iron/dark/textured,
-/area/station/commons/fitness)
"gvX" = (
/obj/structure/sign/poster/official/random/directional/east,
/turf/open/floor/iron/dark/side{
@@ -27877,6 +27867,12 @@
/obj/item/airlock_painter/decal/tile,
/turf/open/floor/iron/dark,
/area/station/commons/storage/primary)
+"hmg" = (
+/obj/machinery/firealarm/directional/west,
+/obj/machinery/power/smes/full,
+/obj/structure/cable,
+/turf/open/floor/circuit,
+/area/station/ai_monitored/turret_protected/aisat_interior)
"hmn" = (
/obj/effect/turf_decal/siding/thinplating_new{
dir = 4
@@ -33619,6 +33615,14 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/pod/light,
/area/station/maintenance/floor3/starboard)
+"iKW" = (
+/obj/machinery/camera/motion/directional/north{
+ c_tag = "Minisat North"
+ },
+/obj/machinery/power/smes/full,
+/obj/structure/cable,
+/turf/open/floor/circuit,
+/area/station/ai_monitored/turret_protected/aisat/service)
"iLy" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 1
@@ -44192,6 +44196,13 @@
},
/turf/open/floor/carpet/blue,
/area/station/command/meeting_room)
+"ltH" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/duct,
+/obj/structure/sign/poster/contraband/hacking_guide/directional/north,
+/obj/structure/extinguisher_cabinet/directional/west,
+/turf/open/floor/iron/dark/textured,
+/area/station/commons/fitness)
"ltI" = (
/obj/effect/spawner/random/trash/graffiti{
pixel_y = -32
@@ -48598,13 +48609,6 @@
},
/turf/open/floor/plating,
/area/station/medical/abandoned)
-"mxS" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/duct,
-/obj/structure/sign/poster/contraband/hacking_guide/directional/north,
-/obj/structure/extinguisher_cabinet/directional/west,
-/turf/open/floor/iron/dark/textured,
-/area/station/commons/fitness)
"mxT" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -61919,11 +61923,6 @@
/obj/structure/extinguisher_cabinet/directional/east,
/turf/open/floor/iron/white,
/area/station/science/lobby)
-"pUB" = (
-/obj/machinery/power/smes/full,
-/obj/structure/cable,
-/turf/open/floor/circuit,
-/area/station/ai_monitored/turret_protected/aisat/service)
"pUC" = (
/obj/effect/spawner/random/trash/graffiti,
/turf/open/floor/pod/light,
@@ -63807,6 +63806,16 @@
},
/turf/open/floor/pod/light,
/area/station/maintenance/floor4/port/fore)
+"qtA" = (
+/obj/structure/railing/corner,
+/obj/structure/chair{
+ dir = 4
+ },
+/obj/effect/turf_decal/trimline/red/filled/corner,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/duct,
+/turf/open/floor/iron/dark/textured,
+/area/station/commons/fitness)
"qtH" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/filingcabinet/chestdrawer{
@@ -69135,6 +69144,11 @@
/obj/item/pen,
/turf/open/floor/iron/dark,
/area/station/security/interrogation)
+"rOa" = (
+/obj/machinery/power/smes/full,
+/obj/structure/cable,
+/turf/open/floor/circuit,
+/area/station/ai_monitored/turret_protected/aisat/service)
"rOb" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 1
@@ -70604,6 +70618,31 @@
dir = 1
},
/area/station/science/genetics)
+"sjj" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/cable,
+/obj/machinery/button/door/directional/west{
+ id = "viro-inner";
+ name = "Inner Virology Lockdown";
+ pixel_y = -8
+ },
+/obj/machinery/button/door/directional/west{
+ id = "viro-outer";
+ name = "Outer Virology Lockdown";
+ pixel_y = 8
+ },
+/obj/machinery/button/door/directional/west{
+ id = "viro-iso";
+ name = "Isolation Bolts";
+ normaldoorcontrol = 1;
+ pixel_x = -36;
+ specialfunctions = 4
+ },
+/obj/effect/turf_decal/tile/green/opposingcorners,
+/obj/effect/landmark/start/virologist,
+/turf/open/floor/iron/white,
+/area/station/medical/virology)
"sjs" = (
/obj/effect/mapping_helpers/airlock/access/any/engineering/ce,
/obj/machinery/door/airlock/engineering{
@@ -72945,31 +72984,6 @@
},
/turf/open/floor/pod/dark,
/area/station/maintenance/floor3/port/fore)
-"sPp" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/cable,
-/obj/machinery/button/door/directional/west{
- id = "viro-inner";
- name = "Inner Virology Lockdown";
- pixel_y = -8
- },
-/obj/machinery/button/door/directional/west{
- id = "viro-outer";
- name = "Outer Virology Lockdown";
- pixel_y = 8
- },
-/obj/machinery/button/door/directional/west{
- id = "viro-iso";
- name = "Isolation Bolts";
- normaldoorcontrol = 1;
- pixel_x = -36;
- specialfunctions = 4
- },
-/obj/effect/turf_decal/tile/green/opposingcorners,
-/obj/effect/landmark/start/virologist,
-/turf/open/floor/iron/white,
-/area/station/medical/virology)
"sPs" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/decal/cleanable/dirt,
@@ -76630,14 +76644,6 @@
},
/turf/open/floor/pod/dark,
/area/station/maintenance/floor3/port/aft)
-"tKr" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/green/opposingcorners,
-/obj/effect/landmark/start/virologist,
-/turf/open/floor/iron/white,
-/area/station/medical/virology)
"tKs" = (
/obj/structure/curtain,
/obj/structure/fans/tiny{
@@ -79797,12 +79803,6 @@
},
/turf/open/floor/iron/corner,
/area/station/maintenance/solars/starboard/fore)
-"uDR" = (
-/obj/machinery/firealarm/directional/west,
-/obj/machinery/power/smes/full,
-/obj/structure/cable,
-/turf/open/floor/circuit,
-/area/station/ai_monitored/turret_protected/aisat_interior)
"uDZ" = (
/obj/machinery/light/directional/north,
/obj/machinery/airalarm/directional/north,
@@ -195562,7 +195562,7 @@ mqc
mRQ
dVV
xNy
-sPp
+sjj
mcI
rPC
sJn
@@ -196076,7 +196076,7 @@ iOA
utl
doh
gJz
-tKr
+gbO
hwQ
piz
aWO
@@ -196590,7 +196590,7 @@ iOA
dfU
pZm
wJy
-tKr
+gbO
dVV
bLm
yhv
@@ -258010,8 +258010,8 @@ qrd
mcU
xCX
nWe
-mxS
-ajz
+ltH
+qtA
lGo
lNX
lNX
@@ -259038,7 +259038,7 @@ qrd
oeQ
xgb
nWe
-gvV
+bWZ
hwr
oWt
wJH
@@ -335641,7 +335641,7 @@ aFj
aFj
sOy
rZC
-uDR
+hmg
knY
sOy
vyR
@@ -336147,7 +336147,7 @@ oyh
oyh
aFj
aFj
-pUB
+rOa
kZZ
kum
kum
@@ -336918,7 +336918,7 @@ dkh
aFj
aFj
aFj
-daa
+iKW
kZZ
tOV
knH
diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm
index 456cf46196e..a06d87aceff 100644
--- a/_maps/map_files/tramstation/tramstation.dmm
+++ b/_maps/map_files/tramstation/tramstation.dmm
@@ -3403,6 +3403,16 @@
/obj/effect/spawner/random/engineering/tracking_beacon,
/turf/open/floor/iron/grimy,
/area/station/ai_monitored/turret_protected/aisat/foyer)
+"aus" = (
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 9
+ },
+/obj/structure/bed{
+ dir = 4
+ },
+/obj/effect/landmark/start/virologist,
+/turf/open/floor/iron/dark,
+/area/station/medical/virology)
"auz" = (
/turf/closed/wall,
/area/station/commons/vacant_room)
@@ -28959,6 +28969,14 @@
/obj/structure/sign/warning/electric_shock/directional/north,
/turf/open/floor/plating,
/area/station/science/xenobiology)
+"jqM" = (
+/obj/effect/landmark/event_spawn,
+/obj/structure/chair/stool/directional/east,
+/obj/effect/landmark/start/virologist,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/iron/white,
+/area/station/medical/virology)
"jqR" = (
/obj/structure/table,
/obj/effect/turf_decal/tile/neutral/fourcorners,
@@ -33445,16 +33463,6 @@
"kOE" = (
/turf/closed/wall,
/area/station/security/detectives_office)
-"kOL" = (
-/obj/effect/turf_decal/trimline/green/filled/line{
- dir = 9
- },
-/obj/structure/bed{
- dir = 4
- },
-/obj/effect/landmark/start/virologist,
-/turf/open/floor/iron/dark,
-/area/station/medical/virology)
"kPf" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 4
@@ -33966,13 +33974,6 @@
},
/turf/open/space/openspace,
/area/station/solars/port)
-"kXq" = (
-/obj/structure/cable/multilayer/multiz,
-/obj/effect/turf_decal/stripes/line{
- dir = 4
- },
-/turf/open/floor/plating,
-/area/station/ai_monitored/turret_protected/ai)
"kXr" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
@@ -34727,11 +34728,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/secondary/construction/engineering)
-"llW" = (
-/obj/machinery/power/smes/full,
-/obj/structure/cable,
-/turf/open/floor/circuit,
-/area/station/ai_monitored/turret_protected/ai)
"lml" = (
/turf/closed/wall/r_wall,
/area/station/engineering/atmos/pumproom)
@@ -42893,6 +42889,11 @@
"oca" = (
/turf/closed/wall,
/area/station/construction/mining/aux_base)
+"ocl" = (
+/obj/machinery/power/smes/full,
+/obj/structure/cable,
+/turf/open/floor/circuit,
+/area/station/ai_monitored/turret_protected/ai)
"ocn" = (
/obj/structure/table/wood,
/obj/machinery/reagentgrinder,
@@ -65311,6 +65312,13 @@
},
/turf/open/floor/plating,
/area/station/construction/mining/aux_base)
+"vTD" = (
+/obj/structure/cable/multilayer/multiz,
+/obj/effect/turf_decal/stripes/line{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/station/ai_monitored/turret_protected/ai)
"vTE" = (
/obj/machinery/camera{
dir = 9;
@@ -67094,14 +67102,6 @@
},
/turf/open/floor/iron/freezer,
/area/station/medical/coldroom)
-"wDt" = (
-/obj/effect/landmark/event_spawn,
-/obj/structure/chair/stool/directional/east,
-/obj/effect/landmark/start/virologist,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron/white,
-/area/station/medical/virology)
"wDv" = (
/obj/structure/rack,
/obj/item/controller{
@@ -172639,7 +172639,7 @@ bWk
svF
xrG
kow
-wDt
+jqM
jqY
jqY
jqY
@@ -173147,7 +173147,7 @@ whz
aaa
aaa
ugt
-kOL
+aus
vrJ
aPS
tMb
@@ -185801,7 +185801,7 @@ jLx
ffe
mgi
pIQ
-llW
+ocl
xZx
rSB
dVM
@@ -186314,7 +186314,7 @@ mYB
njC
aoh
iUO
-kXq
+vTD
lxi
njC
mEb
diff --git a/_maps/shuttles/pirate_medieval.dmm b/_maps/shuttles/pirate_medieval.dmm
new file mode 100644
index 00000000000..03441b8a652
--- /dev/null
+++ b/_maps/shuttles/pirate_medieval.dmm
@@ -0,0 +1,535 @@
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+"a" = (
+/turf/template_noop,
+/area/template_noop)
+"b" = (
+/obj/structure/table/wood,
+/obj/item/stack/sheet/mineral/wood/fifty{
+ pixel_y = 4
+ },
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"c" = (
+/obj/structure/fake_stairs/wood/directional/east,
+/obj/structure/window/reinforced/spawner/directional/north,
+/obj/structure/window/reinforced/spawner/directional/south,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
+ dir = 4
+ },
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"d" = (
+/obj/structure/fake_stairs/wood/directional/east,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
+ dir = 4
+ },
+/obj/structure/mineral_door/gold,
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"e" = (
+/obj/structure/window/reinforced/spawner/directional/west,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/spawner/random/trash/botanical_waste,
+/obj/effect/spawner/random/trash/garbage,
+/obj/effect/mob_spawn/ghost_role/human/pirate/medieval,
+/turf/open/floor/plating,
+/area/shuttle/pirate)
+"f" = (
+/obj/structure/window/reinforced/spawner/directional/east,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/spawner/random/trash/garbage,
+/turf/open/floor/plating,
+/area/shuttle/pirate)
+"g" = (
+/obj/structure/fans/tiny,
+/obj/structure/window/reinforced/spawner/directional/east,
+/obj/structure/mineral_door/iron,
+/turf/open/floor/plating,
+/area/shuttle/pirate)
+"h" = (
+/obj/structure/table/wood,
+/obj/item/spear/military{
+ pixel_y = 8;
+ pixel_x = -7
+ },
+/obj/item/spear/military{
+ pixel_y = 1;
+ pixel_x = -6
+ },
+/obj/item/spear/military{
+ pixel_y = -2;
+ pixel_x = 1
+ },
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"j" = (
+/obj/item/flashlight/lantern{
+ light_on = 1
+ },
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"k" = (
+/obj/structure/table/wood,
+/obj/item/restraints/legcuffs/bola/tactical,
+/obj/item/restraints/legcuffs/bola/tactical,
+/obj/item/restraints/legcuffs/bola/tactical,
+/obj/item/restraints/legcuffs/bola,
+/obj/item/restraints/legcuffs/bola,
+/obj/item/restraints/legcuffs/bola,
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"l" = (
+/obj/structure/fans/tiny,
+/obj/structure/mineral_door/iron,
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"m" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/turf_decal/arrows{
+ dir = 8
+ },
+/obj/effect/spawner/random/trash/cigbutt,
+/obj/effect/spawner/random/trash/botanical_waste,
+/obj/effect/mob_spawn/ghost_role/human/pirate/medieval,
+/obj/machinery/atmospherics/components/unary/vent_pump/on{
+ dir = 8
+ },
+/turf/open/floor/plating,
+/area/shuttle/pirate)
+"n" = (
+/obj/effect/decal/cleanable/vomit/old,
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"o" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/turf_decal/arrows{
+ dir = 4
+ },
+/obj/effect/spawner/random/trash/mess,
+/obj/effect/spawner/random/trash/garbage,
+/obj/effect/mob_spawn/ghost_role/human/pirate/medieval,
+/obj/machinery/atmospherics/components/unary/vent_pump/on{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/shuttle/pirate)
+"p" = (
+/turf/closed/wall/mineral/wood,
+/area/shuttle/pirate)
+"q" = (
+/obj/effect/mob_spawn/ghost_role/human/pirate/medieval/warlord,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
+ dir = 4
+ },
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"r" = (
+/obj/structure/window/reinforced/spawner/directional/east,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/spawner/random/trash/garbage,
+/obj/effect/mob_spawn/ghost_role/human/pirate/medieval,
+/turf/open/floor/plating,
+/area/shuttle/pirate)
+"s" = (
+/obj/structure/fans/tiny,
+/obj/structure/window/reinforced/spawner/directional/east,
+/obj/docking_port/mobile/pirate{
+ launch_status = 0;
+ movement_force = list("KNOCKDOWN"=0,"THROW"=0);
+ name = "Pirate Ship";
+ port_direction = 2
+ },
+/obj/docking_port/stationary{
+ dwidth = 11;
+ height = 16;
+ shuttle_id = "pirate_home";
+ name = "Deep Space";
+ width = 17
+ },
+/obj/structure/mineral_door/iron,
+/turf/open/floor/plating,
+/area/shuttle/pirate)
+"u" = (
+/obj/effect/decal/cleanable/blood/old,
+/obj/effect/decal/cleanable/blood/gibs/limb,
+/obj/effect/decal/cleanable/blood/gibs/body,
+/obj/item/food/meat/slab/human/mutant/zombie,
+/obj/item/kitchen/fork,
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"v" = (
+/obj/structure/window/reinforced/spawner/directional/west,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/spawner/random/trash/garbage,
+/turf/open/floor/plating,
+/area/shuttle/pirate)
+"w" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
+ dir = 4
+ },
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"x" = (
+/obj/structure/fake_stairs/wood/directional/west,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
+ dir = 4
+ },
+/obj/structure/mineral_door/gold,
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"y" = (
+/obj/machinery/shuttle_scrambler,
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"z" = (
+/obj/structure/fans/tiny,
+/obj/structure/window/reinforced/spawner/directional/west,
+/obj/structure/mineral_door/iron,
+/turf/open/floor/plating,
+/area/shuttle/pirate)
+"A" = (
+/obj/structure/window/reinforced/spawner/directional/east,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/item/reagent_containers/cup/glass/bottle/vodka,
+/turf/open/floor/plating,
+/area/shuttle/pirate)
+"C" = (
+/obj/machinery/airalarm/directional/west,
+/obj/effect/mapping_helpers/airalarm/all_access,
+/obj/effect/decal/cleanable/dirt/dust,
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"D" = (
+/obj/machinery/piratepad,
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"E" = (
+/obj/effect/spawner/structure/window/reinforced/plasma/plastitanium,
+/obj/structure/barricade/wooden/crude,
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"F" = (
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"G" = (
+/obj/machinery/computer/piratepad_control,
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"H" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/structure/chair/wood/wings,
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"I" = (
+/obj/structure/fake_stairs/wood/directional/west,
+/obj/structure/window/reinforced/spawner/directional/north,
+/obj/structure/window/reinforced/spawner/directional/south,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
+ dir = 4
+ },
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"J" = (
+/obj/effect/decal/cleanable/blood/gibs/old,
+/obj/item/food/burger/human,
+/obj/structure/table/wood,
+/obj/item/reagent_containers/cup/glass/bottle/rum{
+ pixel_y = 15;
+ pixel_x = -4
+ },
+/obj/item/reagent_containers/cup/glass/bottle/rum{
+ pixel_y = 8;
+ pixel_x = 8
+ },
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"K" = (
+/obj/structure/table/wood,
+/obj/item/stack/medical/poultice{
+ pixel_y = 6;
+ pixel_x = -3
+ },
+/obj/item/stack/medical/poultice{
+ pixel_y = -3;
+ pixel_x = 5
+ },
+/obj/item/storage/medkit/fire,
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"L" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on{
+ dir = 1
+ },
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"M" = (
+/obj/structure/window/reinforced/spawner/directional/west,
+/obj/effect/spawner/random/trash/graffiti,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/effect/spawner/random/trash/garbage,
+/turf/open/floor/plating,
+/area/shuttle/pirate)
+"N" = (
+/obj/machinery/computer/shuttle/pirate/drop_pod,
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"O" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/structure/fermenting_barrel/thermite,
+/obj/item/reagent_containers/cup/beaker/large,
+/obj/item/reagent_containers/cup/beaker/large,
+/obj/item/reagent_containers/cup/beaker/large,
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"P" = (
+/obj/effect/decal/cleanable/glass,
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"Q" = (
+/obj/structure/closet/cabinet,
+/obj/item/claymore,
+/obj/item/shield/kite,
+/obj/item/shield/kite,
+/obj/item/shield/kite,
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"R" = (
+/obj/machinery/atmospherics/components/tank/air{
+ dir = 1
+ },
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"S" = (
+/obj/structure/frame/computer{
+ anchored = 1
+ },
+/obj/item/assault_pod/medieval,
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"T" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
+ dir = 4
+ },
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"U" = (
+/obj/machinery/loot_locator,
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"V" = (
+/obj/effect/spawner/structure/window/reinforced/plasma/plastitanium,
+/obj/structure/barricade/wooden/crude,
+/turf/open/floor/plating,
+/area/shuttle/pirate)
+"W" = (
+/obj/structure/table/wood,
+/obj/item/radio/intercom{
+ pixel_y = 5
+ },
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"X" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
+ dir = 4
+ },
+/obj/structure/table/wood,
+/obj/item/bodypart/head/skeleton{
+ pixel_x = -6
+ },
+/obj/item/bodypart/head/skeleton{
+ pixel_y = -2;
+ pixel_x = 5
+ },
+/obj/item/bodypart/head/skeleton{
+ pixel_x = 1;
+ pixel_y = 8
+ },
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"Y" = (
+/obj/effect/decal/cleanable/dirt/dust,
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+"Z" = (
+/obj/effect/decal/cleanable/dirt,
+/obj/item/flashlight/lantern{
+ light_on = 1
+ },
+/turf/open/floor/stone,
+/area/shuttle/pirate)
+
+(1,1,1) = {"
+a
+a
+p
+p
+l
+p
+p
+p
+a
+"}
+(2,1,1) = {"
+a
+a
+g
+f
+o
+r
+A
+s
+a
+"}
+(3,1,1) = {"
+a
+a
+a
+a
+I
+a
+a
+a
+a
+"}
+(4,1,1) = {"
+p
+p
+p
+p
+x
+p
+E
+p
+a
+"}
+(5,1,1) = {"
+a
+E
+R
+X
+T
+C
+Q
+p
+p
+"}
+(6,1,1) = {"
+p
+p
+W
+F
+T
+j
+Y
+h
+E
+"}
+(7,1,1) = {"
+a
+E
+N
+Y
+T
+Y
+F
+k
+p
+"}
+(8,1,1) = {"
+V
+V
+S
+P
+q
+L
+F
+F
+l
+"}
+(9,1,1) = {"
+a
+E
+y
+F
+w
+n
+H
+b
+p
+"}
+(10,1,1) = {"
+p
+p
+U
+F
+w
+Z
+u
+K
+E
+"}
+(11,1,1) = {"
+a
+E
+G
+D
+T
+O
+J
+p
+p
+"}
+(12,1,1) = {"
+p
+p
+p
+p
+d
+p
+E
+p
+a
+"}
+(13,1,1) = {"
+a
+a
+a
+a
+c
+a
+a
+a
+a
+"}
+(14,1,1) = {"
+a
+a
+z
+M
+m
+e
+v
+z
+a
+"}
+(15,1,1) = {"
+a
+a
+p
+p
+l
+p
+p
+p
+a
+"}
diff --git a/code/__DEFINES/ai/ai.dm b/code/__DEFINES/ai/ai.dm
index 24272a08d71..b8323c1c4e8 100644
--- a/code/__DEFINES/ai/ai.dm
+++ b/code/__DEFINES/ai/ai.dm
@@ -26,6 +26,16 @@
///Flags for ai_behavior new()
#define AI_CONTROLLER_INCOMPATIBLE (1<<0)
+//Return flags for ai_behavior/perform()
+///Update this behavior's cooldown
+#define AI_BEHAVIOR_DELAY (1<<0)
+///Finish the behavior successfully
+#define AI_BEHAVIOR_SUCCEEDED (1<<1)
+///Finish the behavior unsuccessfully
+#define AI_BEHAVIOR_FAILED (1<<2)
+
+#define AI_BEHAVIOR_INSTANT (NONE)
+
///Does this task require movement from the AI before it can be performed?
#define AI_BEHAVIOR_REQUIRE_MOVEMENT (1<<0)
///Does this require the current_movement_target to be adjacent and in reach?
diff --git a/code/__DEFINES/dcs/signals/signals_reagent.dm b/code/__DEFINES/dcs/signals/signals_reagent.dm
index 38d2ae92d9d..08993ad56de 100644
--- a/code/__DEFINES/dcs/signals/signals_reagent.dm
+++ b/code/__DEFINES/dcs/signals/signals_reagent.dm
@@ -19,8 +19,8 @@
///from base of [/datum/reagent/proc/expose_atom]: (/turf, reac_volume)
#define COMSIG_REAGENT_EXPOSE_TURF "reagent_expose_turf"
-///from base of [/datum/controller/subsystem/materials/proc/InitializeMaterial]: (/datum/material)
-#define COMSIG_MATERIALS_INIT_MAT "SSmaterials_init_mat"
+///from base of [/datum/system/materials/proc/InitializeMaterial]: (/datum/material)
+#define COMSIG_MATERIALS_INIT_MAT "DSmaterials_init_mat"
///from base of [/datum/component/multiple_lives/proc/respawn]: (mob/respawned_mob, gibbed, lives_left)
#define COMSIG_ON_MULTIPLE_LIVES_RESPAWN "on_multiple_lives_respawn"
diff --git a/code/__DEFINES/devices.dm b/code/__DEFINES/devices.dm
index 8f98f040dbc..afd41570b5b 100644
--- a/code/__DEFINES/devices.dm
+++ b/code/__DEFINES/devices.dm
@@ -8,8 +8,8 @@
#define INSPECTOR_PRINT_SOUND_MODE_FAFAFOGGY 4
#define BANANIUM_CLOWN_INSPECTOR_PRINT_SOUND_MODE_LAST 4
#define CLOWN_INSPECTOR_PRINT_SOUND_MODE_LAST 4
-#define INSPECTOR_ENERGY_USAGE_HONK (15 KILO JOULES)
-#define INSPECTOR_ENERGY_USAGE_NORMAL (5 KILO JOULES)
+#define INSPECTOR_ENERGY_USAGE_HONK (0.015 * STANDARD_CELL_CHARGE)
+#define INSPECTOR_ENERGY_USAGE_NORMAL (0.005 * STANDARD_CELL_CHARGE)
#define INSPECTOR_TIME_MODE_SLOW 1
#define INSPECTOR_TIME_MODE_FAST 2
#define INSPECTOR_TIME_MODE_HONK 3
diff --git a/code/__DEFINES/lights.dm b/code/__DEFINES/lights.dm
index 8830f919472..48d210fe031 100644
--- a/code/__DEFINES/lights.dm
+++ b/code/__DEFINES/lights.dm
@@ -1,5 +1,5 @@
///How much power emergency lights will consume per tick
-#define LIGHT_EMERGENCY_POWER_USE (0.1 KILO WATTS)
+#define LIGHT_EMERGENCY_POWER_USE (0.0001 * STANDARD_CELL_RATE)
// status values shared between lighting fixtures and items
#define LIGHT_OK 0
#define LIGHT_EMPTY 1
diff --git a/code/__DEFINES/melee.dm b/code/__DEFINES/melee.dm
index 9bef3e32d0d..7544b0176dc 100644
--- a/code/__DEFINES/melee.dm
+++ b/code/__DEFINES/melee.dm
@@ -1,6 +1,7 @@
//Martial arts defines
#define MARTIALART_BOXING "boxing"
+#define MARTIALART_EVIL_BOXING "evil boxing"
#define MARTIALART_CQC "CQC"
#define MARTIALART_KRAVMAGA "krav maga"
#define MARTIALART_MUSHPUNCH "mushroom punch"
diff --git a/code/__DEFINES/power.dm b/code/__DEFINES/power.dm
index 0eda3669a71..b9752eac351 100644
--- a/code/__DEFINES/power.dm
+++ b/code/__DEFINES/power.dm
@@ -19,8 +19,12 @@
///The joule is the standard unit of energy for this codebase. You can use this with other defines to clarify that it will not be multiplied by time.
#define JOULES * JOULE
-///The amount of energy, in joules, a standard powercell has.
-#define STANDARD_CELL_CHARGE (1 MEGA JOULES) // 1 MJ.
+///The capacity of a standard power cell
+#define STANDARD_CELL_VALUE (1 MEGA)
+ ///The amount of energy, in joules, a standard powercell has.
+ #define STANDARD_CELL_CHARGE (STANDARD_CELL_VALUE JOULES) // 1 MJ.
+ ///The amount of power, in watts, a standard powercell can give.
+ #define STANDARD_CELL_RATE (STANDARD_CELL_VALUE WATTS) // 1 MW.
GLOBAL_VAR_INIT(CHARGELEVEL, 0.01) // Cap for how fast cells charge, as a percentage per second (.01 means cellcharge is capped to 1% per second)
diff --git a/code/__DEFINES/pronouns.dm b/code/__DEFINES/pronouns.dm
new file mode 100644
index 00000000000..c0515426e35
--- /dev/null
+++ b/code/__DEFINES/pronouns.dm
@@ -0,0 +1,40 @@
+/// she, he, they, it "%PRONOUN_they" = "p_they"
+/// She, He, They, It "%PRONOUN_They" = "p_They"
+/// her, his, their, its "%PRONOUN_their" = "p_their"
+/// Her, His, Their, Its "%PRONOUN_Their" = "p_Their"
+/// hers, his, theirs, its "%PRONOUN_theirs" = "p_theirs"
+/// Hers, His, Theirs, Its "%PRONOUN_Theirs" = "p_Theirs"
+/// her, him, them, it "%PRONOUN_them" = "p_them"
+/// Her, Him, Them, It "%PRONOUN_Them" = "p_Them"
+/// has, have "%PRONOUN_have" = "p_have"
+/// is, are "%PRONOUN_are" = "p_are"
+/// was, were "%PRONOUN_were" = "p_were"
+/// does, do "%PRONOUN_do" = "p_do"
+/// she has, he has, they have, it has "%PRONOUN_theyve" = "p_theyve"
+/// She has, He has, They have, It has "%PRONOUN_Theyve" = "p_Theyve"
+/// she is, he is, they are, it is "%PRONOUN_theyre" = "p_theyre"
+/// She is, He is, They are, It is "%PRONOUN_Theyre" = "p_Theyre"
+/// s, null (she looks, they look) "%PRONOUN_s" = "p_s"
+/// es, null (she goes, they go) "%PRONOUN_es" = "p_es"
+
+/// A list for all the pronoun procs, if you need to iterate or search through it or something.
+#define ALL_PRONOUNS list( \
+ "%PRONOUN_they" = TYPE_PROC_REF(/datum, p_they), \
+ "%PRONOUN_They" = TYPE_PROC_REF(/datum, p_They), \
+ "%PRONOUN_their" = TYPE_PROC_REF(/datum, p_their), \
+ "%PRONOUN_Their" = TYPE_PROC_REF(/datum, p_Their), \
+ "%PRONOUN_theirs" = TYPE_PROC_REF(/datum, p_theirs), \
+ "%PRONOUN_Theirs" = TYPE_PROC_REF(/datum, p_Theirs), \
+ "%PRONOUN_them" = TYPE_PROC_REF(/datum, p_them), \
+ "%PRONOUN_Them" = TYPE_PROC_REF(/datum, p_Them), \
+ "%PRONOUN_have" = TYPE_PROC_REF(/datum, p_have), \
+ "%PRONOUN_are" = TYPE_PROC_REF(/datum, p_are), \
+ "%PRONOUN_were" = TYPE_PROC_REF(/datum, p_were), \
+ "%PRONOUN_do" = TYPE_PROC_REF(/datum, p_do), \
+ "%PRONOUN_theyve" = TYPE_PROC_REF(/datum, p_theyve), \
+ "%PRONOUN_Theyve" = TYPE_PROC_REF(/datum, p_Theyve), \
+ "%PRONOUN_theyre" = TYPE_PROC_REF(/datum, p_theyre), \
+ "%PRONOUN_Theyre" = TYPE_PROC_REF(/datum, p_Theyre), \
+ "%PRONOUN_s" = TYPE_PROC_REF(/datum, p_s), \
+ "%PRONOUN_es" = TYPE_PROC_REF(/datum, p_es) \
+)
diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm
index a24a929391f..3f84955fe98 100644
--- a/code/__DEFINES/sound.dm
+++ b/code/__DEFINES/sound.dm
@@ -2,7 +2,7 @@
#define CHANNEL_LOBBYMUSIC 1024
#define CHANNEL_ADMIN 1023
#define CHANNEL_VOX 1022
-#define CHANNEL_JUKEBOX 1011 // SKYRAT EDIT - JUKEBOX - ORIGINAL: #define CHANNEL_JUKEBOX 1021
+#define CHANNEL_JUKEBOX 1021
#define CHANNEL_HEARTBEAT 1020 //sound channel for heartbeats
#define CHANNEL_BOSS_MUSIC 1019
#define CHANNEL_AMBIENCE 1018
@@ -10,6 +10,11 @@
#define CHANNEL_TRAITOR 1016
#define CHANNEL_CHARGED_SPELL 1015
#define CHANNEL_ELEVATOR 1014
+//THIS SHOULD ALWAYS BE THE LOWEST ONE!
+//KEEP IT UPDATED
+#define CHANNEL_HIGHEST_AVAILABLE 1013
+
+#define MAX_INSTRUMENT_CHANNELS (128 * 6)
// SKYRAT EDIT START - JUKEBOX
#define CHANNEL_JUKEBOX_START 1006
@@ -28,13 +33,6 @@
///The default exponent of sound falloff
#define SOUND_FALLOFF_EXPONENT 6
-//THIS SHOULD ALWAYS BE THE LOWEST ONE!
-//KEEP IT UPDATED
-
-#define CHANNEL_HIGHEST_AVAILABLE 1005 //SKYRAT EDIT CHANGE - JUKEBOX > ORIGINAL VALUE 1015
-
-#define MAX_INSTRUMENT_CHANNELS (128 * 6)
-
#define SOUND_MINIMUM_PRESSURE 10
#define INTERACTION_SOUND_RANGE_MODIFIER -3
diff --git a/code/__DEFINES/tools.dm b/code/__DEFINES/tools.dm
index 99230559f7e..132ae196239 100644
--- a/code/__DEFINES/tools.dm
+++ b/code/__DEFINES/tools.dm
@@ -2,7 +2,7 @@
#define TOOL_CROWBAR "crowbar"
#define TOOL_MULTITOOL "multitool"
#define TOOL_SCREWDRIVER "screwdriver"
-#define TOOL_WIRECUTTER "wirecutter"
+#define TOOL_WIRECUTTER "cutters"
#define TOOL_WRENCH "wrench"
#define TOOL_WELDER "welder"
#define TOOL_ANALYZER "analyzer"
diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm
index 6a83f33083a..f2cb9069fb6 100644
--- a/code/__DEFINES/traits/declarations.dm
+++ b/code/__DEFINES/traits/declarations.dm
@@ -520,6 +520,15 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Prevents you from twohanding weapons.
#define TRAIT_NO_TWOHANDING "no_twohanding"
+/// Improves boxing damage against boxers and athletics experience gain
+#define TRAIT_STRENGTH "strength"
+
+/// Increases the duration of having exercised
+#define TRAIT_STIMMED "stimmed"
+
+/// Indicates that the target is able to be boxed at a boxer's full power.
+#define TRAIT_BOXING_READY "boxing_ready"
+
/// Halves the time of tying a tie.
#define TRAIT_FAST_TYING "fast_tying"
diff --git a/code/__DEFINES/traits/sources.dm b/code/__DEFINES/traits/sources.dm
index 56bcbf3c90d..278510bd23f 100644
--- a/code/__DEFINES/traits/sources.dm
+++ b/code/__DEFINES/traits/sources.dm
@@ -137,6 +137,7 @@
#define LOCKED_HELMET_TRAIT "locked-helmet"
#define NINJA_SUIT_TRAIT "ninja-suit"
#define SLEEPING_CARP_TRAIT "sleeping_carp"
+#define BOXING_TRAIT "boxing"
#define TIMESTOP_TRAIT "timestop"
#define LIFECANDLE_TRAIT "lifecandle"
#define VENTCRAWLING_TRAIT "ventcrawling"
diff --git a/code/__HELPERS/construction.dm b/code/__HELPERS/construction.dm
index f7b0ece13f8..cf38f690c26 100644
--- a/code/__HELPERS/construction.dm
+++ b/code/__HELPERS/construction.dm
@@ -2,7 +2,7 @@
#define OPTIMAL_COST(cost)(max(1, round(cost)))
/// Wrapper for fetching material references. Exists exclusively so that people don't need to wrap everything in a list every time.
-#define GET_MATERIAL_REF(arguments...) SSmaterials._GetMaterialRef(list(##arguments))
+#define GET_MATERIAL_REF(arguments...) DSmaterials._GetMaterialRef(list(##arguments))
// Wrapper to convert material name into its source name
#define MATERIAL_SOURCE(mat) "[mat.name]_material"
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
index d16b91ee4c8..30626bc0a55 100644
--- a/code/__HELPERS/global_lists.dm
+++ b/code/__HELPERS/global_lists.dm
@@ -165,8 +165,8 @@
GLOB.crafting_recipes += recipe
var/list/material_stack_recipes = list(
- SSmaterials.base_stack_recipes,
- SSmaterials.rigid_stack_recipes,
+ DSmaterials.base_stack_recipes,
+ DSmaterials.rigid_stack_recipes,
)
for(var/list/recipe_list in material_stack_recipes)
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index 1b93f024285..a6b23e08b49 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -251,23 +251,23 @@ GLOBAL_LIST_EMPTY(species_list)
*
* Checks that `user` does not move, change hands, get stunned, etc. for the
* given `delay`. Returns `TRUE` on success or `FALSE` on failure.
- *
+ *
* @param {mob} user - The mob performing the action.
- *
+ *
* @param {number} delay - The time in deciseconds. Use the SECONDS define for readability. `1 SECONDS` is 10 deciseconds.
- *
+ *
* @param {atom} target - The target of the action. This is where the progressbar will display.
- *
+ *
* @param {flag} timed_action_flags - Flags to control the behavior of the timed action.
- *
+ *
* @param {boolean} progress - Whether to display a progress bar / cogbar.
- *
+ *
* @param {datum/callback} extra_checks - Additional checks to perform before the action is executed.
- *
+ *
* @param {string} interaction_key - The assoc key under which the do_after is capped, with max_interact_count being the cap. Interaction key will default to target if not set.
- *
+ *
* @param {number} max_interact_count - The maximum amount of interactions allowed.
- *
+ *
* @param {boolean} hidden - By default, any action 1 second or longer shows a cog over the user while it is in progress. If hidden is set to TRUE, the cog will not be shown.
*/
/proc/do_after(mob/user, delay, atom/target, timed_action_flags = NONE, progress = TRUE, datum/callback/extra_checks, interaction_key, max_interact_count = 1, hidden = FALSE)
@@ -288,7 +288,7 @@ GLOBAL_LIST_EMPTY(species_list)
var/atom/target_loc = target?.loc
var/drifting = FALSE
- if(SSmove_manager.processing_on(user, SSspacedrift))
+ if(DSmove_manager.processing_on(user, SSspacedrift))
drifting = TRUE
var/holding = user.get_active_held_item()
@@ -317,7 +317,7 @@ GLOBAL_LIST_EMPTY(species_list)
if(!QDELETED(progbar))
progbar.update(world.time - starttime)
- if(drifting && !SSmove_manager.processing_on(user, SSspacedrift))
+ if(drifting && !DSmove_manager.processing_on(user, SSspacedrift))
drifting = FALSE
user_loc = user.loc
@@ -337,7 +337,7 @@ GLOBAL_LIST_EMPTY(species_list)
if(!QDELETED(progbar))
progbar.end_progress()
-
+
cog?.remove()
if(interaction_key)
diff --git a/code/__HELPERS/priority_announce.dm b/code/__HELPERS/priority_announce.dm
index d675b252796..380a8707fbe 100644
--- a/code/__HELPERS/priority_announce.dm
+++ b/code/__HELPERS/priority_announce.dm
@@ -107,7 +107,7 @@
message.title = title
message.content = text
- SScommunications.send_message(message)
+ DScommunications.send_message(message)
/**
* Sends a minor annoucement to players.
diff --git a/code/__HELPERS/pronouns.dm b/code/__HELPERS/pronouns.dm
index df84c1cdcf4..fe2357d6ce4 100644
--- a/code/__HELPERS/pronouns.dm
+++ b/code/__HELPERS/pronouns.dm
@@ -1,5 +1,8 @@
+#define GET_TARGET_PRONOUN(target, pronoun, gender) call(target, ALL_PRONOUNS[pronoun])(gender)
+
//pronoun procs, for getting pronouns without using the text macros that only work in certain positions
//datums don't have gender, but most of their subtypes do!
+
/datum/proc/p_they(temp_gender)
return "it"
@@ -69,6 +72,26 @@
else
return "s"
+/// A proc to replace pronouns in a string with the appropriate pronouns for a target atom.
+/// Uses associative list access from a __DEFINE list, since associative access is slightly
+/// faster
+/datum/proc/REPLACE_PRONOUNS(target_string, atom/targeted_atom, targeted_gender = null)
+ /// If someone specifies targeted_gender we choose that,
+ /// otherwise we go off the gender of our object
+ var/gender
+ if(targeted_gender)
+ if(!istext(targeted_gender) || !(targeted_gender in list(MALE, FEMALE, PLURAL, NEUTER)))
+ stack_trace("REPLACE_PRONOUNS called with improper parameters.")
+ return
+ gender = targeted_gender
+ else
+ gender = targeted_atom.gender
+ var/regex/pronoun_regex = regex("%PRONOUN(_(they|They|their|Their|theirs|Theirs|them|Them|have|are|were|do|theyve|Theyve|theyre|Theyre|s|es))")
+ while(pronoun_regex.Find(target_string))
+ target_string = pronoun_regex.Replace(target_string, GET_TARGET_PRONOUN(targeted_atom, pronoun_regex.match, gender))
+ return target_string
+
+
//like clients, which do have gender.
/client/p_they(temp_gender)
if(!temp_gender)
diff --git a/code/__HELPERS/view.dm b/code/__HELPERS/view.dm
index dc25dcc0249..30e8bc8f9f9 100644
--- a/code/__HELPERS/view.dm
+++ b/code/__HELPERS/view.dm
@@ -20,8 +20,23 @@
view_info[2] *= world.icon_size
return view_info
-/proc/in_view_range(mob/user, atom/A)
- var/list/view_range = getviewsize(user.client.view)
- var/turf/source = get_turf(user)
- var/turf/target = get_turf(A)
- return ISINRANGE(target.x, source.x - view_range[1], source.x + view_range[1]) && ISINRANGE(target.y, source.y - view_range[1], source.y + view_range[1])
+/**
+* Frustrated with bugs in can_see(), this instead uses viewers for a much more effective approach.
+* ### Things to note:
+* - Src/source must be a mob. `viewers()` returns mobs.
+* - Adjacent objects are always considered visible.
+*/
+
+/// The default tile-distance between two atoms for one to consider the other as visible.
+#define DEFAULT_SIGHT_DISTANCE 7
+
+/// Basic check to see if the src object can see the target object.
+#define CAN_I_SEE(target) ((src in viewers(DEFAULT_SIGHT_DISTANCE, target)) || in_range(target, src))
+
+
+/// Checks the visibility between two other objects.
+#define CAN_THEY_SEE(target, source) ((source in viewers(DEFAULT_SIGHT_DISTANCE, target)) || in_range(target, source))
+
+
+/// Further checks distance between source and target.
+#define CAN_SEE_RANGED(target, source, dist) ((source in viewers(dist, target)) || in_range(target, source))
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index e0f07ab2835..d298d24e3a0 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -343,6 +343,19 @@ DEFINE_BITFIELD(vis_flags, list(
"VIS_UNDERLAY" = VIS_UNDERLAY,
))
+// I am so sorry. Required because vis_flags is both undefinable and unreadable on mutable_appearance
+// But we need to display them anyway. See /mutable_appearance/appearance_mirror
+DEFINE_BITFIELD(_vis_flags, list(
+ "VIS_HIDE" = VIS_HIDE,
+ "VIS_INHERIT_DIR" = VIS_INHERIT_DIR,
+ "VIS_INHERIT_ICON" = VIS_INHERIT_ICON,
+ "VIS_INHERIT_ICON_STATE" = VIS_INHERIT_ICON_STATE,
+ "VIS_INHERIT_ID" = VIS_INHERIT_ID,
+ "VIS_INHERIT_LAYER" = VIS_INHERIT_LAYER,
+ "VIS_INHERIT_PLANE" = VIS_INHERIT_PLANE,
+ "VIS_UNDERLAY" = VIS_UNDERLAY,
+))
+
DEFINE_BITFIELD(zap_flags, list(
"ZAP_ALLOW_DUPLICATES" = ZAP_ALLOW_DUPLICATES,
"ZAP_MACHINE_EXPLOSIVE" = ZAP_MACHINE_EXPLOSIVE,
diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm
index f67ed4f6d07..9e3c2ed7ee0 100644
--- a/code/_globalvars/traits/_traits.dm
+++ b/code/_globalvars/traits/_traits.dm
@@ -498,6 +498,9 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_XRAY_VISION" = TRAIT_XRAY_VISION,
"TRAIT_DISCO_DANCER" = TRAIT_DISCO_DANCER,
"TRAIT_MAFIAINITIATE" = TRAIT_MAFIAINITIATE,
+ "TRAIT_STRENGTH" = TRAIT_STRENGTH,
+ "TRAIT_STIMMED" = TRAIT_STIMMED,
+ "TRAIT_BOXING_READY" = TRAIT_BOXING_READY,
),
/obj/item = list(
"TRAIT_APC_SHOCKING" = TRAIT_APC_SHOCKING,
diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm
index 0a6e54a46e0..ae5cc36b8ad 100644
--- a/code/_onclick/ai.dm
+++ b/code/_onclick/ai.dm
@@ -55,7 +55,7 @@
ShiftClickOn(A)
return
if(LAZYACCESS(modifiers, ALT_CLICK)) // alt and alt-gr (rightalt)
- A.ai_click_alt(src)
+ ai_base_click_alt(A)
return
if(LAZYACCESS(modifiers, CTRL_CLICK))
CtrlClickOn(A)
@@ -121,6 +121,24 @@
target.AICtrlClick(src)
+/// Reimplementation of base_click_alt for AI
+/mob/living/silicon/ai/proc/ai_base_click_alt(atom/target)
+ // If for some reason we can't alt click
+ if(SEND_SIGNAL(src, COMSIG_MOB_ALTCLICKON, target) & COMSIG_MOB_CANCEL_CLICKON)
+ return
+
+ if(!isturf(target) && can_perform_action(target, (target.interaction_flags_click | SILENT_ADJACENCY)))
+ // Signal intercept
+ if(SEND_SIGNAL(target, COMSIG_CLICK_ALT, src) & CLICK_ACTION_ANY)
+ return
+
+ // AI alt click interaction succeeds
+ if(target.ai_click_alt(src) & CLICK_ACTION_ANY)
+ return
+
+ client.loot_panel.open(get_turf(target))
+
+
/*
The following criminally helpful code is just the previous code cleaned up;
I have no idea why it was in atoms.dm instead of respective files.
@@ -132,6 +150,7 @@
return
/atom/proc/ai_click_alt(mob/living/silicon/ai/user)
+ SHOULD_CALL_PARENT(FALSE)
return
/atom/proc/AIShiftClick(mob/living/silicon/ai/user)
@@ -149,12 +168,13 @@
/obj/machinery/door/airlock/ai_click_alt(mob/living/silicon/ai/user)
if(obj_flags & EMAGGED)
- return
+ return NONE
if(!secondsElectrified)
shock_perm(user)
else
shock_restore(user)
+ return CLICK_ACTION_SUCCESS
/obj/machinery/door/airlock/AIShiftClick(mob/living/silicon/ai/user) // Opens and closes doors!
if(obj_flags & EMAGGED)
@@ -218,10 +238,10 @@
/// Toggle APC equipment settings
/obj/machinery/power/apc/ai_click_alt(mob/living/silicon/ai/user)
if(!can_use(user, loud = TRUE))
- return
+ return NONE
if(!is_operational || failure_timer)
- return
+ return CLICK_ACTION_BLOCKING
equipment = equipment ? APC_CHANNEL_OFF : APC_CHANNEL_ON
if (user)
@@ -231,6 +251,7 @@
user.log_message("turned [enabled_or_disabled] the [src] equipment settings", LOG_GAME)
update_appearance()
update()
+ return CLICK_ACTION_SUCCESS
/obj/machinery/power/apc/attack_ai_secondary(mob/living/silicon/user, list/modifiers)
if(!can_use(user, loud = TRUE))
@@ -242,8 +263,9 @@
/* AI Turrets */
/obj/machinery/turretid/ai_click_alt(mob/living/silicon/ai/user) //toggles lethal on turrets
if(ailock)
- return
+ return CLICK_ACTION_BLOCKING
toggle_lethal(user)
+ return CLICK_ACTION_SUCCESS
/obj/machinery/turretid/AICtrlClick(mob/living/silicon/ai/user) //turns off/on Turrets
if(ailock)
@@ -256,6 +278,7 @@
balloon_alert(user, "disrupted all active calls")
add_hiddenprint(user)
hangup_all_calls()
+ return CLICK_ACTION_SUCCESS
//
// Override TurfAdjacent for AltClicking
diff --git a/code/_onclick/click_alt.dm b/code/_onclick/click_alt.dm
index 16c8e843995..11419a60816 100644
--- a/code/_onclick/click_alt.dm
+++ b/code/_onclick/click_alt.dm
@@ -6,32 +6,36 @@
/mob/proc/base_click_alt(atom/target)
SHOULD_NOT_OVERRIDE(TRUE)
- var/turf/tile = isturf(target) ? target : get_turf(target)
-
- if(isobserver(src) || isrevenant(src))
- open_lootpanel(tile)
+ // Check if they've hooked in to prevent src from alt clicking anything
+ if(SEND_SIGNAL(src, COMSIG_MOB_ALTCLICKON, target) & COMSIG_MOB_CANCEL_CLICKON)
return
+ // Is it visible (and we're not wearing it (our clothes are invisible))?
+ if(!(src in viewers(7, target)) && !CanReach(target))
+ return
+
+ var/turf/tile = get_turf(target)
+
+ // Ghosties just see loot
+ if(isobserver(src) || isrevenant(src))
+ client.loot_panel.open(tile)
+ return
+
+ // Turfs don't have a click_alt currently, so this saves some time.
if(!isturf(target) && can_perform_action(target, (target.interaction_flags_click | SILENT_ADJACENCY)))
+ // If it has a signal handler that returns a click action, done.
if(SEND_SIGNAL(target, COMSIG_CLICK_ALT, src) & CLICK_ACTION_ANY)
return
+ // If it has a custom click_alt that returns success/block, done.
if(target.click_alt(src) & CLICK_ACTION_ANY)
return
- open_lootpanel(tile)
-
-
-/// Helper for opening the lootpanel
-/mob/proc/open_lootpanel(turf/target)
+ // No alt clicking to view turf from beneath
if(HAS_TRAIT(src, TRAIT_MOVE_VENTCRAWLING))
return
- var/datum/lootpanel/panel = client?.loot_panel
- if(isnull(panel))
- return
-
- panel.open(target)
+ client.loot_panel.open(tile)
/**
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index a1ca5ebf85a..d5ba848fc8d 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -387,7 +387,7 @@
glasses.add_mob_blood(src)
update_worn_glasses()
- if(!attacking_item.get_sharpness() && !HAS_TRAIT(src, TRAIT_HEAD_INJURY_BLOCKED))
+ if(!attacking_item.get_sharpness() && !HAS_TRAIT(src, TRAIT_HEAD_INJURY_BLOCKED) && attacking_item.damtype == BRUTE)
if(prob(damage_done))
adjustOrganLoss(ORGAN_SLOT_BRAIN, 20)
if(stat == CONSCIOUS)
@@ -417,7 +417,7 @@
w_uniform.add_mob_blood(src)
update_worn_undersuit()
- if(stat == CONSCIOUS && !attacking_item.get_sharpness() && !HAS_TRAIT(src, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED))
+ if(stat == CONSCIOUS && !attacking_item.get_sharpness() && !HAS_TRAIT(src, TRAIT_BRAWLING_KNOCKDOWN_BLOCKED) && attacking_item.damtype == BRUTE)
if(prob(damage_done))
visible_message(
span_danger("[src] is knocked down!"),
diff --git a/code/controllers/master.dm b/code/controllers/master.dm
index d7996890f98..5686de234bf 100644
--- a/code/controllers/master.dm
+++ b/code/controllers/master.dm
@@ -138,7 +138,7 @@ GLOBAL_REAL(Master, /datum/controller/master)
ss.Shutdown()
log_world("Shutdown complete")
-ADMIN_VERB(cmd_controller_view_ui, R_SERVER|R_DEBUG, "Controller Overview", "View the current states of the Subsystem Controllers.", ADMIN_CATEGORY_SERVER)
+ADMIN_VERB(cmd_controller_view_ui, R_SERVER|R_DEBUG, "Controller Overview", "View the current states of the Subsystem Controllers.", ADMIN_CATEGORY_DEBUG)
Master.ui_interact(user.mob)
/datum/controller/master/ui_status(mob/user, datum/ui_state/state)
diff --git a/code/controllers/subsystem/dynamic/dynamic.dm b/code/controllers/subsystem/dynamic/dynamic.dm
index 29451ea10ed..736b55d7c99 100644
--- a/code/controllers/subsystem/dynamic/dynamic.dm
+++ b/code/controllers/subsystem/dynamic/dynamic.dm
@@ -317,7 +317,7 @@ SUBSYSTEM_DEF(dynamic)
SSticker.news_report = SSshuttle.emergency?.is_hijacked() ? SHUTTLE_HIJACK : STATION_EVACUATED
/datum/controller/subsystem/dynamic/proc/send_intercept()
- if(SScommunications.block_command_report) //If we don't want the report to be printed just yet, we put it off until it's ready
+ if(DScommunications.block_command_report) //If we don't want the report to be printed just yet, we put it off until it's ready
addtimer(CALLBACK(src, PROC_REF(send_intercept)), 10 SECONDS)
return
@@ -349,10 +349,10 @@ SUBSYSTEM_DEF(dynamic)
if(trait_list_strings.len > 0)
. += "
Identified shift divergencies: " + trait_list_strings.Join()
- if(length(SScommunications.command_report_footnotes))
+ if(length(DScommunications.command_report_footnotes))
var/footnote_pile = ""
- for(var/datum/command_footnote/footnote in SScommunications.command_report_footnotes)
+ for(var/datum/command_footnote/footnote in DScommunications.command_report_footnotes)
footnote_pile += "[footnote.message] "
footnote_pile += "[footnote.signature] "
footnote_pile += " "
diff --git a/code/controllers/subsystem/movement/cliff_falling.dm b/code/controllers/subsystem/movement/cliff_falling.dm
index 80e2f236eb7..65089f0ea1b 100644
--- a/code/controllers/subsystem/movement/cliff_falling.dm
+++ b/code/controllers/subsystem/movement/cliff_falling.dm
@@ -10,7 +10,7 @@ MOVEMENT_SUBSYSTEM_DEF(cliff_falling)
/datum/controller/subsystem/movement/cliff_falling/proc/start_falling(atom/movable/faller, turf/open/cliff/cliff)
// Make them move
- var/mover = SSmove_manager.move(moving = faller, direction = cliff.fall_direction, delay = cliff.fall_speed, subsystem = src, priority = MOVEMENT_ABOVE_SPACE_PRIORITY, flags = MOVEMENT_LOOP_OUTSIDE_CONTROL | MOVEMENT_LOOP_NO_DIR_UPDATE)
+ var/mover = DSmove_manager.move(moving = faller, direction = cliff.fall_direction, delay = cliff.fall_speed, subsystem = src, priority = MOVEMENT_ABOVE_SPACE_PRIORITY, flags = MOVEMENT_LOOP_OUTSIDE_CONTROL | MOVEMENT_LOOP_NO_DIR_UPDATE)
cliff_grinders[faller] = mover
diff --git a/code/controllers/subsystem/movement/movement_types.dm b/code/controllers/subsystem/movement/movement_types.dm
index ebb12c84e4b..3567e881b14 100644
--- a/code/controllers/subsystem/movement/movement_types.dm
+++ b/code/controllers/subsystem/movement/movement_types.dm
@@ -162,7 +162,7 @@
status &= ~MOVELOOP_STATUS_PAUSED
///Removes the atom from some movement subsystem. Defaults to SSmovement
-/datum/controller/subsystem/move_manager/proc/stop_looping(atom/movable/moving, datum/controller/subsystem/movement/subsystem = SSmovement)
+/datum/system/move_manager/proc/stop_looping(atom/movable/moving, datum/controller/subsystem/movement/subsystem = SSmovement)
var/datum/movement_packet/our_info = moving.move_packet
if(!our_info)
return FALSE
@@ -183,7 +183,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
-/datum/controller/subsystem/move_manager/proc/move(moving, direction, delay, timeout, subsystem, priority, flags, datum/extra_info)
+/datum/system/move_manager/proc/move(moving, direction, delay, timeout, subsystem, priority, flags, datum/extra_info)
return add_to_loop(moving, subsystem, /datum/move_loop/move, priority, flags, extra_info, delay, timeout, direction)
///Replacement for walk()
@@ -224,7 +224,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
-/datum/controller/subsystem/move_manager/proc/force_move_dir(moving, direction, delay, timeout, subsystem, priority, flags, datum/extra_info)
+/datum/system/move_manager/proc/force_move_dir(moving, direction, delay, timeout, subsystem, priority, flags, datum/extra_info)
return add_to_loop(moving, subsystem, /datum/move_loop/move/force, priority, flags, extra_info, delay, timeout, direction)
/datum/move_loop/move/force
@@ -281,7 +281,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
-/datum/controller/subsystem/move_manager/proc/force_move(moving, chasing, delay, timeout, subsystem, priority, flags, datum/extra_info)
+/datum/system/move_manager/proc/force_move(moving, chasing, delay, timeout, subsystem, priority, flags, datum/extra_info)
return add_to_loop(moving, subsystem, /datum/move_loop/has_target/force_move, priority, flags, extra_info, delay, timeout, chasing)
///Used for force-move loops
@@ -315,7 +315,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
-/datum/controller/subsystem/move_manager/proc/jps_move(moving,
+/datum/system/move_manager/proc/jps_move(moving,
chasing,
delay,
timeout,
@@ -493,7 +493,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
-/datum/controller/subsystem/move_manager/proc/move_to(moving, chasing, min_dist, delay, timeout, subsystem, priority, flags, datum/extra_info)
+/datum/system/move_manager/proc/move_to(moving, chasing, min_dist, delay, timeout, subsystem, priority, flags, datum/extra_info)
return add_to_loop(moving, subsystem, /datum/move_loop/has_target/dist_bound/move_to, priority, flags, extra_info, delay, timeout, chasing, min_dist)
///Wrapper around walk_to()
@@ -527,7 +527,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
-/datum/controller/subsystem/move_manager/proc/move_away(moving, chasing, max_dist, delay, timeout, subsystem, priority, flags, datum/extra_info)
+/datum/system/move_manager/proc/move_away(moving, chasing, max_dist, delay, timeout, subsystem, priority, flags, datum/extra_info)
return add_to_loop(moving, subsystem, /datum/move_loop/has_target/dist_bound/move_away, priority, flags, extra_info, delay, timeout, chasing, max_dist)
///Wrapper around walk_away()
@@ -562,7 +562,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
-/datum/controller/subsystem/move_manager/proc/move_towards(moving, chasing, delay, home, timeout, subsystem, priority, flags, datum/extra_info)
+/datum/system/move_manager/proc/move_towards(moving, chasing, delay, home, timeout, subsystem, priority, flags, datum/extra_info)
return add_to_loop(moving, subsystem, /datum/move_loop/has_target/move_towards, priority, flags, extra_info, delay, timeout, chasing, home)
/**
@@ -581,7 +581,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
-/datum/controller/subsystem/move_manager/proc/home_onto(moving, chasing, delay, timeout, subsystem, priority, flags, datum/extra_info)
+/datum/system/move_manager/proc/home_onto(moving, chasing, delay, timeout, subsystem, priority, flags, datum/extra_info)
return move_towards(moving, chasing, delay, TRUE, timeout, subsystem, priority, flags, extra_info)
///Used as a alternative to walk_towards
@@ -717,7 +717,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
-/datum/controller/subsystem/move_manager/proc/move_towards_legacy(moving, chasing, delay, timeout, subsystem, priority, flags, datum/extra_info)
+/datum/system/move_manager/proc/move_towards_legacy(moving, chasing, delay, timeout, subsystem, priority, flags, datum/extra_info)
return add_to_loop(moving, subsystem, /datum/move_loop/has_target/move_towards_budget, priority, flags, extra_info, delay, timeout, chasing)
///The actual implementation of walk_towards()
@@ -743,7 +743,7 @@
* priority - Defines how different move loops override each other. Lower numbers beat higher numbers, equal defaults to what currently exists. Defaults to MOVEMENT_DEFAULT_PRIORITY
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*/
-/datum/controller/subsystem/move_manager/proc/freeze(moving, halted_turf, delay, timeout, subsystem, priority, flags, datum/extra_info)
+/datum/system/move_manager/proc/freeze(moving, halted_turf, delay, timeout, subsystem, priority, flags, datum/extra_info)
return add_to_loop(moving, subsystem, /datum/move_loop/freeze, priority, flags, extra_info, delay, timeout, halted_turf)
/// As close as you can get to a "do-nothing" move loop, the pure intention of this is to absolutely resist all and any automated movement until the move loop times out.
@@ -767,7 +767,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
-/datum/controller/subsystem/move_manager/proc/move_rand(moving, directions, delay, timeout, subsystem, priority, flags, datum/extra_info)
+/datum/system/move_manager/proc/move_rand(moving, directions, delay, timeout, subsystem, priority, flags, datum/extra_info)
if(!directions)
directions = GLOB.alldirs
return add_to_loop(moving, subsystem, /datum/move_loop/move_rand, priority, flags, extra_info, delay, timeout, directions)
@@ -819,7 +819,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
-/datum/controller/subsystem/move_manager/proc/move_to_rand(moving, delay, timeout, subsystem, priority, flags, datum/extra_info)
+/datum/system/move_manager/proc/move_to_rand(moving, delay, timeout, subsystem, priority, flags, datum/extra_info)
return add_to_loop(moving, subsystem, /datum/move_loop/move_to_rand, priority, flags, extra_info, delay, timeout)
///Wrapper around step_rand
@@ -845,7 +845,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
-/datum/controller/subsystem/move_manager/proc/move_disposals(moving, delay, timeout, subsystem, priority, flags, datum/extra_info)
+/datum/system/move_manager/proc/move_disposals(moving, delay, timeout, subsystem, priority, flags, datum/extra_info)
return add_to_loop(moving, subsystem, /datum/move_loop/disposal_holder, priority, flags, extra_info, delay, timeout)
/// Disposal holders need to move through a chain of pipes
diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm
index 7b1394ada16..a35798ce627 100644
--- a/code/controllers/subsystem/statpanel.dm
+++ b/code/controllers/subsystem/statpanel.dm
@@ -190,6 +190,7 @@ SUBSYSTEM_DEF(statpanels)
list("World Time:", "[world.time]"),
list("Globals:", GLOB.stat_entry(), text_ref(GLOB)),
list("[config]:", config.stat_entry(), text_ref(config)),
+ list("Datasystem Manager:", "Edit", text_ref(SysMgr)),
list("Byond:", "(FPS:[world.fps]) (TickCount:[world.time/world.tick_lag]) (TickDrift:[round(Master.tickdrift,1)]([round((Master.tickdrift/(world.time/world.tick_lag))*100,0.1)]%)) (Internal Tick Usage: [round(MAPTICK_LAST_INTERNAL_TICK_USAGE,0.1)]%)"),
list("Master Controller:", Master.stat_entry(), text_ref(Master)),
list("Failsafe Controller:", Failsafe.stat_entry(), text_ref(Failsafe)),
diff --git a/code/datums/actions/mobs/charge.dm b/code/datums/actions/mobs/charge.dm
index 3cca055a541..07c6330c71a 100644
--- a/code/datums/actions/mobs/charge.dm
+++ b/code/datums/actions/mobs/charge.dm
@@ -44,7 +44,7 @@
if(charger in charging)
// Stop any existing charging, this'll clean things up properly
- SSmove_manager.stop_looping(charger)
+ DSmove_manager.stop_looping(charger)
charging += charger
actively_moving = FALSE
@@ -60,7 +60,7 @@
var/time_to_hit = min(get_dist(charger, target), charge_distance) * charge_speed
- var/datum/move_loop/new_loop = SSmove_manager.home_onto(charger, target, delay = charge_speed, timeout = time_to_hit, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
+ var/datum/move_loop/new_loop = DSmove_manager.home_onto(charger, target, delay = charge_speed, timeout = time_to_hit, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
if(!new_loop)
return
RegisterSignal(new_loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(pre_move), override = TRUE)
@@ -96,7 +96,7 @@
/datum/action/cooldown/mob_cooldown/charge/update_status_on_signal(mob/source, new_stat, old_stat)
. = ..()
if(new_stat == DEAD)
- SSmove_manager.stop_looping(source) //This will cause the loop to qdel, triggering an end to our charging
+ DSmove_manager.stop_looping(source) //This will cause the loop to qdel, triggering an end to our charging
/datum/action/cooldown/mob_cooldown/charge/proc/do_charge_indicator(atom/charger, atom/charge_target)
var/turf/target_turf = get_turf(charge_target)
diff --git a/code/datums/actions/mobs/charge_apc.dm b/code/datums/actions/mobs/charge_apc.dm
index 47436beab76..8086ba72207 100644
--- a/code/datums/actions/mobs/charge_apc.dm
+++ b/code/datums/actions/mobs/charge_apc.dm
@@ -1,5 +1,5 @@
///how much charge are we giving off to an APC?
-#define CHARGE_AMOUNT (80 KILO JOULES)
+#define CHARGE_AMOUNT (0.08 * STANDARD_CELL_CHARGE)
/datum/action/cooldown/mob_cooldown/charge_apc
name = "Charge APCs"
diff --git a/code/datums/ai/_ai_behavior.dm b/code/datums/ai/_ai_behavior.dm
index 233b57b1577..eb8f7370dc2 100644
--- a/code/datums/ai/_ai_behavior.dm
+++ b/code/datums/ai/_ai_behavior.dm
@@ -19,8 +19,8 @@
return TRUE
///Called by the AI controller when this action is performed
+///Returns a set of flags defined in [code/__DEFINES/ai/ai.dm]
/datum/ai_behavior/proc/perform(seconds_per_tick, datum/ai_controller/controller, ...)
- controller.behavior_cooldowns[src] = world.time + get_cooldown(controller)
return
///Called when the action is finished. This needs the same args as perform besides the default ones
diff --git a/code/datums/ai/_ai_controller.dm b/code/datums/ai/_ai_controller.dm
index 806009398ee..c5717ceb044 100644
--- a/code/datums/ai/_ai_controller.dm
+++ b/code/datums/ai/_ai_controller.dm
@@ -279,7 +279,7 @@ multiple modular subtrees with behaviors
/datum/ai_controller/process(seconds_per_tick)
if(!able_to_run())
- SSmove_manager.stop_looping(pawn) //stop moving
+ DSmove_manager.stop_looping(pawn) //stop moving
return //this should remove them from processing in the future through event-based stuff.
if(!LAZYLEN(current_behaviors) && idle_behavior)
@@ -359,14 +359,12 @@ multiple modular subtrees with behaviors
break
SEND_SIGNAL(src, COMSIG_AI_CONTROLLER_PICKED_BEHAVIORS, current_behaviors, planned_behaviors)
- for(var/datum/ai_behavior/current_behavior as anything in current_behaviors)
- if(LAZYACCESS(planned_behaviors, current_behavior))
- continue
+ for(var/datum/ai_behavior/forgotten_behavior as anything in current_behaviors - planned_behaviors)
var/list/arguments = list(src, FALSE)
var/list/stored_arguments = behavior_args[type]
if(stored_arguments)
arguments += stored_arguments
- current_behavior.finish_action(arglist(arguments))
+ forgotten_behavior.finish_action(arglist(arguments))
///This proc handles changing ai status, and starts/stops processing if required.
/datum/ai_controller/proc/set_ai_status(new_ai_status)
@@ -381,10 +379,7 @@ multiple modular subtrees with behaviors
switch(ai_status)
if(AI_STATUS_ON)
START_PROCESSING(SSai_behaviors, src)
- if(AI_STATUS_OFF)
- STOP_PROCESSING(SSai_behaviors, src)
- CancelActions()
- if(AI_STATUS_IDLE)
+ if(AI_STATUS_OFF, AI_STATUS_IDLE)
STOP_PROCESSING(SSai_behaviors, src)
CancelActions()
@@ -392,7 +387,7 @@ multiple modular subtrees with behaviors
paused_until = world.time + time
/datum/ai_controller/proc/modify_cooldown(datum/ai_behavior/behavior, new_cooldown)
- behavior_cooldowns[behavior.type] = new_cooldown
+ behavior_cooldowns[behavior] = new_cooldown
///Call this to add a behavior to the stack.
/datum/ai_controller/proc/queue_behavior(behavior_type, ...)
@@ -422,13 +417,23 @@ multiple modular subtrees with behaviors
var/list/stored_arguments = behavior_args[behavior.type]
if(stored_arguments)
arguments += stored_arguments
- behavior.perform(arglist(arguments))
+
+ var/process_flags = behavior.perform(arglist(arguments))
+ if(process_flags & AI_BEHAVIOR_DELAY)
+ behavior_cooldowns[behavior] = world.time + behavior.get_cooldown(src)
+ if(process_flags & AI_BEHAVIOR_FAILED)
+ arguments[1] = src
+ arguments[2] = FALSE
+ behavior.finish_action(arglist(arguments))
+ else if (process_flags & AI_BEHAVIOR_SUCCEEDED)
+ arguments[1] = src
+ arguments[2] = TRUE
+ behavior.finish_action(arglist(arguments))
/datum/ai_controller/proc/CancelActions()
if(!LAZYLEN(current_behaviors))
return
- for(var/i in current_behaviors)
- var/datum/ai_behavior/current_behavior = i
+ for(var/datum/ai_behavior/current_behavior as anything in current_behaviors)
var/list/arguments = list(src, FALSE)
var/list/stored_arguments = behavior_args[current_behavior.type]
if(stored_arguments)
diff --git a/code/datums/ai/_item_behaviors.dm b/code/datums/ai/_item_behaviors.dm
index 6cfb539f7a0..c9f3441fdd6 100644
--- a/code/datums/ai/_item_behaviors.dm
+++ b/code/datums/ai/_item_behaviors.dm
@@ -2,14 +2,14 @@
/datum/ai_behavior/item_escape_grasp
/datum/ai_behavior/item_escape_grasp/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
var/obj/item/item_pawn = controller.pawn
var/mob/item_holder = item_pawn.loc
if(!istype(item_holder))
- finish_action(controller, FALSE) //We're no longer being held. abort abort!!
+ //We're no longer being held. abort abort!!
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
item_pawn.visible_message(span_warning("[item_pawn] slips out of the hands of [item_holder]!"))
item_holder.dropItemToGround(item_pawn, TRUE)
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
///This behavior is for obj/items, it is used to move closer to a target and throw themselves towards them.
@@ -30,7 +30,6 @@
set_movement_target(controller, target)
/datum/ai_behavior/item_move_close_and_attack/perform(seconds_per_tick, datum/ai_controller/controller, target_key, throw_count_key)
- . = ..()
var/obj/item/item_pawn = controller.pawn
var/atom/throw_target = controller.blackboard[target_key]
@@ -39,7 +38,8 @@
playsound(item_pawn.loc, attack_sound, 100, TRUE)
controller.add_blackboard_key(throw_count_key, 1)
if(controller.blackboard[throw_count_key] >= max_attempts)
- finish_action(controller, TRUE, target_key, throw_count_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
+ return AI_BEHAVIOR_DELAY
/datum/ai_behavior/item_move_close_and_attack/finish_action(datum/ai_controller/controller, succeeded, target_key, throw_count_key)
. = ..()
diff --git a/code/datums/ai/babies/babies_behaviors.dm b/code/datums/ai/babies/babies_behaviors.dm
index 8cc03d72f6b..ad57d309a2c 100644
--- a/code/datums/ai/babies/babies_behaviors.dm
+++ b/code/datums/ai/babies/babies_behaviors.dm
@@ -8,7 +8,6 @@
var/max_children = 3
/datum/ai_behavior/find_partner/perform(seconds_per_tick, datum/ai_controller/controller, target_key, partner_types_key, child_types_key)
- . = ..()
max_children = controller.blackboard[BB_MAX_CHILDREN] || max_children
var/mob/pawn_mob = controller.pawn
var/list/partner_types = controller.blackboard[partner_types_key]
@@ -18,12 +17,10 @@
var/children = 0
for(var/mob/living/other in oview(range, pawn_mob))
if(!pawn_mob.faction_check_atom(other))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
if(children >= max_children)
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
if(other.stat != CONSCIOUS) //Check if it's conscious FIRST.
continue
@@ -40,10 +37,9 @@
if(other.gender != living_pawn.gender && !(other.flags_1 & HOLOGRAM_1)) //Better safe than sorry ;_;
controller.set_blackboard_key(target_key, other)
- finish_action(controller, TRUE)
-
- finish_action(controller, FALSE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
/**
* Reproduce.
@@ -59,15 +55,13 @@
set_movement_target(controller, target)
/datum/ai_behavior/make_babies/perform(seconds_per_tick, datum/ai_controller/controller, target_key, child_types_key)
- . = ..()
var/mob/target = controller.blackboard[target_key]
if(QDELETED(target) || target.stat != CONSCIOUS)
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/mob/living/basic/living_pawn = controller.pawn
living_pawn.set_combat_mode(FALSE)
living_pawn.melee_attack(target)
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/make_babies/finish_action(datum/ai_controller/controller, succeeded, target_key)
. = ..()
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm
index 144de535d5a..883c157a96b 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/basic_attacking.dm
@@ -21,17 +21,15 @@
if (isliving(controller.pawn))
var/mob/living/pawn = controller.pawn
if (world.time < pawn.next_move)
- return
+ return AI_BEHAVIOR_INSTANT
- . = ..()
var/mob/living/basic/basic_mob = controller.pawn
//targeting strategy will kill the action if not real anymore
var/atom/target = controller.blackboard[target_key]
var/datum/targeting_strategy/targeting_strategy = GET_TARGETING_STRATEGY(controller.blackboard[targeting_strategy_key])
if(!targeting_strategy.can_attack(basic_mob, target))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/hiding_target = targeting_strategy.find_hidden_mobs(basic_mob, target) //If this is valid, theyre hidden in something!
@@ -43,7 +41,8 @@
basic_mob.melee_attack(target)
if(terminate_after_action)
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
+ return AI_BEHAVIOR_DELAY
/datum/ai_behavior/basic_melee_attack/finish_action(datum/ai_controller/controller, succeeded, target_key, targeting_strategy_key, hiding_location_key)
. = ..()
@@ -82,22 +81,21 @@
var/datum/targeting_strategy/targeting_strategy = GET_TARGETING_STRATEGY(controller.blackboard[targeting_strategy_key])
if(!targeting_strategy.can_attack(basic_mob, target, chase_range))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
var/atom/hiding_target = targeting_strategy.find_hidden_mobs(basic_mob, target) //If this is valid, theyre hidden in something!
var/atom/final_target = hiding_target ? hiding_target : target
if(!can_see(basic_mob, final_target, required_distance))
- return
+ return AI_BEHAVIOR_INSTANT
if(avoid_friendly_fire && check_friendly_in_path(basic_mob, target, targeting_strategy))
adjust_position(basic_mob, target)
- return ..()
+ return AI_BEHAVIOR_DELAY
controller.set_blackboard_key(hiding_location_key, hiding_target)
basic_mob.RangedAttack(final_target)
- return ..() //only start the cooldown when the shot is shot
+ return AI_BEHAVIOR_DELAY //only start the cooldown when the shot is shot
/datum/ai_behavior/basic_ranged_attack/finish_action(datum/ai_controller/controller, succeeded, target_key, targeting_strategy_key, hiding_location_key)
. = ..()
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/befriend_target.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/befriend_target.dm
index e1fd8bed640..865b028e156 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/befriend_target.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/befriend_target.dm
@@ -2,19 +2,17 @@
/datum/ai_behavior/befriend_target
/datum/ai_behavior/befriend_target/perform(seconds_per_tick, datum/ai_controller/controller, target_key, befriend_message)
- . = ..()
var/mob/living/living_pawn = controller.pawn
var/mob/living/living_target = controller.blackboard[target_key]
if(QDELETED(living_target))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
living_pawn.befriend(living_target)
var/befriend_text = controller.blackboard[befriend_message]
if(befriend_text)
to_chat(living_target, span_nicegreen("[living_pawn] [befriend_text]"))
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/befriend_target/finish_action(datum/ai_controller/controller, succeeded, target_key)
. = ..()
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/climb_tree.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/climb_tree.dm
index c8c18072a4a..5046baa7e0f 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/climb_tree.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/climb_tree.dm
@@ -22,13 +22,12 @@
set_movement_target(controller, target)
/datum/ai_behavior/climb_tree/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/obj/structure/flora/target_tree = controller.blackboard[target_key]
var/mob/living/basic/living_pawn = controller.pawn
if(QDELETED(living_pawn)) // pawn can be null at this point
return
SEND_SIGNAL(living_pawn, COMSIG_LIVING_CLIMB_TREE, target_tree)
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/climb_tree/finish_action(datum/ai_controller/controller, succeeded, target_key)
. = ..()
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/find_parent.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/find_parent.dm
index 9e4ccef4936..07b4845f027 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/find_parent.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/find_parent.dm
@@ -3,16 +3,13 @@
var/look_range = 7
/datum/ai_behavior/find_mom/perform(seconds_per_tick, datum/ai_controller/controller, mom_key, ignore_mom_key, found_mom)
- . = ..()
-
var/mob/living_pawn = controller.pawn
var/list/mom_types = controller.blackboard[mom_key]
var/list/all_moms = list()
var/list/ignore_types = controller.blackboard[ignore_mom_key]
if(!length(mom_types))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
for(var/mob/mother in oview(look_range, living_pawn))
if(!is_type_in_list(mother, mom_types))
@@ -23,6 +20,5 @@
if(length(all_moms))
controller.set_blackboard_key(found_mom, pick(all_moms))
- finish_action(controller, TRUE)
- return
- finish_action(controller, FALSE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/pick_up_item.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/pick_up_item.dm
index e81c9f95751..1b65eaa507c 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/pick_up_item.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/pick_up_item.dm
@@ -11,16 +11,13 @@
return isitem(target) && isturf(target.loc) && !target.anchored
/datum/ai_behavior/pick_up_item/perform(seconds_per_tick, datum/ai_controller/controller, target_key, storage_key)
- . = ..()
var/obj/item/target = controller.blackboard[target_key]
if(QDELETED(target) || !isturf(target.loc)) // Someone picked it up or it got deleted
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
if(!controller.pawn.Adjacent(target)) // It teleported
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
pickup_item(controller, target, storage_key)
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/pick_up_item/finish_action(datum/ai_controller/controller, success, target_key, storage_key)
. = ..()
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/pull_target.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/pull_target.dm
index 9bfc3f85d24..900b122dcb3 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/pull_target.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/pull_target.dm
@@ -9,15 +9,12 @@
set_movement_target(controller, target)
/datum/ai_behavior/pull_target/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
-
var/atom/movable/target = controller.blackboard[target_key]
if(QDELETED(target) || target.anchored || target.pulledby)
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/mob/living/our_mob = controller.pawn
our_mob.start_pulling(target)
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/pull_target/finish_action(datum/ai_controller/controller, succeeded, target_key)
. = ..()
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm
index 172a31d4793..f23707e72b8 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm
@@ -18,18 +18,16 @@
return ..()
/datum/ai_behavior/run_away_from_target/perform(seconds_per_tick, datum/ai_controller/controller, target_key, hiding_location_key)
- . = ..()
if (controller.blackboard[BB_BASIC_MOB_STOP_FLEEING])
- return
+ return AI_BEHAVIOR_DELAY
var/atom/target = controller.blackboard[hiding_location_key] || controller.blackboard[target_key]
if (QDELETED(target) || !can_see(controller.pawn, target, run_distance))
- finish_action(controller, succeeded = TRUE, target_key = target_key, hiding_location_key = hiding_location_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
if (get_dist(controller.pawn, controller.current_movement_target) > required_distance)
- return // Still heading over
+ return AI_BEHAVIOR_DELAY // Still heading over
if (plot_path_away_from(controller, target))
- return
- finish_action(controller, succeeded = FALSE, target_key = target_key, hiding_location_key = hiding_location_key)
+ return AI_BEHAVIOR_DELAY
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
/datum/ai_behavior/run_away_from_target/proc/plot_path_away_from(datum/ai_controller/controller, atom/target)
var/turf/target_destination = get_turf(controller.pawn)
@@ -71,7 +69,7 @@
/datum/ai_behavior/run_away_from_target/run_and_shoot/perform(seconds_per_tick, datum/ai_controller/controller, target_key, hiding_location_key)
var/atom/target = controller.blackboard[target_key]
if(QDELETED(target))
- finish_action(controller, succeeded = FALSE, target_key = target_key, hiding_location_key = hiding_location_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/mob/living/living_pawn = controller.pawn
living_pawn.RangedAttack(target)
return ..()
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/set_travel_destination.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/set_travel_destination.dm
index 207df442457..6bf6dbb7fdb 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/set_travel_destination.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/set_travel_destination.dm
@@ -1,13 +1,10 @@
/datum/ai_behavior/set_travel_destination
/datum/ai_behavior/set_travel_destination/perform(seconds_per_tick, datum/ai_controller/controller, target_key, location_key)
- . = ..()
var/atom/target = controller.blackboard[target_key]
if(QDELETED(target))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
controller.set_blackboard_key(location_key, target)
-
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/step_towards_turf.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/step_towards_turf.dm
index f941b2eb95d..7cb3a7b9f14 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/step_towards_turf.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/step_towards_turf.dm
@@ -47,8 +47,7 @@
// We actually only wanted the movement so if we've arrived we're done
/datum/ai_behavior/step_towards_turf/perform(seconds_per_tick, datum/ai_controller/controller, area_key, turf_key)
- . = ..()
- finish_action(controller, succeeded = TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/**
* # Step towards turf in area
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/stop_and_stare.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/stop_and_stare.dm
index df066ac0418..4ce1f877b18 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/stop_and_stare.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/stop_and_stare.dm
@@ -11,10 +11,9 @@
return cooldown_for.blackboard[BB_STATIONARY_COOLDOWN]
/datum/ai_behavior/stop_and_stare/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/atom/movable/target = controller.blackboard[target_key]
if(!ismovable(target) || !isturf(target.loc)) // just to make sure that nothing funky happened between setup and perform
- return
+ return AI_BEHAVIOR_DELAY
var/mob/pawn_mob = controller.pawn
var/turf/pawn_turf = get_turf(pawn_mob)
@@ -25,3 +24,4 @@
if(controller.blackboard[BB_STATIONARY_MOVE_TO_TARGET])
addtimer(CALLBACK(src, PROC_REF(set_movement_target), controller, target, initial(controller.ai_movement)), (controller.blackboard[BB_STATIONARY_SECONDS] + 1 SECONDS))
+ return AI_BEHAVIOR_DELAY
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/targeted_mob_ability.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/targeted_mob_ability.dm
index ba167b34f29..2d2ad013aa2 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/targeted_mob_ability.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/targeted_mob_ability.dm
@@ -8,12 +8,13 @@
var/datum/action/cooldown/ability = get_ability_to_use(controller, ability_key)
var/mob/living/target = controller.blackboard[target_key]
if(QDELETED(ability) || QDELETED(target))
- finish_action(controller, FALSE, ability_key, target_key)
- return
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
var/mob/pawn = controller.pawn
pawn.face_atom(target)
var/result = ability.Trigger(target = target)
- finish_action(controller, result, ability_key, target_key)
+ if(result)
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
/datum/ai_behavior/targeted_mob_ability/finish_action(datum/ai_controller/controller, succeeded, ability_key, target_key)
. = ..()
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/targeting.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/targeting.dm
index b54bfe82f90..f0ee4bb9bba 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/targeting.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/targeting.dm
@@ -26,8 +26,7 @@ GLOBAL_LIST_INIT(target_interested_atoms, typecacheof(list(/mob, /obj/machinery/
var/atom/current_target = controller.blackboard[target_key]
if (targeting_strategy.can_attack(living_mob, current_target, vision_range))
- finish_action(controller, succeeded = FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/aggro_range = controller.blackboard[aggro_range_key] || vision_range
@@ -45,8 +44,7 @@ GLOBAL_LIST_INIT(target_interested_atoms, typecacheof(list(/mob, /obj/machinery/
if(!potential_targets.len)
failed_to_find_anyone(controller, target_key, targeting_strategy_key, hiding_location_key)
- finish_action(controller, succeeded = FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/list/filtered_targets = list()
@@ -57,8 +55,7 @@ GLOBAL_LIST_INIT(target_interested_atoms, typecacheof(list(/mob, /obj/machinery/
if(!filtered_targets.len)
failed_to_find_anyone(controller, target_key, targeting_strategy_key, hiding_location_key)
- finish_action(controller, succeeded = FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/atom/target = pick_final_target(controller, filtered_targets)
controller.set_blackboard_key(target_key, target)
@@ -68,7 +65,7 @@ GLOBAL_LIST_INIT(target_interested_atoms, typecacheof(list(/mob, /obj/machinery/
if(potential_hiding_location) //If they're hiding inside of something, we need to know so we can go for that instead initially.
controller.set_blackboard_key(hiding_location_key, potential_hiding_location)
- finish_action(controller, succeeded = TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/find_potential_targets/proc/failed_to_find_anyone(datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key)
var/aggro_range = controller.blackboard[aggro_range_key] || vision_range
@@ -149,7 +146,7 @@ GLOBAL_LIST_INIT(target_interested_atoms, typecacheof(list(/mob, /obj/machinery/
var/datum/proximity_monitor/field = controller.blackboard[BB_FIND_TARGETS_FIELD(type)]
qdel(field) // autoclears so it's fine
controller.CancelActions() // On retarget cancel any further queued actions so that they will setup again with new target
- controller.modify_cooldown(controller, get_cooldown(controller))
+ controller.modify_cooldown(src, get_cooldown(controller))
/// Returns the desired final target from the filtered list of targets
/datum/ai_behavior/find_potential_targets/proc/pick_final_target(datum/ai_controller/controller, list/filtered_targets)
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/tipped_reaction.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/tipped_reaction.dm
index 643bb9ced5a..c734d961b5e 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/tipped_reaction.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/tipped_reaction.dm
@@ -3,8 +3,6 @@
/datum/ai_behavior/tipped_reaction
/datum/ai_behavior/tipped_reaction/perform(seconds_per_tick, datum/ai_controller/controller, tipper_key, reacting_key)
- . = ..()
-
var/mob/living/carbon/tipper = controller.blackboard[tipper_key]
// visible part of the visible message
@@ -28,7 +26,7 @@
seen_message = "[controller.pawn] seems resigned to its fate."
self_message = "You resign yourself to your fate."
controller.pawn.visible_message(span_notice("[seen_message]"), span_notice("[self_message]"))
- finish_action(controller, TRUE, tipper_key, reacting_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/tipped_reaction/finish_action(datum/ai_controller/controller, succeeded, tipper_key, reacting_key)
. = ..()
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/travel_towards.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/travel_towards.dm
index 6eb7c36dadd..808fe6b8873 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/travel_towards.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/travel_towards.dm
@@ -19,8 +19,7 @@
set_movement_target(controller, target, new_movement_type)
/datum/ai_behavior/travel_towards/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/travel_towards/finish_action(datum/ai_controller/controller, succeeded, target_key)
. = ..()
@@ -48,5 +47,4 @@
set_movement_target(controller, target_atom)
/datum/ai_behavior/travel_towards_atom/perform(seconds_per_tick, datum/ai_controller/controller, atom/target_atom)
- . = ..()
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/unbuckle_mob.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/unbuckle_mob.dm
index 655b335d3b6..34e651f8e52 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/unbuckle_mob.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/unbuckle_mob.dm
@@ -1,14 +1,11 @@
/datum/ai_behavior/unbuckle_mob
/datum/ai_behavior/unbuckle_mob/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
-
var/mob/living/living_pawn = controller.pawn
var/atom/movable/buckled_to = living_pawn.buckled
if(isnull(buckled_to))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
buckled_to.unbuckle_mob(living_pawn)
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/ventcrawling.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/ventcrawling.dm
index 889b474ad03..aca89d83281 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/ventcrawling.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/ventcrawling.dm
@@ -17,26 +17,23 @@
return istype(target) && isliving(controller.pawn) // only mobs can vent crawl in the current framework
/datum/ai_behavior/crawl_through_vents/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/obj/machinery/atmospherics/components/unary/vent_pump/entry_vent = controller.blackboard[target_key] || controller.blackboard[BB_ENTRY_VENT_TARGET]
var/mob/living/cached_pawn = controller.pawn
if(HAS_TRAIT(cached_pawn, TRAIT_MOVE_VENTCRAWLING) || !controller.blackboard[BB_CURRENTLY_TARGETING_VENT] || !is_vent_valid(entry_vent))
- return
+ return AI_BEHAVIOR_DELAY
if(!cached_pawn.can_enter_vent(entry_vent, provide_feedback = FALSE)) // we're an AI we scoff at feedback
- finish_action(controller, FALSE, target_key) // "never enter a hole you can't get out of"
- return
+ // "never enter a hole you can't get out of"
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/vent_we_exit_out_of = calculate_exit_vent(controller, target_key)
if(isnull(vent_we_exit_out_of)) // don't get into the vents if we can't get out of them, that's SILLY.
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
controller.set_blackboard_key(BB_CURRENTLY_TARGETING_VENT, FALSE) // must be done here because we have a do_after sleep in handle_ventcrawl unfortunately and double dipping could lead to erroneous suicide pill calls.
cached_pawn.handle_ventcrawl(entry_vent)
if(!HAS_TRAIT(cached_pawn, TRAIT_MOVE_VENTCRAWLING)) //something failed and we ARE NOT IN THE VENT even though the earlier check said we were good to go! odd.
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
controller.set_blackboard_key(BB_EXIT_VENT_TARGET, vent_we_exit_out_of)
@@ -50,7 +47,8 @@
var/upper_vent_time_limit = controller.blackboard[BB_UPPER_VENT_TIME_LIMIT] // the most amount of time we spend in the vents
addtimer(CALLBACK(src, PROC_REF(exit_the_vents), controller), rand(lower_vent_time_limit, upper_vent_time_limit))
- controller.set_blackboard_key(BB_GIVE_UP_ON_VENT_PATHING_TIMER_ID, addtimer(CALLBACK(src, PROC_REF(suicide_pill), controller), controller.blackboard[BB_TIME_TO_GIVE_UP_ON_VENT_PATHING], TIMER_STOPPABLE))
+ controller.set_blackboard_key(BB_GIVE_UP_ON_VENT_PATHING_TIMER_ID, addtimer(CALLBACK(src, PROC_REF(delayed_suicide_pill), controller, target_key), controller.blackboard[BB_TIME_TO_GIVE_UP_ON_VENT_PATHING], TIMER_STOPPABLE))
+ return AI_BEHAVIOR_DELAY
/// Figure out an exit vent that we should head towards. If we don't have one, default to the entry vent. If they're all kaput, we die.
/datum/ai_behavior/crawl_through_vents/proc/calculate_exit_vent(datum/ai_controller/controller, target_key)
@@ -83,8 +81,8 @@
var/mob/living/living_pawn = controller.pawn
if(!HAS_TRAIT(living_pawn, TRAIT_MOVE_VENTCRAWLING) && isturf(get_turf(living_pawn))) // we're out of the vents, so no need to do an exit
- finish_action(controller, TRUE, target_key) // assume that we got yeeted out somehow and call this so we can halt the suicide pill timer.
- return
+ // assume that we got yeeted out somehow and return this so we can halt the suicide pill timer.
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
living_pawn.forceMove(exit_vent)
if(!living_pawn.can_enter_vent(exit_vent, provide_feedback = FALSE))
@@ -92,8 +90,7 @@
emergency_vent = calculate_exit_vent(controller)
if(isnull(emergency_vent))
// it's joever. we cooked too hard.
- suicide_pill(controller, target_key)
- return
+ return suicide_pill(controller) | AI_BEHAVIOR_DELAY
controller.set_blackboard_key(BB_EXIT_VENT_TARGET, emergency_vent) // assign and go again
addtimer(CALLBACK(src, PROC_REF(exit_the_vents), controller), (rand(controller.blackboard[BB_LOWER_VENT_TIME_LIMIT], controller.blackboard[BB_UPPER_VENT_TIME_LIMIT]) / 2)) // we're in danger mode, so scurry out at half the time it would normally take.
@@ -102,32 +99,34 @@
living_pawn.handle_ventcrawl(exit_vent)
if(HAS_TRAIT(living_pawn, TRAIT_MOVE_VENTCRAWLING)) // how'd we fail? what the fuck
stack_trace("We failed to exit the vents, even though we should have been fine? This is very weird.")
- suicide_pill() // all of the prior checks say we should have definitely made it through, but we didn't. dammit.
- return
+ return suicide_pill(controller) | AI_BEHAVIOR_DELAY // all of the prior checks say we should have definitely made it through, but we didn't. dammit.
- finish_action(controller, TRUE, target_key) // we did it! we went into the vents and out of the vents. poggers.
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED // we did it! we went into the vents and out of the vents. poggers.
/// Incredibly stripped down version of the overarching `can_enter_vent` proc on `/mob, just meant for rapid rechecking of a vent. Will be TRUE if not blocked, FALSE otherwise.
/datum/ai_behavior/crawl_through_vents/proc/is_vent_valid(obj/machinery/atmospherics/components/unary/vent_pump/checkable)
return !QDELETED(checkable) && !checkable.welded
+/// Wraps a delayed defeat, so we gotta handle the return value properly ya feel?
+/datum/ai_behavior/crawl_through_vents/proc/delayed_suicide_pill(datum/ai_controller/controller, target_key)
+ if(suicide_pill(controller) & AI_BEHAVIOR_FAILED)
+ finish_action(controller, FALSE, target_key)
+
/// Aw fuck, we may have been bested somehow. Regardless of what we do, we can't exit through a vent! Let's end our misery and prevent useless endless calculations.
-/datum/ai_behavior/crawl_through_vents/proc/suicide_pill(datum/ai_controller/controller, target_key)
+/datum/ai_behavior/crawl_through_vents/proc/suicide_pill(datum/ai_controller/controller)
var/mob/living/living_pawn = controller.pawn
if(istype(living_pawn))
- finish_action(controller, FALSE, target_key)
-
if(isnull(living_pawn.client)) // only call death if we don't have a client because maybe their natural intelligence can pick up where our AI calculations have failed
living_pawn.death(TRUE) // call gibbed as true because we are never coming back it is so fucking joever
- return
+ return AI_BEHAVIOR_FAILED
if(QDELETED(living_pawn)) // we got deleted by some other means, just presume the action is a wash and get outta here
- return
+ return NONE
qdel(living_pawn) // failover, we really should've been caught in the istype() but lets just bow out of existing at this point
-
+ return NONE
/datum/ai_behavior/crawl_through_vents/finish_action(datum/ai_controller/controller, succeeded, target_key)
. = ..()
diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/write_on_paper.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/write_on_paper.dm
index f5dba58416d..51826676e9e 100644
--- a/code/datums/ai/basic_mobs/basic_ai_behaviors/write_on_paper.dm
+++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/write_on_paper.dm
@@ -1,7 +1,6 @@
/datum/ai_behavior/write_on_paper
/datum/ai_behavior/write_on_paper/perform(seconds_per_tick, datum/ai_controller/controller, found_paper, list_of_writings)
- . = ..()
var/mob/living/wizard = controller.pawn
var/list/writing_list = controller.blackboard[list_of_writings]
var/obj/item/paper/target = controller.blackboard[found_paper]
@@ -9,7 +8,7 @@
target.add_raw_text(pick(writing_list))
target.update_appearance()
wizard.dropItemToGround(target)
- finish_action(controller, TRUE, found_paper)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/write_on_paper/finish_action(datum/ai_controller/controller, succeeded, target_key)
. = ..()
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/attack_adjacent_target.dm b/code/datums/ai/basic_mobs/basic_subtrees/attack_adjacent_target.dm
index 41169004354..8effc7a0fa7 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/attack_adjacent_target.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/attack_adjacent_target.dm
@@ -27,7 +27,6 @@
/datum/ai_behavior/basic_melee_attack/opportunistic/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key)
var/atom/movable/atom_pawn = controller.pawn
if(!atom_pawn.CanReach(controller.blackboard[target_key]))
- finish_action(controller, TRUE, target_key) // Don't clear target
- return FALSE
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
. = ..()
- finish_action(controller, TRUE, target_key) // Try doing something else
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/attack_obstacle_in_path.dm b/code/datums/ai/basic_mobs/basic_subtrees/attack_obstacle_in_path.dm
index 7059bec93fe..bc8efdeb4ff 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/attack_obstacle_in_path.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/attack_obstacle_in_path.dm
@@ -27,13 +27,11 @@
var/can_attack_dense_objects = FALSE
/datum/ai_behavior/attack_obstructions/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/mob/living/basic/basic_mob = controller.pawn
var/atom/target = controller.blackboard[target_key]
if (QDELETED(target))
- finish_action(controller, succeeded = FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/turf/next_step = get_step_towards(basic_mob, target)
var/dir_to_next_step = get_dir(basic_mob, next_step)
@@ -48,8 +46,8 @@
for (var/direction in dirs_to_move)
if (attack_in_direction(controller, basic_mob, direction))
- return
- finish_action(controller, succeeded = TRUE)
+ return AI_BEHAVIOR_DELAY
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/attack_obstructions/proc/attack_in_direction(datum/ai_controller/controller, mob/living/basic/basic_mob, direction)
var/turf/next_step = get_step(basic_mob, direction)
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/call_reinforcements.dm b/code/datums/ai/basic_mobs/basic_subtrees/call_reinforcements.dm
index 59ff88b4879..44d7cb4fe48 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/call_reinforcements.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/call_reinforcements.dm
@@ -36,8 +36,6 @@
var/reinforcements_range = 15
/datum/ai_behavior/call_reinforcements/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
-
var/mob/pawn_mob = controller.pawn
for(var/mob/other_mob in oview(reinforcements_range, pawn_mob))
if(pawn_mob.faction_check_atom(other_mob) && !isnull(other_mob.ai_controller))
@@ -46,5 +44,6 @@
other_mob.ai_controller.set_blackboard_key(BB_BASIC_MOB_REINFORCEMENT_TARGET, pawn_mob)
controller.set_blackboard_key(BB_BASIC_MOB_REINFORCEMENTS_COOLDOWN, world.time + REINFORCEMENTS_COOLDOWN)
+ return AI_BEHAVIOR_DELAY
#undef REINFORCEMENTS_COOLDOWN
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/capricious_retaliate.dm b/code/datums/ai/basic_mobs/basic_subtrees/capricious_retaliate.dm
index 4d5319bca86..a4fc49facc0 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/capricious_retaliate.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/capricious_retaliate.dm
@@ -14,29 +14,25 @@
action_cooldown = 1 SECONDS
/datum/ai_behavior/capricious_retaliate/perform(seconds_per_tick, datum/ai_controller/controller, targeting_strategy_key, ignore_faction)
- . = ..()
var/atom/pawn = controller.pawn
if (controller.blackboard_key_exists(BB_BASIC_MOB_RETALIATE_LIST))
var/deaggro_chance = controller.blackboard[BB_RANDOM_DEAGGRO_CHANCE] || 10
if (!SPT_PROB(deaggro_chance, seconds_per_tick))
- finish_action(controller, TRUE, ignore_faction) // "true" here means "don't clear our ignoring factions status"
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
pawn.visible_message(span_notice("[pawn] calms down.")) // We can blackboard key this if anyone else actually wants to customise it
controller.clear_blackboard_key(BB_BASIC_MOB_RETALIATE_LIST)
- finish_action(controller, FALSE, ignore_faction)
controller.CancelActions() // Otherwise they will try and get one last kick in
- return
+ return AI_BEHAVIOR_DELAY
var/aggro_chance = controller.blackboard[BB_RANDOM_AGGRO_CHANCE] || 0.5
if (!SPT_PROB(aggro_chance, seconds_per_tick))
- finish_action(controller, FALSE, ignore_faction)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/aggro_range = controller.blackboard[BB_AGGRO_RANGE] || 9
var/list/potential_targets = hearers(aggro_range, get_turf(pawn)) - pawn
if (!length(potential_targets))
- failed_targeting(controller, pawn, ignore_faction)
- return
+ failed_targeting(pawn)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/datum/targeting_strategy/target_helper = GET_TARGETING_STRATEGY(controller.blackboard[targeting_strategy_key])
@@ -49,16 +45,15 @@
final_target = test_target
if (isnull(final_target))
- failed_targeting(controller, pawn, ignore_faction)
- return
+ failed_targeting(pawn)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
controller.insert_blackboard_key_lazylist(BB_BASIC_MOB_RETALIATE_LIST, final_target)
pawn.visible_message(span_warning("[pawn] glares grumpily at [final_target]!"))
- finish_action(controller, TRUE, ignore_faction)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/// Called if we try but fail to target something
-/datum/ai_behavior/capricious_retaliate/proc/failed_targeting(datum/ai_controller/controller, atom/pawn, ignore_faction)
- finish_action(controller, FALSE, ignore_faction)
+/datum/ai_behavior/capricious_retaliate/proc/failed_targeting(atom/pawn)
pawn.visible_message(span_notice("[pawn] grumbles.")) // We're pissed off but with no outlet to vent our frustration upon
/datum/ai_behavior/capricious_retaliate/finish_action(datum/ai_controller/controller, succeeded, ignore_faction)
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/maintain_distance.dm b/code/datums/ai/basic_mobs/basic_subtrees/maintain_distance.dm
index 2a85e9e902b..549abbc75ec 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/maintain_distance.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/maintain_distance.dm
@@ -60,8 +60,7 @@
return FALSE
/datum/ai_behavior/step_away/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
- finish_action(controller, succeeded = TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/step_away/finish_action(datum/ai_controller/controller, succeeded)
. = ..()
@@ -83,8 +82,8 @@
/datum/ai_behavior/pursue_to_range/perform(seconds_per_tick, datum/ai_controller/controller, target_key, range)
var/atom/current_target = controller.blackboard[target_key]
if (!QDELETED(current_target) && get_dist(controller.pawn, current_target) > range)
- return
- finish_action(controller, succeeded = TRUE)
+ return AI_BEHAVIOR_INSTANT
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
///instead of taking a single step, we cover the entire distance
/datum/ai_behavior/cover_minimum_distance
@@ -112,5 +111,4 @@
set_movement_target(controller, target = chosen_turf)
/datum/ai_behavior/cover_minimum_distance/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
- finish_action(controller, succeeded = TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/mine_walls.dm b/code/datums/ai/basic_mobs/basic_subtrees/mine_walls.dm
index 3c03702b699..dc3f6ddcf90 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/mine_walls.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/mine_walls.dm
@@ -21,19 +21,16 @@
set_movement_target(controller, target)
/datum/ai_behavior/mine_wall/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/mob/living/basic/living_pawn = controller.pawn
var/turf/closed/mineral/target = controller.blackboard[target_key]
var/is_gibtonite_turf = istype(target, /turf/closed/mineral/gibtonite)
if(QDELETED(target))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
living_pawn.melee_attack(target)
if(is_gibtonite_turf)
living_pawn.manual_emote("sighs...") //accept whats about to happen to us
- finish_action(controller, TRUE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/mine_wall/finish_action(datum/ai_controller/controller, success, target_key)
. = ..()
@@ -42,17 +39,15 @@
/datum/ai_behavior/find_mineral_wall
/datum/ai_behavior/find_mineral_wall/perform(seconds_per_tick, datum/ai_controller/controller, found_wall_key)
- . = ..()
var/mob/living_pawn = controller.pawn
for(var/turf/closed/mineral/potential_wall in oview(9, living_pawn))
if(!check_if_mineable(controller, potential_wall)) //check if its surrounded by walls
continue
controller.set_blackboard_key(found_wall_key, potential_wall) //closest wall first!
- finish_action(controller, TRUE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
- finish_action(controller, FALSE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
/datum/ai_behavior/find_mineral_wall/proc/check_if_mineable(datum/ai_controller/controller, turf/target_wall)
var/mob/living/source = controller.pawn
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/move_to_cardinal.dm b/code/datums/ai/basic_mobs/basic_subtrees/move_to_cardinal.dm
index c98878e0fd7..bcf5c829025 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/move_to_cardinal.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/move_to_cardinal.dm
@@ -51,19 +51,17 @@
/datum/ai_behavior/move_to_cardinal/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
var/atom/target = controller.blackboard[target_key]
if (QDELETED(target))
- finish_action(controller = controller, succeeded = FALSE, target_key = target_key)
- return
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
if (!(get_dir(controller.pawn, target) in GLOB.cardinals))
target_nearest_cardinal(controller, target)
- return
+ return AI_BEHAVIOR_INSTANT
var/distance_to_target = get_dist(controller.pawn, target)
if (distance_to_target < minimum_distance)
target_nearest_cardinal(controller, target)
- return
+ return AI_BEHAVIOR_INSTANT
if (distance_to_target > maximum_distance)
- return
- finish_action(controller = controller, succeeded = TRUE, target_key = target_key)
- return
+ return AI_BEHAVIOR_INSTANT
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/move_to_cardinal/finish_action(datum/ai_controller/controller, succeeded, target_key)
if (!succeeded)
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/ranged_skirmish.dm b/code/datums/ai/basic_mobs/basic_subtrees/ranged_skirmish.dm
index 95a125eea5c..3640a2052b5 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/ranged_skirmish.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/ranged_skirmish.dm
@@ -26,16 +26,13 @@
return !QDELETED(target)
/datum/ai_behavior/ranged_skirmish/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key, max_range, min_range)
- . = ..()
var/atom/target = controller.blackboard[target_key]
if (QDELETED(target))
- finish_action(controller, succeeded = FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/datum/targeting_strategy/targeting_strategy = GET_TARGETING_STRATEGY(controller.blackboard[targeting_strategy_key])
if(!targeting_strategy.can_attack(controller.pawn, target))
- finish_action(controller, succeeded = FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/hiding_target = targeting_strategy.find_hidden_mobs(controller.pawn, target)
controller.set_blackboard_key(hiding_location_key, hiding_target)
@@ -44,9 +41,8 @@
var/distance = get_dist(controller.pawn, target)
if (distance > max_range || distance < min_range)
- finish_action(controller, succeeded = FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/mob/living/basic/gunman = controller.pawn
gunman.RangedAttack(target)
- finish_action(controller, succeeded = TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/run_emote.dm b/code/datums/ai/basic_mobs/basic_subtrees/run_emote.dm
index 6f2f5cdc203..c0c0da96584 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/run_emote.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/run_emote.dm
@@ -15,8 +15,7 @@
/datum/ai_behavior/run_emote/perform(seconds_per_tick, datum/ai_controller/controller, emote_key)
var/mob/living/living_pawn = controller.pawn
if (!isliving(living_pawn))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
var/list/emote_list = controller.blackboard[emote_key]
var/emote
@@ -26,8 +25,7 @@
emote = emote_list
if(isnull(emote))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
living_pawn.emote(emote)
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/sleep_with_no_target.dm b/code/datums/ai/basic_mobs/basic_subtrees/sleep_with_no_target.dm
index 93499cf673c..5d9841a5247 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/sleep_with_no_target.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/sleep_with_no_target.dm
@@ -16,7 +16,9 @@
/datum/ai_behavior/sleep_after_targetless_time/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
var/atom/target = controller.blackboard[target_key]
- finish_action(controller, succeeded = QDELETED(target), seconds_per_tick = seconds_per_tick)
+ if(QDELETED(target))
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
/datum/ai_behavior/sleep_after_targetless_time/finish_action(datum/ai_controller/controller, succeeded, seconds_per_tick)
. = ..()
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/target_retaliate.dm b/code/datums/ai/basic_mobs/basic_subtrees/target_retaliate.dm
index 55ec7387613..d327b1047cf 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/target_retaliate.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/target_retaliate.dm
@@ -39,6 +39,7 @@
var/mob/living/living_mob = controller.pawn
var/datum/targeting_strategy/targeting_strategy = GET_TARGETING_STRATEGY(controller.blackboard[targeting_strategy_key])
if(!targeting_strategy)
+ . = AI_BEHAVIOR_DELAY
CRASH("No target datum was supplied in the blackboard for [controller.pawn]")
var/list/shitlist = controller.blackboard[shitlist_key]
@@ -48,8 +49,7 @@
controller.set_blackboard_key(BB_TEMPORARILY_IGNORE_FACTION, TRUE)
if (!QDELETED(existing_target) && (locate(existing_target) in shitlist) && targeting_strategy.can_attack(living_mob, existing_target, vision_range))
- finish_action(controller, succeeded = TRUE, check_faction = check_faction)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
var/list/enemies_list = list()
for(var/mob/living/potential_target as anything in shitlist)
@@ -59,8 +59,7 @@
if(!length(enemies_list))
controller.clear_blackboard_key(target_key)
- finish_action(controller, succeeded = FALSE, check_faction = check_faction)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/atom/new_target = pick_final_target(controller, enemies_list)
controller.set_blackboard_key(target_key, new_target)
@@ -70,7 +69,7 @@
if(potential_hiding_location) //If they're hiding inside of something, we need to know so we can go for that instead initially.
controller.set_blackboard_key(hiding_location_key, potential_hiding_location)
- finish_action(controller, succeeded = TRUE, check_faction = check_faction)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/// Returns the desired final target from the filtered list of enemies
/datum/ai_behavior/target_from_retaliate_list/proc/pick_final_target(datum/ai_controller/controller, list/enemies_list)
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/teleport_away_from_target.dm b/code/datums/ai/basic_mobs/basic_subtrees/teleport_away_from_target.dm
index dadba992e9f..25f0e4a4249 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/teleport_away_from_target.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/teleport_away_from_target.dm
@@ -34,7 +34,7 @@
/datum/ai_behavior/find_furthest_turf_from_target/perform(seconds_per_tick, datum/ai_controller/controller, target_key, set_key, range)
var/mob/living/living_target = controller.blackboard[target_key]
if(QDELETED(living_target))
- return
+ return AI_BEHAVIOR_INSTANT
var/distance = 0
var/turf/chosen_turf
@@ -49,8 +49,7 @@
break //we have already found the max distance
if(isnull(chosen_turf))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
controller.set_blackboard_key(set_key, chosen_turf)
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
diff --git a/code/datums/ai/basic_mobs/basic_subtrees/use_mob_ability.dm b/code/datums/ai/basic_mobs/basic_subtrees/use_mob_ability.dm
index a59a901d57d..4c794a73d8a 100644
--- a/code/datums/ai/basic_mobs/basic_subtrees/use_mob_ability.dm
+++ b/code/datums/ai/basic_mobs/basic_subtrees/use_mob_ability.dm
@@ -27,7 +27,7 @@
/datum/ai_behavior/use_mob_ability/perform(seconds_per_tick, datum/ai_controller/controller, ability_key)
var/datum/action/using_action = controller.blackboard[ability_key]
if (QDELETED(using_action))
- finish_action(controller, FALSE, ability_key)
- return
- var/result = using_action.Trigger()
- finish_action(controller, result, ability_key)
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
+ if(using_action.Trigger())
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
diff --git a/code/datums/ai/basic_mobs/pet_commands/fetch.dm b/code/datums/ai/basic_mobs/pet_commands/fetch.dm
index a9147eaf681..87606fa0c65 100644
--- a/code/datums/ai/basic_mobs/pet_commands/fetch.dm
+++ b/code/datums/ai/basic_mobs/pet_commands/fetch.dm
@@ -14,19 +14,15 @@
set_movement_target(controller, fetch_thing)
/datum/ai_behavior/fetch_seek/perform(seconds_per_tick, datum/ai_controller/controller, target_key, delivery_key)
- . = ..()
var/obj/item/fetch_thing = controller.blackboard[target_key]
// It stopped existing
if (QDELETED(fetch_thing))
- finish_action(controller, FALSE, target_key, delivery_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
// We can't pick this up
if (fetch_thing.anchored)
- finish_action(controller, FALSE, target_key, delivery_key)
- return
-
- finish_action(controller, TRUE, target_key, delivery_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/fetch_seek/finish_action(datum/ai_controller/controller, success, target_key, delivery_key)
. = ..()
@@ -53,14 +49,13 @@
set_movement_target(controller, return_target)
/datum/ai_behavior/deliver_fetched_item/perform(seconds_per_tick, datum/ai_controller/controller, delivery_key, storage_key)
- . = ..()
var/mob/living/return_target = controller.blackboard[delivery_key]
if(QDELETED(return_target))
- finish_action(controller, FALSE, delivery_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
- deliver_item(controller, return_target, storage_key)
- finish_action(controller, TRUE, delivery_key)
+ if(!deliver_item(controller, return_target, storage_key))
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/deliver_fetched_item/finish_action(datum/ai_controller/controller, success, delivery_key)
. = ..()
@@ -68,13 +63,13 @@
controller.clear_blackboard_key(BB_ACTIVE_PET_COMMAND)
/// Actually deliver the fetched item to the target, if we still have it
+/// Returns TRUE if we succeeded, FALSE if we failed
/datum/ai_behavior/deliver_fetched_item/proc/deliver_item(datum/ai_controller/controller, return_target, storage_key)
var/mob/pawn = controller.pawn
var/obj/item/carried_item = controller.blackboard[storage_key]
if(QDELETED(carried_item) || carried_item.loc != pawn)
pawn.visible_message(span_notice("[pawn] looks around as if [pawn.p_they()] [pawn.p_have()] lost something."))
- finish_action(controller, FALSE)
- return
+ return FALSE
pawn.visible_message(span_notice("[pawn] delivers [carried_item] to [return_target]."))
carried_item.forceMove(get_turf(return_target))
@@ -99,26 +94,26 @@
set_movement_target(controller, snack)
/datum/ai_behavior/eat_fetched_snack/perform(seconds_per_tick, datum/ai_controller/controller, target_key, delivery_key)
- . = ..()
var/obj/item/snack = controller.blackboard[target_key]
var/is_living_loc = isliving(snack.loc)
if(QDELETED(snack) || (!isturf(snack.loc) && !is_living_loc))
- finish_action(controller, FALSE) // Where did it go?
- return
+ // Where did it go?
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/mob/living/basic/basic_pawn = controller.pawn
if(is_living_loc)
if(SPT_PROB(10, seconds_per_tick))
basic_pawn.manual_emote("Stares at [snack.loc]'s [snack.name] intently.")
- return
+ return AI_BEHAVIOR_DELAY
if(!basic_pawn.Adjacent(snack))
- return
+ return AI_BEHAVIOR_DELAY
basic_pawn.melee_attack(snack) // snack attack!
if(QDELETED(snack)) // we ate it!
- finish_action(controller, TRUE, target_key, delivery_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
+ return AI_BEHAVIOR_DELAY
/datum/ai_behavior/eat_fetched_snack/finish_action(datum/ai_controller/controller, succeeded, target_key, delivery_key)
. = ..()
@@ -143,7 +138,6 @@
return
/datum/ai_behavior/forget_failed_fetches/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
COOLDOWN_START(src, reset_ignore_cooldown, cooldown_duration)
controller.clear_blackboard_key(BB_FETCH_IGNORE_LIST)
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
diff --git a/code/datums/ai/basic_mobs/pet_commands/pet_follow_friend.dm b/code/datums/ai/basic_mobs/pet_commands/pet_follow_friend.dm
index 397021818aa..38a6939c901 100644
--- a/code/datums/ai/basic_mobs/pet_commands/pet_follow_friend.dm
+++ b/code/datums/ai/basic_mobs/pet_commands/pet_follow_friend.dm
@@ -10,8 +10,7 @@
set_movement_target(controller, target)
/datum/ai_behavior/pet_follow_friend/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/atom/target = controller.blackboard[target_key]
if (QDELETED(target))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
+ return AI_BEHAVIOR_DELAY
diff --git a/code/datums/ai/basic_mobs/pet_commands/pet_use_targeted_ability.dm b/code/datums/ai/basic_mobs/pet_commands/pet_use_targeted_ability.dm
index c7153b0c12f..3c8c06b0099 100644
--- a/code/datums/ai/basic_mobs/pet_commands/pet_use_targeted_ability.dm
+++ b/code/datums/ai/basic_mobs/pet_commands/pet_use_targeted_ability.dm
@@ -13,11 +13,11 @@
var/datum/action/cooldown/mob_cooldown/ability = controller.blackboard[ability_key]
var/mob/living/target = controller.blackboard[target_key]
if (QDELETED(ability) || QDELETED(target))
- finish_action(controller, FALSE, ability_key, target_key)
- return
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
var/mob/pawn = controller.pawn
if(QDELETED(pawn) || ability.InterceptClickOn(pawn, null, target))
- finish_action(controller, TRUE, ability_key, target_key)
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
+ return AI_BEHAVIOR_INSTANT
/datum/ai_behavior/pet_use_ability/finish_action(datum/ai_controller/controller, succeeded, ability_key, target_key)
. = ..()
diff --git a/code/datums/ai/basic_mobs/pet_commands/play_dead.dm b/code/datums/ai/basic_mobs/pet_commands/play_dead.dm
index c4b99cf6f42..5a7a0943026 100644
--- a/code/datums/ai/basic_mobs/pet_commands/play_dead.dm
+++ b/code/datums/ai/basic_mobs/pet_commands/play_dead.dm
@@ -11,9 +11,9 @@
basic_pawn.look_dead()
/datum/ai_behavior/play_dead/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
if(SPT_PROB(10, seconds_per_tick))
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
+ return AI_BEHAVIOR_DELAY
/datum/ai_behavior/play_dead/finish_action(datum/ai_controller/controller, succeeded)
. = ..()
diff --git a/code/datums/ai/dog/dog_behaviors.dm b/code/datums/ai/dog/dog_behaviors.dm
index eed116330fb..00a2f789e12 100644
--- a/code/datums/ai/dog/dog_behaviors.dm
+++ b/code/datums/ai/dog/dog_behaviors.dm
@@ -11,23 +11,21 @@
controller.behavior_cooldowns[src] = world.time + get_cooldown(controller)
var/mob/living/living_pawn = controller.pawn
if(!(isturf(living_pawn.loc) || HAS_TRAIT(living_pawn, TRAIT_AI_BAGATTACK))) // Void puppies can attack from inside bags
- finish_action(controller, FALSE, target_key, targeting_strategy_key, hiding_location_key)
- return
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
// Unfortunately going to repeat this check in parent call but what can you do
var/atom/target = controller.blackboard[target_key]
var/datum/targeting_strategy/targeting_strategy = GET_TARGETING_STRATEGY(controller.blackboard[targeting_strategy_key])
if (!targeting_strategy.can_attack(living_pawn, target))
- finish_action(controller, FALSE, target_key, targeting_strategy_key, hiding_location_key)
- return
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
if (!living_pawn.Adjacent(target))
growl_at(living_pawn, target, seconds_per_tick)
- return
+ return AI_BEHAVIOR_INSTANT
if(!controller.blackboard[BB_DOG_HARASS_HARM])
paw_harmlessly(living_pawn, target, seconds_per_tick)
- return
+ return AI_BEHAVIOR_INSTANT
// Give Ian some teeth
var/old_melee_lower = living_pawn.melee_damage_lower
@@ -39,6 +37,7 @@
living_pawn.melee_damage_lower = old_melee_lower
living_pawn.melee_damage_upper = old_melee_upper
+ return AI_BEHAVIOR_DELAY
/// Swat at someone we don't like but won't hurt
/datum/ai_behavior/basic_melee_attack/dog/proc/paw_harmlessly(mob/living/living_pawn, atom/target, seconds_per_tick)
diff --git a/code/datums/ai/dog/dog_subtrees.dm b/code/datums/ai/dog/dog_subtrees.dm
index 62f63da54bd..74c075adad3 100644
--- a/code/datums/ai/dog/dog_subtrees.dm
+++ b/code/datums/ai/dog/dog_subtrees.dm
@@ -35,5 +35,4 @@
controller.clear_blackboard_key(target_key)
/datum/ai_behavior/find_hated_dog_target/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
diff --git a/code/datums/ai/generic/find_and_set.dm b/code/datums/ai/generic/find_and_set.dm
index fbddc33075c..41f256c9ba7 100644
--- a/code/datums/ai/generic/find_and_set.dm
+++ b/code/datums/ai/generic/find_and_set.dm
@@ -7,19 +7,15 @@
action_cooldown = 2 SECONDS
/datum/ai_behavior/find_and_set/perform(seconds_per_tick, datum/ai_controller/controller, set_key, locate_path, search_range)
- . = ..()
if (controller.blackboard_key_exists(set_key))
- finish_action(controller, TRUE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
if(QDELETED(controller.pawn))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
var/find_this_thing = search_tactic(controller, locate_path, search_range)
if(isnull(find_this_thing))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
controller.set_blackboard_key(set_key, find_this_thing)
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/find_and_set/proc/search_tactic(datum/ai_controller/controller, locate_path, search_range)
return locate(locate_path) in oview(search_range, controller.pawn)
diff --git a/code/datums/ai/generic/generic_behaviors.dm b/code/datums/ai/generic/generic_behaviors.dm
index b70375ef393..1c0e1f65adf 100644
--- a/code/datums/ai/generic/generic_behaviors.dm
+++ b/code/datums/ai/generic/generic_behaviors.dm
@@ -1,28 +1,25 @@
/datum/ai_behavior/resist/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
var/mob/living/living_pawn = controller.pawn
living_pawn.ai_controller.set_blackboard_key(BB_RESISTING, TRUE)
living_pawn.execute_resist()
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/battle_screech
///List of possible screeches the behavior has
var/list/screeches
/datum/ai_behavior/battle_screech/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
var/mob/living/living_pawn = controller.pawn
INVOKE_ASYNC(living_pawn, TYPE_PROC_REF(/mob, emote), pick(screeches))
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
///Moves to target then finishes
/datum/ai_behavior/move_to_target
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT
/datum/ai_behavior/move_to_target/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/break_spine
@@ -42,12 +39,10 @@
var/mob/living/big_guy = controller.pawn //he was molded by the darkness
if(QDELETED(batman) || get_dist(batman, big_guy) >= give_up_distance)
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
if(batman.stat != CONSCIOUS)
- finish_action(controller, TRUE, target_key)
- return
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
big_guy.start_pulling(batman)
big_guy.face_atom(batman)
@@ -63,7 +58,7 @@
else
batman.adjustBruteLoss(150)
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/break_spine/finish_action(datum/ai_controller/controller, succeeded, target_key)
if(succeeded)
@@ -80,14 +75,12 @@
/datum/ai_behavior/use_in_hand/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
var/mob/living/pawn = controller.pawn
var/obj/item/held = pawn.get_active_held_item()
if(!held)
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
pawn.activate_hand()
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/// Use the currently held item, or unarmed, on a weakref to an object in the world
/datum/ai_behavior/use_on_object
@@ -102,13 +95,11 @@
set_movement_target(controller, target)
/datum/ai_behavior/use_on_object/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/mob/living/pawn = controller.pawn
var/obj/item/held_item = pawn.get_item_by_slot(pawn.get_active_hand())
var/atom/target = controller.blackboard[target_key]
if(QDELETED(target))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
pawn.set_combat_mode(FALSE)
if(held_item)
@@ -116,7 +107,7 @@
else
pawn.UnarmedAttack(target, TRUE)
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/give
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH
@@ -127,37 +118,34 @@
set_movement_target(controller, controller.blackboard[target_key])
/datum/ai_behavior/give/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/mob/living/pawn = controller.pawn
var/obj/item/held_item = pawn.get_active_held_item()
var/atom/target = controller.blackboard[target_key]
if(!held_item) //if held_item is null, we pretend that action was succesful
- finish_action(controller, TRUE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
if(!target || !isliving(target))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/mob/living/living_target = target
-
- if(!try_to_give_item(controller, living_target, held_item))
- return
+ var/perform_flags = try_to_give_item(controller, living_target, held_item)
+ if(perform_flags & AI_BEHAVIOR_FAILED)
+ return perform_flags
controller.PauseAi(1.5 SECONDS)
living_target.visible_message(
span_info("[pawn] starts trying to give [held_item] to [living_target]!"),
span_warning("[pawn] tries to give you [held_item]!")
)
if(!do_after(pawn, 1 SECONDS, living_target))
- return
+ return AI_BEHAVIOR_DELAY | perform_flags
- try_to_give_item(controller, living_target, held_item, actually_give = TRUE)
+ perform_flags |= try_to_give_item(controller, living_target, held_item, actually_give = TRUE)
+ return AI_BEHAVIOR_DELAY | perform_flags
/datum/ai_behavior/give/proc/try_to_give_item(datum/ai_controller/controller, mob/living/target, obj/item/held_item, actually_give)
if(QDELETED(held_item) || QDELETED(target))
- finish_action(controller, FALSE)
- return FALSE
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/has_left_pocket = target.can_equip(held_item, ITEM_SLOT_LPOCKET)
var/has_right_pocket = target.can_equip(held_item, ITEM_SLOT_RPOCKET)
@@ -169,17 +157,16 @@
break
if(!has_left_pocket && !has_right_pocket && !has_valid_hand)
- finish_action(controller, FALSE)
- return FALSE
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
if(!actually_give)
- return TRUE
+ return AI_BEHAVIOR_DELAY
if(!has_valid_hand || prob(50))
target.equip_to_slot_if_possible(held_item, (!has_left_pocket ? ITEM_SLOT_RPOCKET : (prob(50) ? ITEM_SLOT_LPOCKET : ITEM_SLOT_RPOCKET)))
else
target.put_in_hands(held_item)
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/consume
@@ -191,21 +178,20 @@
set_movement_target(controller, controller.blackboard[target_key])
/datum/ai_behavior/consume/perform(seconds_per_tick, datum/ai_controller/controller, target_key, hunger_timer_key)
- . = ..()
var/mob/living/living_pawn = controller.pawn
var/obj/item/target = controller.blackboard[target_key]
if(QDELETED(target))
- return
+ return AI_BEHAVIOR_DELAY
if(!(target in living_pawn.held_items))
if(!living_pawn.get_empty_held_indexes() || !living_pawn.put_in_hands(target))
- finish_action(controller, FALSE, target, hunger_timer_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
target.melee_attack_chain(living_pawn, living_pawn)
if(QDELETED(target) || prob(10)) // Even if we don't finish it all we can randomly decide to be done
- finish_action(controller, TRUE, null, hunger_timer_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
+ return AI_BEHAVIOR_DELAY
/datum/ai_behavior/consume/finish_action(datum/ai_controller/controller, succeeded, target_key, hunger_timer_key)
. = ..()
@@ -218,36 +204,34 @@
/datum/ai_behavior/drop_item
/datum/ai_behavior/drop_item/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
var/mob/living/living_pawn = controller.pawn
var/obj/item/best_held = GetBestWeapon(controller, null, living_pawn.held_items)
for(var/obj/item/held as anything in living_pawn.held_items)
if(!held || held == best_held)
continue
living_pawn.dropItemToGround(held)
+ return AI_BEHAVIOR_DELAY
/// This behavior involves attacking a target.
/datum/ai_behavior/attack
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_MOVE_AND_PERFORM | AI_BEHAVIOR_REQUIRE_REACH
/datum/ai_behavior/attack/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
var/mob/living/living_pawn = controller.pawn
if(!istype(living_pawn) || !isturf(living_pawn.loc))
- return
+ return AI_BEHAVIOR_DELAY
var/atom/movable/attack_target = controller.blackboard[BB_ATTACK_TARGET]
if(!attack_target || !can_see(living_pawn, attack_target, length = controller.blackboard[BB_VISION_RANGE]))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/mob/living/living_target = attack_target
if(istype(living_target) && (living_target.stat == DEAD))
- finish_action(controller, TRUE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
set_movement_target(controller, living_target)
attack(controller, living_target)
+ return AI_BEHAVIOR_DELAY
/datum/ai_behavior/attack/finish_action(datum/ai_controller/controller, succeeded)
. = ..()
@@ -265,22 +249,20 @@
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_MOVE_AND_PERFORM
/datum/ai_behavior/follow/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
var/mob/living/living_pawn = controller.pawn
if(!istype(living_pawn) || !isturf(living_pawn.loc))
- return
+ return AI_BEHAVIOR_DELAY
var/atom/movable/follow_target = controller.blackboard[BB_FOLLOW_TARGET]
if(!follow_target || get_dist(living_pawn, follow_target) > controller.blackboard[BB_VISION_RANGE])
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/mob/living/living_target = follow_target
if(istype(living_target) && (living_target.stat == DEAD))
- finish_action(controller, TRUE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
set_movement_target(controller, living_target)
+ return AI_BEHAVIOR_DELAY
/datum/ai_behavior/follow/finish_action(datum/ai_controller/controller, succeeded)
. = ..()
@@ -291,11 +273,11 @@
/datum/ai_behavior/perform_emote/perform(seconds_per_tick, datum/ai_controller/controller, emote, speech_sound)
var/mob/living/living_pawn = controller.pawn
if(!istype(living_pawn))
- return
+ return AI_BEHAVIOR_INSTANT
living_pawn.manual_emote(emote)
if(speech_sound) // Only audible emotes will pass in a sound
playsound(living_pawn, speech_sound, 80, vary = TRUE)
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/perform_speech
@@ -304,29 +286,26 @@
var/mob/living/living_pawn = controller.pawn
if(!istype(living_pawn))
- return
+ return AI_BEHAVIOR_INSTANT
living_pawn.say(speech, forced = "AI Controller")
if(speech_sound)
playsound(living_pawn, speech_sound, 80, vary = TRUE)
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/perform_speech_radio
/datum/ai_behavior/perform_speech_radio/perform(seconds_per_tick, datum/ai_controller/controller, speech, obj/item/radio/speech_radio, list/try_channels = list(RADIO_CHANNEL_COMMON))
var/mob/living/living_pawn = controller.pawn
if(!istype(living_pawn) || !istype(speech_radio) || QDELETED(speech_radio) || !length(try_channels))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
speech_radio.talk_into(living_pawn, speech, pick(try_channels))
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
//song behaviors
/datum/ai_behavior/setup_instrument
/datum/ai_behavior/setup_instrument/perform(seconds_per_tick, datum/ai_controller/controller, song_instrument_key, song_lines_key)
- . = ..()
-
var/obj/item/instrument/song_instrument = controller.blackboard[song_instrument_key]
var/datum/song/song = song_instrument.song
var/song_lines = controller.blackboard[song_lines_key]
@@ -336,24 +315,20 @@
song.ParseSong(new_song = song_lines)
song.repeat = 10
song.volume = song.max_volume - 10
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/play_instrument
/datum/ai_behavior/play_instrument/perform(seconds_per_tick, datum/ai_controller/controller, song_instrument_key)
- . = ..()
-
var/obj/item/instrument/song_instrument = controller.blackboard[song_instrument_key]
var/datum/song/song = song_instrument.song
song.start_playing(controller.pawn)
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/find_nearby
/datum/ai_behavior/find_nearby/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
-
var/list/possible_targets = list()
for(var/atom/thing in view(2, controller.pawn))
if(!thing.mouse_opacity)
@@ -366,6 +341,6 @@
continue
possible_targets += thing
if(!possible_targets.len)
- finish_action(controller, FALSE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
controller.set_blackboard_key(target_key, pick(possible_targets))
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
diff --git a/code/datums/ai/hunting_behavior/hunting_behaviors.dm b/code/datums/ai/hunting_behavior/hunting_behaviors.dm
index 07fc84997a6..609138c1132 100644
--- a/code/datums/ai/hunting_behavior/hunting_behaviors.dm
+++ b/code/datums/ai/hunting_behavior/hunting_behaviors.dm
@@ -52,18 +52,14 @@
/datum/ai_behavior/find_hunt_target
/datum/ai_behavior/find_hunt_target/perform(seconds_per_tick, datum/ai_controller/controller, hunting_target_key, types_to_hunt, hunt_range)
- . = ..()
-
var/mob/living/living_mob = controller.pawn
for(var/atom/possible_dinner as anything in typecache_filter_list(range(hunt_range, living_mob), types_to_hunt))
if(!valid_dinner(living_mob, possible_dinner, hunt_range, controller, seconds_per_tick))
continue
controller.set_blackboard_key(hunting_target_key, possible_dinner)
- finish_action(controller, TRUE, hunting_target_key)
- return
-
- finish_action(controller, FALSE, hunting_target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
/datum/ai_behavior/find_hunt_target/proc/valid_dinner(mob/living/source, atom/dinner, radius, datum/ai_controller/controller, seconds_per_tick)
if(isliving(dinner))
@@ -90,15 +86,13 @@
set_movement_target(controller, hunt_target)
/datum/ai_behavior/hunt_target/perform(seconds_per_tick, datum/ai_controller/controller, hunting_target_key, hunting_cooldown_key)
- . = ..()
var/mob/living/hunter = controller.pawn
var/atom/hunted = controller.blackboard[hunting_target_key]
if(QDELETED(hunted))
- finish_action(controller, FALSE, hunting_target_key)
- else
- target_caught(hunter, hunted)
- finish_action(controller, TRUE, hunting_target_key, hunting_cooldown_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
+ target_caught(hunter, hunted)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/hunt_target/proc/target_caught(mob/living/hunter, atom/hunted)
if(isliving(hunted)) // Are we hunting a living mob?
@@ -153,7 +147,7 @@
/datum/ai_behavior/hunt_target/use_ability_on_target/perform(seconds_per_tick, datum/ai_controller/controller, hunting_target_key, hunting_cooldown_key)
var/datum/action/cooldown/ability = controller.blackboard[ability_key]
if(!ability?.IsAvailable())
- finish_action(controller, FALSE, hunting_target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
return ..()
/datum/ai_behavior/hunt_target/use_ability_on_target/target_caught(mob/living/hunter, atom/hunted)
diff --git a/code/datums/ai/monkey/monkey_behaviors.dm b/code/datums/ai/monkey/monkey_behaviors.dm
index d16110cd702..10a23acdabe 100644
--- a/code/datums/ai/monkey/monkey_behaviors.dm
+++ b/code/datums/ai/monkey/monkey_behaviors.dm
@@ -12,55 +12,51 @@
controller.clear_blackboard_key(BB_MONKEY_PICKUPTARGET)
+/// Equips an item on the monkey
+/// Returns TRUE if it works out, FALSE otherwise
/datum/ai_behavior/monkey_equip/proc/equip_item(datum/ai_controller/controller)
var/mob/living/living_pawn = controller.pawn
var/obj/item/target = controller.blackboard[BB_MONKEY_PICKUPTARGET]
var/best_force = controller.blackboard[BB_MONKEY_BEST_FORCE_FOUND]
-
if(!isturf(living_pawn.loc))
- finish_action(controller, FALSE)
- return
+ return FALSE
if(!target)
- finish_action(controller, FALSE)
- return
+ return FALSE
if(target.anchored) //Can't pick it up, so stop trying.
- finish_action(controller, FALSE)
- return
+ return FALSE
// Strong weapon
else if(target.force > best_force)
living_pawn.drop_all_held_items()
living_pawn.put_in_hands(target)
controller.set_blackboard_key(BB_MONKEY_BEST_FORCE_FOUND, target.force)
- finish_action(controller, TRUE)
- return
+ return TRUE
else if(target.slot_flags) //Clothing == top priority
living_pawn.dropItemToGround(target, TRUE)
living_pawn.update_icons()
if(!living_pawn.equip_to_appropriate_slot(target))
- finish_action(controller, FALSE)
- return //Already wearing something, in the future this should probably replace the current item but the code didn't actually do that, and I dont want to support it right now.
- finish_action(controller, TRUE)
- return
+ return FALSE //Already wearing something, in the future this should probably replace the current item but the code didn't actually do that, and I dont want to support it right now.
+ return TRUE
// EVERYTHING ELSE
else if(living_pawn.get_empty_held_indexes())
living_pawn.put_in_hands(target)
- finish_action(controller, TRUE)
- return
+ return TRUE
- finish_action(controller, FALSE)
+ return FALSE
/datum/ai_behavior/monkey_equip/ground
required_distance = 0
/datum/ai_behavior/monkey_equip/ground/perform(seconds_per_tick, datum/ai_controller/controller)
. = ..()
- equip_item(controller)
+ if(equip_item(controller))
+ return . | AI_BEHAVIOR_SUCCEEDED
+ return . | AI_BEHAVIOR_FAILED
/datum/ai_behavior/monkey_equip/pickpocket
@@ -110,13 +106,10 @@
/datum/ai_behavior/monkey_flee
/datum/ai_behavior/monkey_flee/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
-
var/mob/living/living_pawn = controller.pawn
- if(living_pawn.health >= MONKEY_FLEE_HEALTH)
- finish_action(controller, TRUE) //we're back in bussiness
- return
+ if(living_pawn.health >= MONKEY_FLEE_HEALTH) //we're back in bussiness
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
var/mob/living/target = null
@@ -127,9 +120,9 @@
break
if(target)
- SSmove_manager.move_away(living_pawn, target, max_dist=MONKEY_ENEMY_VISION, delay=5)
- else
- finish_action(controller, TRUE)
+ DSmove_manager.move_away(living_pawn, target, max_dist=MONKEY_ENEMY_VISION, delay=5)
+ return AI_BEHAVIOR_DELAY
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/monkey_attack_mob
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_MOVE_AND_PERFORM //performs to increase frustration
@@ -139,29 +132,28 @@
set_movement_target(controller, controller.blackboard[target_key])
/datum/ai_behavior/monkey_attack_mob/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
-
var/mob/living/target = controller.blackboard[target_key]
var/mob/living/living_pawn = controller.pawn
- if(!target || target.stat != CONSCIOUS)
- finish_action(controller, TRUE) //Target == owned
- return
+ if(!target || target.stat != CONSCIOUS) //Target == owned
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
- if(isturf(target.loc) && !IS_DEAD_OR_INCAP(living_pawn)) // Check if they're a valid target
- // check if target has a weapon
- var/obj/item/W
- for(var/obj/item/I in target.held_items)
- if(!(I.item_flags & ABSTRACT))
- W = I
- break
-
- // if the target has a weapon, chance to disarm them
- if(W && SPT_PROB(MONKEY_ATTACK_DISARM_PROB, seconds_per_tick))
- monkey_attack(controller, target, seconds_per_tick, TRUE)
- else
- monkey_attack(controller, target, seconds_per_tick, FALSE)
+ if(!isturf(target.loc) || IS_DEAD_OR_INCAP(living_pawn)) // Check if they're a valid target
+ return AI_BEHAVIOR_DELAY
+ // check if target has a weapon
+ var/obj/item/W
+ for(var/obj/item/I in target.held_items)
+ if(!(I.item_flags & ABSTRACT))
+ W = I
+ break
+ // if the target has a weapon, chance to disarm them
+ var/perform_flags = NONE
+ if(W && SPT_PROB(MONKEY_ATTACK_DISARM_PROB, seconds_per_tick))
+ perform_flags = monkey_attack(controller, target, seconds_per_tick, TRUE)
+ else
+ perform_flags = monkey_attack(controller, target, seconds_per_tick, FALSE)
+ return AI_BEHAVIOR_DELAY | perform_flags
/datum/ai_behavior/monkey_attack_mob/finish_action(datum/ai_controller/controller, succeeded, target_key)
. = ..()
@@ -169,14 +161,14 @@
controller.clear_blackboard_key(target_key)
if(QDELETED(living_pawn)) // pawn can be null at this point
return
- SSmove_manager.stop_looping(living_pawn)
+ DSmove_manager.stop_looping(living_pawn)
/// attack using a held weapon otherwise bite the enemy, then if we are angry there is a chance we might calm down a little
/datum/ai_behavior/monkey_attack_mob/proc/monkey_attack(datum/ai_controller/controller, mob/living/target, seconds_per_tick, disarm)
var/mob/living/living_pawn = controller.pawn
if(living_pawn.next_move > world.time)
- return
+ return NONE
living_pawn.changeNext_move(CLICK_CD_MELEE) //We play fair
@@ -215,7 +207,7 @@
// no de-aggro
if(controller.blackboard[BB_MONKEY_AGGRESSIVE])
- return
+ return NONE
// we've queued up a monkey attack on a mob which isn't already an enemy, so give them 1 threat to start
// note they might immediately reduce threat and drop from the list.
@@ -238,7 +230,8 @@
if(controller.blackboard[BB_MONKEY_ENEMIES][target] <= 0)
controller.remove_thing_from_blackboard_key(BB_MONKEY_ENEMIES, target)
if(controller.blackboard[BB_MONKEY_CURRENT_ATTACK_TARGET] == target)
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_SUCCEEDED
+ return NONE
/datum/ai_behavior/disposal_mob
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_MOVE_AND_PERFORM //performs to increase frustration
@@ -254,10 +247,8 @@
controller.clear_blackboard_key(disposal_target_key) //No target disposal
/datum/ai_behavior/disposal_mob/perform(seconds_per_tick, datum/ai_controller/controller, attack_target_key, disposal_target_key)
- . = ..()
-
if(controller.blackboard[BB_MONKEY_DISPOSING]) //We are disposing, don't do ANYTHING!!!!
- return
+ return AI_BEHAVIOR_DELAY
var/mob/living/target = controller.blackboard[attack_target_key]
var/mob/living/living_pawn = controller.pawn
@@ -265,25 +256,24 @@
set_movement_target(controller, target)
if(!target)
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
if(target.pulledby != living_pawn && !HAS_AI_CONTROLLER_TYPE(target.pulledby, /datum/ai_controller/monkey)) //Dont steal from my fellow monkeys.
if(living_pawn.Adjacent(target) && isturf(target.loc))
target.grabbedby(living_pawn)
- return //Do the rest next turn
+ return AI_BEHAVIOR_DELAY //Do the rest next turn
var/obj/machinery/disposal/disposal = controller.blackboard[disposal_target_key]
set_movement_target(controller, disposal)
if(!disposal)
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
if(living_pawn.Adjacent(disposal))
INVOKE_ASYNC(src, PROC_REF(try_disposal_mob), controller, attack_target_key, disposal_target_key) //put him in!
- else //This means we might be getting pissed!
- return
+ return AI_BEHAVIOR_DELAY
+ //This means we might be getting pissed!
+ return AI_BEHAVIOR_DELAY
/datum/ai_behavior/disposal_mob/proc/try_disposal_mob(datum/ai_controller/controller, attack_target_key, disposal_target_key)
var/mob/living/living_pawn = controller.pawn
@@ -298,8 +288,6 @@
/datum/ai_behavior/recruit_monkeys/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
-
controller.set_blackboard_key(BB_MONKEY_RECRUIT_COOLDOWN, world.time + MONKEY_RECRUIT_COOLDOWN)
var/mob/living/living_pawn = controller.pawn
@@ -313,7 +301,7 @@
// Other monkeys now also hate the guy we're currently targeting
nearby_monkey.ai_controller.add_blackboard_key_assoc(BB_MONKEY_ENEMIES, controller.blackboard[BB_MONKEY_CURRENT_ATTACK_TARGET], MONKEY_RECRUIT_HATED_AMOUNT)
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/monkey_set_combat_target/perform(seconds_per_tick, datum/ai_controller/controller, set_key, enemies_key)
var/list/enemies = controller.blackboard[enemies_key]
@@ -330,8 +318,7 @@
valids[possible_enemy] = CEILING(100 / (get_dist(controller.pawn, possible_enemy) || 1), 1)
if(!length(valids))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
controller.set_blackboard_key(set_key, pick_weight(valids))
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
diff --git a/code/datums/ai/monkey/monkey_controller.dm b/code/datums/ai/monkey/monkey_controller.dm
index 215f0a96302..693427ba4bd 100644
--- a/code/datums/ai/monkey/monkey_controller.dm
+++ b/code/datums/ai/monkey/monkey_controller.dm
@@ -45,7 +45,7 @@ have ways of interacting with a specific mob and control it.
/datum/ai_controller/monkey/New(atom/new_pawn)
var/static/list/control_examine = list(
- ORGAN_SLOT_EYES = span_monkey("eyes have a primal look in them."),
+ ORGAN_SLOT_EYES = span_monkey("%PRONOUN_They stare%PRONOUN_s around with wild, primal eyes."),
)
AddElement(/datum/element/ai_control_examine, control_examine)
return ..()
diff --git a/code/datums/ai/movement/_ai_movement.dm b/code/datums/ai/movement/_ai_movement.dm
index 3f455b2acd0..a0a75bb227c 100644
--- a/code/datums/ai/movement/_ai_movement.dm
+++ b/code/datums/ai/movement/_ai_movement.dm
@@ -17,7 +17,7 @@
moving_controllers -= controller
// We got deleted as we finished an action
if(!QDELETED(controller.pawn))
- SSmove_manager.stop_looping(controller.pawn, SSai_movement)
+ DSmove_manager.stop_looping(controller.pawn, SSai_movement)
/datum/ai_movement/proc/increment_pathing_failures(datum/ai_controller/controller)
controller.consecutive_pathing_attempts++
diff --git a/code/datums/ai/movement/ai_movement_basic_avoidance.dm b/code/datums/ai/movement/ai_movement_basic_avoidance.dm
index 6b48f1b5e9e..bcfe6833a8d 100644
--- a/code/datums/ai/movement/ai_movement_basic_avoidance.dm
+++ b/code/datums/ai/movement/ai_movement_basic_avoidance.dm
@@ -9,7 +9,7 @@
var/atom/movable/moving = controller.pawn
var/min_dist = controller.blackboard[BB_CURRENT_MIN_MOVE_DISTANCE]
var/delay = controller.movement_delay
- var/datum/move_loop/loop = SSmove_manager.move_to(moving, current_movement_target, min_dist, delay, flags = move_flags, subsystem = SSai_movement, extra_info = controller)
+ var/datum/move_loop/loop = DSmove_manager.move_to(moving, current_movement_target, min_dist, delay, flags = move_flags, subsystem = SSai_movement, extra_info = controller)
RegisterSignal(loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(pre_move))
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(post_move))
diff --git a/code/datums/ai/movement/ai_movement_complete_stop.dm b/code/datums/ai/movement/ai_movement_complete_stop.dm
index dcae93f1ba0..31309256a67 100644
--- a/code/datums/ai/movement/ai_movement_complete_stop.dm
+++ b/code/datums/ai/movement/ai_movement_complete_stop.dm
@@ -8,8 +8,8 @@
var/stopping_time = controller.blackboard[BB_STATIONARY_SECONDS]
var/delay_time = (stopping_time * 0.5) // no real reason to fire any more often than this really
// assume that the current_movement_target is our location
- var/datum/move_loop/loop = SSmove_manager.freeze(moving, current_movement_target, delay = delay_time, timeout = stopping_time, subsystem = SSai_movement, extra_info = controller)
+ var/datum/move_loop/loop = DSmove_manager.freeze(moving, current_movement_target, delay = delay_time, timeout = stopping_time, subsystem = SSai_movement, extra_info = controller)
RegisterSignal(loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(pre_move))
/datum/ai_movement/complete_stop/allowed_to_move(datum/move_loop/source)
- return FALSE
+ return FALSE
diff --git a/code/datums/ai/movement/ai_movement_dumb.dm b/code/datums/ai/movement/ai_movement_dumb.dm
index 06ac4bdd10c..a64a7539eec 100644
--- a/code/datums/ai/movement/ai_movement_dumb.dm
+++ b/code/datums/ai/movement/ai_movement_dumb.dm
@@ -7,7 +7,7 @@
. = ..()
var/atom/movable/moving = controller.pawn
var/delay = controller.movement_delay
- var/datum/move_loop/loop = SSmove_manager.move_towards_legacy(moving, current_movement_target, delay, subsystem = SSai_movement, extra_info = controller)
+ var/datum/move_loop/loop = DSmove_manager.move_towards_legacy(moving, current_movement_target, delay, subsystem = SSai_movement, extra_info = controller)
RegisterSignal(loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(pre_move))
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(post_move))
diff --git a/code/datums/ai/movement/ai_movement_jps.dm b/code/datums/ai/movement/ai_movement_jps.dm
index 825feefabfa..ac16b0aaa23 100644
--- a/code/datums/ai/movement/ai_movement_jps.dm
+++ b/code/datums/ai/movement/ai_movement_jps.dm
@@ -12,7 +12,7 @@
var/atom/movable/moving = controller.pawn
var/delay = controller.movement_delay
- var/datum/move_loop/has_target/jps/loop = SSmove_manager.jps_move(moving,
+ var/datum/move_loop/has_target/jps/loop = DSmove_manager.jps_move(moving,
current_movement_target,
delay,
repath_delay = 0.5 SECONDS,
diff --git a/code/datums/ai/objects/mod.dm b/code/datums/ai/objects/mod.dm
index 67d8121a4e1..edad77aa4c4 100644
--- a/code/datums/ai/objects/mod.dm
+++ b/code/datums/ai/objects/mod.dm
@@ -34,12 +34,11 @@
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT|AI_BEHAVIOR_MOVE_AND_PERFORM
/datum/ai_behavior/mod_attach/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
if(!controller.pawn.Adjacent(controller.blackboard[BB_MOD_TARGET]))
- return
+ return AI_BEHAVIOR_DELAY
var/obj/item/implant/mod/implant = controller.blackboard[BB_MOD_IMPLANT]
implant.module.attach(controller.blackboard[BB_MOD_TARGET])
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/mod_attach/finish_action(datum/ai_controller/controller, succeeded)
. = ..()
diff --git a/code/datums/ai/objects/vending_machines/vending_machine_behaviors.dm b/code/datums/ai/objects/vending_machines/vending_machine_behaviors.dm
index b4e5609531c..d6310bfc9f3 100644
--- a/code/datums/ai/objects/vending_machines/vending_machine_behaviors.dm
+++ b/code/datums/ai/objects/vending_machines/vending_machine_behaviors.dm
@@ -10,15 +10,15 @@
set_movement_target(controller, controller.blackboard[target_key])
/datum/ai_behavior/vendor_crush/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
if(controller.blackboard[BB_VENDING_BUSY_TILTING])
- return
+ return AI_BEHAVIOR_DELAY
controller.ai_movement.stop_moving_towards(controller)
controller.set_blackboard_key(BB_VENDING_BUSY_TILTING, TRUE)
var/turf/target_turf = get_turf(controller.blackboard[BB_VENDING_CURRENT_TARGET])
new /obj/effect/temp_visual/telegraphing/vending_machine_tilt(target_turf)
addtimer(CALLBACK(src, PROC_REF(tiltonmob), controller, target_turf), time_to_tilt)
+ return AI_BEHAVIOR_DELAY
/datum/ai_behavior/vendor_crush/proc/tiltonmob(datum/ai_controller/controller, turf/target_turf)
var/obj/machinery/vending/vendor_pawn = controller.pawn
@@ -40,10 +40,9 @@
var/succes_tilt_cooldown = 5 SECONDS
/datum/ai_behavior/vendor_rise_up/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
var/obj/machinery/vending/vendor_pawn = controller.pawn
vendor_pawn.visible_message(span_warning("[vendor_pawn] untilts itself!"))
if(controller.blackboard[BB_VENDING_LAST_HIT_SUCCESFUL])
controller.set_blackboard_key(BB_VENDING_TILT_COOLDOWN, world.time + succes_tilt_cooldown)
vendor_pawn.untilt()
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
diff --git a/code/datums/ai/robot_customer/robot_customer_behaviors.dm b/code/datums/ai/robot_customer/robot_customer_behaviors.dm
index 35fd26d76f6..7aa0f34f520 100644
--- a/code/datums/ai/robot_customer/robot_customer_behaviors.dm
+++ b/code/datums/ai/robot_customer/robot_customer_behaviors.dm
@@ -2,7 +2,6 @@
action_cooldown = 8 SECONDS
/datum/ai_behavior/find_seat/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
var/mob/living/basic/robot_customer/customer_pawn = controller.pawn
var/datum/customer_data/customer_data = controller.blackboard[BB_CUSTOMER_CUSTOMERINFO]
var/datum/venue/attending_venue = controller.blackboard[BB_CUSTOMER_ATTENDING_VENUE]
@@ -28,22 +27,20 @@
customer_pawn.say(pick(customer_data.found_seat_lines))
controller.set_blackboard_key(BB_CUSTOMER_MY_SEAT, found_seat)
attending_venue.linked_seats[found_seat] = customer_pawn
- finish_action(controller, TRUE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
// SPT_PROB 1.5 is about a 60% chance that the tourist will have vocalised at least once every minute.
if(!controller.blackboard[BB_CUSTOMER_SAID_CANT_FIND_SEAT_LINE] || SPT_PROB(1.5, seconds_per_tick))
customer_pawn.say(pick(customer_data.cant_find_seat_lines))
controller.set_blackboard_key(BB_CUSTOMER_SAID_CANT_FIND_SEAT_LINE, TRUE)
- finish_action(controller, FALSE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
/datum/ai_behavior/order_food
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT
required_distance = 0
/datum/ai_behavior/order_food/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
var/mob/living/basic/robot_customer/customer_pawn = controller.pawn
var/datum/customer_data/customer_data = controller.blackboard[BB_CUSTOMER_CUSTOMERINFO]
var/obj/structure/holosign/robot_seat/seat_marker = controller.blackboard[BB_CUSTOMER_MY_SEAT]
@@ -55,23 +52,19 @@
var/datum/venue/attending_venue = controller.blackboard[BB_CUSTOMER_ATTENDING_VENUE]
controller.set_blackboard_key(BB_CUSTOMER_CURRENT_ORDER, attending_venue.order_food(customer_pawn, customer_data))
-
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/wait_for_food
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_MOVE_AND_PERFORM
required_distance = 0
/datum/ai_behavior/wait_for_food/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
if(controller.blackboard[BB_CUSTOMER_EATING])
- finish_action(controller, TRUE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
controller.add_blackboard_key(BB_CUSTOMER_PATIENCE, seconds_per_tick * -1 SECONDS) // Convert seconds_per_tick to a SECONDS equivalent.
if(controller.blackboard[BB_CUSTOMER_PATIENCE] < 0 || controller.blackboard[BB_CUSTOMER_LEAVING]) // Check if we're leaving because sometthing mightve forced us to
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
// SPT_PROB 1.5 is about a 40% chance that the tourist will have vocalised at least once every minute.
if(SPT_PROB(0.85, seconds_per_tick))
@@ -95,6 +88,7 @@
customer.eat_order(I, attending_venue)
break
+ return AI_BEHAVIOR_DELAY
/datum/ai_behavior/wait_for_food/finish_action(datum/ai_controller/controller, succeeded)
. = ..()
@@ -121,6 +115,5 @@
set_movement_target(controller, attending_venue.restaurant_portal)
/datum/ai_behavior/leave_venue/perform(seconds_per_tick, datum/ai_controller/controller, venue_key)
- . = ..()
qdel(controller.pawn) //save the world, my final message, goodbye.
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
diff --git a/code/datums/brain_damage/special.dm b/code/datums/brain_damage/special.dm
index 5b8666413e3..1bf011e0fab 100644
--- a/code/datums/brain_damage/special.dm
+++ b/code/datums/brain_damage/special.dm
@@ -491,6 +491,7 @@
owner.ai_controller = new /datum/ai_controller/monkey(owner)
owner.ai_controller.continue_processing_when_client = TRUE
+ owner.ai_controller.can_idle = FALSE
owner.ai_controller.set_ai_status(AI_STATUS_OFF)
/datum/brain_trauma/special/primal_instincts/on_lose(silent)
@@ -514,7 +515,7 @@
owner.grant_language(/datum/language/monkey, UNDERSTOOD_LANGUAGE, TRAUMA_TRAIT)
owner.ai_controller.set_blackboard_key(BB_MONKEY_AGGRESSIVE, prob(75))
if(owner.ai_controller.ai_status == AI_STATUS_OFF)
- owner.ai_controller.set_ai_status(AI_STATUS_IDLE)
+ owner.ai_controller.set_ai_status(AI_STATUS_ON)
owner.log_message("became controlled by monkey instincts ([owner.ai_controller.blackboard[BB_MONKEY_AGGRESSIVE] ? "aggressive" : "docile"])", LOG_ATTACK, color = "orange")
to_chat(owner, span_warning("You feel the urge to act on your primal instincts..."))
// extend original timer if we roll the effect while it's already ongoing
diff --git a/code/datums/components/conveyor_movement.dm b/code/datums/components/conveyor_movement.dm
index d8affca3649..61a0066ff4a 100644
--- a/code/datums/components/conveyor_movement.dm
+++ b/code/datums/components/conveyor_movement.dm
@@ -15,7 +15,7 @@
if(!start_delay)
start_delay = speed
var/atom/movable/moving_parent = parent
- var/datum/move_loop/loop = SSmove_manager.move(moving_parent, direction, delay = start_delay, subsystem = SSconveyors, flags=MOVEMENT_LOOP_IGNORE_PRIORITY|MOVEMENT_LOOP_OUTSIDE_CONTROL)
+ var/datum/move_loop/loop = DSmove_manager.move(moving_parent, direction, delay = start_delay, subsystem = SSconveyors, flags=MOVEMENT_LOOP_IGNORE_PRIORITY|MOVEMENT_LOOP_OUTSIDE_CONTROL)
RegisterSignal(loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(should_move))
RegisterSignal(loop, COMSIG_QDELETING, PROC_REF(loop_ended))
diff --git a/code/datums/components/crafting/_recipes.dm b/code/datums/components/crafting/_recipes.dm
index 4254804974e..09121339d30 100644
--- a/code/datums/components/crafting/_recipes.dm
+++ b/code/datums/components/crafting/_recipes.dm
@@ -41,6 +41,8 @@
var/result_amount
/// Whether we should delete the contents of the crafted storage item (Only works with storage items, used for ammo boxes, donut boxes, internals boxes, etc)
var/delete_contents = TRUE
+ /// Allows you to craft so that you don't have to click the craft button many times.
+ var/mass_craftable = FALSE
/datum/crafting_recipe/New()
if(!name && result)
diff --git a/code/datums/components/crafting/crafting.dm b/code/datums/components/crafting/crafting.dm
index a6a905ccdb4..6fc560a293f 100644
--- a/code/datums/components/crafting/crafting.dm
+++ b/code/datums/components/crafting/crafting.dm
@@ -458,28 +458,39 @@
return data
+/datum/component/personal_crafting/proc/make_action(datum/crafting_recipe/recipe, mob/user)
+ var/atom/movable/result = construct_item(user, recipe)
+ if(istext(result)) //We failed to make an item and got a fail message
+ to_chat(user, span_warning("Construction failed[result]"))
+ return FALSE
+ if(ismob(user) && isitem(result)) //In case the user is actually possessing a non mob like a machine
+ user.put_in_hands(result)
+ else if(!istype(result, /obj/effect/spawner))
+ result.forceMove(user.drop_location())
+ to_chat(user, span_notice("[recipe.name] crafted."))
+ user.investigate_log("crafted [recipe]", INVESTIGATE_CRAFTING)
+ recipe.on_craft_completion(user, result)
+ return TRUE
+
+
/datum/component/personal_crafting/ui_act(action, params)
. = ..()
if(.)
return
switch(action)
- if("make")
+ if("make", "make_mass")
var/mob/user = usr
var/datum/crafting_recipe/crafting_recipe = locate(params["recipe"]) in (mode ? GLOB.cooking_recipes : GLOB.crafting_recipes)
busy = TRUE
ui_interact(user)
- var/atom/movable/result = construct_item(user, crafting_recipe)
- if(!istext(result)) //We made an item and didn't get a fail message
- if(ismob(user) && isitem(result)) //In case the user is actually possessing a non mob like a machine
- user.put_in_hands(result)
- else
- if(!istype(result, /obj/effect/spawner))
- result.forceMove(user.drop_location())
- to_chat(user, span_notice("[crafting_recipe.name] crafted."))
- user.investigate_log("crafted [crafting_recipe]", INVESTIGATE_CRAFTING)
- crafting_recipe.on_craft_completion(user, result)
+ if(action == "make_mass")
+ var/crafted_items = 0
+ while(make_action(crafting_recipe, user))
+ crafted_items++
+ if(crafted_items)
+ to_chat(user, span_notice("You made [crafted_items] item\s."))
else
- to_chat(user, span_warning("Construction failed[result]"))
+ make_action(crafting_recipe, user)
busy = FALSE
if("toggle_recipes")
display_craftable_only = !display_craftable_only
@@ -549,6 +560,7 @@
// Crafting
if(recipe.non_craftable)
data["non_craftable"] = recipe.non_craftable
+ data["mass_craftable"] = recipe.mass_craftable
if(recipe.steps)
data["steps"] = recipe.steps
diff --git a/code/datums/components/crafting/entertainment.dm b/code/datums/components/crafting/entertainment.dm
index dae810c220a..84b2ef163bb 100644
--- a/code/datums/components/crafting/entertainment.dm
+++ b/code/datums/components/crafting/entertainment.dm
@@ -112,6 +112,7 @@
/obj/item/spear/explosive,
/obj/item/spear/bonespear,
/obj/item/spear/bamboospear,
+ /obj/item/spear/military,
)
result = /obj/structure/headpike
category = CAT_ENTERTAINMENT
@@ -144,6 +145,20 @@
result = /obj/structure/headpike/bamboo
category = CAT_ENTERTAINMENT
+/datum/crafting_recipe/headpikemilitary
+ name = "Spike Head (Military)"
+ time = 6.5 SECONDS
+ reqs = list(
+ /obj/item/spear/military = 1,
+ /obj/item/bodypart/head = 1,
+ )
+ parts = list(
+ /obj/item/bodypart/head = 1,
+ /obj/item/spear/military = 1,
+ )
+ result = /obj/structure/headpike/military
+ category = CAT_ENTERTAINMENT
+
/datum/crafting_recipe/guillotine
name = "Guillotine"
result = /obj/structure/guillotine
diff --git a/code/datums/components/drift.dm b/code/datums/components/drift.dm
index 6b91a83534f..f8ad46e3ec3 100644
--- a/code/datums/components/drift.dm
+++ b/code/datums/components/drift.dm
@@ -23,7 +23,7 @@
if(instant)
flags |= MOVEMENT_LOOP_START_FAST
var/atom/movable/movable_parent = parent
- drifting_loop = SSmove_manager.move(moving = parent, direction = direction, delay = movable_parent.inertia_move_delay, subsystem = SSspacedrift, priority = MOVEMENT_SPACE_PRIORITY, flags = flags)
+ drifting_loop = DSmove_manager.move(moving = parent, direction = direction, delay = movable_parent.inertia_move_delay, subsystem = SSspacedrift, priority = MOVEMENT_SPACE_PRIORITY, flags = flags)
if(!drifting_loop) //Really want to qdel here but can't
return COMPONENT_INCOMPATIBLE
diff --git a/code/datums/components/explodable.dm b/code/datums/components/explodable.dm
index 956d562bfb6..439b1563521 100644
--- a/code/datums/components/explodable.dm
+++ b/code/datums/components/explodable.dm
@@ -122,13 +122,7 @@
if(!istype(wearer))
return FALSE
- // Maybe switch this over if we have a get_all_clothing or similar proc for carbon mobs.
- // get_all_worn_items is a lie, they include pockets.
- var/list/worn_items = list()
- worn_items += list(wearer.head, wearer.wear_mask, wearer.gloves, wearer.shoes, wearer.glasses, wearer.ears)
- if(ishuman(wearer))
- var/mob/living/carbon/human/human_wearer = wearer
- worn_items += list(human_wearer.wear_suit, human_wearer.w_uniform)
+ var/list/worn_items = wearer.get_equipped_items()
if(!(item in worn_items))
return FALSE
diff --git a/code/datums/components/force_move.dm b/code/datums/components/force_move.dm
index b8c36818621..6c1c1e38e5f 100644
--- a/code/datums/components/force_move.dm
+++ b/code/datums/components/force_move.dm
@@ -9,7 +9,7 @@
var/mob/mob_parent = parent
var/dist = get_dist(mob_parent, target)
- var/datum/move_loop/loop = SSmove_manager.move_towards(mob_parent, target, delay = 1, timeout = dist)
+ var/datum/move_loop/loop = DSmove_manager.move_towards(mob_parent, target, delay = 1, timeout = dist)
RegisterSignal(mob_parent, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE, PROC_REF(stop_move))
RegisterSignal(mob_parent, COMSIG_ATOM_PRE_PRESSURE_PUSH, PROC_REF(stop_pressure))
if(spin)
diff --git a/code/datums/components/fullauto.dm b/code/datums/components/fullauto.dm
index 33b713e8a57..1faa04ceacc 100644
--- a/code/datums/components/fullauto.dm
+++ b/code/datums/components/fullauto.dm
@@ -249,7 +249,7 @@
if(get_dist(shooter, target) <= 0)
target = get_step(shooter, shooter.dir) //Shoot in the direction faced if the mouse is on the same tile as we are.
target_loc = target
- else if(!in_view_range(shooter, target))
+ else if(!CAN_THEY_SEE(target, shooter))
stop_autofiring() //Elvis has left the building.
return FALSE
shooter.face_atom(target)
diff --git a/code/datums/components/material/remote_materials.dm b/code/datums/components/material/remote_materials.dm
index 568b018e58b..695a02bcb96 100644
--- a/code/datums/components/material/remote_materials.dm
+++ b/code/datums/components/material/remote_materials.dm
@@ -86,7 +86,7 @@ handles linking back and forth.
mat_container = parent.AddComponent( \
/datum/component/material_container, \
- SSmaterials.materials_by_category[MAT_CATEGORY_SILO], \
+ DSmaterials.materials_by_category[MAT_CATEGORY_SILO], \
local_size, \
mat_container_flags, \
container_signals = mat_container_signals, \
diff --git a/code/datums/components/plumbing/splitter.dm b/code/datums/components/plumbing/splitter.dm
index 4dd68a9e578..5ade1dfebc3 100644
--- a/code/datums/components/plumbing/splitter.dm
+++ b/code/datums/components/plumbing/splitter.dm
@@ -43,5 +43,6 @@
if(EAST)
if(amount >= S.transfer_side)
amount = S.transfer_side
+ S.use_energy(S.active_power_usage)
return ..()
diff --git a/code/datums/components/ranged_mob_full_auto.dm b/code/datums/components/ranged_mob_full_auto.dm
index a33b705d548..ff3bfcfe60f 100644
--- a/code/datums/components/ranged_mob_full_auto.dm
+++ b/code/datums/components/ranged_mob_full_auto.dm
@@ -56,7 +56,7 @@
if (get_dist(living_parent, target) <= 0)
set_target(get_step(living_parent, living_parent.dir)) // Shoot in the direction faced if the mouse is on the same tile as we are.
target_loc = target
- else if (!in_view_range(living_parent, target))
+ else if (!CAN_THEY_SEE(target, living_parent))
stop_firing()
return FALSE // Can't see shit
diff --git a/code/datums/components/shuttle_cling.dm b/code/datums/components/shuttle_cling.dm
index 6702b9d601d..724060c9cbe 100644
--- a/code/datums/components/shuttle_cling.dm
+++ b/code/datums/components/shuttle_cling.dm
@@ -51,7 +51,7 @@
update_state(parent) //otherwise we'll get moved 1 tile before we can correct ourselves, which isnt super bad but just looks jank
/datum/component/shuttle_cling/proc/initialize_loop()
- hyperloop = SSmove_manager.move(moving = parent, direction = direction, delay = not_clinging_move_delay, subsystem = SShyperspace_drift, priority = MOVEMENT_ABOVE_SPACE_PRIORITY, flags = MOVEMENT_LOOP_NO_DIR_UPDATE|MOVEMENT_LOOP_OUTSIDE_CONTROL)
+ hyperloop = DSmove_manager.move(moving = parent, direction = direction, delay = not_clinging_move_delay, subsystem = SShyperspace_drift, priority = MOVEMENT_ABOVE_SPACE_PRIORITY, flags = MOVEMENT_LOOP_NO_DIR_UPDATE|MOVEMENT_LOOP_OUTSIDE_CONTROL)
update_state()
/datum/component/shuttle_cling/proc/clear_loop()
diff --git a/code/datums/components/surgery_initiator.dm b/code/datums/components/surgery_initiator.dm
index 24bde4b4672..c609d7216e0 100644
--- a/code/datums/components/surgery_initiator.dm
+++ b/code/datums/components/surgery_initiator.dm
@@ -135,8 +135,11 @@
required_tool_type = TOOL_SCREWDRIVER
if(iscyborg(user))
- close_tool = locate(/obj/item/cautery) in user.held_items
- if(!close_tool)
+ var/has_cautery = FALSE
+ for(var/obj/item/borg/cyborg_omnitool/medical/omnitool in user.held_items)
+ if(omnitool.tool_behaviour == TOOL_CAUTERY)
+ has_cautery = TRUE
+ if(!has_cautery)
patient.balloon_alert(user, "need a cautery in an inactive slot to stop the surgery!")
return
else if(!close_tool || close_tool.tool_behaviour != required_tool_type)
diff --git a/code/datums/elements/ai_control_examine.dm b/code/datums/elements/ai_control_examine.dm
index b470ac44b49..279fc80dc81 100644
--- a/code/datums/elements/ai_control_examine.dm
+++ b/code/datums/elements/ai_control_examine.dm
@@ -46,7 +46,7 @@
if(noticable_organ_examines[possibly_noticable.slot])
make_organ_noticable(possibly_noticable.slot, possibly_noticable)
-/datum/element/ai_control_examine/proc/make_organ_noticable(organ_slot, obj/item/organ/noticable_organ)
+/datum/element/ai_control_examine/proc/make_organ_noticable(organ_slot, obj/item/organ/noticable_organ, mob/living/carbon/human/human_pawn)
var/examine_text = noticable_organ_examines[organ_slot]
var/body_zone = organ_slot != ORGAN_SLOT_BRAIN ? noticable_organ.zone : null
noticable_organ.AddElement(/datum/element/noticable_organ/ai_control, examine_text, body_zone)
diff --git a/code/datums/elements/noticable_organ.dm b/code/datums/elements/noticable_organ.dm
index 1a6a895e535..a6247d18bb5 100644
--- a/code/datums/elements/noticable_organ.dm
+++ b/code/datums/elements/noticable_organ.dm
@@ -6,15 +6,13 @@
/datum/element/noticable_organ
element_flags = ELEMENT_BESPOKE
argument_hash_start_idx = 2
- /// whether we wrap the examine text in a notice span.
- var/add_span = TRUE
- /// "[they]|[their] [desc here]", shows on examining someone with an infused organ.
- /// Uses a possessive pronoun (His/Her/Their) if a body zone is given, or a singular pronoun (He/She/They) otherwise.
+
+ ///Shows on examining someone with an infused organ.
var/infused_desc
- /// Which body zone has to be exposed. If none is set, this is always noticable, and the description pronoun becomes singular instead of possesive.
+ /// Which body zone has to be exposed. If none is set, this is always noticable.
var/body_zone
-/datum/element/noticable_organ/Attach(datum/target, infused_desc, body_zone)
+/datum/element/noticable_organ/Attach(obj/item/organ/target, infused_desc, body_zone)
. = ..()
if(!isorgan(target))
@@ -23,8 +21,10 @@
src.infused_desc = infused_desc
src.body_zone = body_zone
- RegisterSignal(target, COMSIG_ORGAN_IMPLANTED, PROC_REF(on_implanted))
+ RegisterSignal(target, COMSIG_ORGAN_IMPLANTED, PROC_REF(enable_description))
RegisterSignal(target, COMSIG_ORGAN_REMOVED, PROC_REF(on_removed))
+ if(target.owner)
+ enable_description(target, target.owner)
/datum/element/noticable_organ/Detach(obj/item/organ/target)
UnregisterSignal(target, list(COMSIG_ORGAN_IMPLANTED, COMSIG_ORGAN_REMOVED))
@@ -38,7 +38,7 @@
return FALSE
return TRUE
-/datum/element/noticable_organ/proc/on_implanted(obj/item/organ/target, mob/living/carbon/receiver)
+/datum/element/noticable_organ/proc/enable_description(obj/item/organ/target, mob/living/carbon/receiver)
SIGNAL_HANDLER
RegisterSignal(receiver, COMSIG_ATOM_EXAMINE, PROC_REF(on_receiver_examine))
@@ -53,16 +53,17 @@
if(!should_show_text(examined))
return
- var/examine_text = replacetext(replacetext("[body_zone ? examined.p_Their() : examined.p_They()] [infused_desc]", "%PRONOUN_ES", examined.p_es()), "%PRONOUN_S", examined.p_s())
- if(add_span)
- examine_text = span_notice(examine_text)
+
+ var/examine_text = REPLACE_PRONOUNS(infused_desc, examined)
+
+
examine_list += examine_text
/**
* Subtype of noticable organs for AI control, that will make a few more ai status checks before forking over the examine.
*/
/datum/element/noticable_organ/ai_control
- add_span = FALSE
+
/datum/element/noticable_organ/ai_control/should_show_text(mob/living/carbon/examined)
. = ..()
diff --git a/code/datums/martial/boxing.dm b/code/datums/martial/boxing.dm
index ec111fb3cf0..8e20dfbef9c 100644
--- a/code/datums/martial/boxing.dm
+++ b/code/datums/martial/boxing.dm
@@ -1,87 +1,271 @@
+#define LEFT_RIGHT_COMBO "DH"
+#define RIGHT_LEFT_COMBO "HD"
+#define LEFT_LEFT_COMBO "HH"
+#define RIGHT_RIGHT_COMBO "DD"
+
/datum/martial_art/boxing
name = "Boxing"
id = MARTIALART_BOXING
pacifist_style = TRUE
+ ///Boolean on whether we are sportsmanlike in our tussling; TRUE means we have restrictions
+ var/honorable_boxer = TRUE
+ /// List of traits applied to users of this martial art.
+ var/list/boxing_traits = list(TRAIT_BOXING_READY)
+ /// Balloon alert cooldown for warning our boxer to alternate their blows to get more damage
+ COOLDOWN_DECLARE(warning_cooldown)
/datum/martial_art/boxing/teach(mob/living/new_holder, make_temporary)
if(!ishuman(new_holder))
return FALSE
+ new_holder.add_traits(boxing_traits, BOXING_TRAIT)
+ RegisterSignal(new_holder, COMSIG_LIVING_CHECK_BLOCK, PROC_REF(check_block))
return ..()
-/datum/martial_art/boxing/disarm_act(mob/living/carbon/human/attacker, mob/living/defender)
- attacker.balloon_alert(attacker, "can't disarm while boxing!")
- return MARTIAL_ATTACK_FAIL
+/datum/martial_art/boxing/on_remove(mob/living/remove_from)
+ remove_from.remove_traits(boxing_traits, BOXING_TRAIT)
+ UnregisterSignal(remove_from, list(COMSIG_LIVING_CHECK_BLOCK))
+ return ..()
-/datum/martial_art/boxing/grab_act(mob/living/carbon/human/attacker, mob/living/defender)
- attacker.balloon_alert(attacker, "can't grab while boxing!")
- return MARTIAL_ATTACK_FAIL
+///Unlike most instances of this proc, this is actually called in _proc/tussle()
+///Returns a multiplier on our skill damage bonus.
+/datum/martial_art/boxing/proc/check_streak(mob/living/attacker, mob/living/defender)
+ var/combo_multiplier = 1
+
+ if(findtext(streak, LEFT_LEFT_COMBO) || findtext(streak, RIGHT_RIGHT_COMBO))
+ reset_streak()
+ if(COOLDOWN_FINISHED(src, warning_cooldown))
+ COOLDOWN_START(src, warning_cooldown, 2 SECONDS)
+ attacker.balloon_alert(attacker, "weak combo, alternate your hits!")
+ return combo_multiplier * 0.5
+
+ if(findtext(streak, LEFT_RIGHT_COMBO) || findtext(streak, RIGHT_LEFT_COMBO))
+ reset_streak()
+ return combo_multiplier * 1.5
+
+ return combo_multiplier
+
+/datum/martial_art/boxing/disarm_act(mob/living/attacker, mob/living/defender)
+ if(honor_check(defender))
+ add_to_streak("D", defender)
+ tussle(attacker, defender, "right hook", "right hooked")
+ return MARTIAL_ATTACK_SUCCESS
+
+/datum/martial_art/boxing/grab_act(mob/living/attacker, mob/living/defender)
+ if(honorable_boxer)
+ attacker.balloon_alert(attacker, "no grabbing while boxing!")
+ return MARTIAL_ATTACK_FAIL
+ return MARTIAL_ATTACK_INVALID //UNLESS YOU'RE EVIL
+
+/datum/martial_art/boxing/harm_act(mob/living/attacker, mob/living/defender)
+ if(honor_check(defender))
+ add_to_streak("H", defender)
+ tussle(attacker, defender, "left hook", "left hooked")
+ return MARTIAL_ATTACK_SUCCESS
+
+// Our only boxing move, which occurs on literally all attacks; the tussle. However, quite a lot morphs the results of this proc. Combos, unlike most martial arts attacks, are checked in this proc rather than our standard unarmed procs
+/datum/martial_art/boxing/proc/tussle(mob/living/attacker, mob/living/defender, atk_verb = "blind jab", atk_verbed = "blind jabbed")
+
+ if(honorable_boxer) //Being a good sport, you never hit someone on the ground or already knocked down. It shows you're the better person.
+ if(defender.body_position == LYING_DOWN && defender.getStaminaLoss() >= 100 || defender.IsUnconscious()) //If they're in stamcrit or unconscious, don't bloody punch them
+ attacker.balloon_alert(attacker, "unsportsmanlike behaviour!")
+ return FALSE
-/datum/martial_art/boxing/harm_act(mob/living/carbon/human/attacker, mob/living/defender)
var/obj/item/bodypart/arm/active_arm = attacker.get_active_hand()
+
+ //The values between which damage is rolled for punches
+ var/lower_force = active_arm.unarmed_damage_low
+ var/upper_force = active_arm.unarmed_damage_high
+
+ //Determines knockout potential and armor penetration (if that matters)
+ var/base_unarmed_effectiveness = active_arm.unarmed_effectiveness
+
+ //Determines attack sound based on attacker arm
+ var/attack_sound = active_arm.unarmed_attack_sound
+
+ // Out athletics skill is added as a damage bonus
+ var/athletics_skill = attacker.mind?.get_skill_level(/datum/skill/athletics)
+
+ // If true, grants experience for punching; we only gain experience if we punch another boxer.
+ var/grant_experience = FALSE
+
+ // What type of damage does our kind of boxing do? Defaults to STAMINA, unless you're performing EVIL BOXING
+ var/damage_type = honorable_boxer ? STAMINA : attacker.get_attack_type()
+
attacker.do_attack_animation(defender, ATTACK_EFFECT_PUNCH)
- var/damage = rand(5, 8) + active_arm.unarmed_damage_low
- var/atk_verb = pick("left hook", "right hook", "straight punch")
- if(damage <= 0)
- playsound(defender, active_arm.unarmed_miss_sound, 25, TRUE, -1)
- defender.visible_message(
- span_warning("[attacker]'s [atk_verb] misses [defender]!"),
- span_danger("You avoid [attacker]'s [atk_verb]!"),
- span_hear("You hear a swoosh!"),
- COMBAT_MESSAGE_RANGE,
- attacker,
- )
- to_chat(attacker, span_warning("Your [atk_verb] misses [defender]!"))
- log_combat(attacker, defender, "attempted to hit", atk_verb)
- return MARTIAL_ATTACK_FAIL
+ //Determines damage dealt on a punch. Against a boxing defender, we apply our skill bonus.
+ var/damage = rand(lower_force, upper_force)
- if(defender.check_block(attacker, damage, "[attacker]'s [atk_verb]", UNARMED_ATTACK))
- return MARTIAL_ATTACK_FAIL
+ if(honor_check(defender))
+ var/strength_bonus = HAS_TRAIT(attacker, TRAIT_STRENGTH) ? 2 : 0 //Investing into genetic strength improvements makes you a better boxer
+ damage += round(athletics_skill * check_streak(attacker, defender) + strength_bonus)
+ grant_experience = TRUE
+
+ var/current_atk_verb = atk_verb
+ var/current_atk_verbed = atk_verbed
+
+ if(is_detective_job(attacker.mind?.assigned_role)) //In short: discombobulate
+ current_atk_verb = "discombobulate"
+ current_atk_verbed = "discombulated"
+
+ // Similar to a normal punch, should we have a value of 0 for our lower force, we simply miss outright.
+ if(!lower_force)
+ playsound(defender.loc, active_arm.unarmed_miss_sound, 25, TRUE, -1)
+ defender.visible_message(span_warning("[attacker]'s [current_atk_verb] misses [defender]!"), \
+ span_danger("You avoid [attacker]'s [current_atk_verb]!"), span_hear("You hear a swoosh!"), COMBAT_MESSAGE_RANGE, attacker)
+ to_chat(attacker, span_warning("Your [current_atk_verb] misses [defender]!"))
+ log_combat(attacker, defender, "attempted to hit", current_atk_verb)
+ return FALSE
+
+ if(defender.check_block(attacker, damage, "[attacker]'s [current_atk_verb]", UNARMED_ATTACK))
+ return FALSE
var/obj/item/bodypart/affecting = defender.get_bodypart(defender.get_random_valid_zone(attacker.zone_selected))
- var/armor_block = defender.run_armor_check(affecting, MELEE)
+ var/armor_block = defender.run_armor_check(affecting, MELEE, armour_penetration = base_unarmed_effectiveness)
+
+ playsound(defender, attack_sound, 25, TRUE, -1)
- playsound(defender, active_arm.unarmed_attack_sound, 25, TRUE, -1)
defender.visible_message(
- span_danger("[attacker] [atk_verb]ed [defender]!"),
- span_userdanger("You're [atk_verb]ed by [attacker]!"),
+ span_danger("[attacker] [current_atk_verbed] [defender]!"),
+ span_userdanger("You're [current_atk_verbed] by [attacker]!"),
span_hear("You hear a sickening sound of flesh hitting flesh!"),
COMBAT_MESSAGE_RANGE,
attacker,
)
- to_chat(attacker, span_danger("You [atk_verb]ed [defender]!"))
- defender.apply_damage(damage, STAMINA, affecting, armor_block)
+
+ to_chat(attacker, span_danger("You [current_atk_verbed] [defender]!"))
+
+ defender.apply_damage(damage, damage_type, affecting, armor_block)
+
log_combat(attacker, defender, "punched (boxing) ")
- if(defender.getStaminaLoss() > 50 && istype(defender.mind?.martial_art, /datum/martial_art/boxing))
- var/knockout_prob = defender.getStaminaLoss() + rand(-15, 15)
- if(defender.stat != DEAD && prob(knockout_prob))
- defender.visible_message(
- span_danger("[attacker] knocks [defender] out with a haymaker!"),
- span_userdanger("You're knocked unconscious by [attacker]!"),
- span_hear("You hear a sickening sound of flesh hitting flesh!"),
- COMBAT_MESSAGE_RANGE,
- attacker,
- )
- to_chat(attacker, span_danger("You knock [defender] out with a haymaker!"))
- defender.apply_effect(20 SECONDS, EFFECT_KNOCKDOWN, armor_block)
- defender.SetSleeping(10 SECONDS)
- log_combat(attacker, defender, "knocked out (boxing) ")
- return MARTIAL_ATTACK_SUCCESS
+
+ if(grant_experience)
+ skill_experience_adjustment(attacker, (damage/lower_force))
+
+ if(defender.stat == DEAD || !honor_check(defender)) //early returning here so we don't worry about knockout probs
+ return TRUE
+
+ //Determine our attackers athletics level as a knockout probability bonus
+ var/attacker_athletics_skill = (attacker.mind?.get_skill_modifier(/datum/skill/athletics, SKILL_RANDS_MODIFIER) + base_unarmed_effectiveness)
+
+ // Defender boxing skill and armor block are used as a defense here. This has already factored in base_unarmed_effectiveness from the attacker
+ var/defender_athletics_skill = clamp(defender.mind?.get_skill_modifier(/datum/skill/athletics, SKILL_RANDS_MODIFIER), 0, 100)
+
+ //Determine our final probability, using a clamp to stop any prob() weirdness.
+ var/final_knockout_probability = clamp(round(attacker_athletics_skill - defender_athletics_skill), 0 , 100)
+
+ if(!prob(final_knockout_probability))
+ return TRUE
+
+ if(defender.get_timed_status_effect_duration(/datum/status_effect/staggered))
+ defender.visible_message(
+ span_danger("[attacker] knocks [defender] out with a haymaker!"),
+ span_userdanger("You're knocked unconscious by [attacker]!"),
+ span_hear("You hear a sickening sound of flesh hitting flesh!"),
+ COMBAT_MESSAGE_RANGE,
+ attacker,
+ )
+ to_chat(attacker, span_danger("You knock [defender] out with a haymaker!"))
+ defender.apply_effect(20 SECONDS, EFFECT_KNOCKDOWN, armor_block)
+ defender.SetSleeping(10 SECONDS)
+ log_combat(attacker, defender, "knocked out (boxing) ")
+ else
+ defender.visible_message(
+ span_danger("[attacker] staggers [defender] with a haymaker!"),
+ span_userdanger("You're nearly knocked off your feet by [attacker]!"),
+ span_hear("You hear a sickening sound of flesh hitting flesh!"),
+ COMBAT_MESSAGE_RANGE,
+ attacker,
+ )
+ defender.adjust_staggered_up_to(STAGGERED_SLOWDOWN_LENGTH, 10 SECONDS)
+ to_chat(attacker, span_danger("You stagger [defender] with a haymaker!"))
+ log_combat(attacker, defender, "staggered (boxing) ")
+
+ playsound(defender, 'sound/effects/coin2.ogg', 40, TRUE)
+ new /obj/effect/temp_visual/crit(get_turf(defender))
+ skill_experience_adjustment(attacker, (damage/lower_force)) //double experience for a successful crit
+
+ return TRUE
+
+/// Returns whether whoever is checked by this proc is complying with the rules of boxing. The boxer cannot block non-boxers, and cannot apply their scariest moves against non-boxers.
+/datum/martial_art/boxing/proc/honor_check(mob/living/possible_boxer)
+ if(!honorable_boxer)
+ return TRUE //You scoundrel!!
+
+ if(!HAS_TRAIT(possible_boxer, TRAIT_BOXING_READY))
+ return FALSE
+
+ return TRUE
+
+/// Handles our instances of experience gain while boxing. It also applies the exercised status effect.
+/datum/martial_art/boxing/proc/skill_experience_adjustment(mob/living/boxer, experience_value)
+ //Boxing in heavier gravity gives you more experience
+ var/gravity_modifier = boxer.has_gravity() > STANDARD_GRAVITY ? 1 : 0.5
+
+ //You gotta sleep before you get any experience!
+ boxer.mind?.adjust_experience(/datum/skill/athletics, experience_value * gravity_modifier)
+ boxer.apply_status_effect(/datum/status_effect/exercised)
+
+/// Handles our blocking signals, similar to hit_reaction() on items. Only blocks while the boxer is in throw mode.
+/datum/martial_art/boxing/proc/check_block(mob/living/boxer, atom/movable/hitby, damage, attack_text, attack_type, ...)
+ SIGNAL_HANDLER
+
+ if(!can_use(boxer) || !boxer.throw_mode || boxer.incapacitated(IGNORE_GRAB))
+ return NONE
+
+ if(attack_type != UNARMED_ATTACK)
+ return NONE
+
+ //Determines unarmed defense against boxers using our current active arm.
+ var/obj/item/bodypart/arm/active_arm = boxer.get_active_hand()
+ var/base_unarmed_effectiveness = active_arm.unarmed_effectiveness
+
+ // Out athletics skill is added to our block potential
+ var/athletics_skill_rands = boxer.mind?.get_skill_modifier(/datum/skill/athletics, SKILL_RANDS_MODIFIER)
+
+ var/block_chance = base_unarmed_effectiveness + athletics_skill_rands
+
+ var/block_text = pick("block", "evade")
+
+ if(!prob(block_chance))
+ return NONE
+
+ var/mob/living/attacker = GET_ASSAILANT(hitby)
+
+ if(!honor_check(attacker))
+ return NONE
+
+ if(istype(attacker) && boxer.Adjacent(attacker))
+ attacker.apply_damage(10, STAMINA)
+ boxer.apply_damage(5, STAMINA)
+
+ boxer.visible_message(
+ span_danger("[boxer] [block_text]s [attack_text]!"),
+ span_userdanger("You [block_text] [attack_text]!"),
+ )
+ if(block_text == "evade")
+ playsound(boxer.loc, active_arm.unarmed_miss_sound, 25, TRUE, -1)
+
+ skill_experience_adjustment(boxer, 1) //just getting hit a bunch doesn't net you much experience
+
+ return SUCCESSFUL_BLOCK
/datum/martial_art/boxing/can_use(mob/living/martial_artist)
if(!ishuman(martial_artist))
return FALSE
return ..()
-/obj/item/clothing/gloves/boxing
+/// Evil Boxing; for sick, evil scoundrels. Has no honor, making it more lethal (therefore unable to be used by pacifists).
+/// Grants Strength and Stimmed to speed up any experience gain.
-/obj/item/clothing/gloves/boxing/Initialize(mapload)
- . = ..()
- var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/extendohand_l, /datum/crafting_recipe/extendohand_r)
+/datum/martial_art/boxing/evil
+ name = "Evil Boxing"
+ id = MARTIALART_EVIL_BOXING
+ pacifist_style = FALSE
+ honorable_boxer = FALSE
+ boxing_traits = list(TRAIT_BOXING_READY, TRAIT_STRENGTH, TRAIT_STIMMED)
- AddComponent(
- /datum/component/slapcrafting,\
- slapcraft_recipes = slapcraft_recipe_list,\
- )
-
- AddComponent(/datum/component/martial_art_giver, /datum/martial_art/boxing)
+#undef LEFT_RIGHT_COMBO
+#undef RIGHT_LEFT_COMBO
+#undef LEFT_LEFT_COMBO
+#undef RIGHT_RIGHT_COMBO
diff --git a/code/datums/materials/_material.dm b/code/datums/materials/_material.dm
index da5a15b8d31..9d6b8674728 100644
--- a/code/datums/materials/_material.dm
+++ b/code/datums/materials/_material.dm
@@ -10,7 +10,7 @@ Simple datum which is instanced once per type and is used for every object of sa
var/name = "material"
/// A short description of the material. Not used anywhere, yet...
var/desc = "its..stuff."
- /// What the material is indexed by in the SSmaterials.materials list. Defaults to the type of the material.
+ /// What the material is indexed by in the DSmaterials.materials list. Defaults to the type of the material.
var/id
///Base color of the material, is used for greyscale. Item isn't changed in color if this is null.
@@ -23,7 +23,7 @@ Simple datum which is instanced once per type and is used for every object of sa
///Starlight color of the material
///This is the color of light it'll emit if its turf is transparent and over space. Defaults to COLOR_STARLIGHT if not set
var/starlight_color
- ///Bitflags that influence how SSmaterials handles this material.
+ ///Bitflags that influence how DSmaterials handles this material.
var/init_flags = MATERIAL_INIT_MAPLOAD
///Materials "Traits". its a map of key = category | Value = Bool. Used to define what it can be used for
var/list/categories = list()
diff --git a/code/datums/mutations/body.dm b/code/datums/mutations/body.dm
index 6d3768704fb..b7b781c1819 100644
--- a/code/datums/mutations/body.dm
+++ b/code/datums/mutations/body.dm
@@ -279,15 +279,42 @@
desc = "The user's muscles slightly expand."
quality = POSITIVE
text_gain_indication = "You feel strong."
+ instability = 5
difficulty = 16
+/datum/mutation/human/strong/on_acquiring(mob/living/carbon/human/owner)
+ . = ..()
+ if(.)
+ return
+ ADD_TRAIT(owner, TRAIT_STRENGTH, GENETIC_MUTATION)
+
+/datum/mutation/human/strong/on_losing(mob/living/carbon/human/owner)
+ . = ..()
+ if(.)
+ return
+ REMOVE_TRAIT(owner, TRAIT_STRENGTH, GENETIC_MUTATION)
+
+
/datum/mutation/human/stimmed
name = "Stimmed"
desc = "The user's chemical balance is more robust."
quality = POSITIVE
text_gain_indication = "You feel stimmed."
+ instability = 5
difficulty = 16
+/datum/mutation/human/stimmed/on_acquiring(mob/living/carbon/human/owner)
+ . = ..()
+ if(.)
+ return
+ ADD_TRAIT(owner, TRAIT_STIMMED, GENETIC_MUTATION)
+
+/datum/mutation/human/stimmed/on_losing(mob/living/carbon/human/owner)
+ . = ..()
+ if(.)
+ return
+ REMOVE_TRAIT(owner, TRAIT_STIMMED, GENETIC_MUTATION)
+
/datum/mutation/human/insulated
name = "Insulated"
desc = "The affected person does not conduct electricity."
diff --git a/code/datums/mutations/hulk.dm b/code/datums/mutations/hulk.dm
index 8c8642a81ea..311725d9cc6 100644
--- a/code/datums/mutations/hulk.dm
+++ b/code/datums/mutations/hulk.dm
@@ -278,4 +278,22 @@
TRAIT_STUNIMMUNE,
) // no chunk
+/datum/mutation/human/hulk/superhuman
+ health_req = 0
+ instability = 0
+ /// List of traits to add/remove when someone gets this mutation.
+ mutation_traits = list(
+ TRAIT_CHUNKYFINGERS,
+ TRAIT_HULK,
+ TRAIT_IGNOREDAMAGESLOWDOWN,
+ TRAIT_NOSOFTCRIT,
+ TRAIT_NOHARDCRIT,
+ TRAIT_PUSHIMMUNE,
+ TRAIT_STUNIMMUNE,
+ TRAIT_ANALGESIA,
+ ) // fight till your last breath
+
+/datum/mutation/human/hulk/superhuman/on_life(seconds_per_tick, times_fired)
+ return
+
#undef HULK_TAILTHROW_STEPS
diff --git a/code/datums/proximity_monitor/fields/timestop.dm b/code/datums/proximity_monitor/fields/timestop.dm
index a3e22483c7a..91e13c79142 100644
--- a/code/datums/proximity_monitor/fields/timestop.dm
+++ b/code/datums/proximity_monitor/fields/timestop.dm
@@ -214,7 +214,7 @@
frozen_mobs += victim
victim.Stun(20, ignore_canstun = TRUE)
victim.add_traits(list(TRAIT_MUTE, TRAIT_EMOTEMUTE), TIMESTOP_TRAIT)
- SSmove_manager.stop_looping(victim) //stops them mid pathing even if they're stunimmune //This is really dumb
+ DSmove_manager.stop_looping(victim) //stops them mid pathing even if they're stunimmune //This is really dumb
if(isanimal(victim))
var/mob/living/simple_animal/animal_victim = victim
animal_victim.toggle_ai(AI_OFF)
diff --git a/code/datums/shuttles/pirate.dm b/code/datums/shuttles/pirate.dm
index c6f94b5684b..99f866d23fc 100644
--- a/code/datums/shuttles/pirate.dm
+++ b/code/datums/shuttles/pirate.dm
@@ -29,3 +29,7 @@
/datum/map_template/shuttle/pirate/geode
suffix = "geode"
name = "pirate ship (Lustrous Geode)"
+
+/datum/map_template/shuttle/pirate/medieval
+ suffix = "medieval"
+ name = "pirate ship (Siege Pod)"
diff --git a/code/datums/skills/athletics.dm b/code/datums/skills/athletics.dm
new file mode 100644
index 00000000000..2ef336e5ba9
--- /dev/null
+++ b/code/datums/skills/athletics.dm
@@ -0,0 +1,27 @@
+/datum/skill/athletics
+ name = "Athletics"
+ title = "Athlete"
+ desc = "Twinkle twinkle little star, hit the gym and lift the bar."
+ // The skill value modifier effects the max duration that is possible for /datum/status_effect/exercised; The rands modifier determines block probability and crit probability while boxing against boxers
+ modifiers = list(
+ SKILL_VALUE_MODIFIER = list(
+ 1 MINUTES,
+ 1.5 MINUTES,
+ 2 MINUTES,
+ 2.5 MINUTES,
+ 3 MINUTES,
+ 3.5 MINUTES,
+ 5 MINUTES
+ ),
+ SKILL_RANDS_MODIFIER = list(
+ 0,
+ 5,
+ 10,
+ 15,
+ 20,
+ 30,
+ 50
+ )
+ )
+
+ skill_item_path = /obj/item/clothing/gloves/boxing/golden
diff --git a/code/datums/skills/fitness.dm b/code/datums/skills/fitness.dm
deleted file mode 100644
index 945b21710c2..00000000000
--- a/code/datums/skills/fitness.dm
+++ /dev/null
@@ -1,25 +0,0 @@
-/datum/skill/fitness
- name = "Fitness"
- title = "Powerlifter"
- desc = "Twinkle twinkle little star, hit the gym and lift the bar."
- /// The skill value modifier effects the max duration that is possible for /datum/status_effect/exercised
- modifiers = list(SKILL_VALUE_MODIFIER = list(1 MINUTES, 1.5 MINUTES, 2 MINUTES, 2.5 MINUTES, 3 MINUTES, 3.5 MINUTES, 5 MINUTES))
- /// How much bigger your mob becomes per level (these effects don't stack together)
- var/static/size_boost = list(0, 1/16, 1/8, 3/16, 2/8, 3/8, 4/8)
- // skill_item_path - your mob sprite gets bigger to showoff so we don't get a special item
-
-/* SKYRAT EDIT REMOVAL START - NO SIZE INCREASE
-/datum/skill/fitness/level_gained(datum/mind/mind, new_level, old_level, silent)
- . = ..()
- var/old_gym_size = RESIZE_DEFAULT_SIZE + size_boost[old_level]
- var/new_gym_size = RESIZE_DEFAULT_SIZE + size_boost[new_level]
-
- mind.current.update_transform(new_gym_size / old_gym_size)
-
-/datum/skill/fitness/level_lost(datum/mind/mind, new_level, old_level, silent)
- . = ..()
- var/old_gym_size = RESIZE_DEFAULT_SIZE + size_boost[old_level]
- var/new_gym_size = RESIZE_DEFAULT_SIZE + size_boost[new_level]
-
- mind.current.update_transform(new_gym_size / old_gym_size)
-SKYRAT EDIT REMOVAL END */
diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm
index 39d5c3a3754..7c9a4e1cc1a 100644
--- a/code/datums/status_effects/buffs.dm
+++ b/code/datums/status_effects/buffs.dm
@@ -195,6 +195,9 @@
if(HAS_TRAIT(new_owner, TRAIT_HULK))
modifier += 0.5
+ if(HAS_TRAIT(new_owner, TRAIT_STIMMED)) // Naturally produces stimulants to help get you PUMPED
+ modifier += 1
+
if(HAS_TRAIT(new_owner, TRAIT_FAT)) // less xp until you get into shape
modifier -= 0.5
@@ -209,10 +212,10 @@
if(new_owner.reagents.has_reagent(workout_reagent))
food_boost += supplementary_reagents_bonus[workout_reagent]
- var/skill_level_boost = (new_owner.mind.get_skill_level(/datum/skill/fitness) - 1) * 2 SECONDS
+ var/skill_level_boost = (new_owner.mind.get_skill_level(/datum/skill/athletics) - 1) * 2 SECONDS
bonus_time = (bonus_time + food_boost + skill_level_boost) * modifier
- var/exhaustion_limit = new_owner.mind.get_skill_modifier(/datum/skill/fitness, SKILL_VALUE_MODIFIER) + world.time
+ var/exhaustion_limit = new_owner.mind.get_skill_modifier(/datum/skill/athletics, SKILL_VALUE_MODIFIER) + world.time
if(duration + bonus_time >= exhaustion_limit)
duration = exhaustion_limit
to_chat(new_owner, span_userdanger("Your muscles are exhausted! Might be a good idea to sleep..."))
@@ -228,10 +231,10 @@
/datum/status_effect/exercised/refresh(mob/living/new_owner, bonus_time)
duration += workout_duration(new_owner, bonus_time)
new_owner.clear_mood_event("exercise") // we need to reset the old mood event in case our fitness skill changes
- new_owner.add_mood_event("exercise", /datum/mood_event/exercise, new_owner.mind.get_skill_level(/datum/skill/fitness))
+ new_owner.add_mood_event("exercise", /datum/mood_event/exercise, new_owner.mind.get_skill_level(/datum/skill/athletics))
/datum/status_effect/exercised/on_apply()
- owner.add_mood_event("exercise", /datum/mood_event/exercise, owner.mind.get_skill_level(/datum/skill/fitness))
+ owner.add_mood_event("exercise", /datum/mood_event/exercise, owner.mind.get_skill_level(/datum/skill/athletics))
return ..()
/datum/status_effect/exercised/on_remove()
diff --git a/code/datums/status_effects/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm
index 362a9eee23b..feabf36312b 100644
--- a/code/datums/status_effects/debuffs/debuffs.dm
+++ b/code/datums/status_effects/debuffs/debuffs.dm
@@ -224,7 +224,7 @@
var/datum/status_effect/exercised/exercised = carbon_owner.has_status_effect(/datum/status_effect/exercised)
if(exercised && carbon_owner.mind)
// the better you sleep, the more xp you gain
- carbon_owner.mind.adjust_experience(/datum/skill/fitness, seconds_between_ticks * sleep_quality * SLEEP_QUALITY_WORKOUT_MULTIPLER)
+ carbon_owner.mind.adjust_experience(/datum/skill/athletics, seconds_between_ticks * sleep_quality * SLEEP_QUALITY_WORKOUT_MULTIPLER)
carbon_owner.adjust_timed_status_effect(-1 * seconds_between_ticks * sleep_quality * SLEEP_QUALITY_WORKOUT_MULTIPLER, /datum/status_effect/exercised)
if(prob(2))
to_chat(carbon_owner, span_notice("You feel your fitness improving!"))
diff --git a/code/datums/systems/_system.dm b/code/datums/systems/_system.dm
new file mode 100644
index 00000000000..fe3271048ab
--- /dev/null
+++ b/code/datums/systems/_system.dm
@@ -0,0 +1,16 @@
+#define NEW_DS_GLOBAL(varname) if(varname != src){if(istype(varname)){qdel(varname);}varname = src;}
+
+#define DATASYSTEM_DEF(X) GLOBAL_REAL(DS##X, /datum/system/##X);\
+/datum/system/##X/New(){\
+ NEW_DS_GLOBAL(DS##X);\
+}\
+/datum/system/##X
+
+
+/**
+ * Global systems which are distinct from subsystems in that they do not process by the MC.
+ * Data systems or "DS" are used to store round information and procs to interface with that data, if needed.
+ */
+/datum/system
+ /// Name of the system
+ var/name = "Datum System"
diff --git a/code/controllers/subsystem/battle_royale.dm b/code/datums/systems/ds/battle_royale.dm
similarity index 96%
rename from code/controllers/subsystem/battle_royale.dm
rename to code/datums/systems/ds/battle_royale.dm
index 139a5aa8b49..1cdc7358a56 100644
--- a/code/controllers/subsystem/battle_royale.dm
+++ b/code/datums/systems/ds/battle_royale.dm
@@ -7,7 +7,7 @@ GLOBAL_LIST_INIT(battle_royale_regions, list(
),
"Research Division" = list(
/area/station/command/heads_quarters/rd,
- /area/station/security/checkpoint/science,
+ /area/station/security/checkpoint/science,
/area/station/science,
),
"Engineering Bay" = list(
@@ -24,14 +24,13 @@ GLOBAL_LIST_INIT(battle_royale_regions, list(
))
/// Basically just exists to hold references to datums so that they don't GC
-SUBSYSTEM_DEF(battle_royale)
+DATASYSTEM_DEF(battle_royale)
name = "Battle Royale"
- flags = SS_NO_INIT | SS_NO_FIRE
/// List of battle royale datums currently running
var/list/active_battles
/// Start a new battle royale using a passed list of implants
-/datum/controller/subsystem/battle_royale/proc/start_battle(list/competitors)
+/datum/system/battle_royale/proc/start_battle(list/competitors)
var/datum/battle_royale_controller/controller = new()
if (!controller.start(competitors))
return FALSE
@@ -42,7 +41,7 @@ SUBSYSTEM_DEF(battle_royale)
return TRUE
/// Drop reference when it kills itself
-/datum/controller/subsystem/battle_royale/proc/battle_ended(datum/source)
+/datum/system/battle_royale/proc/battle_ended(datum/source)
SIGNAL_HANDLER
LAZYREMOVE(active_battles, source)
if (!LAZYLEN(active_battles))
@@ -52,7 +51,7 @@ SUBSYSTEM_DEF(battle_royale)
/// Datum which controls the conflict
/datum/battle_royale_controller
/// Where is our battle taking place?
- var/chosen_area
+ var/chosen_area
/// Is the battle currently in progress?
var/battle_running = TRUE
/// Should we let everyone know that someone has died?
diff --git a/code/controllers/subsystem/communications.dm b/code/datums/systems/ds/communications.dm
similarity index 87%
rename from code/controllers/subsystem/communications.dm
rename to code/datums/systems/ds/communications.dm
index 3ad52bbf150..7c9cee61509 100644
--- a/code/controllers/subsystem/communications.dm
+++ b/code/datums/systems/ds/communications.dm
@@ -2,9 +2,8 @@
#define COMMUNICATION_COOLDOWN_AI (30 SECONDS)
#define COMMUNICATION_COOLDOWN_MEETING (5 MINUTES)
-SUBSYSTEM_DEF(communications)
+DATASYSTEM_DEF(communications)
name = "Communications"
- flags = SS_NO_INIT | SS_NO_FIRE
COOLDOWN_DECLARE(silicon_message_cooldown)
COOLDOWN_DECLARE(nonsilicon_message_cooldown)
@@ -21,7 +20,7 @@ SUBSYSTEM_DEF(communications)
/// The location where the special xenomorph egg was planted
var/area/captivity_area
-/datum/controller/subsystem/communications/proc/can_announce(mob/living/user, is_silicon)
+/datum/system/communications/proc/can_announce(mob/living/user, is_silicon)
if(is_silicon && COOLDOWN_FINISHED(src, silicon_message_cooldown))
return TRUE
else if(!is_silicon && COOLDOWN_FINISHED(src, nonsilicon_message_cooldown))
@@ -29,7 +28,7 @@ SUBSYSTEM_DEF(communications)
else
return FALSE
-/datum/controller/subsystem/communications/proc/make_announcement(mob/living/user, is_silicon, input, syndicate, list/players)
+/datum/system/communications/proc/make_announcement(mob/living/user, is_silicon, input, syndicate, list/players)
if(!can_announce(user, is_silicon))
return FALSE
if(is_silicon)
@@ -45,7 +44,7 @@ SUBSYSTEM_DEF(communications)
user.log_talk(input, LOG_SAY, tag="priority announcement")
message_admins("[ADMIN_LOOKUPFLW(user)] has made a priority announcement.")
-/datum/controller/subsystem/communications/proc/send_message(datum/comm_message/sending,print = TRUE,unique = FALSE)
+/datum/system/communications/proc/send_message(datum/comm_message/sending,print = TRUE,unique = FALSE)
for(var/obj/machinery/computer/communications/C in GLOB.shuttle_caller_list)
if(!(C.machine_stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
if(unique)
diff --git a/code/controllers/subsystem/materials.dm b/code/datums/systems/ds/materials.dm
similarity index 92%
rename from code/controllers/subsystem/materials.dm
rename to code/datums/systems/ds/materials.dm
index 25efd8695dc..527c1a3d642 100644
--- a/code/controllers/subsystem/materials.dm
+++ b/code/datums/systems/ds/materials.dm
@@ -1,13 +1,12 @@
/*! How material datums work
-Materials are now instanced datums, with an associative list of them being kept in SSmaterials. We only instance the materials once and then re-use these instances for everything.
+Materials are now instanced datums, with an associative list of them being kept in DSmaterials. We only instance the materials once and then re-use these instances for everything.
These materials call on_applied() on whatever item they are applied to, common effects are adding components, changing color and changing description. This allows us to differentiate items based on the material they are made out of.area
*/
-SUBSYSTEM_DEF(materials)
+DATASYSTEM_DEF(materials)
name = "Materials"
- flags = SS_NO_FIRE | SS_NO_INIT
///Dictionary of material.id || material ref
var/list/materials
///Dictionary of type || list of material refs
@@ -37,7 +36,7 @@ SUBSYSTEM_DEF(materials)
var/list/datum/dimension_theme/dimensional_themes
///Ran on initialize, populated the materials and materials_by_category dictionaries with their appropiate vars (See these variables for more info)
-/datum/controller/subsystem/materials/proc/InitializeMaterials()
+/datum/system/materials/proc/InitializeMaterials()
materials = list()
materials_by_type = list()
materialids_by_type = list()
@@ -58,7 +57,7 @@ SUBSYSTEM_DEF(materials)
* - [arguments][/list]: The arguments to use to create the material datum
* - The first element is the type of material to initialize.
*/
-/datum/controller/subsystem/materials/proc/InitializeMaterial(list/arguments)
+/datum/system/materials/proc/InitializeMaterial(list/arguments)
var/datum/material/mat_type = arguments[1]
if(initial(mat_type.init_flags) & MATERIAL_INIT_BESPOKE)
arguments[1] = GetIdFromArguments(arguments)
@@ -90,13 +89,13 @@ SUBSYSTEM_DEF(materials)
* - If the material type is bespoke a text ID is generated from the arguments list and used to load a material datum from the cache.
* - The following elements are used to generate bespoke IDs
*/
-/datum/controller/subsystem/materials/proc/_GetMaterialRef(list/arguments)
+/datum/system/materials/proc/_GetMaterialRef(list/arguments)
if(!materials)
InitializeMaterials()
var/datum/material/key = arguments[1]
if(istype(key))
- return key // We are assuming here that the only thing allowed to create material datums is [/datum/controller/subsystem/materials/proc/InitializeMaterial]
+ return key // We are assuming here that the only thing allowed to create material datums is [/datum/system/materials/proc/InitializeMaterial]
if(istext(key)) // Handle text id
. = materials[key]
@@ -124,7 +123,7 @@ SUBSYSTEM_DEF(materials)
* Named arguments can appear in any order and we need them to appear after ordered arguments
* We assume that no one will pass in a named argument with a value of null
**/
-/datum/controller/subsystem/materials/proc/GetIdFromArguments(list/arguments)
+/datum/system/materials/proc/GetIdFromArguments(list/arguments)
var/datum/material/mattype = arguments[1]
var/list/fullid = list("[initial(mattype.id) || mattype]")
var/list/named_arguments = list()
@@ -150,7 +149,7 @@ SUBSYSTEM_DEF(materials)
/// Returns a list to be used as an object's custom_materials. Lists will be cached and re-used based on the parameters.
-/datum/controller/subsystem/materials/proc/FindOrCreateMaterialCombo(list/materials_declaration, multiplier)
+/datum/system/materials/proc/FindOrCreateMaterialCombo(list/materials_declaration, multiplier)
if(!LAZYLEN(materials_declaration))
return null // If we get a null we pass it right back, we don't want to generate stack traces just because something is clearing out its materials list.
diff --git a/code/controllers/subsystem/movement/move_handler.dm b/code/datums/systems/ds/move_handler.dm
similarity index 91%
rename from code/controllers/subsystem/movement/move_handler.dm
rename to code/datums/systems/ds/move_handler.dm
index fcc5c1c6504..dc3458627ef 100644
--- a/code/controllers/subsystem/movement/move_handler.dm
+++ b/code/datums/systems/ds/move_handler.dm
@@ -17,16 +17,14 @@
*
* You can find the logic for this control in this file
*
- * Specifics of how different loops operate can be found in the movement_types.dm file, alongside the [add to loop][/datum/controller/subsystem/move_manager/proc/add_to_loop] helper procs that use them
+ * Specifics of how different loops operate can be found in the movement_types.dm file, alongside the [add to loop][/datum/system/move_manager/proc/add_to_loop] helper procs that use them
*
**/
-SUBSYSTEM_DEF(move_manager)
+DATASYSTEM_DEF(move_manager)
name = "Movement Handler"
- flags = SS_NO_INIT | SS_NO_FIRE
- runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
///Adds a movable thing to a movement subsystem. Returns TRUE if it all worked, FALSE if it failed somehow
-/datum/controller/subsystem/move_manager/proc/add_to_loop(atom/movable/thing_to_add, datum/controller/subsystem/movement/subsystem = SSmovement, datum/move_loop/loop_type, priority = MOVEMENT_DEFAULT_PRIORITY, flags, datum/extra_info)
+/datum/system/move_manager/proc/add_to_loop(atom/movable/thing_to_add, datum/controller/subsystem/movement/subsystem = SSmovement, datum/move_loop/loop_type, priority = MOVEMENT_DEFAULT_PRIORITY, flags, datum/extra_info)
var/datum/movement_packet/our_data = thing_to_add.move_packet
if(!our_data)
our_data = new(thing_to_add)
@@ -35,7 +33,7 @@ SUBSYSTEM_DEF(move_manager)
return our_data.add_loop(arglist(arguments))
///Returns the subsystem's loop if we're processing on it, null otherwise
-/datum/controller/subsystem/move_manager/proc/processing_on(atom/movable/packet_owner, datum/controller/subsystem/movement/subsystem)
+/datum/system/move_manager/proc/processing_on(atom/movable/packet_owner, datum/controller/subsystem/movement/subsystem)
var/datum/movement_packet/packet = packet_owner.move_packet
if(!packet)
return
diff --git a/code/datums/systems/manager.dm b/code/datums/systems/manager.dm
new file mode 100644
index 00000000000..0d5fdb8b839
--- /dev/null
+++ b/code/datums/systems/manager.dm
@@ -0,0 +1,14 @@
+// See initialization order in /code/game/world.dm
+GLOBAL_REAL(SysMgr, /datum/system_manager)
+
+
+/**
+ * Initializes all data systems and keeps track of them.
+ */
+/datum/system_manager
+ /// List of managed data systems, post initialization.
+ var/list/datum/system/managed = list()
+
+
+/datum/system_manager/New()
+ init_subtypes(/datum/system, managed)
diff --git a/code/game/atom/atom_materials.dm b/code/game/atom/atom_materials.dm
index 345a8486dd6..deb27140257 100644
--- a/code/game/atom/atom_materials.dm
+++ b/code/game/atom/atom_materials.dm
@@ -23,7 +23,7 @@
var/datum/material/custom_material = GET_MATERIAL_REF(current_material)
custom_material.on_applied(src, OPTIMAL_COST(materials[current_material] * multiplier * material_modifier), material_flags)
- custom_materials = SSmaterials.FindOrCreateMaterialCombo(materials, multiplier)
+ custom_materials = DSmaterials.FindOrCreateMaterialCombo(materials, multiplier)
/**
* Returns the material composition of the atom.
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index 1bdcba84967..02dfa624d35 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -4,8 +4,8 @@
icon = 'icons/obj/machines/lathes.dmi'
icon_state = "autolathe"
density = TRUE
- //Energy cost per full stack of sheets worth of materials used. Material insertion is 40% of this.
- active_power_usage = 25 * BASE_MACHINE_ACTIVE_CONSUMPTION
+ ///Energy cost per full stack of sheets worth of materials used. Material insertion is 40% of this.
+ active_power_usage = 0.025 * STANDARD_CELL_RATE
circuit = /obj/item/circuitboard/machine/autolathe
layer = BELOW_OBJ_LAYER
processing_flags = NONE
@@ -32,7 +32,7 @@
/obj/machinery/autolathe/Initialize(mapload)
materials = AddComponent( \
/datum/component/material_container, \
- SSmaterials.materials_by_category[MAT_CATEGORY_ITEM_MATERIAL], \
+ DSmaterials.materials_by_category[MAT_CATEGORY_ITEM_MATERIAL], \
0, \
MATCONTAINER_EXAMINE, \
container_signals = list(COMSIG_MATCONTAINER_ITEM_CONSUMED = TYPE_PROC_REF(/obj/machinery/autolathe, AfterMaterialInsert)) \
@@ -252,7 +252,7 @@
var/amount_needed = design.materials[material]
if(istext(material)) // category
var/list/choices = list()
- for(var/datum/material/valid_candidate as anything in SSmaterials.materials_by_category[material])
+ for(var/datum/material/valid_candidate as anything in DSmaterials.materials_by_category[material])
if(materials.get_material_amount(valid_candidate) < amount_needed)
continue
choices[valid_candidate.name] = valid_candidate
diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm
index ae3ae36e51b..c2c1fcaa025 100644
--- a/code/game/machinery/cell_charger.dm
+++ b/code/game/machinery/cell_charger.dm
@@ -7,7 +7,7 @@
circuit = /obj/item/circuitboard/machine/cell_charger
pass_flags = PASSTABLE
var/obj/item/stock_parts/cell/charging = null
- var/charge_rate = 250 KILO WATTS
+ var/charge_rate = 0.25 * STANDARD_CELL_RATE
/* OVERWRITTEN IN modular_skyrat\modules\aesthetics\cells\cell.dm
/obj/machinery/cell_charger/update_overlays()
@@ -133,7 +133,7 @@
/obj/machinery/cell_charger/RefreshParts()
. = ..()
- charge_rate = 250 KILO WATTS
+ charge_rate = 0.25 * STANDARD_CELL_RATE
for(var/datum/stock_part/capacitor/capacitor in component_parts)
charge_rate *= capacitor.tier
@@ -147,7 +147,8 @@
if(!main_draw)
return
- use_energy(main_draw * 0.01) //use a small bit for the charger itself, but power usage scales up with the part tier
+ //use a small bit for the charger itself, but power usage scales up with the part tier
+ use_energy(main_draw * 0.01)
charge_cell(main_draw, charging, grid_only = TRUE)
update_appearance()
diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm
index 1868bc3c38c..f5695dd6284 100644
--- a/code/game/machinery/computer/camera_advanced.dm
+++ b/code/game/machinery/computer/camera_advanced.dm
@@ -53,17 +53,15 @@
actions += new move_down_action(src)
/obj/machinery/computer/camera_advanced/Destroy()
- if(!QDELETED(current_user))
- unset_machine(current_user)
- if(eyeobj)
- QDEL_NULL(eyeobj)
+ unset_machine()
+ QDEL_NULL(eyeobj)
QDEL_LIST(actions)
current_user = null
return ..()
/obj/machinery/computer/camera_advanced/process()
if(!can_use(current_user) || (issilicon(current_user) && !current_user.has_unlimited_silicon_privilege))
- unset_machine(current_user)
+ unset_machine()
return PROCESS_KILL
/obj/machinery/computer/camera_advanced/connect_to_shuttle(mapload, obj/docking_port/mobile/port, obj/docking_port/stationary/dock)
@@ -124,12 +122,12 @@
/obj/machinery/computer/camera_advanced/on_set_is_operational(old_value)
if(!is_operational)
- unset_machine(current_user)
+ unset_machine()
-/obj/machinery/computer/camera_advanced/proc/unset_machine(mob/M)
- if(M == current_user)
- remove_eye_control(M)
- end_processing()
+/obj/machinery/computer/camera_advanced/proc/unset_machine()
+ if(!QDELETED(current_user))
+ remove_eye_control(current_user)
+ end_processing()
/obj/machinery/computer/camera_advanced/proc/can_use(mob/living/user)
return can_interact(user)
@@ -147,7 +145,7 @@
return
if(isnull(user.client))
return
- if(current_user)
+ if(!QDELETED(current_user))
to_chat(user, span_warning("The console is already in use!"))
return
var/mob/living/L = user
@@ -179,7 +177,7 @@
give_eye_control(L)
eyeobj.setLoc(camera_location)
else
- unset_machine(user)
+ unset_machine()
else
give_eye_control(L)
eyeobj.setLoc(eyeobj.loc)
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index caa3452626e..c71d80ccfba 100755
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -335,7 +335,7 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE)
if (!message)
return
- SScommunications.soft_filtering = FALSE
+ DScommunications.soft_filtering = FALSE
var/list/hard_filter_result = is_ic_filtered(message)
if(hard_filter_result)
tgui_alert(usr, "Your message contains: (\"[hard_filter_result[CHAT_FILTER_INDEX_WORD]]\"), which is not allowed on this server.")
@@ -347,7 +347,7 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE)
return
message_admins("[ADMIN_LOOKUPFLW(usr)] has passed the soft filter for \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\". They may be using a disallowed term for a cross-station message. Increasing delay time to reject.\n\n Message: \"[html_encode(message)]\"")
log_admin_private("[key_name(usr)] has passed the soft filter for \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\". They may be using a disallowed term for a cross-station message. Increasing delay time to reject.\n\n Message: \"[message]\"")
- SScommunications.soft_filtering = TRUE
+ DScommunications.soft_filtering = TRUE
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
@@ -358,13 +358,13 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE)
GLOB.admins,
span_adminnotice( \
"CROSS-SECTOR MESSAGE (OUTGOING): [ADMIN_LOOKUPFLW(usr)] is about to send \
- the following message to [destination] (will autoapprove in [SScommunications.soft_filtering ? DisplayTimeText(EXTENDED_CROSS_SECTOR_CANCEL_TIME) : DisplayTimeText(CROSS_SECTOR_CANCEL_TIME)]): \
+ the following message to [destination] (will autoapprove in [DScommunications.soft_filtering ? DisplayTimeText(EXTENDED_CROSS_SECTOR_CANCEL_TIME) : DisplayTimeText(CROSS_SECTOR_CANCEL_TIME)]): \
REJECT \
[html_encode(message)]" \
)
)
- send_cross_comms_message_timer = addtimer(CALLBACK(src, PROC_REF(send_cross_comms_message), usr, destination, message), SScommunications.soft_filtering ? EXTENDED_CROSS_SECTOR_CANCEL_TIME : CROSS_SECTOR_CANCEL_TIME, TIMER_STOPPABLE)
+ send_cross_comms_message_timer = addtimer(CALLBACK(src, PROC_REF(send_cross_comms_message), usr, destination, message), DScommunications.soft_filtering ? EXTENDED_CROSS_SECTOR_CANCEL_TIME : CROSS_SECTOR_CANCEL_TIME, TIMER_STOPPABLE)
COOLDOWN_START(src, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN)
if ("setState")
@@ -445,7 +445,7 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE)
state = STATE_MAIN
playsound(src, 'sound/machines/terminal_on.ogg', 50, FALSE)
imprint_gps(gps_tag = "Encrypted Communications Channel")
-
+
if ("toggleEmergencyAccess")
if(emergency_access_cooldown(usr)) //if were in cooldown, dont allow the following code
return
@@ -552,7 +552,7 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE)
var/network_name = CONFIG_GET(string/cross_comms_network)
if(network_name)
payload["network"] = network_name
- if(SScommunications.soft_filtering)
+ if(DScommunications.soft_filtering)
payload["is_filtered"] = TRUE
var/name_to_send = "[CONFIG_GET(string/cross_comms_name)]([station_name()])" //SKYRAT EDIT ADDITION
@@ -562,7 +562,7 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE)
usr.log_talk(message, LOG_SAY, tag = "message to the other server")
message_admins("[ADMIN_LOOKUPFLW(usr)] has sent a message to the other server\[s].")
deadchat_broadcast(" has sent an outgoing message to the other station(s).", "[usr.real_name]", usr, message_type = DEADCHAT_ANNOUNCEMENT)
- SScommunications.soft_filtering = FALSE // set it to false at the end of the proc to ensure that everything prior reads as intended
+ DScommunications.soft_filtering = FALSE // set it to false at the end of the proc to ensure that everything prior reads as intended
/obj/machinery/computer/communications/ui_data(mob/user)
var/list/data = list(
@@ -727,7 +727,7 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE)
return
deltimer(send_cross_comms_message_timer)
- SScommunications.soft_filtering = FALSE
+ DScommunications.soft_filtering = FALSE
send_cross_comms_message_timer = null
log_admin("[key_name(usr)] has cancelled the outgoing cross-comms message.")
@@ -800,7 +800,7 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE)
/obj/machinery/computer/communications/proc/make_announcement(mob/living/user)
var/is_ai = HAS_SILICON_ACCESS(user)
- if(!SScommunications.can_announce(user, is_ai))
+ if(!DScommunications.can_announce(user, is_ai))
to_chat(user, span_alert("Intercomms recharging. Please stand by."))
return
var/input = tgui_input_text(user, "Message to announce to the station crew", "Announcement")
@@ -821,7 +821,7 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE)
)
var/list/players = get_communication_players()
- SScommunications.make_announcement(user, is_ai, input, syndicate || (obj_flags & EMAGGED), players)
+ DScommunications.make_announcement(user, is_ai, input, syndicate || (obj_flags & EMAGGED), players)
deadchat_broadcast(" made a priority announcement from [span_name("[get_area_name(usr, TRUE)]")].", span_name("[user.real_name]"), user, message_type=DEADCHAT_ANNOUNCEMENT)
/obj/machinery/computer/communications/proc/get_communication_players()
diff --git a/code/game/machinery/computer/orders/order_items/mining/order_mining.dm b/code/game/machinery/computer/orders/order_items/mining/order_mining.dm
index 0882c9ce99a..13f350f1da1 100644
--- a/code/game/machinery/computer/orders/order_items/mining/order_mining.dm
+++ b/code/game/machinery/computer/orders/order_items/mining/order_mining.dm
@@ -107,6 +107,10 @@
item_path = /obj/item/radio/weather_monitor
cost_per_order = 320
+/datum/orderable_item/mining/ventpointer
+ item_path = /obj/item/pinpointer/vent
+ cost_per_order = 1150
+
/datum/orderable_item/mining/boulder_processing
item_path = /obj/item/boulder_beacon
desc = "A Bouldertech brand all-in-one boulder processing beacon. Each use will teleport in a component of a full boulder processing assembly line. Good for when you need to process additional boulders."
diff --git a/code/game/machinery/dna_infuser/dna_infuser.dm b/code/game/machinery/dna_infuser/dna_infuser.dm
index 6c239089f5d..7b5fcb501a0 100644
--- a/code/game/machinery/dna_infuser/dna_infuser.dm
+++ b/code/game/machinery/dna_infuser/dna_infuser.dm
@@ -64,8 +64,7 @@
balloon_alert(user, "not while it's on!")
return
if(occupant && infusing_from)
- // Abort infusion if the occupant is invalid.
- if(!is_valid_occupant(occupant, user))
+ if(!occupant.can_infuse(user))
playsound(src, 'sound/machines/scanbuzz.ogg', 35, vary = TRUE)
return
balloon_alert(user, "starting DNA infusion...")
@@ -77,92 +76,45 @@
var/mob/living/carbon/human/human_occupant = occupant
infusing = TRUE
visible_message(span_notice("[src] hums to life, beginning the infusion process!"))
+
+ infusing_into = infusing_from.get_infusion_entry()
var/fail_title = ""
- var/fail_reason = ""
- // Replace infusing_into with a [/datum/infuser_entry]
- for(var/datum/infuser_entry/entry as anything in GLOB.infuser_entries)
- if(entry.tier == DNA_MUTANT_UNOBTAINABLE)
- continue
- if(is_type_in_list(infusing_from, entry.input_obj_or_mob))
- if(entry.tier > max_tier_allowed)
- fail_title = "Overcomplexity"
- fail_reason = "DNA too complicated to infuse. The machine needs to infuse simpler DNA first."
- infusing_into = entry
- break
- if(!infusing_into)
- //no valid recipe, so you get a fly mutation
- if(!fail_reason)
- fail_title = "Unknown DNA"
- fail_reason = "Unknown DNA. Consult the \"DNA infusion book\"."
- infusing_into = GLOB.infuser_entries[1]
+ var/fail_explanation = ""
+ if(istype(infusing_into, /datum/infuser_entry/fly))
+ fail_title = "Unknown DNA"
+ fail_explanation = "Unknown DNA. Consult the \"DNA infusion book\"."
+ if(infusing_into.tier > max_tier_allowed)
+ infusing_into = GLOB.infuser_entries[/datum/infuser_entry/fly]
+ fail_title = "Overcomplexity"
+ fail_explanation = "DNA too complicated to infuse. The machine needs to infuse simpler DNA first."
playsound(src, 'sound/machines/blender.ogg', 50, vary = TRUE)
to_chat(human_occupant, span_danger("Little needles repeatedly prick you!"))
human_occupant.take_overall_damage(10)
human_occupant.add_mob_memory(/datum/memory/dna_infusion, protagonist = human_occupant, deuteragonist = infusing_from, mutantlike = infusing_into.infusion_desc)
Shake(duration = INFUSING_TIME)
addtimer(CALLBACK(human_occupant, TYPE_PROC_REF(/mob, emote), "scream"), INFUSING_TIME - 1 SECONDS)
- addtimer(CALLBACK(src, PROC_REF(end_infuse), fail_reason, fail_title), INFUSING_TIME)
+ addtimer(CALLBACK(src, PROC_REF(end_infuse), fail_explanation, fail_title), INFUSING_TIME)
update_appearance()
-/obj/machinery/dna_infuser/proc/end_infuse(fail_reason, fail_title)
- if(infuse_organ(occupant))
+/obj/machinery/dna_infuser/proc/end_infuse(fail_explanation, fail_title)
+ var/mob/living/carbon/human/human_occupant = occupant
+ if(human_occupant.infuse_organ(infusing_into))
+ check_tier_progression(src)
to_chat(occupant, span_danger("You feel yourself becoming more... [infusing_into.infusion_desc]?"))
infusing = FALSE
infusing_into = null
QDEL_NULL(infusing_from)
playsound(src, 'sound/machines/microwave/microwave-end.ogg', 100, vary = FALSE)
- if(fail_reason)
+ if(fail_explanation)
playsound(src, 'sound/machines/printer.ogg', 100, TRUE)
visible_message(span_notice("[src] prints an error report."))
var/obj/item/paper/printed_paper = new /obj/item/paper(loc)
printed_paper.name = "error report - '[fail_title]'"
- printed_paper.add_raw_text(fail_reason)
+ printed_paper.add_raw_text(fail_explanation)
printed_paper.update_appearance()
toggle_open()
update_appearance()
-/// Attempt to replace/add-to the occupant's organs with "mutated" equivalents.
-/// Returns TRUE on success, FALSE on failure.
-/// Requires the target mob to have an existing organic organ to "mutate".
-// TODO: In the future, this should have more logic:
-// - Replace non-mutant organs before mutant ones.
-/obj/machinery/dna_infuser/proc/infuse_organ(mob/living/carbon/human/target)
- if(!ishuman(target))
- return FALSE
- var/obj/item/organ/new_organ = pick_organ(target)
- if(!new_organ)
- return FALSE
- // Valid organ successfully picked.
- new_organ = new new_organ()
- new_organ.replace_into(target)
- check_tier_progression(target)
- return TRUE
-
-/// Picks a random mutated organ from the infuser entry which is also compatible with the target mob.
-/// Tries to return a typepath of a valid mutant organ if all of the following criteria are true:
-/// 1. Target must have a pre-existing organ in the same organ slot as the new organ;
-/// - or the new organ must be external.
-/// 2. Target's pre-existing organ must be organic / not robotic.
-/// 3. Target must not have the same/identical organ.
-/obj/machinery/dna_infuser/proc/pick_organ(mob/living/carbon/human/target)
- if(!infusing_into)
- return FALSE
- var/list/obj/item/organ/potential_new_organs = infusing_into.output_organs.Copy()
- // Remove organ typepaths from the list if they're incompatible with target.
- for(var/obj/item/organ/new_organ as anything in infusing_into.output_organs)
- var/obj/item/organ/old_organ = target.get_organ_slot(initial(new_organ.slot))
- if(old_organ)
- if((old_organ.type != new_organ) && !IS_ROBOTIC_ORGAN(old_organ))
- continue // Old organ can be mutated!
- else if(ispath(new_organ, /obj/item/organ/external))
- continue // External organ can be grown!
- // Internal organ is either missing, or is non-organic.
- potential_new_organs -= new_organ
- // Pick a random organ from the filtered list.
- if(length(potential_new_organs))
- return pick(potential_new_organs)
- return FALSE
-
/// checks to see if the machine should progress a new tier.
/obj/machinery/dna_infuser/proc/check_tier_progression(mob/living/carbon/human/target)
if(
@@ -254,19 +206,6 @@
infusing_from = target
infusing_from.forceMove(src)
-/// Verify that the occupant/target is organic, and has mutable DNA.
-/obj/machinery/dna_infuser/proc/is_valid_occupant(mob/living/carbon/human/human_target, mob/user)
- // Invalid: DNA is too damaged to mutate anymore / has TRAIT_BADDNA.
- if(HAS_TRAIT(human_target, TRAIT_BADDNA))
- balloon_alert(user, "dna is corrupted!")
- return FALSE
- // Invalid: Occupant isn't Human, isn't organic, lacks DNA / has TRAIT_GENELESS.
- if(!ishuman(human_target) || !human_target.can_mutate())
- balloon_alert(user, "dna is missing!")
- return FALSE
- // Valid: Occupant is an organic Human who has undamaged and mutable DNA.
- return TRUE
-
/// Verify that the given infusion source/mob is a dead creature.
/obj/machinery/dna_infuser/proc/is_valid_infusion(atom/movable/target, mob/user)
if(user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_UI_BLOCKED) || !Adjacent(user) || !user.Adjacent(target) || !ISADVANCEDTOOLUSER(user))
@@ -291,10 +230,10 @@
/obj/machinery/dna_infuser/click_alt(mob/user)
if(infusing)
balloon_alert(user, "not while it's on!")
- return CLICK_ACTION_BLOCKING
+ return
if(!infusing_from)
balloon_alert(user, "no sample to eject!")
- return CLICK_ACTION_BLOCKING
+ return
balloon_alert(user, "ejected sample")
infusing_from.forceMove(get_turf(src))
infusing_from = null
diff --git a/code/game/machinery/dna_infuser/dna_infusion.dm b/code/game/machinery/dna_infuser/dna_infusion.dm
new file mode 100644
index 00000000000..c902240404c
--- /dev/null
+++ b/code/game/machinery/dna_infuser/dna_infusion.dm
@@ -0,0 +1,75 @@
+
+///returns a boolean whether a machine occupant can be infused
+/atom/movable/proc/can_infuse(mob/feedback_target)
+ if(feedback_target)
+ balloon_alert(feedback_target, "no dna!")
+ return FALSE
+
+/mob/living/can_infuse(mob/feedback_target)
+ if(feedback_target)
+ balloon_alert(feedback_target, "dna too simple!")
+ return FALSE
+
+/mob/living/carbon/human/can_infuse(mob/feedback_target)
+ // Checked by can_mutate but explicit feedback for this issue is good
+ if(HAS_TRAIT(src, TRAIT_BADDNA))
+ if(feedback_target)
+ balloon_alert(feedback_target, "dna is corrupted!")
+ return FALSE
+ if(!can_mutate())
+ if(feedback_target)
+ balloon_alert(feedback_target, "dna is missing!")
+ return FALSE
+ return TRUE
+
+///returns /datum/infuser_entry that matches an item being used for infusion, returns a fly mutation on failure
+/atom/movable/proc/get_infusion_entry() as /datum/infuser_entry
+ var/datum/infuser_entry/found
+ for(var/datum/infuser_entry/entry as anything in flatten_list(GLOB.infuser_entries))
+ if(entry.tier == DNA_MUTANT_UNOBTAINABLE)
+ continue
+ if(is_type_in_list(src, entry.input_obj_or_mob))
+ found = entry
+ break
+ if(!found)
+ found = GLOB.infuser_entries[/datum/infuser_entry/fly]
+ return found
+
+/// Attempt to replace/add-to the occupant's organs with "mutated" equivalents.
+/// Returns TRUE on success, FALSE on failure.
+/// Requires the target mob to have an existing organic organ to "mutate".
+// TODO: In the future, this should have more logic:
+// - Replace non-mutant organs before mutant ones.
+/mob/living/carbon/human/proc/infuse_organ(datum/infuser_entry/entry)
+ var/obj/item/organ/new_organ = pick_infusion_organ(entry)
+ if(!new_organ)
+ return FALSE
+ // Valid organ successfully picked.
+ new_organ = new new_organ()
+ new_organ.replace_into(src)
+ return TRUE
+
+/// Picks a random mutated organ from the given infuser entry which is also compatible with this human.
+/// Tries to return a typepath of a valid mutant organ if all of the following criteria are true:
+/// 1. Target must have a pre-existing organ in the same organ slot as the new organ;
+/// - or the new organ must be external.
+/// 2. Target's pre-existing organ must be organic / not robotic.
+/// 3. Target must not have the same/identical organ.
+/mob/living/carbon/human/proc/pick_infusion_organ(datum/infuser_entry/entry)
+ if(!entry)
+ return FALSE
+ var/list/obj/item/organ/potential_new_organs = entry.output_organs.Copy()
+ // Remove organ typepaths from the list if they're incompatible with target.
+ for(var/obj/item/organ/new_organ as anything in entry.output_organs)
+ var/obj/item/organ/old_organ = get_organ_slot(initial(new_organ.slot))
+ if(old_organ)
+ if((old_organ.type != new_organ) && !IS_ROBOTIC_ORGAN(old_organ))
+ continue // Old organ can be mutated!
+ else if(ispath(new_organ, /obj/item/organ/external))
+ continue // External organ can be grown!
+ // Internal organ is either missing, or is non-organic.
+ potential_new_organs -= new_organ
+ // Pick a random organ from the filtered list.
+ if(length(potential_new_organs))
+ return pick(potential_new_organs)
+ return FALSE
diff --git a/code/game/machinery/dna_infuser/infuser_book.dm b/code/game/machinery/dna_infuser/infuser_book.dm
index 75632178cca..416ed038d64 100644
--- a/code/game/machinery/dna_infuser/infuser_book.dm
+++ b/code/game/machinery/dna_infuser/infuser_book.dm
@@ -29,7 +29,7 @@
var/list/data = list()
// Collect all info from each intry.
var/list/entry_data = list()
- for(var/datum/infuser_entry/entry as anything in GLOB.infuser_entries)
+ for(var/datum/infuser_entry/entry as anything in flatten_list(GLOB.infuser_entries))
if(entry.tier == DNA_MUTANT_UNOBTAINABLE)
continue
var/list/individual_entry_data = list()
diff --git a/code/game/machinery/dna_infuser/infuser_entry.dm b/code/game/machinery/dna_infuser/infuser_entry.dm
index dfcdfbbe08a..8b0bcfb3f79 100644
--- a/code/game/machinery/dna_infuser/infuser_entry.dm
+++ b/code/game/machinery/dna_infuser/infuser_entry.dm
@@ -4,17 +4,10 @@ GLOBAL_LIST_INIT(infuser_entries, prepare_infuser_entries())
/// Global proc that sets up each [/datum/infuser_entry] sub-type as singleton instances in a list, and returns it.
/proc/prepare_infuser_entries()
var/list/entries = list()
- // Regardless of names, we want the fly/failed mutant case to show first.
- var/prepended
for(var/datum/infuser_entry/entry_type as anything in subtypesof(/datum/infuser_entry))
var/datum/infuser_entry/entry = new entry_type()
- if(entry.type == /datum/infuser_entry/fly)
- prepended = entry
- continue
- entries += entry
- var/list/sorted = sort_names(entries)
- sorted.Insert(1, prepended)
- return sorted
+ entries[entry_type] = entry
+ return entries
/datum/infuser_entry
//-- Vars for DNA Infusion Book --//
diff --git a/code/game/machinery/dna_infuser/organ_sets/carp_organs.dm b/code/game/machinery/dna_infuser/organ_sets/carp_organs.dm
index afbb8404060..f44de87e92e 100644
--- a/code/game/machinery/dna_infuser/organ_sets/carp_organs.dm
+++ b/code/game/machinery/dna_infuser/organ_sets/carp_organs.dm
@@ -27,7 +27,7 @@
/obj/item/organ/internal/lungs/carp/Initialize(mapload)
. = ..()
- AddElement(/datum/element/noticable_organ, "neck has odd gills.", BODY_ZONE_HEAD)
+ AddElement(/datum/element/noticable_organ, "%PRONOUN_Their neck has odd gills.", BODY_ZONE_HEAD)
AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/carp)
ADD_TRAIT(src, TRAIT_SPACEBREATHING, REF(src))
@@ -45,7 +45,7 @@
/obj/item/organ/internal/tongue/carp/Initialize(mapload)
. = ..()
- AddElement(/datum/element/noticable_organ, "teeth are big and sharp.", BODY_ZONE_PRECISE_MOUTH)
+ AddElement(/datum/element/noticable_organ, "%PRONOUN_Their teeth are big and sharp.", BODY_ZONE_PRECISE_MOUTH)
AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/carp)
/obj/item/organ/internal/tongue/carp/on_mob_insert(mob/living/carbon/tongue_owner, special, movement_flags)
@@ -113,7 +113,7 @@
/obj/item/organ/internal/brain/carp/Initialize(mapload)
. = ..()
AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/carp)
- AddElement(/datum/element/noticable_organ, "seem%PRONOUN_S unable to stay still.")
+ AddElement(/datum/element/noticable_organ, "%PRONOUN_They seem%PRONOUN_S unable to stay still.")
/obj/item/organ/internal/brain/carp/on_mob_insert(mob/living/carbon/brain_owner)
. = ..()
@@ -151,7 +151,7 @@
/obj/item/organ/internal/heart/carp/Initialize(mapload)
. = ..()
- AddElement(/datum/element/noticable_organ, "skin has small patches of scales growing on it.", BODY_ZONE_CHEST)
+ AddElement(/datum/element/noticable_organ, "%PRONOUN_Their skin has small patches of scales growing on it.", BODY_ZONE_CHEST)
AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/carp)
#undef CARP_ORGAN_COLOR
diff --git a/code/game/machinery/dna_infuser/organ_sets/goliath_organs.dm b/code/game/machinery/dna_infuser/organ_sets/goliath_organs.dm
index f9ccf16812b..ac3dae39b70 100644
--- a/code/game/machinery/dna_infuser/organ_sets/goliath_organs.dm
+++ b/code/game/machinery/dna_infuser/organ_sets/goliath_organs.dm
@@ -31,7 +31,7 @@
/obj/item/organ/internal/eyes/night_vision/goliath/Initialize(mapload)
. = ..()
- AddElement(/datum/element/noticable_organ, "eyes are blood red and stone-like.", BODY_ZONE_PRECISE_EYES)
+ AddElement(/datum/element/noticable_organ, "%PRONOUN_Their eyes are blood red and stone-like.", BODY_ZONE_PRECISE_EYES)
AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/goliath)
///goliath lungs! You can breathe lavaland air mix but can't breath pure O2 from a tank anymore.
@@ -46,7 +46,7 @@
/obj/item/organ/internal/lungs/lavaland/goliath/Initialize(mapload)
. = ..()
- AddElement(/datum/element/noticable_organ, "back is covered in small tendrils.", BODY_ZONE_CHEST)
+ AddElement(/datum/element/noticable_organ, "%PRONOUN_Their back is covered in small tendrils.", BODY_ZONE_CHEST)
AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/goliath)
///goliath brain. you can't use gloves but one of your arms becomes a tendril hammer that can be used to mine!
@@ -63,7 +63,7 @@
/obj/item/organ/internal/brain/goliath/Initialize(mapload)
. = ..()
- AddElement(/datum/element/noticable_organ, "arm is just a mass of plate and tendrils.", BODY_ZONE_CHEST)
+ AddElement(/datum/element/noticable_organ, "%PRONOUN_Their arm is just a mass of plate and tendrils.", BODY_ZONE_CHEST)
AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/goliath)
/obj/item/organ/internal/brain/goliath/on_mob_insert(mob/living/carbon/brain_owner)
@@ -170,7 +170,7 @@
/obj/item/organ/internal/heart/goliath/Initialize(mapload)
. = ..()
- AddElement(/datum/element/noticable_organ, "skin has visible hard plates growing from within.", BODY_ZONE_CHEST)
+ AddElement(/datum/element/noticable_organ, "%PRONOUN_Their skin has visible hard plates growing from within.", BODY_ZONE_CHEST)
AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/goliath)
AddElement(/datum/element/update_icon_blocker)
diff --git a/code/game/machinery/dna_infuser/organ_sets/gondola_organs.dm b/code/game/machinery/dna_infuser/organ_sets/gondola_organs.dm
index 96e41a57789..a36ebc1d3c3 100644
--- a/code/game/machinery/dna_infuser/organ_sets/gondola_organs.dm
+++ b/code/game/machinery/dna_infuser/organ_sets/gondola_organs.dm
@@ -31,7 +31,7 @@ Fluoride Stare: After someone says 5 words, blah blah blah...
/obj/item/organ/internal/heart/gondola/Initialize(mapload)
. = ..()
AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/gondola)
- AddElement(/datum/element/noticable_organ, "radiate%PRONOUN_S an aura of serenity.")
+ AddElement(/datum/element/noticable_organ, "%PRONOUN_They radiate%PRONOUN_S an aura of serenity.")
/obj/item/organ/internal/heart/gondola/Insert(mob/living/carbon/receiver, special, movement_flags)
. = ..()
@@ -60,7 +60,7 @@ Fluoride Stare: After someone says 5 words, blah blah blah...
/obj/item/organ/internal/tongue/gondola/Initialize(mapload)
. = ..()
- AddElement(/datum/element/noticable_organ, "mouth is permanently affixed into a relaxed smile.", BODY_ZONE_PRECISE_MOUTH)
+ AddElement(/datum/element/noticable_organ, "%PRONOUN_Their mouth is permanently affixed into a relaxed smile.", BODY_ZONE_PRECISE_MOUTH)
AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/gondola)
/obj/item/organ/internal/tongue/gondola/Insert(mob/living/carbon/tongue_owner, special, movement_flags)
@@ -83,8 +83,8 @@ Fluoride Stare: After someone says 5 words, blah blah blah...
/obj/item/organ/internal/liver/gondola/Initialize(mapload)
. = ..()
AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/gondola)
- AddElement(/datum/element/noticable_organ, "left arm has small needles breaching the skin all over it.", BODY_ZONE_L_ARM)
- AddElement(/datum/element/noticable_organ, "right arm has small needles breaching the skin all over it.", BODY_ZONE_R_ARM)
+ AddElement(/datum/element/noticable_organ, "%PRONOUN_Their left arm has small needles breaching the skin all over it.", BODY_ZONE_L_ARM)
+ AddElement(/datum/element/noticable_organ, "%PRONOUN_Their right arm has small needles breaching the skin all over it.", BODY_ZONE_R_ARM)
/obj/item/organ/internal/liver/gondola/Insert(mob/living/carbon/liver_owner, special, movement_flags)
. = ..()
diff --git a/code/game/machinery/dna_infuser/organ_sets/rat_organs.dm b/code/game/machinery/dna_infuser/organ_sets/rat_organs.dm
index f19f3d725c7..56b147ffbee 100644
--- a/code/game/machinery/dna_infuser/organ_sets/rat_organs.dm
+++ b/code/game/machinery/dna_infuser/organ_sets/rat_organs.dm
@@ -29,7 +29,7 @@
/obj/item/organ/internal/eyes/night_vision/rat/Initialize(mapload)
. = ..()
- AddElement(/datum/element/noticable_organ, "eyes have deep, shifty black pupils, surrounded by a sickening yellow sclera.", BODY_ZONE_PRECISE_EYES)
+ AddElement(/datum/element/noticable_organ, "%PRONOUN_Their eyes have deep, shifty black pupils, surrounded by a sickening yellow sclera.", BODY_ZONE_PRECISE_EYES)
AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/rat)
///increases hunger, disgust recovers quicker, expands what is defined as "food"
@@ -47,7 +47,7 @@
/obj/item/organ/internal/stomach/rat/Initialize(mapload)
. = ..()
AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/rat)
- AddElement(/datum/element/noticable_organ, "mouth is drooling excessively.", BODY_ZONE_PRECISE_MOUTH)
+ AddElement(/datum/element/noticable_organ, "%PRONOUN_Their mouth is drooling excessively.", BODY_ZONE_PRECISE_MOUTH)
/// makes you smaller, walk over tables, and take 1.5x damage
/obj/item/organ/internal/heart/rat
@@ -61,7 +61,7 @@
/obj/item/organ/internal/heart/rat/Initialize(mapload)
. = ..()
AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/rat)
- AddElement(/datum/element/noticable_organ, "hunch%PRONOUN_ES over unnaturally!")
+ AddElement(/datum/element/noticable_organ, "%PRONOUN_They hunch%PRONOUN_ES over unnaturally!")
/obj/item/organ/internal/heart/rat/on_mob_insert(mob/living/carbon/receiver)
. = ..()
@@ -98,7 +98,7 @@
/obj/item/organ/internal/tongue/rat/Initialize(mapload)
. = ..()
- AddElement(/datum/element/noticable_organ, "teeth are oddly shaped and yellowing.", BODY_ZONE_PRECISE_MOUTH)
+ AddElement(/datum/element/noticable_organ, "%PRONOUN_Their teeth are oddly shaped and yellowing.", BODY_ZONE_PRECISE_MOUTH)
AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/rat)
/obj/item/organ/internal/tongue/rat/modify_speech(datum/source, list/speech_args)
diff --git a/code/game/machinery/dna_infuser/organ_sets/roach_organs.dm b/code/game/machinery/dna_infuser/organ_sets/roach_organs.dm
index 0644bca0354..11880a50cb2 100644
--- a/code/game/machinery/dna_infuser/organ_sets/roach_organs.dm
+++ b/code/game/machinery/dna_infuser/organ_sets/roach_organs.dm
@@ -63,7 +63,7 @@
/obj/item/organ/internal/heart/roach/Initialize(mapload)
. = ..()
- AddElement(/datum/element/noticable_organ, "has hardened, somewhat translucent skin.")
+ AddElement(/datum/element/noticable_organ, "%PRONOUN_They %PRONOUN_have hardened, somewhat translucent skin.")
AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/roach)
roach_shell = new()
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 437acc60cdf..661e9035f01 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -98,6 +98,7 @@
smoothing_groups = SMOOTH_GROUP_AIRLOCK
interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_OPEN
+ interaction_flags_click = ALLOW_SILICON_REACH
blocks_emissive = EMISSIVE_BLOCK_NONE // Custom emissive blocker. We don't want the normal behavior.
///The type of door frame to drop during deconstruction
diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm
index cc084bea23c..13d3b8714be 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -884,7 +884,7 @@
return
if(istype(attacking_object, /obj/item/electroadaptive_pseudocircuit))
var/obj/item/electroadaptive_pseudocircuit/raspberrypi = attacking_object
- if(!raspberrypi.adapt_circuit(user, circuit_cost = DEFAULT_STEP_TIME * 0.5 KILO JOULES))
+ if(!raspberrypi.adapt_circuit(user, circuit_cost = DEFAULT_STEP_TIME * 0.0005 * STANDARD_CELL_CHARGE))
return
user.visible_message(span_notice("[user] fabricates a circuit and places it into [src]."), \
span_notice("You adapt a firelock circuit and slot it into the assembly."))
diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm
index 21494d17b99..c89260f7ceb 100644
--- a/code/game/machinery/firealarm.dm
+++ b/code/game/machinery/firealarm.dm
@@ -406,7 +406,7 @@
else if(istype(tool, /obj/item/electroadaptive_pseudocircuit))
var/obj/item/electroadaptive_pseudocircuit/pseudoc = tool
- if(!pseudoc.adapt_circuit(user, circuit_cost = 15 KILO JOULES))
+ if(!pseudoc.adapt_circuit(user, circuit_cost = 0.015 * STANDARD_CELL_CHARGE))
return
user.visible_message(span_notice("[user] fabricates a circuit and places it into [src]."), \
span_notice("You adapt a fire alarm circuit and slot it into the assembly."))
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index 273538b834b..d2041f80659 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -47,6 +47,7 @@ Possible to do for anyone motivated enough:
armor_type = /datum/armor/machinery_holopad
circuit = /obj/item/circuitboard/machine/holopad
interaction_flags_atom = parent_type::interaction_flags_atom | INTERACT_ATOM_IGNORE_MOBILITY
+ interaction_flags_click = ALLOW_SILICON_REACH
// Blue, dim light
light_power = 0.8
light_color = LIGHT_COLOR_BLUE
diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm
index 06b1b977847..ffbecf91180 100644
--- a/code/game/machinery/porta_turret/portable_turret.dm
+++ b/code/game/machinery/porta_turret/portable_turret.dm
@@ -910,6 +910,7 @@ DEFINE_BITFIELD(turret_flags, list(
density = FALSE
req_access = list(ACCESS_AI_UPLOAD)
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
+ interaction_flags_click = ALLOW_SILICON_REACH
/// Variable dictating if linked turrets are active and will shoot targets
var/enabled = TRUE
/// Variable dictating if linked turrets will shoot lethal projectiles
diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm
index d067c3e8cbb..287fef5057d 100644
--- a/code/game/machinery/rechargestation.dm
+++ b/code/game/machinery/rechargestation.dm
@@ -178,7 +178,7 @@
if(!occupant)
return
- if(!use_energy(active_power_usage * seconds_per_tick))
+ if(!use_energy(active_power_usage * seconds_per_tick, force = FALSE))
return
SEND_SIGNAL(occupant, COMSIG_PROCESS_BORGCHARGER_OCCUPANT, charge_cell, seconds_per_tick, repairs, sendmats)
diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm
index 28aae488866..9df7d584f42 100644
--- a/code/game/machinery/recycler.dm
+++ b/code/game/machinery/recycler.dm
@@ -21,7 +21,7 @@
/obj/machinery/recycler/Initialize(mapload)
materials = AddComponent(
/datum/component/material_container, \
- SSmaterials.materials_by_category[MAT_CATEGORY_SILO], \
+ DSmaterials.materials_by_category[MAT_CATEGORY_SILO], \
INFINITY, \
MATCONTAINER_NO_INSERT \
)
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index d95668975f5..a5e301c2168 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -1,3 +1,4 @@
+
// SUIT STORAGE UNIT /////////////////
/obj/machinery/suit_storage_unit
name = "suit storage unit"
@@ -55,9 +56,9 @@
/// How long it takes to break out of the SSU.
var/breakout_time = 30 SECONDS
/// Power contributed by this machine to charge the mod suits cell without any capacitors
- var/base_charge_rate = 200 KILO WATTS
+ var/base_charge_rate = 0.2 * STANDARD_CELL_RATE
/// Final charge rate which is base_charge_rate + contribution by capacitors
- var/final_charge_rate = 250 KILO WATTS
+ var/final_charge_rate = 0.25 * STANDARD_CELL_RATE
/// is the card reader installed in this machine
var/card_reader_installed = FALSE
/// physical reference of the players id card to check for PERSONAL access level
@@ -287,7 +288,7 @@
. = ..()
for(var/datum/stock_part/capacitor/capacitor in component_parts)
- final_charge_rate = base_charge_rate + (capacitor.tier * 50 KILO WATTS)
+ final_charge_rate = base_charge_rate + (capacitor.tier * 0.05 * STANDARD_CELL_RATE)
set_access()
diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm
index 693668e9e89..154b03e0f98 100644
--- a/code/game/machinery/syndicatebomb.dm
+++ b/code/game/machinery/syndicatebomb.dm
@@ -606,7 +606,7 @@
var/datum/radial_menu_choice/null_choice = new
null_choice.name = DIMENSION_CHOICE_RANDOM
choosable_dimensions[DIMENSION_CHOICE_RANDOM] = null_choice
- for(var/datum/dimension_theme/theme as anything in SSmaterials.dimensional_themes)
+ for(var/datum/dimension_theme/theme as anything in DSmaterials.dimensional_themes)
var/datum/radial_menu_choice/theme_choice = new
theme_choice.image = image(initial(theme.icon), initial(theme.icon_state))
theme_choice.name = initial(theme.name)
@@ -628,14 +628,14 @@
/obj/item/bombcore/dimensional/detonate()
var/list/affected_turfs = circle_range_turfs(src, range_heavy)
- var/theme_count = length(SSmaterials.dimensional_themes)
+ var/theme_count = length(DSmaterials.dimensional_themes)
var/num_affected = 0
for(var/turf/affected as anything in affected_turfs)
var/datum/dimension_theme/theme_to_use
if(isnull(chosen_theme))
- theme_to_use = SSmaterials.dimensional_themes[SSmaterials.dimensional_themes[rand(1, theme_count)]]
+ theme_to_use = DSmaterials.dimensional_themes[DSmaterials.dimensional_themes[rand(1, theme_count)]]
else
- theme_to_use = SSmaterials.dimensional_themes[chosen_theme]
+ theme_to_use = DSmaterials.dimensional_themes[chosen_theme]
if(!theme_to_use.can_convert(affected))
continue
num_affected++
diff --git a/code/game/objects/effects/anomalies/anomalies_dimensional.dm b/code/game/objects/effects/anomalies/anomalies_dimensional.dm
index 026c5974d5f..a4ebfc21f1a 100644
--- a/code/game/objects/effects/anomalies/anomalies_dimensional.dm
+++ b/code/game/objects/effects/anomalies/anomalies_dimensional.dm
@@ -51,7 +51,7 @@
/obj/effect/anomaly/dimensional/proc/prepare_area(new_theme_path)
if (!new_theme_path)
new_theme_path = pick(subtypesof(/datum/dimension_theme))
- theme = SSmaterials.dimensional_themes[new_theme_path]
+ theme = DSmaterials.dimensional_themes[new_theme_path]
apply_theme_icon()
target_turfs = list()
diff --git a/code/game/objects/effects/decals/cleanable/aliens.dm b/code/game/objects/effects/decals/cleanable/aliens.dm
index 4f4b2543792..fb87f788036 100644
--- a/code/game/objects/effects/decals/cleanable/aliens.dm
+++ b/code/game/objects/effects/decals/cleanable/aliens.dm
@@ -47,7 +47,7 @@
break
return
- var/datum/move_loop/loop = SSmove_manager.move(src, direction, delay = delay, timeout = range * delay, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
+ var/datum/move_loop/loop = DSmove_manager.move(src, direction, delay = delay, timeout = range * delay, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(spread_movement_effects))
/obj/effect/decal/cleanable/xenoblood/xgibs/proc/spread_movement_effects(datum/move_loop/has_target/source)
diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm
index ccb05b082b3..7812ba789b5 100644
--- a/code/game/objects/effects/decals/cleanable/humans.dm
+++ b/code/game/objects/effects/decals/cleanable/humans.dm
@@ -163,7 +163,7 @@
break
return
- var/datum/move_loop/loop = SSmove_manager.move_to(src, get_step(src, direction), delay = delay, timeout = range * delay, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
+ var/datum/move_loop/loop = DSmove_manager.move_to(src, get_step(src, direction), delay = delay, timeout = range * delay, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(spread_movement_effects))
/obj/effect/decal/cleanable/blood/gibs/proc/spread_movement_effects(datum/move_loop/has_target/source)
@@ -376,7 +376,7 @@ GLOBAL_LIST_EMPTY(bloody_footprints_cache)
/// Set the splatter up to fly through the air until it rounds out of steam or hits something
/obj/effect/decal/cleanable/blood/hitsplatter/proc/fly_towards(turf/target_turf, range)
var/delay = 2
- var/datum/move_loop/loop = SSmove_manager.move_towards(src, target_turf, delay, timeout = delay * range, priority = MOVEMENT_ABOVE_SPACE_PRIORITY, flags = MOVEMENT_LOOP_START_FAST)
+ var/datum/move_loop/loop = DSmove_manager.move_towards(src, target_turf, delay, timeout = delay * range, priority = MOVEMENT_ABOVE_SPACE_PRIORITY, flags = MOVEMENT_LOOP_START_FAST)
RegisterSignal(loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(pre_move))
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(post_move))
RegisterSignal(loop, COMSIG_QDELETING, PROC_REF(loop_done))
diff --git a/code/game/objects/effects/decals/cleanable/robots.dm b/code/game/objects/effects/decals/cleanable/robots.dm
index d248b5e691d..77034850a0b 100644
--- a/code/game/objects/effects/decals/cleanable/robots.dm
+++ b/code/game/objects/effects/decals/cleanable/robots.dm
@@ -32,7 +32,7 @@
break
return
- var/datum/move_loop/loop = SSmove_manager.move(src, direction, delay = delay, timeout = range * delay, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
+ var/datum/move_loop/loop = DSmove_manager.move(src, direction, delay = delay, timeout = range * delay, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(spread_movement_effects))
/obj/effect/decal/cleanable/robot_debris/proc/spread_movement_effects(datum/move_loop/has_target/source)
diff --git a/code/game/objects/effects/effect_system/effect_system.dm b/code/game/objects/effects/effect_system/effect_system.dm
index 9d2d13f9925..9e5418a94f4 100644
--- a/code/game/objects/effects/effect_system/effect_system.dm
+++ b/code/game/objects/effects/effect_system/effect_system.dm
@@ -67,7 +67,7 @@ would spawn and follow the beaker, even if it is carried or thrown.
var/step_amt = pick(1,2,3)
var/step_delay = 5
- var/datum/move_loop/loop = SSmove_manager.move(effect, direction, step_delay, timeout = step_delay * step_amt, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
+ var/datum/move_loop/loop = DSmove_manager.move(effect, direction, step_delay, timeout = step_delay * step_amt, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
RegisterSignal(loop, COMSIG_QDELETING, PROC_REF(decrement_total_effect))
/datum/effect_system/proc/decrement_total_effect(datum/source)
diff --git a/code/game/objects/effects/effect_system/effects_explosion.dm b/code/game/objects/effects/effect_system/effects_explosion.dm
index 32be64c9353..9153d4151b3 100644
--- a/code/game/objects/effects/effect_system/effects_explosion.dm
+++ b/code/game/objects/effects/effect_system/effects_explosion.dm
@@ -11,7 +11,7 @@
/obj/effect/particle_effect/expl_particles/LateInitialize()
var/step_amt = pick(25;1,50;2,100;3,200;4)
- var/datum/move_loop/loop = SSmove_manager.move(src, pick(GLOB.alldirs), 1, timeout = step_amt, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
+ var/datum/move_loop/loop = DSmove_manager.move(src, pick(GLOB.alldirs), 1, timeout = step_amt, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
RegisterSignal(loop, COMSIG_QDELETING, PROC_REF(end_particle))
/obj/effect/particle_effect/expl_particles/proc/end_particle(datum/source)
diff --git a/code/game/objects/effects/effect_system/effects_water.dm b/code/game/objects/effects/effect_system/effects_water.dm
index 2edca60a320..6444cf3d0ee 100644
--- a/code/game/objects/effects/effect_system/effects_water.dm
+++ b/code/game/objects/effects/effect_system/effects_water.dm
@@ -38,7 +38,7 @@
/// Starts the effect moving at a target with a delay in deciseconds, and a lifetime in moves
/// Returns the created loop
/obj/effect/particle_effect/water/extinguisher/proc/move_at(atom/target, delay, lifetime)
- var/datum/move_loop/loop = SSmove_manager.move_towards_legacy(src, target, delay, timeout = delay * lifetime, flags = MOVEMENT_LOOP_START_FAST, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
+ var/datum/move_loop/loop = DSmove_manager.move_towards_legacy(src, target, delay, timeout = delay * lifetime, flags = MOVEMENT_LOOP_START_FAST, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(post_forcemove))
RegisterSignal(loop, COMSIG_QDELETING, PROC_REF(movement_stopped))
return loop
@@ -63,7 +63,7 @@
// Stomach acid doesn't use legacy because it's not "targeted", and we instead want the circular sorta look
/obj/effect/particle_effect/water/extinguisher/stomach_acid/move_at(atom/target, delay, lifetime)
- var/datum/move_loop/loop = SSmove_manager.move_towards(src, target, delay, timeout = delay * lifetime, flags = MOVEMENT_LOOP_START_FAST, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
+ var/datum/move_loop/loop = DSmove_manager.move_towards(src, target, delay, timeout = delay * lifetime, flags = MOVEMENT_LOOP_START_FAST, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(post_forcemove))
RegisterSignal(loop, COMSIG_QDELETING, PROC_REF(movement_stopped))
return loop
diff --git a/code/game/objects/effects/spawners/xeno_egg_delivery.dm b/code/game/objects/effects/spawners/xeno_egg_delivery.dm
index b09a37f14b1..e87b27e0913 100644
--- a/code/game/objects/effects/spawners/xeno_egg_delivery.dm
+++ b/code/game/objects/effects/spawners/xeno_egg_delivery.dm
@@ -25,5 +25,5 @@
/obj/structure/alien/egg/delivery/Initialize(mapload)
. = ..()
- SScommunications.xenomorph_egg_delivered = TRUE
- SScommunications.captivity_area = get_area(src)
+ DScommunications.xenomorph_egg_delivered = TRUE
+ DScommunications.captivity_area = get_area(src)
diff --git a/code/game/objects/effects/step_triggers.dm b/code/game/objects/effects/step_triggers.dm
index ecfa560bfe6..874104c9202 100644
--- a/code/game/objects/effects/step_triggers.dm
+++ b/code/game/objects/effects/step_triggers.dm
@@ -70,7 +70,7 @@
ADD_TRAIT(AM, TRAIT_IMMOBILIZED, REF(src))
affecting[AM] = AM.dir
- var/datum/move_loop/loop = SSmove_manager.move(AM, direction, speed, tiles ? tiles * speed : INFINITY)
+ var/datum/move_loop/loop = DSmove_manager.move(AM, direction, speed, tiles ? tiles * speed : INFINITY)
RegisterSignal(loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(pre_move))
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(post_move))
RegisterSignal(loop, COMSIG_QDELETING, PROC_REF(set_to_normal))
diff --git a/code/game/objects/effects/temporary_visuals/effect_trail.dm b/code/game/objects/effects/temporary_visuals/effect_trail.dm
index 028e5141653..2fd7d41d22c 100644
--- a/code/game/objects/effects/temporary_visuals/effect_trail.dm
+++ b/code/game/objects/effects/temporary_visuals/effect_trail.dm
@@ -29,7 +29,7 @@
AddElement(/datum/element/floor_loving)
AddComponent(/datum/component/spawner, spawn_types = list(spawned_effect), max_spawned = max_spawned, spawn_time = spawn_interval)
src.target = target
- movement = SSmove_manager.move_towards(src, chasing = target, delay = move_speed, home = homing, timeout = duration, flags = MOVEMENT_LOOP_START_FAST)
+ movement = DSmove_manager.move_towards(src, chasing = target, delay = move_speed, home = homing, timeout = duration, flags = MOVEMENT_LOOP_START_FAST)
RegisterSignal(target, COMSIG_QDELETING, PROC_REF(on_target_invalid))
if (isliving(target))
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index b6241828e86..bd70bf2f475 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -923,7 +923,7 @@
if(flags & ITEM_SLOT_EYES)
owner.update_worn_glasses()
if(flags & ITEM_SLOT_EARS)
- owner.update_inv_ears()
+ owner.update_worn_ears()
if(flags & ITEM_SLOT_MASK)
owner.update_worn_mask()
if(flags & ITEM_SLOT_HEAD)
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index 4cb077808a8..556d0d47646 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -759,7 +759,7 @@
pre_noise = TRUE
post_noise = FALSE
- interaction_flags_click = NEED_DEXTERITY|NEED_HANDS
+ interaction_flags_click = NEED_DEXTERITY|NEED_HANDS|ALLOW_RESTING
/obj/item/toy/crayon/spraycan/Initialize(mapload)
. = ..()
diff --git a/code/game/objects/items/credit_holochip.dm b/code/game/objects/items/credit_holochip.dm
index c9b6fe4a134..7a57782dd39 100644
--- a/code/game/objects/items/credit_holochip.dm
+++ b/code/game/objects/items/credit_holochip.dm
@@ -7,7 +7,7 @@
throwforce = 0
force = 0
w_class = WEIGHT_CLASS_TINY
- interaction_flags_click = NEED_DEXTERITY|FORBID_TELEKINESIS_REACH
+ interaction_flags_click = NEED_DEXTERITY|FORBID_TELEKINESIS_REACH|ALLOW_RESTING
/// Amount on money on the card
var/credits = 0
diff --git a/code/game/objects/items/devices/battle_royale.dm b/code/game/objects/items/devices/battle_royale.dm
index b4ea15c6de7..4a47b164f43 100644
--- a/code/game/objects/items/devices/battle_royale.dm
+++ b/code/game/objects/items/devices/battle_royale.dm
@@ -78,7 +78,7 @@
balloon_alert(user, "[required_contestants - contestant_count] contestants needed!")
return
- SSbattle_royale.start_battle(implanted_implants)
+ DSbattle_royale.start_battle(implanted_implants)
for (var/obj/implanter as anything in linked_implanters)
do_sparks(3, cardinal_only = FALSE, source = implanter)
diff --git a/code/game/objects/items/devices/desynchronizer.dm b/code/game/objects/items/devices/desynchronizer.dm
index b7b693b999f..e43e0a656af 100644
--- a/code/game/objects/items/devices/desynchronizer.dm
+++ b/code/game/objects/items/devices/desynchronizer.dm
@@ -9,7 +9,7 @@
lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi'
custom_materials = list(/datum/material/iron= SMALL_MATERIAL_AMOUNT * 2.5, /datum/material/glass= SMALL_MATERIAL_AMOUNT * 5)
- interaction_flags_click = NEED_DEXTERITY
+ interaction_flags_click = NEED_DEXTERITY|ALLOW_RESTING
/// Max time this can be set
var/max_duration = 300 SECONDS
/// Currently set time
diff --git a/code/game/objects/items/devices/electroadaptive_pseudocircuit.dm b/code/game/objects/items/devices/electroadaptive_pseudocircuit.dm
index de14a9e123f..d5d2e6c4d14 100644
--- a/code/game/objects/items/devices/electroadaptive_pseudocircuit.dm
+++ b/code/game/objects/items/devices/electroadaptive_pseudocircuit.dm
@@ -1,3 +1,6 @@
+#define MIN_ENERGY_COST (0.01 * STANDARD_CELL_CHARGE)
+#define MAX_ENERGY_COST (0.5 * STANDARD_CELL_CHARGE)
+
//Used by engineering cyborgs in place of generic circuits.
/obj/item/electroadaptive_pseudocircuit
name = "electroadaptive pseudocircuit"
@@ -32,12 +35,12 @@
if(!R.cell)
to_chat(R, span_warning("You need a power cell installed for that."))
return
- if(!R.cell.use(circuit_cost))
- to_chat(R, span_warning("You don't have the energy for that (you need [display_energy(circuit_cost)].)"))
- return
if(recharging)
to_chat(R, span_warning("[src] needs some time to recharge first."))
return
+ if(!R.cell.use(circuit_cost))
+ to_chat(R, span_warning("You don't have the energy for that (you need [display_energy(circuit_cost)].)"))
+ return
if(!circuits)
to_chat(R, span_warning("You need more material. Use [src] on existing simple circuits to break them down."))
return
@@ -46,8 +49,10 @@
circuits--
maptext = MAPTEXT(circuits)
icon_state = "[initial(icon_state)]_recharging"
- var/recharge_time = min(600, circuit_cost * 5) //40W of cost for one fabrication = 20 seconds of recharge time; this is to prevent spamming
- addtimer(CALLBACK(src, PROC_REF(recharge)), recharge_time)
+ var/recharge_time = (circuit_cost - MIN_ENERGY_COST) / (MAX_ENERGY_COST - MIN_ENERGY_COST)
+ recharge_time = clamp(recharge_time, 0, 1)
+ recharge_time = (5 SECONDS) + (55 SECONDS) * recharge_time //anywhere between 5 seconds to 1 minute
+ addtimer(CALLBACK(src, PROC_REF(recharge)), ROUND_UP(recharge_time))
return TRUE //The actual circuit magic itself is done on a per-object basis
/obj/item/electroadaptive_pseudocircuit/afterattack(atom/target, mob/living/user, proximity)
@@ -68,3 +73,6 @@
playsound(src, 'sound/machines/chime.ogg', 25, TRUE)
recharging = FALSE
icon_state = initial(icon_state)
+
+#undef MIN_ENERGY_COST
+#undef MAX_ENERGY_COST
diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm
index 66a8f29ed1d..ebd7729b4c5 100644
--- a/code/game/objects/items/devices/multitool.dm
+++ b/code/game/objects/items/devices/multitool.dm
@@ -152,7 +152,7 @@
name = "electronic multitool"
desc = "Optimised version of a regular multitool. Streamlines processes handled by its internal microchip."
icon = 'icons/obj/items_cyborg.dmi'
- icon_state = "multitool_cyborg"
+ icon_state = "toolkit_engiborg_multitool"
toolspeed = 0.5
#undef PROXIMITY_NEAR
diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm
index 1b000ea2f91..1925737143e 100644
--- a/code/game/objects/items/devices/powersink.dm
+++ b/code/game/objects/items/devices/powersink.dm
@@ -171,7 +171,7 @@
if(istype(terminal.master, /obj/machinery/power/apc))
var/obj/machinery/power/apc/apc = terminal.master
if(apc.operating && apc.cell)
- drained += 0.001 * apc.cell.use(50 KILO JOULES, force = TRUE)
+ drained += 0.001 * apc.cell.use(0.05 * STANDARD_CELL_CHARGE, force = TRUE)
internal_heat += drained
/obj/item/powersink/process()
diff --git a/code/game/objects/items/devices/quantum_keycard.dm b/code/game/objects/items/devices/quantum_keycard.dm
index 34b83a62092..ccaef00cfc6 100644
--- a/code/game/objects/items/devices/quantum_keycard.dm
+++ b/code/game/objects/items/devices/quantum_keycard.dm
@@ -10,7 +10,7 @@
righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi'
w_class = WEIGHT_CLASS_TINY
obj_flags = UNIQUE_RENAME
- interaction_flags_click = NEED_DEXTERITY
+ interaction_flags_click = NEED_DEXTERITY|ALLOW_RESTING
/// The linked quantum pad
var/obj/machinery/quantumpad/qpad
diff --git a/code/game/objects/items/devices/scanners/gas_analyzer.dm b/code/game/objects/items/devices/scanners/gas_analyzer.dm
index 0898c73aa2e..44975ae417b 100644
--- a/code/game/objects/items/devices/scanners/gas_analyzer.dm
+++ b/code/game/objects/items/devices/scanners/gas_analyzer.dm
@@ -17,7 +17,7 @@
tool_behaviour = TOOL_ANALYZER
custom_materials = list(/datum/material/iron=SMALL_MATERIAL_AMOUNT * 0.3, /datum/material/glass=SMALL_MATERIAL_AMOUNT * 0.2)
grind_results = list(/datum/reagent/mercury = 5, /datum/reagent/iron = 5, /datum/reagent/silicon = 5)
- interaction_flags_click = NEED_LITERACY|NEED_LIGHT
+ interaction_flags_click = NEED_LITERACY|NEED_LIGHT|ALLOW_RESTING
/// Boolean whether this has a CD
var/cooldown = FALSE
/// The time in deciseconds
diff --git a/code/game/objects/items/devices/scanners/health_analyzer.dm b/code/game/objects/items/devices/scanners/health_analyzer.dm
index 1a264cf3924..f52f97aeeb5 100644
--- a/code/game/objects/items/devices/scanners/health_analyzer.dm
+++ b/code/game/objects/items/devices/scanners/health_analyzer.dm
@@ -20,7 +20,7 @@
throw_speed = 3
throw_range = 7
custom_materials = list(/datum/material/iron=SMALL_MATERIAL_AMOUNT *2)
- interaction_flags_click = NEED_LITERACY|NEED_LIGHT
+ interaction_flags_click = NEED_LITERACY|NEED_LIGHT|ALLOW_RESTING
/// Verbose/condensed
var/mode = SCANNER_VERBOSE
/// HEALTH/WOUND
diff --git a/code/game/objects/items/devices/swapper.dm b/code/game/objects/items/devices/swapper.dm
index 6db67049174..96f378c6e32 100644
--- a/code/game/objects/items/devices/swapper.dm
+++ b/code/game/objects/items/devices/swapper.dm
@@ -8,7 +8,7 @@
item_flags = NOBLUDGEON
lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi'
- interaction_flags_click = NEED_DEXTERITY
+ interaction_flags_click = NEED_DEXTERITY|ALLOW_RESTING
/// Cooldown for usage
var/cooldown = 30 SECONDS
/// Next available time
diff --git a/code/game/objects/items/extinguisher.dm b/code/game/objects/items/extinguisher.dm
index c78242255a6..0132cc0f0d8 100644
--- a/code/game/objects/items/extinguisher.dm
+++ b/code/game/objects/items/extinguisher.dm
@@ -258,7 +258,7 @@
//Chair movement loop
/obj/item/extinguisher/proc/move_chair(obj/buckled_object, movementdirection)
- var/datum/move_loop/loop = SSmove_manager.move(buckled_object, movementdirection, 1, timeout = 9, flags = MOVEMENT_LOOP_START_FAST, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
+ var/datum/move_loop/loop = DSmove_manager.move(buckled_object, movementdirection, 1, timeout = 9, flags = MOVEMENT_LOOP_START_FAST, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
//This means the chair slowing down is dependant on the extinguisher existing, which is weird
//Couldn't figure out a better way though
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(manage_chair_speed))
diff --git a/code/game/objects/items/fireaxe.dm b/code/game/objects/items/fireaxe.dm
index 901e506194e..2859b4d3b2c 100644
--- a/code/game/objects/items/fireaxe.dm
+++ b/code/game/objects/items/fireaxe.dm
@@ -86,3 +86,13 @@
tool_behaviour = TOOL_CROWBAR
toolspeed = 1
usesound = 'sound/items/crowbar.ogg'
+
+//boarding axe
+/obj/item/fireaxe/boardingaxe
+ icon_state = "boarding_axe0"
+ base_icon_state = "boarding_axe"
+ name = "boarding axe"
+ desc = "A hulking cleaver that feels like a burden just looking at it. Seems excellent at halving obstacles like windows, airlocks, barricades and people."
+ force_unwielded = 5
+ force_wielded = 30
+ demolition_mod = 3
diff --git a/code/game/objects/items/flamethrower.dm b/code/game/objects/items/flamethrower.dm
index d2f4b0cfc71..be89193ba7e 100644
--- a/code/game/objects/items/flamethrower.dm
+++ b/code/game/objects/items/flamethrower.dm
@@ -20,7 +20,7 @@
light_range = 2
light_power = 2
light_on = FALSE
- interaction_flags_click = NEED_DEXTERITY|NEED_HANDS
+ interaction_flags_click = NEED_DEXTERITY|NEED_HANDS|ALLOW_RESTING
var/status = FALSE
var/lit = FALSE //on or off
var/operating = FALSE//cooldown
diff --git a/code/game/objects/items/implants/implantpad.dm b/code/game/objects/items/implants/implantpad.dm
index 0d0391126c9..dffd7aa77a4 100644
--- a/code/game/objects/items/implants/implantpad.dm
+++ b/code/game/objects/items/implants/implantpad.dm
@@ -10,7 +10,7 @@
throw_speed = 3
throw_range = 5
w_class = WEIGHT_CLASS_SMALL
- interaction_flags_click = FORBID_TELEKINESIS_REACH
+ interaction_flags_click = FORBID_TELEKINESIS_REACH|ALLOW_RESTING
///The implant case currently inserted into the pad.
var/obj/item/implantcase/inserted_case
diff --git a/code/game/objects/items/inspector.dm b/code/game/objects/items/inspector.dm
index f96c1beb573..ab5db9b65ce 100644
--- a/code/game/objects/items/inspector.dm
+++ b/code/game/objects/items/inspector.dm
@@ -1,3 +1,6 @@
+///Energy used to say an error message.
+#define ENERGY_TO_SPEAK (0.001 * STANDARD_CELL_CHARGE)
+
/**
* # N-spect scanner
*
@@ -28,8 +31,6 @@
var/cell_cover_open = FALSE
///Energy used per print.
var/energy_per_print = INSPECTOR_ENERGY_USAGE_NORMAL
- ///Energy used to say an error message.
- var/energy_to_speak = 1 KILO JOULES
/obj/item/inspector/Initialize(mapload)
. = ..()
@@ -112,7 +113,7 @@
to_chat(user, "\The [src] doesn't seem to be on... Perhaps it ran out of power?")
return
if(!cell.use(energy_per_print))
- if(cell.use(energy_to_speak))
+ if(cell.use(ENERGY_TO_SPEAK))
say("ERROR! POWER CELL CHARGE LEVEL TOO LOW TO PRINT REPORT!")
return
@@ -258,7 +259,7 @@
/obj/item/inspector/clown/bananium/proc/check_settings_legality()
if(print_sound_mode == INSPECTOR_PRINT_SOUND_MODE_NORMAL && time_mode == INSPECTOR_TIME_MODE_HONK)
- if(cell.use(energy_to_speak))
+ if(cell.use(ENERGY_TO_SPEAK))
say("Setting combination forbidden by Geneva convention revision CCXXIII selected, reverting to defaults")
time_mode = INSPECTOR_TIME_MODE_SLOW
print_sound_mode = INSPECTOR_PRINT_SOUND_MODE_NORMAL
@@ -296,7 +297,7 @@
if(time_mode != INSPECTOR_TIME_MODE_HONK)
return ..()
if(paper_charges == 0)
- if(cell.use(energy_to_speak))
+ if(cell.use(ENERGY_TO_SPEAK))
say("ERROR! OUT OF PAPER! MAXIMUM PRINTING SPEED UNAVAIBLE! SWITCH TO A SLOWER SPEED TO OR PROVIDE PAPER!")
else
to_chat(user, "\The [src] doesn't seem to be on... Perhaps it ran out of power?")
@@ -372,7 +373,7 @@
*/
/obj/item/paper/fake_report/water
grind_results = list(/datum/reagent/water = 5)
- interaction_flags_click = NEED_DEXTERITY|NEED_HANDS
+ interaction_flags_click = NEED_DEXTERITY|NEED_HANDS|ALLOW_RESTING
/obj/item/paper/fake_report/water/click_alt(mob/living/user)
var/datum/action/innate/origami/origami_action = locate() in user.actions
@@ -383,5 +384,6 @@
target.MakeSlippery(TURF_WET_WATER, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS)
to_chat(user, span_notice("As you try to fold [src] into the shape of a plane, it disintegrates into water!"))
qdel(src)
-
return CLICK_ACTION_SUCCESS
+
+#undef ENERGY_TO_SPEAK
diff --git a/code/game/objects/items/machine_wand.dm b/code/game/objects/items/machine_wand.dm
index c1dd0bf382d..7ce94b9ad40 100644
--- a/code/game/objects/items/machine_wand.dm
+++ b/code/game/objects/items/machine_wand.dm
@@ -150,7 +150,7 @@
CRASH("a moving bug has been created but isn't moving towards anything!")
src.controller = controller
src.thing_moving_towards = thing_moving_towards
- var/datum/move_loop/loop = SSmove_manager.home_onto(src, thing_moving_towards, delay = 5, flags = MOVEMENT_LOOP_NO_DIR_UPDATE)
+ var/datum/move_loop/loop = DSmove_manager.home_onto(src, thing_moving_towards, delay = 5, flags = MOVEMENT_LOOP_NO_DIR_UPDATE)
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(reached_destination_check))
RegisterSignal(thing_moving_towards, COMSIG_QDELETING, PROC_REF(on_machine_del))
diff --git a/code/game/objects/items/maintenance_loot.dm b/code/game/objects/items/maintenance_loot.dm
index 52ed1880081..f6d7fd1c329 100644
--- a/code/game/objects/items/maintenance_loot.dm
+++ b/code/game/objects/items/maintenance_loot.dm
@@ -30,7 +30,7 @@
icon_state = "lead_battery"
throwforce = 10
maxcharge = STANDARD_CELL_CHARGE * 20 //decent max charge
- chargerate = STANDARD_CELL_CHARGE * 0.7 //charging is about 30% less efficient than lithium batteries.
+ chargerate = STANDARD_CELL_RATE * 0.7 //charging is about 30% less efficient than lithium batteries.
charge_light_type = null
connector_type = "leadacid"
rating = 2 //Kind of a mid-tier battery
diff --git a/code/game/objects/items/rcd/RCD.dm b/code/game/objects/items/rcd/RCD.dm
index 91b51053b0e..88daf279c59 100644
--- a/code/game/objects/items/rcd/RCD.dm
+++ b/code/game/objects/items/rcd/RCD.dm
@@ -428,7 +428,7 @@
desc = "A device used to rapidly build walls and floors."
banned_upgrades = RCD_UPGRADE_SILO_LINK
/// enery usage
- var/energyfactor = 72 KILO JOULES
+ var/energyfactor = 0.072 * STANDARD_CELL_CHARGE
/obj/item/construction/rcd/borg/get_matter(mob/user)
if(!iscyborg(user))
@@ -470,7 +470,7 @@
desc = "A reverse-engineered RCD with black market upgrades that allow this device to deconstruct reinforced walls. Property of Donk Co."
icon_state = "ircd"
inhand_icon_state = "ircd"
- energyfactor = 66 KILO JOULES
+ energyfactor = 0.066 * STANDARD_CELL_CHARGE
canRturf = TRUE
/obj/item/construction/rcd/loaded
@@ -522,7 +522,7 @@
upgrade = RCD_ALL_UPGRADES & ~RCD_UPGRADE_SILO_LINK
///How much charge is used up for each matter unit.
-#define MASS_TO_ENERGY (16 KILO JOULES)
+#define MASS_TO_ENERGY (0.016 * STANDARD_CELL_CHARGE)
/obj/item/construction/rcd/exosuit
name = "mounted RCD"
diff --git a/code/game/objects/items/robot/items/food.dm b/code/game/objects/items/robot/items/food.dm
index 1878b0c1e00..40166a6a8fb 100644
--- a/code/game/objects/items/robot/items/food.dm
+++ b/code/game/objects/items/robot/items/food.dm
@@ -121,7 +121,7 @@
check_amount()
if(iscyborg(user))
var/mob/living/silicon/robot/robot_user = user
- if(!robot_user.cell.use(12 KILO JOULES))
+ if(!robot_user.cell.use(0.012 * STANDARD_CELL_CHARGE))
to_chat(user, span_warning("Not enough power."))
return AFTERATTACK_PROCESSED_ITEM
switch(mode)
diff --git a/code/game/objects/items/robot/items/hypo.dm b/code/game/objects/items/robot/items/hypo.dm
index 847807ee9f4..b685d5405f1 100644
--- a/code/game/objects/items/robot/items/hypo.dm
+++ b/code/game/objects/items/robot/items/hypo.dm
@@ -109,7 +109,7 @@
*/
var/max_volume_per_reagent = 30
/// Cell cost for charging a reagent
- var/charge_cost = 50 KILO JOULES
+ var/charge_cost = 0.05 * STANDARD_CELL_CHARGE
/// Counts up to the next time we charge
var/charge_timer = 0
/// Time it takes for shots to recharge (in seconds)
@@ -310,7 +310,7 @@ SKYRAT EDIT REMOVAL END */
Also metabolizes potassium iodide for radiation poisoning, inacusiate for ear damage and morphine for offense."
icon_state = "borghypo_s"
tgui_theme = "syndicate"
- charge_cost = 20 KILO JOULES
+ charge_cost = 0.02 * STANDARD_CELL_CHARGE
recharge_time = 2
default_reagent_types = BASE_SYNDICATE_REAGENTS
bypass_protection = TRUE
@@ -323,7 +323,7 @@ SKYRAT EDIT REMOVAL END */
icon_state = "shaker"
possible_transfer_amounts = list(5,10,20,1)
// Lots of reagents all regenerating at once, so the charge cost is lower. They also regenerate faster.
- charge_cost = 20 KILO JOULES
+ charge_cost = 0.02 * STANDARD_CELL_CHARGE
recharge_time = 3
dispensed_temperature = WATER_MATTERSTATE_CHANGE_TEMP //Water stays wet, ice stays ice
default_reagent_types = BASE_SERVICE_REAGENTS
@@ -395,7 +395,7 @@ SKYRAT EDIT REMOVAL END */
icon_state = "flour"
possible_transfer_amounts = list(5,10,20,1)
// Lots of reagents all regenerating at once, so the charge cost is lower. They also regenerate faster.
- charge_cost = 40 KILO JOULES //Costs double the power of the borgshaker due to synthesizing solids
+ charge_cost = 0.04 * STANDARD_CELL_CHARGE //Costs double the power of the borgshaker due to synthesizing solids
recharge_time = 6 //Double the recharge time too, for the same reason.
dispensed_temperature = WATER_MATTERSTATE_CHANGE_TEMP
default_reagent_types = EXPANDED_SERVICE_REAGENTS
diff --git a/code/game/objects/items/robot/items/tools.dm b/code/game/objects/items/robot/items/tools.dm
index 538fd1b7ca1..49c3197ae1e 100644
--- a/code/game/objects/items/robot/items/tools.dm
+++ b/code/game/objects/items/robot/items/tools.dm
@@ -1,5 +1,7 @@
#define PKBORG_DAMPEN_CYCLE_DELAY (2 SECONDS)
-#define POWER_RECHARGE_CYBORG_DRAIN_MULTIPLIER (0.4 KILO WATTS)
+#define POWER_RECHARGE_CYBORG_DRAIN_MULTIPLIER (0.0004 * STANDARD_CELL_RATE)
+#define NO_TOOL "deactivated"
+#define TOOL_DRAPES "surgical_drapes"
/obj/item/cautery/prt //it's a subtype of cauteries so that it inherits the cautery sprites and behavior and stuff, because I'm too lazy to make sprites for this thing
name = "plating repair tool"
@@ -174,5 +176,214 @@
projectile.speed *= (1 / projectile_speed_coefficient)
projectile.cut_overlay(projectile_effect)
+//bare minimum omni-toolset for modularity
+/obj/item/borg/cyborg_omnitool
+ name = "cyborg omni-toolset"
+ desc = "You shouldn't see this in-game normally."
+ icon = 'icons/mob/silicon/robot_items.dmi'
+ icon_state = "toolkit_medborg"
+ ///our tools
+ var/list/radial_menu_options = list()
+ ///object we are referencing to for force, sharpness and sound
+ var/obj/item/reference
+ //is the toolset upgraded or not
+ var/upgraded = FALSE
+ ///how much faster should the toolspeed be?
+ var/upgraded_toolspeed = 0.7
+
+/obj/item/borg/cyborg_omnitool/get_all_tool_behaviours()
+ return list(TOOL_SCALPEL, TOOL_HEMOSTAT)
+
+/obj/item/borg/cyborg_omnitool/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/butchering, \
+ speed = 8 SECONDS, \
+ effectiveness = 100, \
+ disabled = TRUE, \
+ )
+ radial_menu_options = list(
+ NO_TOOL = image(icon = 'icons/mob/silicon/robot_items.dmi', icon_state = initial(icon_state)),
+ TOOL_SCALPEL = image(icon = 'icons/obj/medical/surgery_tools.dmi', icon_state = "[TOOL_SCALPEL]"),
+ TOOL_HEMOSTAT = image(icon = 'icons/obj/medical/surgery_tools.dmi', icon_state = "[TOOL_HEMOSTAT]"),
+ )
+
+/obj/item/borg/cyborg_omnitool/attack_self(mob/user)
+ var/new_tool_behaviour = show_radial_menu(user, src, radial_menu_options, require_near = TRUE, tooltips = TRUE)
+
+ if(isnull(new_tool_behaviour) || new_tool_behaviour == tool_behaviour)
+ return
+ if(new_tool_behaviour == NO_TOOL)
+ tool_behaviour = null
+ else
+ tool_behaviour = new_tool_behaviour
+
+ reference_item_for_parameters()
+ update_tool_parameters(reference)
+ update_appearance(UPDATE_ICON_STATE)
+ playsound(src, 'sound/items/change_jaws.ogg', 50, TRUE)
+
+/// Used to get reference item for the tools
+/obj/item/borg/cyborg_omnitool/proc/reference_item_for_parameters()
+ SHOULD_CALL_PARENT(FALSE)
+ switch(tool_behaviour)
+ if(TOOL_SCALPEL)
+ reference = /obj/item/scalpel
+ if(TOOL_HEMOSTAT)
+ reference = /obj/item/hemostat
+
+/// Used to update sounds and tool parameters during switching
+/obj/item/borg/cyborg_omnitool/proc/update_tool_parameters(/obj/item/reference)
+ if(isnull(reference))
+ sharpness = NONE
+ force = initial(force)
+ hitsound = initial(hitsound)
+ usesound = initial(usesound)
+ else
+ force = initial(reference.force)
+ sharpness = initial(reference.sharpness)
+ hitsound = initial(reference.hitsound)
+ usesound = initial(reference.usesound)
+
+/obj/item/borg/cyborg_omnitool/update_icon_state()
+ icon_state = initial(icon_state)
+
+ if (tool_behaviour)
+ icon_state += "_[sanitize_css_class_name(tool_behaviour)]"
+
+ if(tool_behaviour)
+ inhand_icon_state = initial(inhand_icon_state) + "_deactivated"
+ else
+ inhand_icon_state = initial(inhand_icon_state)
+
+ return ..()
+
+/**
+ * proc that's used when cyborg is upgraded with an omnitool upgrade board
+ *
+ * adds name and desc changes. also changes tools to default configuration to indicate it's been sucessfully upgraded
+ * changes the toolspeed to the upgraded_toolspeed variable
+ */
+/obj/item/borg/cyborg_omnitool/proc/upgrade_omnitool()
+ name = "advanced [name]"
+ desc += "\nIt seems that this one has been upgraded to perform tasks faster."
+ toolspeed = upgraded_toolspeed
+ upgraded = TRUE
+ tool_behaviour = null
+ reference_item_for_parameters()
+ update_tool_parameters(reference)
+ update_appearance(UPDATE_ICON_STATE)
+ playsound(src, 'sound/items/change_jaws.ogg', 50, TRUE)
+
+/**
+ * proc that's used when a cyborg with an upgraded omnitool is downgraded
+ *
+ * reverts all name and desc changes to it's initial variables. also changes tools to default configuration to indicate it's been downgraded
+ * changes the toolspeed to default variable
+ */
+/obj/item/borg/cyborg_omnitool/proc/downgrade_omnitool()
+ name = initial(name)
+ desc = initial(desc)
+ toolspeed = initial(toolspeed)
+ upgraded = FALSE
+ tool_behaviour = null
+ reference_item_for_parameters()
+ update_tool_parameters(reference)
+ update_appearance(UPDATE_ICON_STATE)
+ playsound(src, 'sound/items/change_jaws.ogg', 50, TRUE)
+
+/obj/item/borg/cyborg_omnitool/medical
+ name = "surgical omni-toolset"
+ desc = "A set of surgical tools used by cyborgs to operate on various surgical operations."
+ item_flags = SURGICAL_TOOL
+
+/obj/item/borg/cyborg_omnitool/medical/get_all_tool_behaviours()
+ return list(TOOL_SCALPEL, TOOL_HEMOSTAT, TOOL_RETRACTOR, TOOL_SAW, TOOL_DRILL, TOOL_CAUTERY, TOOL_BONESET)
+
+/obj/item/borg/cyborg_omnitool/medical/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/butchering, \
+ speed = 8 SECONDS, \
+ effectiveness = 100, \
+ disabled = TRUE, \
+ )
+ radial_menu_options = list(
+ TOOL_SCALPEL = image(icon = 'icons/obj/medical/surgery_tools.dmi', icon_state = "[TOOL_SCALPEL]"),
+ TOOL_HEMOSTAT = image(icon = 'icons/obj/medical/surgery_tools.dmi', icon_state = "[TOOL_HEMOSTAT]"),
+ TOOL_RETRACTOR = image(icon = 'icons/obj/medical/surgery_tools.dmi', icon_state = "[TOOL_RETRACTOR]"),
+ TOOL_SAW = image(icon = 'icons/obj/medical/surgery_tools.dmi', icon_state = "[TOOL_SAW]"),
+ TOOL_DRILL = image(icon = 'icons/obj/medical/surgery_tools.dmi', icon_state = "[TOOL_DRILL]"),
+ TOOL_CAUTERY = image(icon = 'icons/obj/medical/surgery_tools.dmi', icon_state = "[TOOL_CAUTERY]"),
+ TOOL_BONESET = image(icon = 'icons/obj/medical/surgery_tools.dmi', icon_state = "[TOOL_BONESET]"),
+ TOOL_DRAPES = image(icon = 'icons/obj/medical/surgery_tools.dmi', icon_state = "[TOOL_DRAPES]"),
+ )
+
+/obj/item/borg/cyborg_omnitool/medical/reference_item_for_parameters()
+ var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering)
+ butchering.butchering_enabled = (tool_behaviour == TOOL_SCALPEL || tool_behaviour == TOOL_SAW)
+ RemoveElement(/datum/element/eyestab)
+ qdel(GetComponent(/datum/component/surgery_initiator))
+ item_flags = SURGICAL_TOOL
+ switch(tool_behaviour)
+ if(TOOL_SCALPEL)
+ reference = /obj/item/scalpel
+ AddElement(/datum/element/eyestab)
+ if(TOOL_DRILL)
+ reference = /obj/item/surgicaldrill
+ AddElement(/datum/element/eyestab)
+ if(TOOL_HEMOSTAT)
+ reference = /obj/item/hemostat
+ if(TOOL_RETRACTOR)
+ reference = /obj/item/retractor
+ if(TOOL_CAUTERY)
+ reference = /obj/item/cautery
+ if(TOOL_SAW)
+ reference = /obj/item/circular_saw
+ if(TOOL_BONESET)
+ reference = /obj/item/bonesetter
+ if(TOOL_DRAPES)
+ reference = /obj/item/surgical_drapes
+ AddComponent(/datum/component/surgery_initiator)
+ item_flags = null
+
+//Toolset for engineering cyborgs, this is all of the tools except for the welding tool. since it's quite hard to implement (read:can't be arsed to)
+/obj/item/borg/cyborg_omnitool/engineering
+ name = "engineering omni-toolset"
+ desc = "A set of engineering tools used by cyborgs to conduct various engineering tasks."
+ icon = 'icons/obj/items_cyborg.dmi'
+ icon_state = "toolkit_engiborg"
+ item_flags = null
+ toolspeed = 0.5
+ upgraded_toolspeed = 0.3
+
+/obj/item/borg/cyborg_omnitool/engineering/get_all_tool_behaviours()
+ return list(TOOL_SCREWDRIVER, TOOL_CROWBAR, TOOL_WRENCH, TOOL_WIRECUTTER, TOOL_MULTITOOL)
+
+/obj/item/borg/cyborg_omnitool/engineering/Initialize(mapload)
+ . = ..()
+ radial_menu_options = list(
+ TOOL_SCREWDRIVER = image(icon = 'icons/obj/tools.dmi', icon_state = "[TOOL_SCREWDRIVER]_map"),
+ TOOL_CROWBAR = image(icon = 'icons/obj/tools.dmi', icon_state = "[TOOL_CROWBAR]"),
+ TOOL_WRENCH = image(icon = 'icons/obj/tools.dmi', icon_state = "[TOOL_WRENCH]"),
+ TOOL_WIRECUTTER = image(icon = 'icons/obj/tools.dmi', icon_state = "[TOOL_WIRECUTTER]_map"),
+ TOOL_MULTITOOL = image(icon = 'icons/obj/devices/tool.dmi', icon_state = "[TOOL_MULTITOOL]"),
+ )
+
+/obj/item/borg/cyborg_omnitool/engineering/reference_item_for_parameters()
+ RemoveElement(/datum/element/eyestab)
+ switch(tool_behaviour)
+ if(TOOL_SCREWDRIVER)
+ reference = /obj/item/crowbar
+ AddElement(/datum/element/eyestab)
+ if(TOOL_CROWBAR)
+ reference = /obj/item/surgicaldrill
+ if(TOOL_WRENCH)
+ reference = /obj/item/wrench
+ if(TOOL_WIRECUTTER)
+ reference = /obj/item/wirecutters
+ if(TOOL_MULTITOOL)
+ reference = /obj/item/multitool
+
#undef PKBORG_DAMPEN_CYCLE_DELAY
#undef POWER_RECHARGE_CYBORG_DRAIN_MULTIPLIER
+#undef NO_TOOL
+#undef TOOL_DRAPES
diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm
index 885a97a9329..666ae97105f 100644
--- a/code/game/objects/items/robot/robot_upgrades.dm
+++ b/code/game/objects/items/robot/robot_upgrades.dm
@@ -298,7 +298,7 @@
/// Minimum time between repairs in seconds
var/repair_cooldown = 4
var/on = FALSE
- var/energy_cost = 10 KILO JOULES
+ var/energy_cost = 0.01 * STANDARD_CELL_CHARGE
var/datum/action/toggle_action
/obj/item/borg/upgrade/selfrepair/action(mob/living/silicon/robot/R, user = usr)
@@ -366,16 +366,16 @@
if(cyborg.health < cyborg.maxHealth)
if(cyborg.health < 0)
repair_amount = -2.5
- energy_cost = 30 KILO JOULES
+ energy_cost = 0.03 * STANDARD_CELL_CHARGE
else
repair_amount = -1
- energy_cost = 10 KILO JOULES
+ energy_cost = 0.01 * STANDARD_CELL_CHARGE
cyborg.adjustBruteLoss(repair_amount)
cyborg.adjustFireLoss(repair_amount)
cyborg.updatehealth()
cyborg.cell.use(energy_cost)
else
- cyborg.cell.use(5 KILO JOULES)
+ cyborg.cell.use(0.005 * STANDARD_CELL_CHARGE)
next_repair = world.time + repair_cooldown * 10 // Multiply by 10 since world.time is in deciseconds
if(TIMER_COOLDOWN_FINISHED(src, COOLDOWN_BORG_SELF_REPAIR))
@@ -444,6 +444,60 @@
for(var/obj/item/reagent_containers/borghypo/H in R.model.modules)
H.bypass_protection = initial(H.bypass_protection)
+/obj/item/borg/upgrade/surgery_omnitool
+ name = "cyborg surgical omni-tool upgrade"
+ desc = "An upgrade to the Medical model, upgrading the built-in \
+ surgical omnitool, to be on par with advanced surgical tools"
+ icon_state = "cyborg_upgrade3"
+ require_model = TRUE
+ model_type = list(/obj/item/robot_model/medical, /obj/item/robot_model/syndicate_medical)
+ model_flags = BORG_MODEL_MEDICAL
+
+/obj/item/borg/upgrade/surgery_omnitool/action(mob/living/silicon/robot/cyborg, user = usr)
+ . = ..()
+ if(!.)
+ return FALSE
+ for(var/obj/item/borg/cyborg_omnitool/medical/omnitool_upgrade in cyborg.model.modules)
+ if(omnitool_upgrade.upgraded)
+ to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!"))
+ return FALSE
+ for(var/obj/item/borg/cyborg_omnitool/medical/omnitool in cyborg.model.modules)
+ omnitool.upgrade_omnitool()
+
+/obj/item/borg/upgrade/surgery_omnitool/deactivate(mob/living/silicon/robot/cyborg, user = usr)
+ . = ..()
+ if(!.)
+ return FALSE
+ for(var/obj/item/borg/cyborg_omnitool/omnitool in cyborg.model.modules)
+ omnitool.downgrade_omnitool()
+
+/obj/item/borg/upgrade/engineering_omnitool
+ name = "cyborg engineering omni-tool upgrade"
+ desc = "An upgrade to the Engineering model, upgrading the built-in \
+ engineering omnitool, to be on par with advanced engineering tools"
+ icon_state = "cyborg_upgrade3"
+ require_model = TRUE
+ model_type = list(/obj/item/robot_model/engineering, /obj/item/robot_model/saboteur)
+ model_flags = BORG_MODEL_ENGINEERING
+
+/obj/item/borg/upgrade/engineering_omnitool/action(mob/living/silicon/robot/cyborg, user = usr)
+ . = ..()
+ if(!.)
+ return FALSE
+ for(var/obj/item/borg/cyborg_omnitool/engineering/omnitool_upgrade in cyborg.model.modules)
+ if(omnitool_upgrade.upgraded)
+ to_chat(user, span_warning("This unit is already equipped with an omnitool upgrade!"))
+ return FALSE
+ for(var/obj/item/borg/cyborg_omnitool/engineering/omnitool in cyborg.model.modules)
+ omnitool.upgrade_omnitool()
+
+/obj/item/borg/upgrade/engineering_omnitool/deactivate(mob/living/silicon/robot/cyborg, user = usr)
+ . = ..()
+ if(!.)
+ return FALSE
+ for(var/obj/item/borg/cyborg_omnitool/omnitool in cyborg.model.modules)
+ omnitool.downgrade_omnitool()
+
/obj/item/borg/upgrade/defib
name = "medical cyborg defibrillator"
desc = "An upgrade to the Medical model, installing a built-in \
diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm
index 66dd5a34b6a..2cc41b5d9f2 100644
--- a/code/game/objects/items/shields.dm
+++ b/code/game/objects/items/shields.dm
@@ -99,6 +99,15 @@
max_integrity = 55
w_class = WEIGHT_CLASS_NORMAL
+/obj/item/shield/kite
+ name = "kite shield"
+ desc = "Protect your internal organs with this almond shaped shield."
+ icon_state = "kite"
+ inhand_icon_state = "kite"
+ custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT * 15)
+ shield_break_sound = 'sound/effects/grillehit.ogg'
+ max_integrity = 60
+
/obj/item/shield/roman
name = "\improper Roman shield"
desc = "Bears an inscription on the inside: \"Romanes venio domus\"."
diff --git a/code/game/objects/items/spear.dm b/code/game/objects/items/spear.dm
index 401ffd46934..f4c0b58a11b 100644
--- a/code/game/objects/items/spear.dm
+++ b/code/game/objects/items/spear.dm
@@ -216,6 +216,31 @@
M.Copy_Parent(user, 100, user.health/2.5, 12, 30)
M.GiveTarget(L)
+//MILITARY
+/obj/item/spear/military
+ icon_state = "military_spear0"
+ base_icon_state = "military_spear0"
+ icon_prefix = "military_spear"
+ name = "military Javelin"
+ desc = "A stick with a seemingly blunt spearhead on its end. Looks like it might break bones easily."
+ attack_verb_continuous = list("attacks", "pokes", "jabs")
+ attack_verb_simple = list("attack", "poke", "jab")
+ throwforce = 30
+ demolition_mod = 1
+ wound_bonus = 5
+ bare_wound_bonus = 25
+ throw_range = 9
+ throw_speed = 5
+ sharpness = NONE // we break bones instead of cutting flesh
+
+/obj/item/spear/military/add_headpike_component()
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/headpikemilitary)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
/*
* Bone Spear
*/
diff --git a/code/game/objects/items/stacks/golem_food/golem_status_effects.dm b/code/game/objects/items/stacks/golem_food/golem_status_effects.dm
index c55a39c20f7..bf2c628ab97 100644
--- a/code/game/objects/items/stacks/golem_food/golem_status_effects.dm
+++ b/code/game/objects/items/stacks/golem_food/golem_status_effects.dm
@@ -160,6 +160,11 @@
owner.remove_traits(list(TRAIT_ANTIMAGIC, TRAIT_HOLY), TRAIT_STATUS_EFFECT(id))
return ..()
+/// What do we multiply our damage by to convert it into power?
+#define ENERGY_PER_DAMAGE (0.005 * STANDARD_CELL_CHARGE)
+/// Multiplier to apply to burn damage, not 0 so that we can reverse it more easily
+#define BURN_MULTIPLIER 0.05
+
/// Heat immunity, turns heat damage into local power
/datum/status_effect/golem/plasma
overlay_state_prefix = "plasma"
@@ -167,10 +172,6 @@
applied_fluff = "Plasma cooling rods sprout from your body. You can take the heat!"
alert_icon_state = "sheet-plasma"
alert_desc = "You are protected from high pressure and can convert heat damage into power."
- /// What do we multiply our damage by to convert it into power?
- var/energy_per_damage = 5 KILO JOULES
- /// Multiplier to apply to burn damage, not 0 so that we can reverse it more easily
- var/burn_multiplier = 0.05
/datum/status_effect/golem/plasma/on_apply()
. = ..()
@@ -179,14 +180,14 @@
owner.add_traits(list(TRAIT_RESISTHIGHPRESSURE, TRAIT_RESISTHEAT, TRAIT_ASHSTORM_IMMUNE), TRAIT_STATUS_EFFECT(id))
RegisterSignal(owner, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(on_burned))
var/mob/living/carbon/human/human_owner = owner
- human_owner.physiology.burn_mod *= burn_multiplier
+ human_owner.physiology.burn_mod *= BURN_MULTIPLIER
return TRUE
/datum/status_effect/golem/plasma/on_remove()
owner.remove_traits(list(TRAIT_RESISTHIGHPRESSURE, TRAIT_RESISTHEAT, TRAIT_ASHSTORM_IMMUNE), TRAIT_STATUS_EFFECT(id))
UnregisterSignal(owner, COMSIG_MOB_APPLY_DAMAGE)
var/mob/living/carbon/human/human_owner = owner
- human_owner.physiology.burn_mod /= burn_multiplier
+ human_owner.physiology.burn_mod /= BURN_MULTIPLIER
return ..()
/// When we take fire damage (or... technically also cold damage, we don't differentiate), zap a nearby APC
@@ -195,7 +196,6 @@
if(damagetype != BURN)
return
- var/power = damage * energy_per_damage
var/obj/machinery/power/energy_accumulator/ground = get_closest_atom(/obj/machinery/power/energy_accumulator, view(4, owner), owner)
if (ground)
zap_effect(ground)
@@ -206,7 +206,10 @@
if (!our_apc)
return
zap_effect(our_apc)
- our_apc.cell?.give(power)
+ our_apc.cell?.give(damage * ENERGY_PER_DAMAGE)
+
+#undef ENERGY_PER_DAMAGE
+#undef BURN_MULTIPLIER
/// Shoot a beam at the target atom
/datum/status_effect/golem/plasma/proc/zap_effect(atom/target)
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index 18a95cd77d3..83235796a45 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -110,9 +110,9 @@
for(var/category in what_are_we_made_of.categories)
switch(category)
if(MAT_CATEGORY_BASE_RECIPES)
- recipes |= SSmaterials.base_stack_recipes.Copy()
+ recipes |= DSmaterials.base_stack_recipes.Copy()
if(MAT_CATEGORY_RIGID)
- recipes |= SSmaterials.rigid_stack_recipes.Copy()
+ recipes |= DSmaterials.rigid_stack_recipes.Copy()
update_weight()
update_appearance()
@@ -131,7 +131,7 @@
* - multiplier: The amount to multiply the mats per unit by. Defaults to 1.
*/
/obj/item/stack/proc/set_mats_per_unit(list/mats, multiplier=1)
- mats_per_unit = SSmaterials.FindOrCreateMaterialCombo(mats, multiplier)
+ mats_per_unit = DSmaterials.FindOrCreateMaterialCombo(mats, multiplier)
update_custom_materials()
/** Updates the custom materials list of this stack.
diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm
index cc548be16d2..dd4fb325858 100644
--- a/code/game/objects/items/storage/bags.dm
+++ b/code/game/objects/items/storage/bags.dm
@@ -406,7 +406,7 @@
/obj/item/storage/bag/tray/proc/do_scatter(obj/item/tray_item)
var/delay = rand(2,4)
- var/datum/move_loop/loop = SSmove_manager.move_rand(tray_item, list(NORTH,SOUTH,EAST,WEST), delay, timeout = rand(1, 2) * delay, flags = MOVEMENT_LOOP_START_FAST)
+ var/datum/move_loop/loop = DSmove_manager.move_rand(tray_item, list(NORTH,SOUTH,EAST,WEST), delay, timeout = rand(1, 2) * delay, flags = MOVEMENT_LOOP_START_FAST)
//This does mean scattering is tied to the tray. Not sure how better to handle it
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(change_speed))
diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm
index ebfa73aa2f9..a2c553fbea1 100644
--- a/code/game/objects/items/storage/belt.dm
+++ b/code/game/objects/items/storage/belt.dm
@@ -839,7 +839,7 @@
inhand_icon_state = "sheath"
worn_icon_state = "sheath"
w_class = WEIGHT_CLASS_BULKY
- interaction_flags_click = NEED_DEXTERITY|NEED_HANDS
+ interaction_flags_click = parent_type::interaction_flags_click | NEED_DEXTERITY | NEED_HANDS
/obj/item/storage/belt/sabre/Initialize(mapload)
. = ..()
diff --git a/code/game/objects/items/storage/storage.dm b/code/game/objects/items/storage/storage.dm
index 8631d62e79e..75ca06ff0ff 100644
--- a/code/game/objects/items/storage/storage.dm
+++ b/code/game/objects/items/storage/storage.dm
@@ -2,6 +2,7 @@
name = "storage"
icon = 'icons/obj/storage/storage.dmi'
w_class = WEIGHT_CLASS_NORMAL
+ interaction_flags_click = ALLOW_RESTING|FORBID_TELEKINESIS_REACH
var/rummage_if_nodrop = TRUE
/// Should we preload the contents of this type?
/// BE CAREFUL, THERE'S SOME REALLY NASTY SHIT IN THIS TYPEPATH
diff --git a/code/game/objects/items/tanks/tank_types.dm b/code/game/objects/items/tanks/tank_types.dm
index b21deb35581..70c0ea0822a 100644
--- a/code/game/objects/items/tanks/tank_types.dm
+++ b/code/game/objects/items/tanks/tank_types.dm
@@ -8,7 +8,7 @@
* Generic
*/
/obj/item/tank/internals
- interaction_flags_click = FORBID_TELEKINESIS_REACH|NEED_HANDS
+ interaction_flags_click = FORBID_TELEKINESIS_REACH|NEED_HANDS|ALLOW_RESTING
/// Allows carbon to toggle internals via AltClick of the equipped tank.
diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm
index 9950b8e9c93..5cef642634a 100644
--- a/code/game/objects/items/tanks/watertank.dm
+++ b/code/game/objects/items/tanks/watertank.dm
@@ -309,7 +309,7 @@
user.log_message("used Resin Launcher", LOG_GAME)
playsound(src,'sound/items/syringeproj.ogg',40,TRUE)
var/delay = 2
- var/datum/move_loop/loop = SSmove_manager.move_towards(resin, target, delay, timeout = delay * 5, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
+ var/datum/move_loop/loop = DSmove_manager.move_towards(resin, target, delay, timeout = delay * 5, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(resin_stop_check))
RegisterSignal(loop, COMSIG_QDELETING, PROC_REF(resin_landed))
return
diff --git a/code/game/objects/items/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm
index 56d7344f31b..9bb61e847b7 100644
--- a/code/game/objects/items/tools/crowbar.dm
+++ b/code/game/objects/items/tools/crowbar.dm
@@ -189,7 +189,7 @@
name = "hydraulic crowbar"
desc = "A hydraulic prying tool, simple but powerful."
icon = 'icons/obj/items_cyborg.dmi'
- icon_state = "crowbar_cyborg"
+ icon_state = "toolkit_engiborg_crowbar"
worn_icon_state = "crowbar"
usesound = 'sound/items/jaws_pry.ogg'
force = 10
diff --git a/code/game/objects/items/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm
index cbdc79e0420..02765122a13 100644
--- a/code/game/objects/items/tools/screwdriver.dm
+++ b/code/game/objects/items/tools/screwdriver.dm
@@ -148,7 +148,7 @@
name = "automated screwdriver"
desc = "A powerful automated screwdriver, designed to be both precise and quick."
icon = 'icons/obj/items_cyborg.dmi'
- icon_state = "screwdriver_cyborg"
+ icon_state = "toolkit_engiborg_screwdriver"
hitsound = 'sound/items/drill_hit.ogg'
usesound = 'sound/items/drill_use.ogg'
toolspeed = 0.5
diff --git a/code/game/objects/items/tools/wirecutters.dm b/code/game/objects/items/tools/wirecutters.dm
index dad9763bd3d..e7e4dbe699a 100644
--- a/code/game/objects/items/tools/wirecutters.dm
+++ b/code/game/objects/items/tools/wirecutters.dm
@@ -77,7 +77,7 @@
name = "powered wirecutters"
desc = "Cuts wires with the power of ELECTRICITY. Faster than normal wirecutters."
icon = 'icons/obj/items_cyborg.dmi'
- icon_state = "wirecutters_cyborg"
+ icon_state = "toolkit_engiborg_cutters"
worn_icon_state = "cutters"
toolspeed = 0.5
random_color = FALSE
diff --git a/code/game/objects/items/tools/wrench.dm b/code/game/objects/items/tools/wrench.dm
index c4326cf3de8..8fbb681acfc 100644
--- a/code/game/objects/items/tools/wrench.dm
+++ b/code/game/objects/items/tools/wrench.dm
@@ -87,7 +87,7 @@
name = "hydraulic wrench"
desc = "An advanced robotic wrench, powered by internal hydraulics. Twice as fast as the handheld version."
icon = 'icons/obj/items_cyborg.dmi'
- icon_state = "wrench_cyborg"
+ icon_state = "toolkit_engiborg_wrench"
toolspeed = 0.5
/obj/item/wrench/combat
diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm
index 2aa649844e5..f7717da19e7 100644
--- a/code/game/objects/items/weaponry.dm
+++ b/code/game/objects/items/weaponry.dm
@@ -175,6 +175,18 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
block_chance = 10
resistance_flags = NONE
+//bootleg claymore
+/obj/item/claymore/shortsword
+ name = "shortsword"
+ desc = "A mercenary's sword, chipped and worn from battles long gone. You could say it is a swordsman's shortsword short sword."
+ icon_state = "shortsword"
+ inhand_icon_state = "shortsword"
+ worn_icon_state = "shortsword"
+ slot_flags = ITEM_SLOT_BELT
+ force = 20
+ demolition_mod = 0.75
+ block_chance = 30
+
/obj/item/claymore/highlander //ALL COMMENTS MADE REGARDING THIS SWORD MUST BE MADE IN ALL CAPS
desc = "THERE CAN BE ONLY ONE, AND IT WILL BE YOU!!!\nActivate it in your hand to point to the nearest victim."
obj_flags = CONDUCTS_ELECTRICITY
diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm
index 8b4fef65293..ba2a8685b8b 100644
--- a/code/game/objects/structures/bedsheet_bin.dm
+++ b/code/game/objects/structures/bedsheet_bin.dm
@@ -20,7 +20,7 @@ LINEN BINS
w_class = WEIGHT_CLASS_TINY
resistance_flags = FLAMMABLE
dying_key = DYE_REGISTRY_BEDSHEET
- interaction_flags_click = NEED_DEXTERITY
+ interaction_flags_click = NEED_DEXTERITY|ALLOW_RESTING
dog_fashion = /datum/dog_fashion/head/ghost
/// Custom nouns to act as the subject of dreams
diff --git a/code/game/objects/structures/gym/punching_bag.dm b/code/game/objects/structures/gym/punching_bag.dm
index f441887f2c1..ef0db16e953 100644
--- a/code/game/objects/structures/gym/punching_bag.dm
+++ b/code/game/objects/structures/gym/punching_bag.dm
@@ -57,9 +57,12 @@
stamina_exhaustion = 2
if (is_heavy_gravity)
stamina_exhaustion *= 1.5
+
+ if(HAS_TRAIT(user, TRAIT_STRENGTH)) //The strong get reductions to stamina damage taken while exercising
+ stamina_exhaustion *= 0.5
user.adjustStaminaLoss(stamina_exhaustion)
- user.mind?.adjust_experience(/datum/skill/fitness, is_heavy_gravity ? 0.2 : 0.1)
+ user.mind?.adjust_experience(/datum/skill/athletics, is_heavy_gravity ? 0.2 : 0.1)
user.apply_status_effect(/datum/status_effect/exercised)
/obj/structure/punching_bag/wrench_act_secondary(mob/living/user, obj/item/tool)
diff --git a/code/game/objects/structures/gym/weight_machine.dm b/code/game/objects/structures/gym/weight_machine.dm
index d3614ee6815..3c531f04889 100644
--- a/code/game/objects/structures/gym/weight_machine.dm
+++ b/code/game/objects/structures/gym/weight_machine.dm
@@ -109,7 +109,7 @@
if(do_after(user, 8 SECONDS, src) && user.has_gravity())
// with enough dedication, even clowns can overcome their handicaps
- var/clumsy_chance = 30 - (user.mind.get_skill_level(/datum/skill/fitness) * 5)
+ var/clumsy_chance = 30 - (user.mind.get_skill_level(/datum/skill/athletics) * 5)
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(clumsy_chance))
playsound(src, 'sound/effects/bang.ogg', 50, TRUE)
to_chat(user, span_warning("Your hand slips, causing the [name] to smash you!"))
@@ -135,7 +135,7 @@
if(iscarbon(user))
var/gravity_modifier = user.has_gravity() > STANDARD_GRAVITY ? 2 : 1
// remember the real xp gain is from sleeping after working out
- user.mind.adjust_experience(/datum/skill/fitness, WORKOUT_XP * gravity_modifier)
+ user.mind.adjust_experience(/datum/skill/athletics, WORKOUT_XP * gravity_modifier)
user.apply_status_effect(/datum/status_effect/exercised, EXERCISE_STATUS_DURATION)
end_workout()
@@ -168,9 +168,13 @@
return TRUE // No weight? I could do this all day
var/gravity_modifier = affected_gravity > STANDARD_GRAVITY ? 0.75 : 1
// the amount of workouts you can do before you hit stamcrit
- var/workout_reps = total_workout_reps[user.mind.get_skill_level(/datum/skill/fitness)] * gravity_modifier
+ var/workout_reps = total_workout_reps[user.mind.get_skill_level(/datum/skill/athletics)] * gravity_modifier
// total stamina drain of 1 workout calculated based on the workout length
var/stamina_exhaustion = FLOOR(user.maxHealth / workout_reps / WORKOUT_LENGTH, 0.1)
+
+ if(HAS_TRAIT(user, TRAIT_STRENGTH)) //The strong get reductions to stamina damage taken while exercising
+ stamina_exhaustion *= 0.5
+
user.adjustStaminaLoss(stamina_exhaustion * seconds_per_tick)
return TRUE
diff --git a/code/game/objects/structures/headpike.dm b/code/game/objects/structures/headpike.dm
index 0c29d92d53b..b4cffdb654d 100644
--- a/code/game/objects/structures/headpike.dm
+++ b/code/game/objects/structures/headpike.dm
@@ -17,6 +17,10 @@
icon_state = "headpike-bamboo"
speartype = /obj/item/spear/bamboospear
+/obj/structure/headpike/military //for military spears
+ icon_state = "headpike-military"
+ speartype = /obj/item/spear/military
+
/obj/structure/headpike/Initialize(mapload)
. = ..()
if(mapload)
diff --git a/code/game/objects/structures/lavaland/gulag_vent.dm b/code/game/objects/structures/lavaland/gulag_vent.dm
index aa13a1621d8..b564908cdc6 100644
--- a/code/game/objects/structures/lavaland/gulag_vent.dm
+++ b/code/game/objects/structures/lavaland/gulag_vent.dm
@@ -34,9 +34,10 @@
occupied = FALSE
if (!succeeded)
return
- living_user.mind?.adjust_experience(/datum/skill/fitness, 10)
+ var/stamina_damage_to_inflict = HAS_TRAIT(user, TRAIT_STRENGTH) ? 60 : 120 //Decreases the amount of stamina damage inflicted by half if you're STRONG
+ living_user.mind?.adjust_experience(/datum/skill/athletics, 10)
living_user.apply_status_effect(/datum/status_effect/exercised)
new spawned_boulder(get_turf(living_user))
living_user.visible_message(span_notice("[living_user] hauls a boulder out of [src]."))
- living_user.apply_damage(120, STAMINA)
+ living_user.apply_damage(stamina_damage_to_inflict, STAMINA)
playsound(src, 'sound/weapons/genhit.ogg', vol = 50, vary = TRUE)
diff --git a/code/game/objects/structures/lavaland/ore_vent.dm b/code/game/objects/structures/lavaland/ore_vent.dm
index 70ab15427b7..a6ab8a58d70 100644
--- a/code/game/objects/structures/lavaland/ore_vent.dm
+++ b/code/game/objects/structures/lavaland/ore_vent.dm
@@ -270,6 +270,7 @@
balloon_alert_to_viewers("vent tapped!")
icon_state = icon_state_tapped
update_appearance(UPDATE_ICON_STATE)
+ qdel(GetComponent(/datum/component/gps))
else
visible_message(span_danger("\the [src] creaks and groans as the mining attempt fails, and the vent closes back up."))
icon_state = initial(icon_state)
@@ -308,6 +309,7 @@
discovered = TRUE
generate_description(user)
balloon_alert_to_viewers("vent scanned!")
+ AddComponent(/datum/component/gps, name)
return
if(DOING_INTERACTION_WITH_TARGET(user, src))
@@ -321,6 +323,7 @@
discovered = TRUE
balloon_alert(user, "vent scanned!")
generate_description(user)
+ AddComponent(/datum/component/gps, name)
var/obj/item/card/id/user_id_card = user.get_idcard(TRUE)
if(isnull(user_id_card))
return
diff --git a/code/game/objects/structures/mystery_box.dm b/code/game/objects/structures/mystery_box.dm
index 1843ef99761..ab8a25f04c6 100644
--- a/code/game/objects/structures/mystery_box.dm
+++ b/code/game/objects/structures/mystery_box.dm
@@ -67,6 +67,32 @@ GLOBAL_LIST_INIT(mystery_box_extended, list(
/obj/item/circular_saw,
))
+GLOBAL_LIST_INIT(mystery_magic, list(
+ /obj/item/gun/magic/wand/arcane_barrage,
+ /obj/item/gun/magic/wand/arcane_barrage/blood,
+ /obj/item/gun/magic/wand/fireball,
+ /obj/item/gun/magic/wand/resurrection,
+ /obj/item/gun/magic/wand/death,
+ /obj/item/gun/magic/wand/polymorph,
+ /obj/item/gun/magic/wand/teleport,
+ /obj/item/gun/magic/wand/door,
+ /obj/item/gun/magic/wand/nothing,
+ /obj/item/storage/belt/wands/full,
+ /obj/item/gun/magic/staff/healing,
+ /obj/item/gun/magic/staff/change,
+ /obj/item/gun/magic/staff/animate,
+ /obj/item/gun/magic/staff/chaos,
+ /obj/item/gun/magic/staff/door,
+ /obj/item/gun/magic/staff/honk,
+ /obj/item/gun/magic/staff/spellblade,
+ /obj/item/gun/magic/staff/locker,
+ /obj/item/gun/magic/staff/flying,
+ /obj/item/gun/magic/staff/babel,
+ /obj/item/singularityhammer,
+ /obj/item/mod/control/pre_equipped/enchanted,
+ /obj/item/runic_vendor_scepter,
+))
+
/obj/structure/mystery_box
name = "mystery box"
@@ -207,6 +233,12 @@ GLOBAL_LIST_INIT(mystery_box_extended, list(
/obj/structure/mystery_box/tdome/generate_valid_types()
valid_types = GLOB.mystery_box_guns + GLOB.mystery_box_extended
+/obj/structure/mystery_box/wands
+ desc = "A wooden crate that seems equally magical and mysterious, capable of granting the user all kinds of different magical items."
+
+/obj/structure/mystery_box/wands/generate_valid_types()
+ valid_types = GLOB.mystery_magic
+
/// This represents the item that comes out of the box and is constantly changing before the box finishes deciding. Can probably be just an /atom or /movable.
/obj/mystery_box_item
diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
index b1168302f68..48848df0fd5 100644
--- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
+++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
@@ -94,7 +94,7 @@
moving = TRUE
current_tube = tube
- var/datum/move_loop/engine = SSmove_manager.force_move_dir(src, dir, 0, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
+ var/datum/move_loop/engine = DSmove_manager.force_move_dir(src, dir, 0, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
RegisterSignal(engine, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(before_pipe_transfer))
RegisterSignal(engine, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(after_pipe_transfer))
RegisterSignal(engine, COMSIG_QDELETING, PROC_REF(engine_finish))
diff --git a/code/game/turfs/open/lava.dm b/code/game/turfs/open/lava.dm
index 8165b35a256..02c714c25ff 100644
--- a/code/game/turfs/open/lava.dm
+++ b/code/game/turfs/open/lava.dm
@@ -40,6 +40,8 @@
var/mask_state = "lava-lightmask"
/// The type for the preset fishing spot of this type of turf.
var/fish_source_type = /datum/fish_source/lavaland
+ /// The color we use for our immersion overlay
+ var/immerse_overlay_color = "#a15e1b"
/turf/open/lava/Initialize(mapload)
. = ..()
@@ -48,7 +50,7 @@
refresh_light()
if(!smoothing_flags)
update_appearance()
-
+ AddElement(/datum/element/immerse, icon, icon_state, "immerse", immerse_overlay_color)
/turf/open/lava/Destroy()
for(var/mob/living/leaving_mob in contents)
@@ -337,6 +339,7 @@
smoothing_groups = SMOOTH_GROUP_TURF_OPEN + SMOOTH_GROUP_FLOOR_LAVA
canSmoothWith = SMOOTH_GROUP_FLOOR_LAVA
underfloor_accessibility = 2 //This avoids strangeness when routing pipes / wires along catwalks over lava
+ immerse_overlay_color = "#F98511"
/turf/open/lava/smooth/lava_land_surface
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
@@ -360,6 +363,7 @@
immunity_trait = TRAIT_SNOWSTORM_IMMUNE
immunity_resistance_flags = FREEZE_PROOF
lava_temperature = 100
+ immerse_overlay_color = "#CD4C9F"
/turf/open/lava/plasma/examine(mob/user)
. = ..()
diff --git a/code/game/world.dm b/code/game/world.dm
index 53f3a0fe95d..a7391f2ab15 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -17,6 +17,7 @@ GLOBAL_VAR(restart_counter)
* - world.init_byond_tracy()
* - (Start native profiling)
* - world.init_debugger()
+ * - SysMgr (all data systems)
* - Master =>
* - config *unloaded
* - (all subsystems) PreInit()
@@ -84,6 +85,9 @@ GLOBAL_VAR(restart_counter)
// Create the logger
logger = new
+ // Initialize all the data systems
+ SysMgr = new
+
// THAT'S IT, WE'RE DONE, THE. FUCKING. END.
Master = new
diff --git a/code/modules/admin/verbs/adminevents.dm b/code/modules/admin/verbs/adminevents.dm
index 32e49cf2e73..fe62bb97d81 100644
--- a/code/modules/admin/verbs/adminevents.dm
+++ b/code/modules/admin/verbs/adminevents.dm
@@ -253,11 +253,11 @@ ADMIN_VERB(run_weather, R_FUN, "Run Weather", "Triggers specific weather on the
ADMIN_VERB(command_report_footnote, R_ADMIN, "Command Report Footnote", "Adds a footnote to the roundstart command report.", ADMIN_CATEGORY_EVENTS)
var/datum/command_footnote/command_report_footnote = new /datum/command_footnote()
- SScommunications.block_command_report += 1 //Add a blocking condition to the counter until the inputs are done.
+ DScommunications.block_command_report += 1 //Add a blocking condition to the counter until the inputs are done.
command_report_footnote.message = tgui_input_text(user, "This message will be attached to the bottom of the roundstart threat report. Be sure to delay the roundstart report if you need extra time.", "P.S.")
if(!command_report_footnote.message)
- SScommunications.block_command_report -= 1
+ DScommunications.block_command_report -= 1
qdel(command_report_footnote)
return
@@ -266,8 +266,8 @@ ADMIN_VERB(command_report_footnote, R_ADMIN, "Command Report Footnote", "Adds a
if(!command_report_footnote.signature)
command_report_footnote.signature = "Classified"
- SScommunications.command_report_footnotes += command_report_footnote
- SScommunications.block_command_report--
+ DScommunications.command_report_footnotes += command_report_footnote
+ DScommunications.block_command_report--
message_admins("[user] has added a footnote to the command report: [command_report_footnote.message], signed [command_report_footnote.signature]")
@@ -276,5 +276,5 @@ ADMIN_VERB(command_report_footnote, R_ADMIN, "Command Report Footnote", "Adds a
var/signature
ADMIN_VERB(delay_command_report, R_FUN, "Delay Command Report", "Prevents the roundstart command report from being sent; or forces it to send it delayed.", ADMIN_CATEGORY_EVENTS)
- SScommunications.block_command_report = !SScommunications.block_command_report
- message_admins("[key_name_admin(user)] has [(SScommunications.block_command_report ? "delayed" : "sent")] the roundstart command report.")
+ DScommunications.block_command_report = !DScommunications.block_command_report
+ message_admins("[key_name_admin(user)] has [(DScommunications.block_command_report ? "delayed" : "sent")] the roundstart command report.")
diff --git a/code/modules/admin/view_variables/debug_variable_appearance.dm b/code/modules/admin/view_variables/debug_variable_appearance.dm
new file mode 100644
index 00000000000..9e92eba4605
--- /dev/null
+++ b/code/modules/admin/view_variables/debug_variable_appearance.dm
@@ -0,0 +1,101 @@
+/// Shows a header name on top when you investigate an appearance/image
+/image/vv_get_header()
+ . = list()
+ var/icon_name = "[icon || "null"] "
+ . += replacetext(icon_name, "icons/obj", "") // shortens the name. We know the path already.
+ if(icon)
+ . += icon_state ? "\"[icon_state]\"" : "(icon_state = null)"
+
+/// Makes nice short vv names for images
+/image/debug_variable_value(name, level, datum/owner, sanitize, display_flags)
+ var/display_name = "[type]"
+ if("[src]" != "[type]") // If we have a name var, let's use it.
+ display_name = "[src] [type]"
+
+ var/display_value
+ var/list/icon_file_name = splittext("[icon]", "/")
+ if(length(icon_file_name))
+ display_value = icon_file_name[length(icon_file_name)]
+ else
+ display_value = "null"
+
+ if(icon_state)
+ display_value = "[display_value]:[icon_state]"
+
+ var/display_ref = get_vv_link_ref()
+ return "[display_name] ([display_value]) [display_ref]"
+
+/// Returns the ref string to use when displaying this image in the vv menu of something else
+/image/proc/get_vv_link_ref()
+ return REF(src)
+
+// It is endlessly annoying to display /appearance directly for stupid byond reasons, so we copy everything we care about into a holder datum
+// That we can override procs on and store other vars on and such.
+/mutable_appearance/appearance_mirror
+ // So people can see where it came from
+ var/appearance_ref
+ // vis flags can't be displayed by mutable appearances cause it don't make sense as overlays, but appearances do carry them
+ // can't use the name either for byond reasons
+ var/_vis_flags
+
+// all alone at the end of the universe
+GLOBAL_DATUM_INIT(pluto, /atom/movable, new /atom/movable(null))
+
+// arg is actually an appearance, typed as mutable_appearance as closest mirror
+/mutable_appearance/appearance_mirror/New(mutable_appearance/appearance_father)
+ . = ..() // /mutable_appearance/New() copies over all the appearance vars MAs care about by default
+ // We copy over our appearance onto an atom. This is done so we can read vars carried by but not accessible on appearances
+ GLOB.pluto.appearance = appearance_father
+ _vis_flags = GLOB.pluto.vis_flags
+ appearance_ref = REF(appearance_father)
+
+// This means if the appearance loses refs before a click it's gone, but that's consistent to other datums so it's fine
+// Need to ref the APPEARANCE because we just free on our own, which sorta fucks this operation up you know?
+/mutable_appearance/appearance_mirror/get_vv_link_ref()
+ return appearance_ref
+
+/mutable_appearance/appearance_mirror/can_vv_get(var_name)
+ var/static/datum/beloved = new()
+ if(beloved.vars.Find(var_name)) // If datums have it, get out
+ return FALSE
+ // If it is one of the two args on /image, yeet (I am sorry)
+ if(var_name == NAMEOF(src, realized_overlays))
+ return FALSE
+ if(var_name == NAMEOF(src, realized_underlays))
+ return FALSE
+ // Filtering out the stuff I know we don't care about
+ if(var_name == NAMEOF(src, x))
+ return FALSE
+ if(var_name == NAMEOF(src, y))
+ return FALSE
+ if(var_name == NAMEOF(src, z))
+ return FALSE
+ // Could make an argument for these but I think they will just confuse people, so yeeet
+#ifndef SPACEMAN_DMM // Spaceman doesn't believe in contents on appearances, sorry lads
+ if(var_name == NAMEOF(src, contents))
+ return FALSE
+#endif
+ if(var_name == NAMEOF(src, loc))
+ return FALSE
+ if(var_name == NAMEOF(src, vis_contents))
+ return FALSE
+ return ..()
+
+/mutable_appearance/appearance_mirror/vv_get_var(var_name)
+ // No editing for you
+ var/value = vars[var_name]
+ return "
- )}
- {cart.length > 0 && !requestonly && (
-
- {(away === 1 && docked === 1 && (
- act('send')}
- />
- )) || Shuttle in {location}.}
-
- )}
-
- );
-};
-
-const CargoHelp = (props) => {
- return (
- <>
-
- Each department on the station will order crates from their own personal
- consoles. These orders are ENTIRELY FREE! They do not come out of
- cargo's budget, and rather put the consoles on cooldown. So
- here's where you come in: The ordered crates will show up on your
- supply console, and you need to deliver the crates to the orderers.
- You'll actually be paid the full value of the department crate on
- delivery if the crate was not tampered with, making the system a good
- source of income.
-
-
- Examine a department order crate to get specific details about where
- the crate needs to go.
-
-
-
- MULEbots are slow but loyal delivery bots that will get crates delivered
- with minimal technician effort required. It is slow, though, and can be
- tampered with while en route.
-
- Setting up a MULEbot is easy:
-
- 1. Drag the crate you want to deliver next to the MULEbot.
-
- 2. Drag the crate on top of MULEbot. It should load on.
-
- 3. Open your PDA.
-
- 4. Click Delivery Bot Control.
- 5. Click Scan for Active Bots.
- 6. Choose your MULE.
-
- 7. Click on Destination: (set).
- 8. Choose a destination and click OK.
-
- 9. Click Proceed.
-
-
- In addition to MULEs and hand-deliveries, you can also make use of the
- disposals mailing system. Note that a break in the disposal piping could
- cause your package to be lost (this hardly ever happens), so this is not
- always the most secure ways to deliver something. You can wrap up a
- piece of paper and mail it the same way if you (or someone at the desk)
- wants to mail a letter.
-
- Using the Disposals Delivery System is even easier:
-
- 1. Wrap your item/crate in packaging paper.
-
- 2. Use the destinations tagger to choose where to send it.
-
- 3. Tag the package.
-
- 4. Stick it on the conveyor and let the system handle it.
-
-
-
- Pondering something not included here? When in doubt, ask the QM!
-
- >
- );
-};
diff --git a/tgui/packages/tgui/interfaces/Cargo/CargoButtons.tsx b/tgui/packages/tgui/interfaces/Cargo/CargoButtons.tsx
new file mode 100644
index 00000000000..82c0d51a1f4
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/Cargo/CargoButtons.tsx
@@ -0,0 +1,39 @@
+import { useBackend } from '../../backend';
+import { Box, Button } from '../../components';
+import { formatMoney } from '../../format';
+import { CargoData } from './types';
+
+export function CargoCartButtons(props) {
+ const { act, data } = useBackend();
+ const { cart = [], requestonly, can_send, can_approve_requests } = data;
+
+ let total = 0;
+ let amount = 0;
+ for (let i = 0; i < cart.length; i++) {
+ amount += cart[i].amount;
+ total += cart[i].cost;
+ }
+
+ const canClear =
+ !requestonly && !!can_send && !!can_approve_requests && cart.length > 0;
+
+ return (
+ <>
+
+ {amount === 0 && 'Cart is empty'}
+ {amount === 1 && '1 item'}
+ {amount >= 2 && amount + ' items'}{' '}
+ {total > 0 && `(${formatMoney(total)} cr)`}
+
+
+ act('clear')}
+ >
+ Clear
+
+ >
+ );
+}
diff --git a/tgui/packages/tgui/interfaces/Cargo/CargoCart.tsx b/tgui/packages/tgui/interfaces/Cargo/CargoCart.tsx
new file mode 100644
index 00000000000..a595d5c0e3b
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/Cargo/CargoCart.tsx
@@ -0,0 +1,130 @@
+import { useBackend } from '../../backend';
+import {
+ Button,
+ Icon,
+ Input,
+ NoticeBox,
+ RestrictedInput,
+ Section,
+ Stack,
+ Table,
+} from '../../components';
+import { formatMoney } from '../../format';
+import { CargoCartButtons } from './CargoButtons';
+import { CargoData } from './types';
+
+export function CargoCart(props) {
+ const { act, data } = useBackend();
+ const { requestonly, away, cart = [], docked, location } = data;
+
+ const sendable = !away && !!docked;
+
+ return (
+
+
+ }>
+
+
+
+
+ {cart.length > 0 && !requestonly && (
+
+
+
+ {!sendable && }
+
+
+ act('send')}
+ px={2}
+ py={1}
+ tooltip={sendable ? '' : `Shuttle is at ${location}`}
+ >
+ Confirm the order
+
+
+
+
+ )}
+
+
+ );
+}
+
+function CheckoutItems(props) {
+ const { act, data } = useBackend();
+ const { amount_by_name = {}, can_send, cart = [], max_order } = data;
+
+ if (cart.length === 0) {
+ return Nothing in cart;
+ }
+
+ return (
+
+
+ );
+}
diff --git a/tgui/packages/tgui/interfaces/Cargo/CargoHelp.tsx b/tgui/packages/tgui/interfaces/Cargo/CargoHelp.tsx
new file mode 100644
index 00000000000..841ded71fb7
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/Cargo/CargoHelp.tsx
@@ -0,0 +1,80 @@
+import { Box, NoticeBox, Section, Stack } from '../../components';
+
+const ORDER_TEXT = `Each department on the station will order crates from their own personal
+ consoles. These orders are ENTIRELY FREE! They do not come out of
+ cargo's budget, and rather put the consoles on cooldown. So
+ here's where you come in: The ordered crates will show up on your
+ supply console, and you need to deliver the crates to the orderers.
+ You'll actually be paid the full value of the department crate on
+ delivery if the crate was not tampered with, making the system a good
+ source of income.`;
+
+const DISPOSAL_TEXT = `In addition to MULEs and hand-deliveries, you can also make use of the
+ disposals mailing system. Note that a break in the disposal piping could
+ cause your package to be lost (this hardly ever happens), so this is not
+ always the most secure ways to deliver something. You can wrap up a
+ piece of paper and mail it the same way if you (or someone at the desk)
+ wants to mail a letter.`;
+
+export function CargoHelp(props) {
+ return (
+
+
+
+
+ {ORDER_TEXT}
+
+
+ Examine a department order crate to get specific details about where
+ the crate needs to go.
+
+
+
+ MULEbots are slow but loyal delivery bots that will get crates
+ delivered with minimal technician effort required. It is slow,
+ though, and can be tampered with while en route.
+
+
+
+ Setting up a MULEbot is easy:
+
+ 1. Drag the crate you want to deliver next to the MULEbot.
+
+ 2. Drag the crate on top of MULEbot. It should load on.
+
+ 3. Open your PDA.
+
+ 4. Click Delivery Bot Control.
+ 5. Click Scan for Active Bots.
+ 6. Choose your MULE.
+
+ 7. Click on Destination: (set).
+ 8. Choose a destination and click OK.
+
+ 9. Click Proceed.
+
+
+ {DISPOSAL_TEXT}
+
+
+ Using the Disposals Delivery System is even easier:
+
+ 1. Wrap your item/crate in packaging paper.
+
+ 2. Use the destinations tagger to choose where to send it.
+
+ 3. Tag the package.
+
+ 4. Stick it on the conveyor and let the system handle it.
+
+
+
+
+
+
+ Pondering something not included here? When in doubt, ask the QM!
+
+
+
+ );
+}
diff --git a/tgui/packages/tgui/interfaces/Cargo/CargoRequests.tsx b/tgui/packages/tgui/interfaces/Cargo/CargoRequests.tsx
new file mode 100644
index 00000000000..3a53efb45e9
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/Cargo/CargoRequests.tsx
@@ -0,0 +1,85 @@
+import { decodeHtmlEntities } from 'common/string';
+
+import { useBackend } from '../../backend';
+import { Button, NoticeBox, Section, Table } from '../../components';
+import { TableCell, TableRow } from '../../components/Table';
+import { formatMoney } from '../../format';
+import { CargoData } from './types';
+
+export function CargoRequests(props) {
+ const { act, data } = useBackend();
+ const { requests = [], requestonly, can_send, can_approve_requests } = data;
+
+ return (
+ act('denyall')}
+ >
+ Clear
+
+ )
+ }
+ >
+ {requests.length === 0 && No Requests}
+ {requests.length > 0 && (
+