diff --git a/.github/guides/HARDDELETES.md b/.github/guides/HARDDELETES.md
index cdbdb2a126d..6817de0d9b3 100644
--- a/.github/guides/HARDDELETES.md
+++ b/.github/guides/HARDDELETES.md
@@ -1,6 +1,6 @@
# Hard Deletes
-> Garbage collection is pretty gothic when you think about it.
+> Garbage collection is pretty gothic when you think about it.
>
>An object in code is like a ghost, clinging to its former life, and especially to the people it knew. It can only pass on and truly die when it has dealt with its unfinished business. And only when its been forgotten by everyone who ever knew it. If even one other object remembers it, it has a connection to the living world that lets it keep hanging on
>
@@ -52,7 +52,7 @@ This of course means they can store that location in memory in another object's
/proc/someshit(mem_location)
var/datum/some_obj = new()
- some_obj.reference = mem_location
+ some_obj.reference = mem_location
```
But what happens when you get rid of the object we're passing around references to? If we just cleared it out from memory, everything that holds a reference to it would suddenly be pointing to nowhere, or worse, something totally different!
@@ -135,13 +135,13 @@ If that fails, search the object's typepath, and look and see if anything is hol
BYOND currently doesn't have the capability to give us information about where a hard delete is. Fortunately we can search for most all of then ourselves.
The procs to perform this search are hidden behind compile time defines, since they'd be way too risky to expose to admin button pressing
-If you're having issues solving a harddel and want to perform this check yourself, go to `_compile_options.dm` and uncomment `TESTING`, `REFERENCE_TRACKING`, and `GC_FAILURE_HARD_LOOKUP`
+If you're having issues solving a harddel and want to perform this check yourself, go to `_compile_options.dm` and uncomment `REFERENCE_TRACKING_STANDARD`.
-You can read more about what each of these do in that file, but the long and short of it is if something would hard delete our code will search for the reference (This will look like your game crashing, just hold out) and print information about anything it finds to the runtime log, which you can find inside the round folder inside `/data/logs/year/month/day`
+You can read more about what each of these do in that file, but the long and short of it is if something would hard delete our code will search for the reference (This will look like your game crashing, just hold out) and print information about anything it finds to [log_dir]/harddels.log, which you can find inside the round folder inside `/data/logs/year/month/day`
-It'll tell you what object is holding the ref if it's in an object, or what pattern of list transversal was required to find the ref if it's hiding in a list of some sort
+It'll tell you what object is holding the ref if it's in an object, or what pattern of list transversal was required to find the ref if it's hiding in a list of some sort, alongside the references remaining.
-## Techniques For Fixing Hard Deletes
+## Techniques For Fixing Hard Deletes
Once you've found the issue, it becomes a matter of making sure the ref is cleared as a part of Destroy(). I'm gonna walk you through a few patterns and discuss how you might go about fixing them
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/RandomRuins/SpaceRuins/listeningstation.dmm b/_maps/RandomRuins/SpaceRuins/listeningstation.dmm
index 2c7a240d679..ad27c03ab9a 100644
--- a/_maps/RandomRuins/SpaceRuins/listeningstation.dmm
+++ b/_maps/RandomRuins/SpaceRuins/listeningstation.dmm
@@ -755,7 +755,7 @@
/turf/open/floor/iron/small,
/area/ruin/space/has_grav/listeningstation)
"NO" = (
-/obj/machinery/power/smes/full,
+/obj/machinery/power/smes/super/full,
/obj/effect/turf_decal/stripes/line{
dir = 10
},
diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/interdynefob.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/interdynefob.dmm
index 6773053b46b..56a47d5bdbb 100644
--- a/_maps/RandomRuins/SpaceRuins/skyrat/interdynefob.dmm
+++ b/_maps/RandomRuins/SpaceRuins/skyrat/interdynefob.dmm
@@ -3499,7 +3499,8 @@
},
/obj/item/circuitboard/computer/rdconsole,
/obj/structure/frame/computer{
- dir = 8
+ dir = 8;
+ anchored = 1
},
/obj/machinery/airalarm/directional/east,
/obj/effect/mapping_helpers/airalarm/syndicate_access,
diff --git a/_maps/RandomRuins/SpaceRuins/waystation.dmm b/_maps/RandomRuins/SpaceRuins/waystation.dmm
index 245473c8fae..e5262d32425 100644
--- a/_maps/RandomRuins/SpaceRuins/waystation.dmm
+++ b/_maps/RandomRuins/SpaceRuins/waystation.dmm
@@ -357,7 +357,7 @@
/area/ruin/space/has_grav/waystation/cargobay)
"gE" = (
/obj/structure/sign/poster/contraband/missing_gloves/directional/north,
-/obj/machinery/power/smes/full,
+/obj/machinery/power/smes/super/full,
/obj/structure/cable,
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -464,7 +464,7 @@
/area/ruin/space)
"iT" = (
/obj/machinery/light/dim/directional/north,
-/obj/machinery/power/smes/full,
+/obj/machinery/power/smes/super/full,
/obj/structure/cable,
/turf/open/floor/plating,
/area/ruin/space/has_grav/waystation/power)
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..5c83910411f 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,
@@ -15511,6 +15527,12 @@
dir = 4
},
/area/station/science/lobby)
+"gyf" = (
+/obj/structure/cable,
+/obj/machinery/power/smes/super/full,
+/obj/machinery/status_display/ai/directional/north,
+/turf/open/floor/iron/smooth,
+/area/station/ai_monitored/turret_protected/aisat/equipment)
"gyi" = (
/obj/effect/mapping_helpers/broken_floor,
/obj/effect/decal/cleanable/dirt,
@@ -19298,13 +19320,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,
@@ -20173,6 +20188,16 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/engine,
/area/station/engineering/gravity_generator)
+"hYA" = (
+/obj/structure/cable,
+/obj/machinery/power/smes/super/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)
"hYC" = (
/turf/closed/wall,
/area/station/engineering/atmos)
@@ -24920,16 +24945,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 +25653,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,
@@ -26480,6 +26491,18 @@
/obj/effect/mapping_helpers/airlock/access/all/service/chapel_office,
/turf/open/floor/iron/textured_half,
/area/station/service/chapel/office)
+"kas" = (
+/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)
"kat" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment,
@@ -26989,12 +27012,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
@@ -31141,18 +31158,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 +33044,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 +35259,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 +36945,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{
@@ -38541,6 +38537,10 @@
/obj/effect/decal/cleanable/dirt/dust,
/turf/open/floor/iron/small,
/area/station/engineering/atmos)
+"nIO" = (
+/obj/effect/landmark/start/virologist,
+/turf/open/floor/iron/showroomfloor,
+/area/station/medical/virology)
"nIS" = (
/obj/structure/disposalpipe/segment,
/obj/machinery/door/airlock{
@@ -52619,6 +52619,13 @@
/obj/machinery/status_display/ai/directional/north,
/turf/open/floor/iron,
/area/station/commons/dorms)
+"rHW" = (
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/effect/landmark/start/virologist,
+/turf/open/floor/iron/white,
+/area/station/medical/medbay/aft)
"rIb" = (
/obj/effect/turf_decal/tile/dark_red/opposingcorners,
/obj/structure/closet/secure_closet/security/sec,
@@ -68883,17 +68890,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{
@@ -69619,6 +69615,13 @@
/obj/effect/mapping_helpers/airlock/access/any/science/maintenance,
/turf/open/floor/iron/cafeteria,
/area/station/maintenance/starboard/fore)
+"wxm" = (
+/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)
"wxp" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -70060,6 +70063,19 @@
"wCY" = (
/turf/closed/wall,
/area/station/command/heads_quarters/cmo)
+"wDg" = (
+/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)
"wDo" = (
/obj/effect/turf_decal/tile/blue{
dir = 1
@@ -74884,22 +74900,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)
@@ -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
+hYA
xTV
dua
gnA
@@ -104086,7 +104086,7 @@ wct
hJp
wct
gOm
-kiQ
+gyf
eFe
eYk
xvT
@@ -106247,7 +106247,7 @@ tRc
tRc
tRc
tRc
-hGt
+rHW
dHT
sSQ
sSQ
@@ -107022,7 +107022,7 @@ bUv
cSk
gLb
nlS
-mIa
+wxm
gpM
sSQ
hrF
@@ -108560,12 +108560,12 @@ jrk
gIF
wYA
bpS
-jLi
+nIO
nYk
vVP
xAA
hgf
-agb
+wDg
uGj
wgL
oiA
@@ -113421,7 +113421,7 @@ dDB
blb
dDB
ldq
-lwl
+kas
vXn
ldq
ldq
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index d97755766cb..2efaa2533c8 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,
@@ -10586,12 +10548,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 +11220,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 +12114,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,
@@ -17020,6 +16959,12 @@
/obj/effect/turf_decal/tile/red/half/contrasted,
/turf/open/floor/iron/dark,
/area/station/security/execution/education)
+"eht" = (
+/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)
"ehy" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -17175,6 +17120,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 +18196,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 +18946,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 +20700,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 +22731,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 +24030,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 +24515,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 +26234,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 +27844,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 +29265,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 +29364,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 +30773,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{
@@ -30908,6 +30876,13 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron,
/area/station/commons/vacant_room/commissary)
+"hHe" = (
+/obj/machinery/power/terminal{
+ dir = 4
+ },
+/obj/structure/sign/warning/electric_shock/directional/north,
+/turf/open/floor/plating,
+/area/station/maintenance/department/electrical)
"hHi" = (
/obj/structure/closet/crate/hydroponics,
/obj/item/paper/guides/jobs/hydroponics,
@@ -31696,15 +31671,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 +32047,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 +32219,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,
@@ -34949,6 +34927,18 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron,
/area/station/engineering/atmos/storage/gas)
+"iHd" = (
+/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)
"iHg" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -35456,15 +35446,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 +36977,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,
@@ -38729,14 +38698,6 @@
},
/turf/open/floor/iron,
/area/station/security/prison/garden)
-"jCw" = (
-/obj/machinery/power/terminal{
- dir = 4
- },
-/obj/structure/cable,
-/obj/structure/sign/warning/electric_shock/directional/north,
-/turf/open/floor/plating,
-/area/station/maintenance/department/electrical)
"jCI" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -39497,6 +39458,13 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/iron/large,
/area/station/security/checkpoint/escape)
+"jMb" = (
+/obj/machinery/power/terminal{
+ dir = 4
+ },
+/obj/structure/sign/warning/electric_shock/directional/south,
+/turf/open/floor/plating,
+/area/station/maintenance/department/electrical)
"jMk" = (
/obj/machinery/door/window/left/directional/east{
name = "Danger: Conveyor Access";
@@ -41333,6 +41301,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 +41891,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 +43498,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 +44609,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 +46462,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 +48425,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,
@@ -49251,42 +49276,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 +49689,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 +49788,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 +51051,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 +51756,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 +52048,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 +54532,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 +58062,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 +58205,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 +58728,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 +59077,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 +59170,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 +59207,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 +59472,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 +59673,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 +59808,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 +61069,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,
@@ -62751,6 +62748,19 @@
/obj/machinery/duct,
/turf/open/floor/iron,
/area/station/science/breakroom)
+"pKa" = (
+/obj/machinery/power/smes/super/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)
"pKb" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/cable,
@@ -63115,16 +63125,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 +63339,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 +63913,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 +65093,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 +65566,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 +66020,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 +67061,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 +67609,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 +67738,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 +68524,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 +68887,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 +69299,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 +70720,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 +72416,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 +72437,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 +72465,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 +72771,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 +74664,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 +75569,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 +76124,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,
@@ -77297,33 +77286,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)
@@ -77799,14 +77761,6 @@
},
/turf/open/floor/iron/dark,
/area/station/engineering/atmos)
-"tuH" = (
-/obj/machinery/power/terminal{
- dir = 4
- },
-/obj/structure/cable,
-/obj/structure/sign/warning/electric_shock/directional/south,
-/turf/open/floor/plating,
-/area/station/maintenance/department/electrical)
"tuN" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/door/poddoor/shutters/preopen{
@@ -78607,6 +78561,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 +80161,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 +80334,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 +82976,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 +83291,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 +84249,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 +85076,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 +85170,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 +86927,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,
@@ -87554,6 +87525,14 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/science/ordnance/testlab)
+"vQx" = (
+/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)
"vQB" = (
/obj/structure/disposalpipe/segment,
/obj/machinery/power/apc/auto_name/directional/east,
@@ -88645,13 +88624,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 +88971,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 +90902,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 +91406,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 +91593,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 +92833,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 +93054,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 +93495,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{
@@ -95511,6 +95492,16 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/station/science/robotics/lab)
+"xQi" = (
+/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)
"xQm" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/brown/visible,
/obj/machinery/incident_display/delam/directional/south,
@@ -95800,6 +95791,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 +103563,7 @@ btH
btH
btH
bPC
-pOu
+rgH
bTq
jYp
vgi
@@ -105352,7 +105350,7 @@ alK
qPm
btH
btH
-tpX
+pKa
kXJ
bEl
xMy
@@ -117181,7 +117179,7 @@ xqR
qzc
kUx
kTV
-vke
+chv
dQl
oIE
fFu
@@ -118512,7 +118510,7 @@ pWL
jjm
rUl
rTW
-oRq
+vlS
rTW
oVW
oUe
@@ -120054,7 +120052,7 @@ kSA
jjm
nkj
rTW
-oRq
+vlS
rTW
oVW
fmi
@@ -120517,7 +120515,7 @@ fXF
jgZ
mrd
rDL
-qUL
+pQo
uCa
wkj
bqP
@@ -120774,7 +120772,7 @@ fXF
suH
ikV
gIk
-wkV
+ekF
leE
bfq
iFn
@@ -120815,7 +120813,7 @@ uKY
gcr
mQO
rTW
-oRq
+vlS
rTW
iWX
csO
@@ -121031,7 +121029,7 @@ nmi
xvf
oQJ
xJJ
-oBa
+wGm
uCa
aTz
ygM
@@ -121544,7 +121542,7 @@ wiZ
fXF
xkz
hwe
-wRJ
+tFu
vpV
uCa
gQk
@@ -126730,7 +126728,7 @@ nIa
hSf
ffb
cMn
-hkZ
+xrS
sIX
sIX
cLR
@@ -128272,15 +128270,15 @@ txc
pZM
ffb
dqP
-anU
+aFp
sIX
sIX
xbJ
sIX
sIX
-aCA
-aqU
-aJj
+mRl
+scp
+tYN
dNN
qMB
wtS
@@ -129304,7 +129302,7 @@ ikZ
oRh
oHq
wNV
-roh
+eyl
dNN
uMV
sEF
@@ -129563,7 +129561,7 @@ dNN
dNN
dNN
dNN
-oPF
+oLD
dCx
aJT
fDF
@@ -131407,7 +131405,7 @@ tgT
rZl
wjV
jpN
-mIg
+vQx
rJG
gqm
qYo
@@ -131910,8 +131908,8 @@ bMV
wjP
aaa
uUx
-oDw
-rIO
+xQi
+iHd
qJA
gKl
ecC
@@ -131921,7 +131919,7 @@ gqm
jyT
wjV
sFR
-wOz
+eht
fLV
gqm
qYo
@@ -132094,7 +132092,7 @@ fxs
lAg
kPM
pRS
-qLa
+pqo
nLS
xld
uqZ
@@ -132352,7 +132350,7 @@ rgW
vze
pRS
pRS
-eIu
+hWA
iaL
pRS
iaL
@@ -132608,7 +132606,7 @@ sEm
dEA
nxd
pRS
-mlM
+lZC
eGs
ykB
jpe
@@ -133078,7 +133076,7 @@ sid
sBG
sLz
vRB
-sgG
+gch
xMe
kVP
bSp
@@ -133334,8 +133332,8 @@ cnL
kfa
pPI
kVP
-sbZ
-oXX
+xiu
+uMT
jVP
kVP
pET
@@ -133591,8 +133589,8 @@ vdZ
qPp
pXt
kVP
-cVD
-uJl
+fWB
+rky
iXO
kVP
pgN
@@ -133848,8 +133846,8 @@ vBt
tyK
kVP
kVP
-jgG
-wgz
+pWB
+qsv
gMB
kVP
kVP
@@ -133893,7 +133891,7 @@ wmp
rgW
mGw
pRS
-paD
+kNB
lAv
nAz
jce
@@ -134105,11 +134103,11 @@ kVP
kVP
kVP
dUH
-cBB
-bJi
+ubJ
+xlf
giz
kVr
-hRU
+kix
kVP
sGS
qOT
@@ -135134,7 +135132,7 @@ mqV
kVP
giz
giz
-sYe
+qSC
lJJ
maV
ptC
@@ -135391,7 +135389,7 @@ kVP
kVP
vat
kVP
-hjH
+sRs
hUh
kVP
cAV
@@ -135648,7 +135646,7 @@ pOD
tWU
sSH
kVP
-scJ
+aUZ
qPX
kVP
aVE
@@ -136510,9 +136508,9 @@ umA
veM
veM
ako
-tpV
-cJQ
-gPH
+nFf
+hFQ
+fEV
uQF
ibh
cYk
@@ -136767,7 +136765,7 @@ oCo
fiU
jRJ
ako
-iOp
+lcl
dNc
dNc
dNc
@@ -137024,7 +137022,7 @@ euF
oCo
sJG
ako
-oUf
+mtD
rjO
oOI
oOI
@@ -137495,7 +137493,7 @@ ilI
ilI
ilI
hup
-mVX
+qlY
cMD
ilI
ilI
@@ -144471,7 +144469,7 @@ lsJ
ffP
gBi
tqy
-hYh
+msL
qMf
oci
bqS
@@ -146275,10 +146273,10 @@ qMf
lrr
qTb
wZE
-jCw
+hHe
nEM
uEv
-tuH
+jMb
wZE
pSr
wlD
@@ -149040,7 +149038,7 @@ nzR
gKp
gDP
rTG
-sGp
+xUs
ozu
dql
pWH
@@ -149554,8 +149552,8 @@ ieg
eIl
ieg
ieg
-uZc
-bDx
+fes
+vHq
dql
eBE
gIV
@@ -149800,7 +149798,7 @@ ouc
qWZ
iCo
krO
-qyK
+guZ
lET
gBA
xtf
@@ -149812,7 +149810,7 @@ bdx
lpI
iIb
tXW
-cfx
+kqI
vgK
wdC
lTt
@@ -150069,7 +150067,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..ef1d3e2a0d8 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,
@@ -4028,6 +4038,11 @@
},
/turf/open/floor/iron/white,
/area/mine/laborcamp)
+"bmr" = (
+/obj/structure/cable,
+/obj/machinery/power/smes/engineering,
+/turf/open/floor/plating,
+/area/station/maintenance/department/electrical)
"bmv" = (
/obj/structure/cable,
/turf/open/floor/iron,
@@ -4336,6 +4351,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,
@@ -8226,6 +8245,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 +9916,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
@@ -11136,12 +11152,6 @@
/obj/effect/turf_decal/tile/yellow/full,
/turf/open/floor/iron/white/smooth_large,
/area/station/medical/pharmacy)
-"dmL" = (
-/obj/structure/cable,
-/obj/effect/decal/cleanable/dirt,
-/obj/machinery/light_switch/directional/south,
-/turf/open/floor/iron,
-/area/station/maintenance/department/electrical)
"dmR" = (
/obj/machinery/door/airlock/external{
glass = 1;
@@ -12647,12 +12657,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 +14914,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,11 +16614,18 @@
/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/machinery/power/smes/super/full,
/obj/structure/cable,
/turf/open/floor/circuit,
/area/station/ai_monitored/turret_protected/ai)
@@ -17260,14 +17275,6 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/iron/white,
/area/mine/living_quarters)
-"fkc" = (
-/obj/machinery/power/terminal{
- dir = 8
- },
-/obj/structure/cable,
-/obj/structure/sign/poster/contraband/missing_gloves/directional/east,
-/turf/open/floor/plating,
-/area/station/maintenance/department/electrical)
"fkj" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -18008,6 +18015,14 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/station/maintenance/starboard/aft)
+"fwE" = (
+/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)
"fwI" = (
/obj/machinery/door/airlock/maintenance_hatch,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -18232,6 +18247,12 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/engineering/storage/tech)
+"fAh" = (
+/obj/machinery/power/terminal{
+ dir = 4
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/department/electrical)
"fAF" = (
/obj/structure/rack,
/obj/item/clothing/gloves/boxing/green,
@@ -18366,6 +18387,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 +19344,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 +20990,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 +22788,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
@@ -23575,11 +23588,6 @@
dir = 1
},
/area/station/security/office)
-"hkd" = (
-/obj/structure/cable,
-/obj/machinery/light/small/directional/west,
-/turf/open/floor/plating,
-/area/station/maintenance/department/electrical)
"hkl" = (
/obj/structure/table/wood,
/obj/effect/turf_decal/siding/wood/corner{
@@ -24054,13 +24062,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 +25147,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 +26031,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 +26914,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 +27471,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 +27647,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 +27880,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
@@ -30788,6 +30769,11 @@
/obj/effect/mapping_helpers/airlock/access/all/security/entrance,
/turf/open/floor/iron,
/area/station/security/brig/upper)
+"jzP" = (
+/obj/structure/chair/stool/directional/south,
+/obj/effect/decal/cleanable/oil/slippery,
+/turf/open/floor/plating,
+/area/station/maintenance/department/electrical)
"jzY" = (
/obj/machinery/airalarm/directional/west,
/obj/effect/turf_decal/trimline/blue/filled/corner{
@@ -32830,9 +32816,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{
@@ -34255,6 +34238,10 @@
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/iron,
/area/station/command/gateway)
+"kyl" = (
+/obj/machinery/light/small/directional/west,
+/turf/open/floor/plating,
+/area/station/maintenance/department/electrical)
"kyp" = (
/obj/effect/turf_decal/box/corners,
/obj/effect/turf_decal/box/corners{
@@ -36287,17 +36274,6 @@
/obj/structure/sign/poster/official/random/directional/west,
/turf/open/floor/iron/dark,
/area/mine/mechbay)
-"ldi" = (
-/obj/structure/table,
-/obj/item/wallframe/camera,
-/obj/item/wallframe/camera,
-/obj/item/assembly/prox_sensor{
- pixel_x = -8;
- pixel_y = 4
- },
-/obj/structure/cable,
-/turf/open/floor/plating,
-/area/station/maintenance/department/electrical)
"ldn" = (
/obj/machinery/door/poddoor/preopen{
id = "maint3"
@@ -36520,6 +36496,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 +41317,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,
@@ -41566,6 +41543,16 @@
},
/turf/open/floor/plating/icemoon,
/area/station/science/ordnance/bomb)
+"mMZ" = (
+/obj/structure/table,
+/obj/item/wallframe/camera,
+/obj/item/wallframe/camera,
+/obj/item/assembly/prox_sensor{
+ pixel_x = -8;
+ pixel_y = 4
+ },
+/turf/open/floor/plating,
+/area/station/maintenance/department/electrical)
"mNj" = (
/obj/machinery/computer/security{
dir = 4
@@ -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,
@@ -45950,6 +45921,11 @@
/obj/effect/spawner/random/structure/steam_vent,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
+"obg" = (
+/obj/machinery/light_switch/directional/south,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/iron,
+/area/station/maintenance/department/electrical)
"obj" = (
/obj/structure/disposalpipe/segment,
/obj/structure/cable,
@@ -46008,6 +45984,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 +47711,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
@@ -52479,6 +52442,13 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
/area/station/engineering/atmos)
+"pYw" = (
+/obj/machinery/power/terminal{
+ dir = 8
+ },
+/obj/structure/sign/poster/contraband/missing_gloves/directional/east,
+/turf/open/floor/plating,
+/area/station/maintenance/department/electrical)
"pYz" = (
/obj/structure/railing/corner,
/obj/machinery/door/firedoor/border_only,
@@ -56730,6 +56700,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 +56851,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 +57431,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,
@@ -58492,11 +58480,6 @@
/obj/structure/fake_stairs/wood/directional/north,
/turf/open/misc/asteroid/snow/icemoon,
/area/icemoon/surface/outdoors/nospawn)
-"rPu" = (
-/obj/machinery/power/smes,
-/obj/structure/cable,
-/turf/open/floor/plating,
-/area/station/maintenance/department/electrical)
"rPL" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/rack,
@@ -60232,6 +60215,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 +60379,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 +61124,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{
@@ -63510,12 +63504,6 @@
/obj/structure/cable,
/turf/open/floor/iron/dark,
/area/station/commons/storage/mining)
-"tsR" = (
-/obj/structure/cable,
-/obj/structure/chair/stool/directional/south,
-/obj/effect/decal/cleanable/oil/slippery,
-/turf/open/floor/plating,
-/area/station/maintenance/department/electrical)
"ttb" = (
/obj/effect/turf_decal/trimline/yellow/filled/line{
dir = 4
@@ -64854,6 +64842,13 @@
/obj/effect/spawner/random/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
+"tNb" = (
+/obj/structure/chair/office/light{
+ dir = 4
+ },
+/obj/effect/landmark/start/virologist,
+/turf/open/floor/iron/white,
+/area/station/medical/virology)
"tNd" = (
/obj/effect/spawner/random/engineering/tracking_beacon,
/obj/effect/turf_decal/siding/green{
@@ -68392,13 +68387,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/starboard)
-"uXu" = (
-/obj/machinery/power/terminal{
- dir = 4
- },
-/obj/structure/cable,
-/turf/open/floor/plating,
-/area/station/maintenance/department/electrical)
"uXy" = (
/obj/machinery/light_switch/directional/east,
/obj/structure/table,
@@ -72462,6 +72450,23 @@
/obj/structure/closet/boxinggloves,
/turf/open/floor/iron,
/area/station/security/prison/workout)
+"wlT" = (
+/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)
"wlW" = (
/obj/item/radio/intercom/directional/south,
/obj/machinery/computer/robotics{
@@ -73904,10 +73909,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 +74040,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 +74379,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 +116635,7 @@ dhq
dhq
iDt
iDt
-grY
+ssu
iDt
dLN
rbT
@@ -116905,7 +116899,7 @@ rbT
lLN
vRO
ggV
-cSm
+eYz
tGP
tGP
iRp
@@ -183834,7 +183828,7 @@ cDb
vEJ
wGX
oQY
-hrZ
+tNb
wsF
jUB
jUB
@@ -184605,7 +184599,7 @@ uCe
xKe
dRz
pwn
-oCs
+wlT
aru
rqY
tAg
@@ -184863,7 +184857,7 @@ lzX
dRz
jUB
cAM
-nNB
+fwE
qkB
vqH
xDb
@@ -193606,8 +193600,8 @@ uIf
uIf
uIf
uIf
-fSG
-fSG
+roW
+roW
bId
gcy
jJG
@@ -193859,12 +193853,12 @@ thA
thA
rcY
iDt
-inb
-keV
-gWZ
-wHd
-izc
-wHd
+fCS
+iwq
+cuB
+iCe
+lgP
+iCe
vcH
gnq
xEF
@@ -194116,12 +194110,12 @@ thA
thA
rcY
iDt
-inb
-sDA
-mYd
-mIC
-dJk
-wPC
+fCS
+ocd
+bqX
+rmG
+ryX
+sqH
qSk
sbd
rEh
@@ -194373,12 +194367,12 @@ thA
thA
rcY
iDt
-inb
-keV
-nBV
-iao
-hKj
-iao
+fCS
+iwq
+evc
+wKh
+aEK
+wKh
odf
sbd
jaY
@@ -256267,8 +256261,8 @@ kKL
lOU
glI
buY
-hkd
-uXu
+kyl
+fAh
kKL
pzV
uZn
@@ -256525,7 +256519,7 @@ qAS
fUc
jaX
glI
-rPu
+bmr
kKL
kKL
mbG
@@ -256782,7 +256776,7 @@ mqO
fUc
sBi
xYA
-ldi
+mMZ
lUC
vhm
oLG
@@ -257295,7 +257289,7 @@ kKL
bpQ
epd
oih
-dmL
+obg
lUC
lUC
dMH
@@ -257552,8 +257546,8 @@ kKL
dvS
pwd
glI
-tsR
-rPu
+jzP
+bmr
lUC
tXV
kvX
@@ -257810,7 +257804,7 @@ pfP
apD
ugG
gIt
-fkc
+pYw
lUC
ccT
nyC
diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm
index ba796554019..ea41050f854 100644
--- a/_maps/map_files/KiloStation/KiloStation.dmm
+++ b/_maps/map_files/KiloStation/KiloStation.dmm
@@ -2,14 +2,6 @@
"aaa" = (
/turf/open/space/basic,
/area/space)
-"aac" = (
-/obj/machinery/power/smes{
- charge = 5e+006;
- name = "ai power storage unit"
- },
-/obj/structure/cable,
-/turf/open/floor/circuit/green,
-/area/station/ai_monitored/turret_protected/ai)
"aak" = (
/obj/effect/turf_decal/stripes/line,
/obj/effect/turf_decal/stripes/line{
@@ -346,25 +338,6 @@
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/plating,
/area/station/maintenance/starboard)
-"adx" = (
-/obj/structure/bed{
- dir = 4
- },
-/obj/machinery/airalarm/directional/west,
-/obj/effect/landmark/start/assistant,
-/obj/effect/spawner/random/bedsheet{
- dir = 4
- },
-/obj/effect/landmark/start/hangover,
-/obj/machinery/button/door/directional/north{
- id = "Cabin_3";
- name = "Cabin 3 Privacy Lock";
- normaldoorcontrol = 1;
- specialfunctions = 4
- },
-/obj/item/pillow/random,
-/turf/open/floor/wood,
-/area/station/commons/locker)
"adI" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -600,19 +573,6 @@
/obj/effect/turf_decal/tile/yellow,
/turf/open/floor/iron,
/area/station/construction/mining/aux_base)
-"ahS" = (
-/obj/machinery/door/poddoor/preopen{
- id = "xeno3";
- name = "Creature Cell 3"
- },
-/obj/effect/turf_decal/delivery,
-/obj/machinery/door/window/left/directional/east{
- name = "Creature Cell";
- req_access = list("xenobiology")
- },
-/obj/structure/cable,
-/turf/open/floor/iron/dark,
-/area/station/science/xenobiology)
"aia" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -1449,6 +1409,25 @@
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/security/prison/mess)
+"aww" = (
+/obj/structure/bed{
+ dir = 4
+ },
+/obj/machinery/airalarm/directional/west,
+/obj/effect/landmark/start/assistant,
+/obj/effect/spawner/random/bedsheet{
+ dir = 4
+ },
+/obj/effect/landmark/start/hangover,
+/obj/machinery/button/door/directional/north{
+ id = "Cabin_3";
+ name = "Cabin 3 Privacy Lock";
+ normaldoorcontrol = 1;
+ specialfunctions = 4
+ },
+/obj/item/pillow/random,
+/turf/open/floor/wood,
+/area/station/commons/locker)
"awG" = (
/obj/machinery/atmospherics/pipe/smart/simple/yellow/visible{
dir = 4
@@ -1489,6 +1468,20 @@
/obj/effect/turf_decal/tile/red,
/turf/open/floor/iron/showroomfloor,
/area/station/commons/toilet/restrooms)
+"awX" = (
+/obj/structure/plasticflaps/opaque,
+/obj/machinery/navbeacon{
+ codes_txt = "delivery;dir=2";
+ location = "Research Division"
+ },
+/obj/machinery/door/window/left/directional/south{
+ name = "Research Division Delivery Access";
+ req_access = list("research")
+ },
+/obj/effect/turf_decal/delivery,
+/obj/structure/cable,
+/turf/open/floor/iron/dark,
+/area/station/maintenance/starboard)
"axd" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/sign/warning/vacuum/external,
@@ -1523,33 +1516,6 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/iron/dark,
/area/station/command/bridge)
-"axH" = (
-/obj/effect/landmark/start/ai/secondary,
-/obj/item/radio/intercom/directional/north{
- freerange = 1;
- listening = 0;
- name = "Custom Channel";
- pixel_x = -8
- },
-/obj/item/radio/intercom/directional/west{
- freerange = 1;
- listening = 0;
- name = "Common Channel"
- },
-/obj/item/radio/intercom/directional/south{
- freerange = 1;
- frequency = 1447;
- listening = 0;
- name = "Private Channel";
- pixel_x = -8
- },
-/obj/machinery/door/window/left/directional/east{
- name = "Secondary AI Core Access";
- pixel_x = 4;
- req_access = list("ai_upload")
- },
-/turf/open/floor/circuit/red,
-/area/station/ai_monitored/turret_protected/ai)
"axT" = (
/obj/effect/turf_decal/stripes/line{
dir = 10
@@ -1663,19 +1629,6 @@
},
/turf/open/floor/iron/showroomfloor,
/area/station/science/genetics)
-"aAN" = (
-/obj/structure/plasticflaps/opaque,
-/obj/machinery/navbeacon{
- codes_txt = "delivery;dir=1";
- location = "Research and Development"
- },
-/obj/machinery/door/window/left/directional/north{
- name = "Research and Development Delivery Access";
- req_access = list("science")
- },
-/obj/effect/turf_decal/delivery,
-/turf/open/floor/iron/dark,
-/area/station/maintenance/starboard)
"aAP" = (
/obj/effect/turf_decal/tile/yellow/anticorner/contrasted,
/turf/open/floor/iron/showroomfloor,
@@ -2269,6 +2222,27 @@
/obj/effect/turf_decal/tile/neutral/opposingcorners,
/turf/open/floor/iron/showroomfloor,
/area/station/security/lockers)
+"aJH" = (
+/obj/structure/plasticflaps/opaque,
+/obj/machinery/navbeacon{
+ codes_txt = "delivery;dir=8";
+ location = "Atmospherics";
+ name = "navigation beacon (Atmospherics Delivery)"
+ },
+/obj/machinery/door/window/left/directional/west{
+ name = "Atmospherics Delivery Access";
+ req_access = list("atmospherics")
+ },
+/obj/machinery/door/poddoor/preopen{
+ id = "atmos";
+ name = "Atmospherics Blast Door"
+ },
+/obj/effect/turf_decal/delivery,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/iron/dark,
+/area/station/engineering/atmos/storage/gas)
"aJM" = (
/obj/machinery/hydroponics/soil,
/obj/item/shovel/spade,
@@ -2412,6 +2386,28 @@
/obj/effect/turf_decal/tile/yellow,
/turf/open/floor/iron,
/area/station/hallway/primary/starboard)
+"aMJ" = (
+/obj/structure/plasticflaps/opaque,
+/obj/machinery/navbeacon{
+ codes_txt = "delivery;dir=1";
+ location = "Engineering";
+ name = "navigation beacon (Engineering Delivery)"
+ },
+/obj/machinery/door/window/right/directional/east{
+ name = "Engineering Delivery Access";
+ req_access = list("engineering")
+ },
+/obj/machinery/door/poddoor/preopen{
+ id = "Engineering";
+ name = "Engineering Blast Doors"
+ },
+/obj/effect/turf_decal/delivery,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/iron/dark,
+/area/station/engineering/lobby)
"aMK" = (
/obj/structure/grille/broken,
/obj/effect/decal/cleanable/cobweb,
@@ -3743,6 +3739,18 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/maintenance/fore)
+"boo" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible,
+/obj/machinery/door/window/left/directional/north{
+ name = "Maximum Security Test Chamber";
+ req_access = list("xenobiology")
+ },
+/obj/structure/cable,
+/obj/effect/turf_decal/stripes/line{
+ dir = 1
+ },
+/turf/open/floor/iron/dark,
+/area/station/science/xenobiology)
"boq" = (
/obj/effect/turf_decal/box,
/obj/effect/turf_decal/stripes/line,
@@ -3983,6 +3991,21 @@
},
/turf/open/floor/iron/showroomfloor,
/area/station/science/ordnance/storage)
+"bsB" = (
+/obj/structure/table/reinforced,
+/obj/effect/turf_decal/delivery,
+/obj/machinery/door/firedoor,
+/obj/item/storage/box/lights/mixed{
+ pixel_y = 6
+ },
+/obj/machinery/door/window/right/directional/east{
+ name = "Cargo Desk";
+ req_access = list("shipping")
+ },
+/obj/item/flashlight,
+/obj/effect/spawner/random/bureaucracy/birthday_wrap,
+/turf/open/floor/plating,
+/area/station/cargo/office)
"bsJ" = (
/obj/structure/destructible/cult/item_dispenser/archives/library,
/obj/item/book/codex_gigas{
@@ -4242,20 +4265,6 @@
/obj/machinery/airalarm/directional/west,
/turf/open/floor/engine/telecomms,
/area/station/tcommsat/server)
-"bxD" = (
-/obj/machinery/door/window/left/directional/west{
- name = "Creature Cell";
- req_access = list("xenobiology")
- },
-/obj/structure/cable,
-/obj/effect/turf_decal/stripes/line{
- dir = 8
- },
-/obj/effect/turf_decal/tile/neutral/half/contrasted{
- dir = 8
- },
-/turf/open/floor/iron/dark,
-/area/station/science/xenobiology)
"bxE" = (
/obj/machinery/portable_atmospherics/pump,
/obj/effect/turf_decal/box,
@@ -4514,6 +4523,26 @@
/obj/item/seeds/watermelon,
/turf/open/floor/grass,
/area/station/security/prison/garden)
+"bCz" = (
+/obj/structure/table/reinforced,
+/obj/machinery/door/firedoor,
+/obj/item/clipboard{
+ pixel_x = 3
+ },
+/obj/item/folder/yellow{
+ pixel_x = 3
+ },
+/obj/machinery/door/window/left/directional/east{
+ name = "Mailroom Desk";
+ req_access = list("shipping")
+ },
+/obj/effect/landmark/start/hangover,
+/obj/structure/desk_bell{
+ pixel_x = -8;
+ pixel_y = 10
+ },
+/turf/open/floor/iron,
+/area/station/cargo/sorting)
"bCO" = (
/obj/item/paper_bin{
pixel_x = -4;
@@ -4986,18 +5015,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/aft)
-"bLX" = (
-/obj/structure/table/reinforced,
-/obj/effect/turf_decal/delivery,
-/obj/machinery/door/firedoor,
-/obj/machinery/door/window/left/directional/north{
- name = "Security Desk";
- req_access = list("security")
- },
-/obj/item/crowbar/red,
-/obj/item/storage/fancy/donut_box,
-/turf/open/floor/plating,
-/area/station/hallway/secondary/exit/departure_lounge)
"bMw" = (
/obj/effect/decal/cleanable/dirt,
/obj/item/toy/basketball,
@@ -6176,6 +6193,24 @@
},
/turf/open/floor/iron/dark,
/area/station/maintenance/port/greater)
+"cfR" = (
+/obj/structure/table/reinforced,
+/obj/effect/turf_decal/delivery,
+/obj/machinery/door/firedoor,
+/obj/item/folder/blue,
+/obj/machinery/door/poddoor/shutters/preopen{
+ id = "hop";
+ name = "Privacy Shutters"
+ },
+/obj/machinery/door/window/brigdoor/left/directional/north{
+ name = "Head of Personnel's Desk";
+ req_access = list("hop")
+ },
+/obj/machinery/door/window/right/directional/south{
+ name = "Reception Desk"
+ },
+/turf/open/floor/iron,
+/area/station/command/heads_quarters/hop)
"cgb" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -7932,18 +7967,6 @@
},
/turf/open/floor/iron/dark,
/area/station/science/genetics)
-"cLn" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible,
-/obj/machinery/door/window/left/directional/north{
- name = "Maximum Security Test Chamber";
- req_access = list("xenobiology")
- },
-/obj/structure/cable,
-/obj/effect/turf_decal/stripes/line{
- dir = 1
- },
-/turf/open/floor/iron/dark,
-/area/station/science/xenobiology)
"cLq" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -8052,6 +8075,23 @@
},
/turf/open/floor/engine,
/area/station/maintenance/disposal/incinerator)
+"cNO" = (
+/obj/machinery/atmospherics/pipe/smart/simple/dark/visible,
+/obj/machinery/portable_atmospherics/pump/lil_pump,
+/obj/machinery/camera/directional/west{
+ c_tag = "Ordnance Mixing Lab";
+ name = "science camera";
+ network = list("ss13","rd")
+ },
+/obj/machinery/airalarm/directional/west{
+ pixel_x = -28
+ },
+/obj/effect/mapping_helpers/airalarm/mixingchamber_access,
+/obj/effect/turf_decal/tile/purple/anticorner/contrasted{
+ dir = 1
+ },
+/turf/open/floor/iron/showroomfloor,
+/area/station/science/ordnance/burnchamber)
"cNP" = (
/obj/machinery/atmospherics/pipe/smart/simple/cyan/visible{
dir = 4
@@ -8076,6 +8116,18 @@
/obj/structure/sign/warning/docking,
/turf/closed/wall/rust,
/area/space/nearstation)
+"cOt" = (
+/obj/structure/table/reinforced,
+/obj/effect/turf_decal/delivery,
+/obj/machinery/door/firedoor,
+/obj/item/folder/yellow,
+/obj/item/pen,
+/obj/machinery/door/window/left/directional/south{
+ name = "Cargo Desk";
+ req_access = list("shipping")
+ },
+/turf/open/floor/plating,
+/area/station/hallway/secondary/exit/departure_lounge)
"cON" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -8159,6 +8211,25 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
/area/station/engineering/supermatter/room)
+"cQI" = (
+/obj/structure/table,
+/obj/item/paper_bin{
+ pixel_x = 6;
+ pixel_y = 5
+ },
+/obj/machinery/ecto_sniffer{
+ pixel_x = -6
+ },
+/obj/item/mod/core/standard{
+ pixel_x = -4
+ },
+/obj/item/mod/core/standard{
+ pixel_x = 4
+ },
+/obj/item/mod/core/standard,
+/obj/effect/turf_decal/tile/neutral/half/contrasted,
+/turf/open/floor/iron/dark,
+/area/station/science/robotics/lab)
"cQJ" = (
/obj/effect/decal/cleanable/cobweb/cobweb2,
/obj/effect/decal/cleanable/dirt,
@@ -8448,17 +8519,6 @@
},
/turf/open/floor/engine,
/area/station/tcommsat/computer)
-"cVn" = (
-/obj/machinery/firealarm/directional/east,
-/mob/living/simple_animal/bot/mulebot,
-/obj/machinery/navbeacon{
- codes_txt = "delivery;dir=8";
- location = "QM #1"
- },
-/obj/effect/turf_decal/delivery,
-/obj/effect/decal/cleanable/cobweb/cobweb2,
-/turf/open/floor/iron/dark,
-/area/station/cargo/storage)
"cVr" = (
/obj/structure/sign/warning/vacuum/external,
/turf/closed/wall,
@@ -9701,6 +9761,15 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/smooth_large,
/area/station/maintenance/department/chapel/monastery)
+"dot" = (
+/obj/effect/decal/cleanable/blood/old,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/mob/living/basic/trooper/russian{
+ environment_smash = 0;
+ loot = list(/obj/effect/mob_spawn/corpse/human/russian)
+ },
+/turf/open/floor/carpet/green,
+/area/station/maintenance/port/greater)
"doy" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/door/poddoor/preopen{
@@ -10927,6 +10996,29 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
/area/station/maintenance/starboard)
+"dJT" = (
+/obj/structure/bed{
+ dir = 4
+ },
+/obj/effect/landmark/start/assistant,
+/obj/effect/spawner/random/bedsheet{
+ dir = 4
+ },
+/obj/effect/landmark/start/hangover,
+/obj/item/pillow/random,
+/turf/open/floor/wood,
+/area/station/commons/locker)
+"dJU" = (
+/obj/machinery/door/window/left/directional/east,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/turf_decal/tile/neutral/anticorner/contrasted{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 1
+ },
+/turf/open/floor/iron/dark,
+/area/station/medical/morgue)
"dKa" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/disposalpipe/segment{
@@ -11184,6 +11276,16 @@
},
/turf/open/floor/iron,
/area/station/security/prison)
+"dNO" = (
+/obj/structure/kitchenspike,
+/obj/effect/turf_decal/bot/left,
+/obj/machinery/airalarm/directional/north{
+ pixel_y = 24
+ },
+/obj/effect/mapping_helpers/airalarm/tlv_cold_room,
+/obj/item/radio/intercom/directional/east,
+/turf/open/floor/iron/freezer,
+/area/station/service/kitchen/coldroom)
"dOg" = (
/obj/item/kirbyplants{
icon_state = "plant-22"
@@ -11397,6 +11499,17 @@
/obj/effect/turf_decal/tile/neutral/anticorner/contrasted,
/turf/open/floor/iron/dark,
/area/station/science/robotics/lab)
+"dRY" = (
+/obj/structure/table,
+/obj/structure/window/reinforced/spawner/directional/east,
+/obj/structure/window/reinforced/spawner/directional/west,
+/obj/effect/spawner/random/aimodule/neutral,
+/obj/machinery/door/window/left/directional/south{
+ name = "Core Modules";
+ req_access = list("captain")
+ },
+/turf/open/floor/circuit,
+/area/station/ai_monitored/turret_protected/ai_upload)
"dSe" = (
/obj/effect/turf_decal/bot,
/obj/structure/rack,
@@ -13044,6 +13157,14 @@
},
/turf/open/floor/iron/dark,
/area/station/security/courtroom)
+"ewr" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 8
+ },
+/obj/effect/decal/cleanable/blood/old,
+/mob/living/basic/goat/pete,
+/turf/open/floor/iron/freezer,
+/area/station/service/kitchen/coldroom)
"ewt" = (
/obj/effect/turf_decal/arrows/red{
dir = 4;
@@ -13124,18 +13245,6 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/station/engineering/supermatter/room)
-"exG" = (
-/obj/structure/bed{
- dir = 4
- },
-/obj/effect/landmark/start/assistant,
-/obj/effect/spawner/random/bedsheet{
- dir = 4
- },
-/obj/effect/landmark/start/hangover,
-/obj/item/pillow/random,
-/turf/open/floor/wood,
-/area/station/commons/locker)
"exH" = (
/obj/effect/turf_decal/bot,
/obj/effect/spawner/random/vending/colavend,
@@ -15077,6 +15186,14 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/hallway/primary/central)
+"fgV" = (
+/obj/structure/bed,
+/obj/effect/landmark/start/assistant,
+/obj/effect/spawner/random/bedsheet,
+/obj/effect/landmark/start/hangover,
+/obj/item/pillow/random,
+/turf/open/floor/wood,
+/area/station/commons/locker)
"fhe" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/bot,
@@ -18499,6 +18616,15 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
+"ggK" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/landmark/event_spawn,
+/mob/living/basic/trooper/russian{
+ environment_smash = 0;
+ loot = list(/obj/effect/mob_spawn/corpse/human/russian)
+ },
+/turf/open/floor/carpet/green,
+/area/station/maintenance/port/greater)
"ggS" = (
/turf/closed/wall/r_wall,
/area/station/science/ordnance)
@@ -20141,6 +20267,18 @@
/obj/machinery/digital_clock/directional/north,
/turf/open/floor/iron/showroomfloor,
/area/station/service/bar/atrium)
+"gHA" = (
+/obj/structure/table/reinforced,
+/obj/effect/turf_decal/delivery,
+/obj/machinery/door/firedoor,
+/obj/machinery/door/window/left/directional/north{
+ name = "Security Desk";
+ req_access = list("security")
+ },
+/obj/item/crowbar/red,
+/obj/item/storage/fancy/donut_box,
+/turf/open/floor/plating,
+/area/station/hallway/secondary/exit/departure_lounge)
"gHC" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/door/poddoor/shutters/preopen{
@@ -21207,6 +21345,19 @@
/obj/item/radio/intercom/prison/directional/west,
/turf/open/floor/iron,
/area/station/security/prison/garden)
+"hbe" = (
+/obj/machinery/door/poddoor/preopen{
+ id = "xeno4";
+ name = "Creature Cell 4"
+ },
+/obj/effect/turf_decal/delivery,
+/obj/machinery/door/window/left/directional/east{
+ name = "Creature Cell";
+ req_access = list("xenobiology")
+ },
+/obj/structure/cable,
+/turf/open/floor/iron/dark,
+/area/station/science/xenobiology)
"hbf" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -21749,27 +21900,6 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
/area/station/security/prison)
-"hkH" = (
-/obj/structure/plasticflaps/opaque,
-/obj/machinery/navbeacon{
- codes_txt = "delivery;dir=8";
- location = "Atmospherics";
- name = "navigation beacon (Atmospherics Delivery)"
- },
-/obj/machinery/door/window/left/directional/west{
- name = "Atmospherics Delivery Access";
- req_access = list("atmospherics")
- },
-/obj/machinery/door/poddoor/preopen{
- id = "atmos";
- name = "Atmospherics Blast Door"
- },
-/obj/effect/turf_decal/delivery,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/iron/dark,
-/area/station/engineering/atmos/storage/gas)
"hkI" = (
/obj/effect/turf_decal/tile/yellow{
dir = 1
@@ -21811,6 +21941,14 @@
/obj/effect/mapping_helpers/airlock/access/all/security/armory,
/turf/open/floor/iron/dark,
/area/station/ai_monitored/security/armory)
+"hkW" = (
+/obj/structure/plasticflaps/opaque,
+/obj/machinery/door/window/left/directional/south{
+ name = "Cargo Delivery Access";
+ req_access = list("shipping")
+ },
+/turf/open/floor/plating,
+/area/station/hallway/secondary/exit/departure_lounge)
"hlb" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/tile/yellow/half/contrasted{
@@ -21819,6 +21957,25 @@
/obj/structure/sign/poster/official/safety_eye_protection/directional/east,
/turf/open/floor/iron/showroomfloor,
/area/station/medical/chemistry)
+"hlC" = (
+/obj/machinery/turretid{
+ icon_state = "control_stun";
+ name = "AI Chamber turret control";
+ pixel_x = 3;
+ pixel_y = 28
+ },
+/obj/machinery/door/window/left/directional/west{
+ name = "Primary AI Core Access";
+ req_access = list("ai_upload")
+ },
+/obj/machinery/door/poddoor/shutters/preopen{
+ dir = 8;
+ id = "AI Core shutters";
+ name = "AI Core Shutter"
+ },
+/obj/effect/turf_decal/delivery,
+/turf/open/floor/engine,
+/area/station/ai_monitored/turret_protected/ai)
"hlJ" = (
/obj/effect/turf_decal/bot,
/obj/machinery/modular_computer/preset/civilian{
@@ -21934,6 +22091,29 @@
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/plating,
/area/station/maintenance/fore)
+"hnl" = (
+/obj/machinery/door/window/left/directional/south{
+ name = "Cargo Delivery Access";
+ req_access = list("shipping")
+ },
+/obj/structure/plasticflaps/opaque,
+/obj/effect/turf_decal/delivery,
+/obj/structure/disposalpipe/segment,
+/turf/open/floor/iron/dark,
+/area/station/maintenance/starboard)
+"hnw" = (
+/obj/machinery/door/poddoor/preopen{
+ id = "xeno2";
+ name = "Creature Cell 2"
+ },
+/obj/effect/turf_decal/delivery,
+/obj/machinery/door/window/left/directional/west{
+ name = "Creature Cell";
+ req_access = list("xenobiology")
+ },
+/obj/structure/cable,
+/turf/open/floor/iron/dark,
+/area/station/science/xenobiology)
"hnA" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -23092,24 +23272,6 @@
},
/turf/open/floor/iron/dark,
/area/station/cargo/storage)
-"hGG" = (
-/obj/structure/table/reinforced,
-/obj/effect/turf_decal/delivery,
-/obj/machinery/door/firedoor,
-/obj/item/folder/blue,
-/obj/machinery/door/poddoor/shutters/preopen{
- id = "hop";
- name = "Privacy Shutters"
- },
-/obj/machinery/door/window/brigdoor/left/directional/north{
- name = "Head of Personnel's Desk";
- req_access = list("hop")
- },
-/obj/machinery/door/window/right/directional/south{
- name = "Reception Desk"
- },
-/turf/open/floor/iron,
-/area/station/command/heads_quarters/hop)
"hGX" = (
/obj/effect/turf_decal/bot,
/obj/structure/closet/emcloset,
@@ -25853,14 +26015,6 @@
},
/turf/open/floor/iron/dark,
/area/station/command/teleporter)
-"iuX" = (
-/obj/structure/chair/stool/bar/directional/west,
-/mob/living/basic/trooper/russian{
- environment_smash = 0;
- loot = list(/obj/effect/mob_spawn/corpse/human/russian)
- },
-/turf/open/floor/wood,
-/area/station/maintenance/port/greater)
"ivh" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/door/poddoor/shutters/preopen{
@@ -27038,6 +27192,33 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
/area/station/maintenance/fore)
+"iMJ" = (
+/obj/effect/landmark/start/ai/secondary,
+/obj/item/radio/intercom/directional/north{
+ freerange = 1;
+ listening = 0;
+ name = "Custom Channel";
+ pixel_x = 8
+ },
+/obj/item/radio/intercom/directional/east{
+ freerange = 1;
+ listening = 0;
+ name = "Common Channel"
+ },
+/obj/item/radio/intercom/directional/south{
+ freerange = 1;
+ frequency = 1447;
+ listening = 0;
+ name = "Private Channel";
+ pixel_x = 8
+ },
+/obj/machinery/door/window/left/directional/west{
+ name = "Tertiary AI Core Access";
+ pixel_x = -3;
+ req_access = list("ai_upload")
+ },
+/turf/open/floor/circuit/red,
+/area/station/ai_monitored/turret_protected/ai)
"iMN" = (
/obj/machinery/vending/boozeomat,
/turf/closed/wall,
@@ -28477,14 +28658,6 @@
},
/turf/open/floor/wood,
/area/station/service/chapel/monastery)
-"jjI" = (
-/obj/structure/bed,
-/obj/effect/landmark/start/assistant,
-/obj/effect/spawner/random/bedsheet,
-/obj/effect/landmark/start/hangover,
-/obj/item/pillow/random,
-/turf/open/floor/wood,
-/area/station/commons/locker)
"jjP" = (
/obj/structure/table,
/obj/effect/decal/cleanable/cobweb/cobweb2,
@@ -29028,31 +29201,6 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/cargo/warehouse)
-"jvY" = (
-/obj/item/storage/medkit/regular{
- pixel_x = 3;
- pixel_y = -3
- },
-/obj/item/storage/medkit/o2{
- pixel_x = 3;
- pixel_y = 3
- },
-/obj/item/storage/medkit/o2,
-/obj/item/storage/medkit/o2{
- pixel_x = -3;
- pixel_y = -3
- },
-/obj/structure/table/glass,
-/obj/structure/window/reinforced/spawner/directional/south,
-/obj/machinery/door/window/left/directional/west{
- name = "First-Aid Supplies";
- req_access = list("medical")
- },
-/obj/effect/turf_decal/tile/neutral/half/contrasted{
- dir = 8
- },
-/turf/open/floor/iron/dark,
-/area/station/medical/storage)
"jwi" = (
/obj/machinery/door/firedoor,
/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
@@ -32316,19 +32464,6 @@
/obj/structure/sign/warning/secure_area,
/turf/closed/wall,
/area/station/engineering/storage/tech)
-"kEg" = (
-/obj/machinery/conveyor{
- dir = 1;
- id = "mining";
- name = "crate return belt"
- },
-/obj/machinery/door/window/left/directional/north{
- name = "Crate Return Door";
- req_access = list("shipping")
- },
-/obj/effect/decal/cleanable/dirt,
-/turf/open/floor/plating,
-/area/station/cargo/storage)
"kEm" = (
/obj/item/kirbyplants/random,
/obj/structure/sign/poster/contraband/self_ai_liberation/directional/west,
@@ -33528,6 +33663,19 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/carpet/royalblue,
/area/station/service/chapel/office)
+"kXJ" = (
+/obj/machinery/door/poddoor/preopen{
+ id = "xeno1";
+ name = "Creature Cell 1"
+ },
+/obj/effect/turf_decal/delivery,
+/obj/machinery/door/window/left/directional/west{
+ name = "Creature Cell";
+ req_access = list("xenobiology")
+ },
+/obj/structure/cable,
+/turf/open/floor/iron/dark,
+/area/station/science/xenobiology)
"kXN" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/effect/decal/cleanable/dirt,
@@ -33874,21 +34022,6 @@
},
/turf/open/floor/iron,
/area/station/commons/fitness/recreation)
-"lcj" = (
-/obj/structure/table/reinforced,
-/obj/effect/turf_decal/delivery,
-/obj/machinery/door/firedoor,
-/obj/item/storage/box/lights/mixed{
- pixel_y = 6
- },
-/obj/machinery/door/window/right/directional/east{
- name = "Cargo Desk";
- req_access = list("shipping")
- },
-/obj/item/flashlight,
-/obj/effect/spawner/random/bureaucracy/birthday_wrap,
-/turf/open/floor/plating,
-/area/station/cargo/office)
"lck" = (
/obj/structure/chair{
dir = 1
@@ -33918,6 +34051,23 @@
/obj/item/assembly/health,
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
+"lcK" = (
+/obj/machinery/door/window/left/directional/east{
+ name = "Primary AI Core Access";
+ req_access = list("ai_upload")
+ },
+/obj/machinery/door/poddoor/shutters/preopen{
+ dir = 4;
+ id = "AI Core shutters";
+ name = "AI Core Shutter"
+ },
+/obj/effect/turf_decal/delivery,
+/obj/machinery/light_switch/directional/north{
+ pixel_x = 8
+ },
+/obj/machinery/door/firedoor,
+/turf/open/floor/engine,
+/area/station/ai_monitored/turret_protected/ai)
"lcN" = (
/obj/machinery/portable_atmospherics/canister/oxygen,
/obj/effect/turf_decal/box,
@@ -33971,23 +34121,6 @@
},
/turf/open/floor/iron/dark,
/area/station/cargo/storage)
-"leg" = (
-/obj/machinery/atmospherics/pipe/smart/simple/dark/visible,
-/obj/machinery/portable_atmospherics/pump/lil_pump,
-/obj/machinery/camera/directional/west{
- c_tag = "Ordnance Mixing Lab";
- name = "science camera";
- network = list("ss13","rd")
- },
-/obj/machinery/airalarm/directional/west{
- pixel_x = -28
- },
-/obj/effect/mapping_helpers/airalarm/mixingchamber_access,
-/obj/effect/turf_decal/tile/purple/anticorner/contrasted{
- dir = 1
- },
-/turf/open/floor/iron/showroomfloor,
-/area/station/science/ordnance/burnchamber)
"lep" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/obj/machinery/computer/operating{
@@ -34227,22 +34360,6 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/grass,
/area/station/science/genetics)
-"lhM" = (
-/obj/structure/window/reinforced/spawner/directional/south,
-/obj/machinery/door/window/right/directional/east{
- name = "Mail Chute";
- req_access = list("shipping")
- },
-/obj/effect/turf_decal/stripes/line{
- dir = 6
- },
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/effect/turf_decal/tile/brown/half/contrasted,
-/obj/effect/turf_decal/tile/yellow,
-/turf/open/floor/iron,
-/area/station/cargo/sorting)
"lia" = (
/obj/effect/turf_decal/tile/brown/half/contrasted{
dir = 4
@@ -35808,13 +35925,6 @@
},
/turf/open/floor/iron/showroomfloor,
/area/station/medical/medbay/central)
-"lIb" = (
-/obj/machinery/door/window/left/directional/east{
- name = "Monkey Pen";
- req_access = list("genetics")
- },
-/turf/open/floor/grass,
-/area/station/science/genetics)
"lIr" = (
/obj/effect/turf_decal/stripes/line,
/obj/effect/turf_decal/stripes/line{
@@ -36817,6 +36927,18 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central/fore)
+"map" = (
+/obj/effect/turf_decal/bot,
+/obj/item/radio/intercom/directional/north,
+/obj/effect/decal/cleanable/cobweb,
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/cable,
+/obj/effect/turf_decal/tile/neutral/half/contrasted,
+/obj/machinery/power/smes/super/full{
+ name = "ai power storage unit"
+ },
+/turf/open/floor/iron/dark,
+/area/station/ai_monitored/command/storage/satellite)
"maA" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/tile/yellow/anticorner/contrasted{
@@ -37020,6 +37142,19 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron,
/area/station/security/brig)
+"mdw" = (
+/obj/structure/plasticflaps/opaque,
+/obj/machinery/navbeacon{
+ codes_txt = "delivery;dir=1";
+ location = "Research and Development"
+ },
+/obj/machinery/door/window/left/directional/north{
+ name = "Research and Development Delivery Access";
+ req_access = list("science")
+ },
+/obj/effect/turf_decal/delivery,
+/turf/open/floor/iron/dark,
+/area/station/maintenance/starboard)
"mdB" = (
/obj/machinery/door/airlock/external{
name = "External Freight Airlock"
@@ -37299,19 +37434,6 @@
dir = 1
},
/area/station/hallway/primary/starboard)
-"mhw" = (
-/obj/machinery/door/poddoor/preopen{
- id = "xeno1";
- name = "Creature Cell 1"
- },
-/obj/effect/turf_decal/delivery,
-/obj/machinery/door/window/left/directional/west{
- name = "Creature Cell";
- req_access = list("xenobiology")
- },
-/obj/structure/cable,
-/turf/open/floor/iron/dark,
-/area/station/science/xenobiology)
"mhP" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -39101,6 +39223,17 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/green/visible,
/turf/closed/wall/r_wall,
/area/station/engineering/supermatter)
+"mMF" = (
+/obj/machinery/firealarm/directional/east,
+/mob/living/simple_animal/bot/mulebot,
+/obj/machinery/navbeacon{
+ codes_txt = "delivery;dir=8";
+ location = "QM #1"
+ },
+/obj/effect/turf_decal/delivery,
+/obj/effect/decal/cleanable/cobweb/cobweb2,
+/turf/open/floor/iron/dark,
+/area/station/cargo/storage)
"mMJ" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/turf_decal/stripes/corner{
@@ -41733,6 +41866,24 @@
},
/turf/open/floor/iron/dark,
/area/station/engineering/atmos)
+"nGT" = (
+/obj/structure/window/reinforced/spawner/directional/north,
+/obj/structure/window/reinforced/spawner/directional/south,
+/obj/machinery/door/window/left/directional/east{
+ name = "Inner Pipe Access";
+ req_access = list("atmospherics")
+ },
+/obj/effect/decal/cleanable/dirt,
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible,
+/obj/effect/turf_decal/tile/neutral/half/contrasted{
+ dir = 8
+ },
+/obj/machinery/atmospherics/pipe/bridge_pipe/yellow/visible{
+ dir = 4
+ },
+/turf/open/floor/iron/dark,
+/area/station/engineering/atmos)
"nHd" = (
/obj/structure/cable,
/obj/effect/turf_decal/tile/yellow/half/contrasted{
@@ -42443,23 +42594,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron,
/area/station/hallway/primary/aft)
-"nVN" = (
-/obj/structure/bed,
-/obj/effect/decal/cleanable/cobweb/cobweb2,
-/obj/machinery/airalarm/directional/east,
-/obj/effect/landmark/start/assistant,
-/obj/effect/spawner/random/bedsheet,
-/obj/effect/landmark/start/hangover,
-/obj/machinery/button/door/directional/north{
- id = "Cabin_2";
- name = "Cabin 2 Privacy Lock";
- normaldoorcontrol = 1;
- specialfunctions = 4
- },
-/obj/effect/mapping_helpers/broken_floor,
-/obj/item/pillow/random,
-/turf/open/floor/wood,
-/area/station/commons/locker)
"nWG" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -42888,17 +43022,6 @@
},
/turf/open/floor/engine/n2,
/area/station/engineering/atmos)
-"oeZ" = (
-/obj/structure/table,
-/obj/structure/window/reinforced/spawner/directional/east,
-/obj/structure/window/reinforced/spawner/directional/west,
-/obj/effect/spawner/random/aimodule/neutral,
-/obj/machinery/door/window/left/directional/south{
- name = "Core Modules";
- req_access = list("captain")
- },
-/turf/open/floor/circuit,
-/area/station/ai_monitored/turret_protected/ai_upload)
"ofa" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/decal/cleanable/dirt,
@@ -43235,6 +43358,20 @@
dir = 8
},
/area/station/service/chapel/funeral)
+"okt" = (
+/obj/machinery/door/window/left/directional/east{
+ name = "Creature Cell";
+ req_access = list("xenobiology")
+ },
+/obj/structure/cable,
+/obj/effect/turf_decal/stripes/line{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral/half/contrasted{
+ dir = 4
+ },
+/turf/open/floor/iron/dark,
+/area/station/science/xenobiology)
"okJ" = (
/obj/effect/decal/cleanable/dirt,
/obj/structure/disposalpipe/segment{
@@ -43451,22 +43588,6 @@
},
/turf/open/floor/plating,
/area/station/maintenance/fore)
-"ooX" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 9
- },
-/obj/effect/turf_decal/box/corners,
-/obj/effect/decal/cleanable/blood/old,
-/obj/structure/window/reinforced/spawner/directional/north{
- pixel_y = 1
- },
-/obj/machinery/door/window/right/directional/west{
- name = "Fitness Ring"
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/turf_decal/tile/neutral,
-/turf/open/floor/iron/dark,
-/area/station/commons/fitness/recreation)
"opE" = (
/obj/effect/landmark/start/scientist,
/obj/effect/decal/cleanable/dirt,
@@ -43886,6 +44007,23 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/station/maintenance/central)
+"owJ" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 6
+ },
+/obj/effect/turf_decal/box/corners{
+ dir = 1
+ },
+/obj/structure/window/reinforced/spawner/directional/south,
+/obj/machinery/door/window/right/directional/east{
+ name = "Fitness Ring"
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/tile/neutral{
+ dir = 1
+ },
+/turf/open/floor/iron/dark,
+/area/station/commons/fitness/recreation)
"owT" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/pipe/smart/simple/green/visible{
@@ -44351,16 +44489,6 @@
},
/turf/open/floor/iron/dark,
/area/station/service/hydroponics)
-"oGf" = (
-/obj/machinery/door/window/left/directional/south{
- name = "Cargo Delivery Access";
- req_access = list("shipping")
- },
-/obj/structure/plasticflaps/opaque,
-/obj/effect/turf_decal/delivery,
-/obj/structure/disposalpipe/segment,
-/turf/open/floor/iron/dark,
-/area/station/maintenance/starboard)
"oGo" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -44460,6 +44588,23 @@
/obj/effect/spawner/random/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/starboard)
+"oIe" = (
+/obj/structure/bed,
+/obj/effect/decal/cleanable/cobweb/cobweb2,
+/obj/machinery/airalarm/directional/east,
+/obj/effect/landmark/start/assistant,
+/obj/effect/spawner/random/bedsheet,
+/obj/effect/landmark/start/hangover,
+/obj/machinery/button/door/directional/north{
+ id = "Cabin_2";
+ name = "Cabin 2 Privacy Lock";
+ normaldoorcontrol = 1;
+ specialfunctions = 4
+ },
+/obj/effect/mapping_helpers/broken_floor,
+/obj/item/pillow/random,
+/turf/open/floor/wood,
+/area/station/commons/locker)
"oIg" = (
/obj/effect/turf_decal/delivery,
/obj/effect/turf_decal/tile/yellow/anticorner/contrasted{
@@ -44508,6 +44653,22 @@
},
/turf/open/floor/plating,
/area/station/maintenance/port/lesser)
+"oJd" = (
+/obj/structure/window/reinforced/spawner/directional/south,
+/obj/machinery/door/window/right/directional/east{
+ name = "Mail Chute";
+ req_access = list("shipping")
+ },
+/obj/effect/turf_decal/stripes/line{
+ dir = 6
+ },
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/brown/half/contrasted,
+/obj/effect/turf_decal/tile/yellow,
+/turf/open/floor/iron,
+/area/station/cargo/sorting)
"oJm" = (
/obj/structure/cable,
/turf/open/floor/iron/showroomfloor,
@@ -46368,6 +46529,14 @@
},
/turf/open/floor/plating/airless,
/area/space/nearstation)
+"pmR" = (
+/obj/structure/chair/stool/bar/directional/west,
+/mob/living/basic/trooper/russian{
+ environment_smash = 0;
+ loot = list(/obj/effect/mob_spawn/corpse/human/russian)
+ },
+/turf/open/floor/wood,
+/area/station/maintenance/port/greater)
"pnl" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -46839,6 +47008,20 @@
/obj/machinery/light_switch/directional/south,
/turf/open/floor/iron/dark,
/area/station/command/gateway)
+"puJ" = (
+/obj/machinery/door/window/left/directional/west{
+ name = "Creature Cell";
+ req_access = list("xenobiology")
+ },
+/obj/structure/cable,
+/obj/effect/turf_decal/stripes/line{
+ dir = 8
+ },
+/obj/effect/turf_decal/tile/neutral/half/contrasted{
+ dir = 8
+ },
+/turf/open/floor/iron/dark,
+/area/station/science/xenobiology)
"puS" = (
/obj/effect/turf_decal/delivery,
/obj/machinery/power/emitter,
@@ -47162,6 +47345,19 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/iron/freezer,
/area/station/service/kitchen/coldroom)
+"pCa" = (
+/obj/machinery/door/poddoor/preopen{
+ id = "xeno3";
+ name = "Creature Cell 3"
+ },
+/obj/effect/turf_decal/delivery,
+/obj/machinery/door/window/left/directional/east{
+ name = "Creature Cell";
+ req_access = list("xenobiology")
+ },
+/obj/structure/cable,
+/turf/open/floor/iron/dark,
+/area/station/science/xenobiology)
"pCb" = (
/obj/effect/landmark/event_spawn,
/obj/effect/turf_decal/tile/neutral,
@@ -47295,6 +47491,17 @@
/obj/effect/decal/cleanable/generic,
/turf/open/floor/plating,
/area/station/maintenance/department/bridge)
+"pEf" = (
+/mob/living/simple_animal/bot/mulebot,
+/obj/machinery/navbeacon{
+ codes_txt = "delivery;dir=8";
+ location = "QM #2"
+ },
+/obj/effect/turf_decal/delivery,
+/obj/effect/decal/cleanable/dirt,
+/obj/effect/decal/cleanable/blood/old,
+/turf/open/floor/iron/dark,
+/area/station/cargo/storage)
"pEt" = (
/obj/machinery/door/airlock/maintenance,
/obj/structure/cable,
@@ -48275,16 +48482,6 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/maintenance/department/electrical)
-"pSx" = (
-/obj/structure/kitchenspike,
-/obj/effect/turf_decal/bot/left,
-/obj/machinery/airalarm/directional/north{
- pixel_y = 24
- },
-/obj/effect/mapping_helpers/airalarm/tlv_cold_room,
-/obj/item/radio/intercom/directional/east,
-/turf/open/floor/iron/freezer,
-/area/station/service/kitchen/coldroom)
"pSE" = (
/obj/machinery/atmospherics/components/binary/pump{
dir = 4;
@@ -48481,6 +48678,31 @@
},
/turf/open/floor/iron/dark,
/area/station/cargo/storage)
+"pXf" = (
+/obj/item/storage/medkit/regular{
+ pixel_x = 3;
+ pixel_y = -3
+ },
+/obj/item/storage/medkit/o2{
+ pixel_x = 3;
+ pixel_y = 3
+ },
+/obj/item/storage/medkit/o2,
+/obj/item/storage/medkit/o2{
+ pixel_x = -3;
+ pixel_y = -3
+ },
+/obj/structure/table/glass,
+/obj/structure/window/reinforced/spawner/directional/south,
+/obj/machinery/door/window/left/directional/west{
+ name = "First-Aid Supplies";
+ req_access = list("medical")
+ },
+/obj/effect/turf_decal/tile/neutral/half/contrasted{
+ dir = 8
+ },
+/turf/open/floor/iron/dark,
+/area/station/medical/storage)
"pXh" = (
/obj/effect/turf_decal/stripes/corner{
dir = 8
@@ -48650,15 +48872,6 @@
/obj/structure/sign/departments/medbay/alt,
/turf/closed/wall,
/area/station/medical/paramedic)
-"qaX" = (
-/obj/effect/decal/cleanable/blood/old,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/mob/living/basic/trooper/russian{
- environment_smash = 0;
- loot = list(/obj/effect/mob_spawn/corpse/human/russian)
- },
-/turf/open/floor/carpet/green,
-/area/station/maintenance/port/greater)
"qaZ" = (
/obj/machinery/atmospherics/components/unary/vent_pump/siphon/monitored/mix_output{
dir = 1
@@ -49800,23 +50013,6 @@
/obj/structure/flora/rock/style_random,
/turf/open/misc/asteroid/lowpressure,
/area/space/nearstation)
-"qvt" = (
-/obj/effect/turf_decal/stripes/line{
- dir = 6
- },
-/obj/effect/turf_decal/box/corners{
- dir = 1
- },
-/obj/structure/window/reinforced/spawner/directional/south,
-/obj/machinery/door/window/right/directional/east{
- name = "Fitness Ring"
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/turf_decal/tile/neutral{
- dir = 1
- },
-/turf/open/floor/iron/dark,
-/area/station/commons/fitness/recreation)
"qvG" = (
/obj/effect/turf_decal/stripes/corner,
/obj/structure/cable,
@@ -52047,6 +52243,28 @@
},
/turf/open/floor/wood,
/area/station/service/library)
+"riS" = (
+/obj/structure/table/reinforced,
+/obj/effect/turf_decal/delivery,
+/obj/machinery/door/firedoor,
+/obj/machinery/door/window/left/directional/east{
+ name = "Cargo Desk";
+ req_access = list("shipping")
+ },
+/obj/item/clipboard{
+ pixel_x = 3;
+ pixel_y = -2
+ },
+/obj/item/folder{
+ pixel_x = 3;
+ pixel_y = -2
+ },
+/obj/structure/desk_bell{
+ pixel_x = -8;
+ pixel_y = 10
+ },
+/turf/open/floor/plating,
+/area/station/cargo/office)
"riW" = (
/obj/effect/turf_decal/siding/wood{
dir = 6
@@ -52248,6 +52466,22 @@
/obj/structure/sign/poster/contraband/missing_gloves/directional/east,
/turf/open/floor/circuit/red,
/area/station/engineering/supermatter/room)
+"rnB" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 9
+ },
+/obj/effect/turf_decal/box/corners,
+/obj/effect/decal/cleanable/blood/old,
+/obj/structure/window/reinforced/spawner/directional/north{
+ pixel_y = 1
+ },
+/obj/machinery/door/window/right/directional/west{
+ name = "Fitness Ring"
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/turf_decal/tile/neutral,
+/turf/open/floor/iron/dark,
+/area/station/commons/fitness/recreation)
"rnG" = (
/turf/closed/wall/r_wall,
/area/station/hallway/secondary/service)
@@ -52660,26 +52894,6 @@
},
/turf/open/floor/iron/dark,
/area/station/hallway/secondary/exit/departure_lounge)
-"rsm" = (
-/obj/structure/table/reinforced,
-/obj/machinery/door/firedoor,
-/obj/item/clipboard{
- pixel_x = 3
- },
-/obj/item/folder/yellow{
- pixel_x = 3
- },
-/obj/machinery/door/window/left/directional/east{
- name = "Mailroom Desk";
- req_access = list("shipping")
- },
-/obj/effect/landmark/start/hangover,
-/obj/structure/desk_bell{
- pixel_x = -8;
- pixel_y = 10
- },
-/turf/open/floor/iron,
-/area/station/cargo/sorting)
"rsw" = (
/obj/effect/turf_decal/tile/blue/half/contrasted,
/obj/effect/turf_decal/tile/neutral,
@@ -53421,6 +53635,13 @@
},
/turf/open/floor/iron/showroomfloor,
/area/station/security/medical)
+"rEB" = (
+/obj/structure/cable,
+/obj/machinery/power/smes/super/full{
+ name = "ai power storage unit"
+ },
+/turf/open/floor/circuit/green,
+/area/station/ai_monitored/turret_protected/ai)
"rEE" = (
/obj/effect/turf_decal/bot,
/obj/machinery/conveyor{
@@ -53666,24 +53887,6 @@
/obj/effect/turf_decal/tile/neutral/half/contrasted,
/turf/open/floor/iron/dark,
/area/station/service/janitor)
-"rJj" = (
-/obj/structure/window/reinforced/spawner/directional/north,
-/obj/structure/window/reinforced/spawner/directional/south,
-/obj/machinery/door/window/left/directional/east{
- name = "Inner Pipe Access";
- req_access = list("atmospherics")
- },
-/obj/effect/decal/cleanable/dirt,
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible,
-/obj/effect/turf_decal/tile/neutral/half/contrasted{
- dir = 8
- },
-/obj/machinery/atmospherics/pipe/bridge_pipe/yellow/visible{
- dir = 4
- },
-/turf/open/floor/iron/dark,
-/area/station/engineering/atmos)
"rJJ" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -53875,19 +54078,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/misc/asteroid,
/area/space/nearstation)
-"rLN" = (
-/obj/effect/turf_decal/bot,
-/obj/item/radio/intercom/directional/north,
-/obj/effect/decal/cleanable/cobweb,
-/obj/effect/decal/cleanable/dirt,
-/obj/machinery/power/smes{
- charge = 5e+006;
- name = "ai power storage unit"
- },
-/obj/structure/cable,
-/obj/effect/turf_decal/tile/neutral/half/contrasted,
-/turf/open/floor/iron/dark,
-/area/station/ai_monitored/command/storage/satellite)
"rLR" = (
/obj/structure/sign/warning/docking,
/turf/closed/wall/rust,
@@ -54211,20 +54401,6 @@
},
/turf/open/floor/iron/dark,
/area/station/service/hydroponics)
-"rQY" = (
-/obj/machinery/door/window/left/directional/east{
- name = "Creature Cell";
- req_access = list("xenobiology")
- },
-/obj/structure/cable,
-/obj/effect/turf_decal/stripes/line{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral/half/contrasted{
- dir = 4
- },
-/turf/open/floor/iron/dark,
-/area/station/science/xenobiology)
"rQZ" = (
/obj/structure/cable,
/obj/machinery/door/airlock/maintenance,
@@ -54969,18 +55145,6 @@
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
/area/station/commons/storage/primary)
-"scY" = (
-/obj/structure/table/reinforced,
-/obj/effect/turf_decal/delivery,
-/obj/machinery/door/firedoor,
-/obj/item/folder/yellow,
-/obj/item/pen,
-/obj/machinery/door/window/left/directional/south{
- name = "Cargo Desk";
- req_access = list("shipping")
- },
-/turf/open/floor/plating,
-/area/station/hallway/secondary/exit/departure_lounge)
"sda" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/sign/warning/secure_area/directional/south,
@@ -55031,17 +55195,6 @@
/obj/effect/turf_decal/tile/neutral/half/contrasted,
/turf/open/floor/iron/dark,
/area/station/command/heads_quarters/ce)
-"sdJ" = (
-/mob/living/simple_animal/bot/mulebot,
-/obj/machinery/navbeacon{
- codes_txt = "delivery;dir=8";
- location = "QM #2"
- },
-/obj/effect/turf_decal/delivery,
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/decal/cleanable/blood/old,
-/turf/open/floor/iron/dark,
-/area/station/cargo/storage)
"sdT" = (
/obj/structure/girder,
/obj/effect/decal/cleanable/dirt,
@@ -55100,25 +55253,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron,
/area/station/hallway/secondary/exit/departure_lounge)
-"seT" = (
-/obj/structure/table,
-/obj/item/paper_bin{
- pixel_x = 6;
- pixel_y = 5
- },
-/obj/machinery/ecto_sniffer{
- pixel_x = -6
- },
-/obj/item/mod/core/standard{
- pixel_x = -4
- },
-/obj/item/mod/core/standard{
- pixel_x = 4
- },
-/obj/item/mod/core/standard,
-/obj/effect/turf_decal/tile/neutral/half/contrasted,
-/turf/open/floor/iron/dark,
-/area/station/science/robotics/lab)
"seU" = (
/obj/structure/table,
/obj/item/clothing/gloves/color/yellow,
@@ -55228,20 +55362,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron,
/area/station/security/office)
-"sgQ" = (
-/obj/machinery/door/firedoor,
-/obj/effect/turf_decal/stripes/box,
-/obj/machinery/mineral/ore_redemption{
- dir = 8;
- input_dir = 4;
- output_dir = 8
- },
-/obj/machinery/door/window/left/directional/west{
- name = "Ore Redemtion Window";
- req_access = list("mineral_storeroom")
- },
-/turf/open/floor/plating,
-/area/station/cargo/office)
"shk" = (
/obj/machinery/telecomms/bus/preset_four,
/turf/open/floor/circuit/green/telecomms/mainframe,
@@ -56959,6 +57079,19 @@
/obj/machinery/status_display/evac/directional/west,
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
+"sJI" = (
+/obj/structure/window/reinforced/spawner/directional/north,
+/obj/structure/window/reinforced/spawner/directional/south,
+/obj/machinery/door/window/left/directional/east{
+ name = "Inner Pipe Access";
+ req_access = list("atmospherics")
+ },
+/obj/machinery/atmospherics/pipe/smart/simple/green/visible,
+/obj/effect/turf_decal/tile/neutral/half/contrasted{
+ dir = 8
+ },
+/turf/open/floor/iron/dark,
+/area/station/engineering/atmos)
"sJJ" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/structure/chair/office{
@@ -59114,14 +59247,6 @@
/obj/effect/turf_decal/tile/blue,
/turf/open/floor/iron/showroomfloor,
/area/station/medical/medbay/central)
-"tpB" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 8
- },
-/obj/effect/decal/cleanable/blood/old,
-/mob/living/basic/goat/pete,
-/turf/open/floor/iron/freezer,
-/area/station/service/kitchen/coldroom)
"tpD" = (
/obj/machinery/atmospherics/components/tank/air{
dir = 8
@@ -60664,6 +60789,20 @@
/obj/structure/reagent_dispensers/watertank,
/turf/open/floor/plating,
/area/station/maintenance/starboard)
+"tQI" = (
+/obj/machinery/door/firedoor,
+/obj/effect/turf_decal/stripes/box,
+/obj/machinery/mineral/ore_redemption{
+ dir = 8;
+ input_dir = 4;
+ output_dir = 8
+ },
+/obj/machinery/door/window/left/directional/west{
+ name = "Ore Redemtion Window";
+ req_access = list("mineral_storeroom")
+ },
+/turf/open/floor/plating,
+/area/station/cargo/office)
"tQM" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -61096,23 +61235,6 @@
},
/turf/open/floor/plating,
/area/station/commons/fitness/recreation)
-"tYG" = (
-/obj/machinery/door/window/left/directional/east{
- name = "Primary AI Core Access";
- req_access = list("ai_upload")
- },
-/obj/machinery/door/poddoor/shutters/preopen{
- dir = 4;
- id = "AI Core shutters";
- name = "AI Core Shutter"
- },
-/obj/effect/turf_decal/delivery,
-/obj/machinery/light_switch/directional/north{
- pixel_x = 8
- },
-/obj/machinery/door/firedoor,
-/turf/open/floor/engine,
-/area/station/ai_monitored/turret_protected/ai)
"tYZ" = (
/obj/machinery/atmospherics/components/binary/pump{
dir = 1;
@@ -61382,6 +61504,19 @@
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/plating,
/area/station/maintenance/port/greater)
+"udt" = (
+/obj/machinery/conveyor{
+ dir = 1;
+ id = "mining";
+ name = "crate return belt"
+ },
+/obj/machinery/door/window/left/directional/north{
+ name = "Crate Return Door";
+ req_access = list("shipping")
+ },
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/station/cargo/storage)
"udA" = (
/obj/machinery/door/airlock/external{
name = "Abandoned External Airlock"
@@ -61743,6 +61878,23 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
/area/station/maintenance/disposal)
+"uik" = (
+/obj/structure/table/reinforced,
+/obj/effect/turf_decal/delivery,
+/obj/item/folder/white,
+/obj/item/pen,
+/obj/machinery/door/poddoor/shutters/preopen{
+ dir = 1;
+ id = "chemistry_shutters";
+ name = "Chemistry Lobby Shutters"
+ },
+/obj/machinery/door/firedoor/heavy,
+/obj/machinery/door/window/left/directional/south{
+ name = "Chemistry Desk";
+ req_access = list("pharmacy")
+ },
+/turf/open/floor/plating,
+/area/station/medical/pharmacy)
"uiu" = (
/obj/structure/flora/bush/jungle/b/style_random,
/turf/open/floor/grass,
@@ -63048,31 +63200,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/dark,
/area/station/service/chapel/storage)
-"uFf" = (
-/obj/structure/table/reinforced,
-/obj/effect/turf_decal/delivery,
-/obj/item/folder/yellow{
- pixel_x = -4
- },
-/obj/item/pen{
- pixel_x = -4
- },
-/obj/machinery/door/poddoor/shutters/preopen{
- dir = 4;
- id = "chemistry_shutters_2";
- name = "Chemistry Hall Shutters"
- },
-/obj/machinery/door/firedoor/heavy,
-/obj/machinery/door/window/left/directional/west{
- name = "Chemistry Desk";
- req_access = list("pharmacy")
- },
-/obj/structure/desk_bell{
- pixel_x = 7;
- pixel_y = 6
- },
-/turf/open/floor/plating,
-/area/station/medical/pharmacy)
"uFh" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -63361,6 +63488,13 @@
/obj/effect/mapping_helpers/airlock/access/all/engineering/general,
/turf/open/floor/iron/dark,
/area/station/engineering/supermatter/room)
+"uJP" = (
+/obj/machinery/door/window/left/directional/east{
+ name = "Monkey Pen";
+ req_access = list("genetics")
+ },
+/turf/open/floor/grass,
+/area/station/science/genetics)
"uJV" = (
/turf/closed/wall,
/area/station/commons/vacant_room/commissary)
@@ -64009,14 +64143,6 @@
/obj/structure/cable,
/turf/open/floor/grass,
/area/station/security/prison/garden)
-"uXq" = (
-/obj/structure/plasticflaps/opaque,
-/obj/machinery/door/window/left/directional/south{
- name = "Cargo Delivery Access";
- req_access = list("shipping")
- },
-/turf/open/floor/plating,
-/area/station/hallway/secondary/exit/departure_lounge)
"uXB" = (
/obj/effect/turf_decal/bot,
/obj/structure/closet/firecloset,
@@ -64985,6 +65111,17 @@
},
/turf/open/floor/iron/dark,
/area/station/security/courtroom)
+"vnj" = (
+/obj/effect/turf_decal/stripes/corner,
+/obj/effect/decal/cleanable/blood/old,
+/obj/effect/turf_decal/tile/neutral/half/contrasted,
+/obj/machinery/brm,
+/obj/machinery/conveyor{
+ dir = 1;
+ id = "mining"
+ },
+/turf/open/floor/iron/dark,
+/area/station/cargo/miningoffice)
"vns" = (
/obj/machinery/air_sensor/plasma_tank,
/turf/open/floor/engine/plasma,
@@ -65838,6 +65975,16 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron,
/area/station/hallway/primary/central/fore)
+"vAa" = (
+/obj/structure/table/reinforced,
+/obj/machinery/door/window/left/directional/north,
+/obj/machinery/door/poddoor/shutters{
+ dir = 1;
+ id = "visitation";
+ name = "Visitation Shutters"
+ },
+/turf/open/floor/iron/showroomfloor,
+/area/station/security/execution/transfer)
"vAh" = (
/obj/effect/landmark/start/chaplain,
/obj/structure/chair/wood{
@@ -67400,19 +67547,6 @@
/obj/structure/sign/warning/fire,
/turf/closed/wall,
/area/station/maintenance/port/greater)
-"vVK" = (
-/obj/structure/window/reinforced/spawner/directional/north,
-/obj/structure/window/reinforced/spawner/directional/south,
-/obj/machinery/door/window/left/directional/east{
- name = "Inner Pipe Access";
- req_access = list("atmospherics")
- },
-/obj/machinery/atmospherics/pipe/smart/simple/green/visible,
-/obj/effect/turf_decal/tile/neutral/half/contrasted{
- dir = 8
- },
-/turf/open/floor/iron/dark,
-/area/station/engineering/atmos)
"vVM" = (
/obj/structure/table,
/obj/effect/decal/cleanable/dirt,
@@ -68018,28 +68152,6 @@
},
/turf/open/floor/iron,
/area/station/commons/fitness/recreation)
-"weZ" = (
-/obj/structure/plasticflaps/opaque,
-/obj/machinery/navbeacon{
- codes_txt = "delivery;dir=1";
- location = "Engineering";
- name = "navigation beacon (Engineering Delivery)"
- },
-/obj/machinery/door/window/right/directional/east{
- name = "Engineering Delivery Access";
- req_access = list("engineering")
- },
-/obj/machinery/door/poddoor/preopen{
- id = "Engineering";
- name = "Engineering Blast Doors"
- },
-/obj/effect/turf_decal/delivery,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/iron/dark,
-/area/station/engineering/lobby)
"wfk" = (
/obj/effect/turf_decal/bot,
/obj/machinery/holopad,
@@ -68139,15 +68251,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central)
-"whc" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/landmark/event_spawn,
-/mob/living/basic/trooper/russian{
- environment_smash = 0;
- loot = list(/obj/effect/mob_spawn/corpse/human/russian)
- },
-/turf/open/floor/carpet/green,
-/area/station/maintenance/port/greater)
"whj" = (
/obj/structure/girder,
/obj/effect/decal/cleanable/cobweb,
@@ -68194,20 +68297,6 @@
},
/turf/open/floor/iron/dark,
/area/station/engineering/storage_shared)
-"whS" = (
-/obj/structure/plasticflaps/opaque,
-/obj/machinery/navbeacon{
- codes_txt = "delivery;dir=2";
- location = "Research Division"
- },
-/obj/machinery/door/window/left/directional/south{
- name = "Research Division Delivery Access";
- req_access = list("research")
- },
-/obj/effect/turf_decal/delivery,
-/obj/structure/cable,
-/turf/open/floor/iron/dark,
-/area/station/maintenance/starboard)
"wij" = (
/obj/effect/spawner/structure/window/reinforced/tinted,
/turf/open/floor/plating,
@@ -68536,25 +68625,6 @@
/obj/structure/noticeboard/directional/north,
/turf/open/floor/wood,
/area/station/service/theater)
-"wnh" = (
-/obj/machinery/turretid{
- icon_state = "control_stun";
- name = "AI Chamber turret control";
- pixel_x = 3;
- pixel_y = 28
- },
-/obj/machinery/door/window/left/directional/west{
- name = "Primary AI Core Access";
- req_access = list("ai_upload")
- },
-/obj/machinery/door/poddoor/shutters/preopen{
- dir = 8;
- id = "AI Core shutters";
- name = "AI Core Shutter"
- },
-/obj/effect/turf_decal/delivery,
-/turf/open/floor/engine,
-/area/station/ai_monitored/turret_protected/ai)
"wnl" = (
/obj/machinery/power/port_gen/pacman,
/obj/item/stack/sheet/mineral/plasma{
@@ -68811,28 +68881,6 @@
},
/turf/open/floor/engine/vacuum,
/area/station/science/ordnance/bomb)
-"wpZ" = (
-/obj/structure/table/reinforced,
-/obj/effect/turf_decal/delivery,
-/obj/machinery/door/firedoor,
-/obj/machinery/door/window/left/directional/east{
- name = "Cargo Desk";
- req_access = list("shipping")
- },
-/obj/item/clipboard{
- pixel_x = 3;
- pixel_y = -2
- },
-/obj/item/folder{
- pixel_x = 3;
- pixel_y = -2
- },
-/obj/structure/desk_bell{
- pixel_x = -8;
- pixel_y = 10
- },
-/turf/open/floor/plating,
-/area/station/cargo/office)
"wqd" = (
/obj/item/radio/intercom/directional/west,
/obj/machinery/modular_computer/preset/cargochat/service{
@@ -70609,17 +70657,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/cargo/warehouse)
-"wUX" = (
-/obj/machinery/door/window/left/directional/east,
-/obj/effect/decal/cleanable/dirt,
-/obj/effect/turf_decal/tile/neutral/anticorner/contrasted{
- dir = 8
- },
-/obj/effect/turf_decal/stripes/white/line{
- dir = 1
- },
-/turf/open/floor/iron/dark,
-/area/station/medical/morgue)
"wVb" = (
/obj/effect/turf_decal/stripes/corner{
dir = 4
@@ -71212,16 +71249,6 @@
/obj/effect/spawner/structure/window/reinforced/tinted,
/turf/open/floor/plating,
/area/station/maintenance/department/security)
-"xfB" = (
-/obj/structure/table/reinforced,
-/obj/machinery/door/window/left/directional/north,
-/obj/machinery/door/poddoor/shutters{
- dir = 1;
- id = "visitation";
- name = "Visitation Shutters"
- },
-/turf/open/floor/iron/showroomfloor,
-/area/station/security/execution/transfer)
"xfU" = (
/obj/item/circuitboard/computer/solar_control,
/turf/open/misc/asteroid/airless,
@@ -71961,17 +71988,6 @@
},
/turf/open/floor/iron/showroomfloor,
/area/station/medical/chemistry)
-"xts" = (
-/obj/effect/turf_decal/stripes/corner,
-/obj/effect/decal/cleanable/blood/old,
-/obj/effect/turf_decal/tile/neutral/half/contrasted,
-/obj/machinery/brm,
-/obj/machinery/conveyor{
- dir = 1;
- id = "mining"
- },
-/turf/open/floor/iron/dark,
-/area/station/cargo/miningoffice)
"xtt" = (
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -72319,33 +72335,6 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
/area/station/maintenance/department/bridge)
-"xyQ" = (
-/obj/effect/landmark/start/ai/secondary,
-/obj/item/radio/intercom/directional/north{
- freerange = 1;
- listening = 0;
- name = "Custom Channel";
- pixel_x = 8
- },
-/obj/item/radio/intercom/directional/east{
- freerange = 1;
- listening = 0;
- name = "Common Channel"
- },
-/obj/item/radio/intercom/directional/south{
- freerange = 1;
- frequency = 1447;
- listening = 0;
- name = "Private Channel";
- pixel_x = 8
- },
-/obj/machinery/door/window/left/directional/west{
- name = "Tertiary AI Core Access";
- pixel_x = -3;
- req_access = list("ai_upload")
- },
-/turf/open/floor/circuit/red,
-/area/station/ai_monitored/turret_protected/ai)
"xzc" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/stripes/line{
@@ -72595,6 +72584,33 @@
},
/turf/open/floor/plating,
/area/station/maintenance/starboard)
+"xCY" = (
+/obj/effect/landmark/start/ai/secondary,
+/obj/item/radio/intercom/directional/north{
+ freerange = 1;
+ listening = 0;
+ name = "Custom Channel";
+ pixel_x = -8
+ },
+/obj/item/radio/intercom/directional/west{
+ freerange = 1;
+ listening = 0;
+ name = "Common Channel"
+ },
+/obj/item/radio/intercom/directional/south{
+ freerange = 1;
+ frequency = 1447;
+ listening = 0;
+ name = "Private Channel";
+ pixel_x = -8
+ },
+/obj/machinery/door/window/left/directional/east{
+ name = "Secondary AI Core Access";
+ pixel_x = 4;
+ req_access = list("ai_upload")
+ },
+/turf/open/floor/circuit/red,
+/area/station/ai_monitored/turret_protected/ai)
"xDb" = (
/obj/effect/turf_decal/stripes/line,
/obj/effect/turf_decal/tile/neutral/half/contrasted{
@@ -72682,19 +72698,6 @@
dir = 1
},
/area/station/hallway/primary/fore)
-"xEh" = (
-/obj/machinery/door/poddoor/preopen{
- id = "xeno2";
- name = "Creature Cell 2"
- },
-/obj/effect/turf_decal/delivery,
-/obj/machinery/door/window/left/directional/west{
- name = "Creature Cell";
- req_access = list("xenobiology")
- },
-/obj/structure/cable,
-/turf/open/floor/iron/dark,
-/area/station/science/xenobiology)
"xEm" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -73255,19 +73258,6 @@
/obj/effect/mapping_helpers/airlock/access/all/science/xenobio,
/turf/open/floor/iron/dark,
/area/station/science/xenobiology)
-"xNw" = (
-/obj/machinery/door/poddoor/preopen{
- id = "xeno4";
- name = "Creature Cell 4"
- },
-/obj/effect/turf_decal/delivery,
-/obj/machinery/door/window/left/directional/east{
- name = "Creature Cell";
- req_access = list("xenobiology")
- },
-/obj/structure/cable,
-/turf/open/floor/iron/dark,
-/area/station/science/xenobiology)
"xNJ" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -73818,23 +73808,6 @@
/obj/effect/mapping_helpers/airlock/access/all/engineering/atmos,
/turf/open/floor/engine,
/area/station/maintenance/disposal/incinerator)
-"xXd" = (
-/obj/structure/table/reinforced,
-/obj/effect/turf_decal/delivery,
-/obj/item/folder/white,
-/obj/item/pen,
-/obj/machinery/door/poddoor/shutters/preopen{
- dir = 1;
- id = "chemistry_shutters";
- name = "Chemistry Lobby Shutters"
- },
-/obj/machinery/door/firedoor/heavy,
-/obj/machinery/door/window/left/directional/south{
- name = "Chemistry Desk";
- req_access = list("pharmacy")
- },
-/turf/open/floor/plating,
-/area/station/medical/pharmacy)
"xXo" = (
/obj/structure/sign/departments/xenobio,
/turf/closed/wall/r_wall,
@@ -73999,6 +73972,31 @@
/obj/structure/sign/warning/electric_shock,
/turf/closed/wall/r_wall,
/area/station/ai_monitored/turret_protected/ai_upload)
+"yaH" = (
+/obj/structure/table/reinforced,
+/obj/effect/turf_decal/delivery,
+/obj/item/folder/yellow{
+ pixel_x = -4
+ },
+/obj/item/pen{
+ pixel_x = -4
+ },
+/obj/machinery/door/poddoor/shutters/preopen{
+ dir = 4;
+ id = "chemistry_shutters_2";
+ name = "Chemistry Hall Shutters"
+ },
+/obj/machinery/door/firedoor/heavy,
+/obj/machinery/door/window/left/directional/west{
+ name = "Chemistry Desk";
+ req_access = list("pharmacy")
+ },
+/obj/structure/desk_bell{
+ pixel_x = 7;
+ pixel_y = 6
+ },
+/turf/open/floor/plating,
+/area/station/medical/pharmacy)
"yaK" = (
/obj/machinery/disposal/bin,
/obj/effect/turf_decal/bot,
@@ -85399,7 +85397,7 @@ vku
acm
vjh
xVH
-qaX
+dot
oFt
gfc
vjh
@@ -86170,7 +86168,7 @@ whj
jKJ
vjh
jeZ
-whc
+ggK
kJx
paM
fvr
@@ -86428,7 +86426,7 @@ xpM
sjV
spr
xKn
-iuX
+pmR
iEy
vjh
eVP
@@ -86980,7 +86978,7 @@ wDz
bYK
dnF
mvF
-xfB
+vAa
qxD
qVF
cXv
@@ -91845,7 +91843,7 @@ csa
eNQ
aPj
deZ
-ooX
+rnB
pIX
pHx
qrn
@@ -92619,7 +92617,7 @@ deZ
sTB
sVQ
qpT
-qvt
+owJ
jbf
lWJ
pqD
@@ -93109,7 +93107,7 @@ ghX
lUM
qGK
tOR
-jvY
+pXf
xQq
rHc
sxM
@@ -95449,7 +95447,7 @@ uHv
vgm
tSI
cYv
-jjI
+fgV
iuC
fKJ
cuD
@@ -95962,7 +95960,7 @@ bCO
uHv
nQX
rhN
-adx
+aww
vea
jWD
bHP
@@ -96969,7 +96967,7 @@ msL
jhr
dQG
phY
-xXd
+uik
vQD
erH
gaE
@@ -96990,7 +96988,7 @@ nkd
tDs
xTt
rhN
-nVN
+oIe
amn
pqD
ckJ
@@ -97211,7 +97209,7 @@ fPh
nki
oLs
bFm
-wUX
+dJU
kxU
emx
dkh
@@ -97487,7 +97485,7 @@ ofg
aDL
ofg
cRW
-uFf
+yaH
cRW
iyI
iyI
@@ -97505,7 +97503,7 @@ ikE
vgm
lqP
uhE
-exG
+dJT
pqD
pqD
iza
@@ -102159,11 +102157,11 @@ oPO
cRu
tGj
aZe
-rJj
+nGT
svp
whz
buu
-vVK
+sJI
bSw
kHq
bWx
@@ -102313,7 +102311,7 @@ aAg
aAg
asZ
asZ
-axH
+xCY
asZ
asZ
aAg
@@ -103084,7 +103082,7 @@ aaw
uqv
cdY
cdZ
-wnh
+hlC
cdY
upZ
qKf
@@ -103336,7 +103334,7 @@ ciI
rRJ
asZ
asZ
-aac
+rEB
aay
iBD
cdY
@@ -103598,7 +103596,7 @@ aaI
uqv
cdZ
cdY
-tYG
+lcK
cdY
nhd
wjs
@@ -103676,7 +103674,7 @@ kMM
nsp
iWy
qbA
-hGG
+cfR
boq
pPe
tmZ
@@ -104369,13 +104367,13 @@ asZ
asZ
aAg
asZ
-xyQ
+iMJ
asZ
aAg
asZ
asZ
ihg
-rLN
+map
fSZ
mHd
kZH
@@ -107292,7 +107290,7 @@ aWD
aWD
rWT
qPf
-hkH
+aJH
vbj
knh
pRO
@@ -108023,9 +108021,9 @@ pLB
hxw
irL
bXz
-pSx
+dNO
dMp
-tpB
+ewr
jDF
rzV
jgB
@@ -108806,7 +108804,7 @@ ycr
niQ
dch
slo
-oeZ
+dRY
lzv
reT
vRQ
@@ -108835,7 +108833,7 @@ xOI
qkm
uHD
qkm
-weZ
+aMJ
ewK
qkm
tPP
@@ -111090,7 +111088,7 @@ lhJ
mQu
ggZ
cDZ
-seT
+cQI
dqw
bla
lGQ
@@ -111344,7 +111342,7 @@ dBV
nmu
lZi
aYX
-lIb
+uJP
moG
lYg
ylT
@@ -111381,7 +111379,7 @@ xcV
gUK
kUN
kvL
-rsm
+bCz
bpn
ihU
xNe
@@ -111590,11 +111588,11 @@ iPY
odd
wpw
ffN
-xEh
+hnw
ffN
wpw
gRg
-mhw
+kXJ
gRg
lZi
tcn
@@ -111847,11 +111845,11 @@ prr
mIT
wpw
xFw
-rQY
+okt
ppB
syu
gqk
-rQY
+okt
qVc
lZi
rAO
@@ -111884,10 +111882,10 @@ kNY
rZV
rZV
oNO
-wpZ
-lcj
+riS
+bsB
oNO
-sgQ
+tQI
xlf
liB
cBc
@@ -112352,7 +112350,7 @@ vct
rRz
saA
tGx
-cLn
+boo
vse
jmM
mQe
@@ -112411,7 +112409,7 @@ qAn
qJi
nIR
jYL
-lhM
+oJd
uov
uIx
uqI
@@ -112650,10 +112648,10 @@ wqQ
rwR
gPy
gxu
-aAN
+mdw
nOJ
bls
-oGf
+hnl
iuE
peY
dcq
@@ -112875,11 +112873,11 @@ hvl
mOt
wpw
gcp
-bxD
+puJ
aNt
ndz
kYR
-bxD
+puJ
vna
lDu
avo
@@ -113132,11 +113130,11 @@ aQl
xNu
kwx
doy
-xNw
+hbe
doy
wpw
iBt
-ahS
+pCa
iBt
lDu
kaW
@@ -113697,7 +113695,7 @@ lJD
fLo
nFy
hfr
-kEg
+udt
nQO
lKq
lkF
@@ -115486,8 +115484,8 @@ chT
wrY
tVt
qAR
-cVn
-sdJ
+mMF
+pEf
sFt
lmO
wer
@@ -115975,7 +115973,7 @@ rZV
rKY
mrt
gyd
-whS
+awX
iSC
wxl
nSf
@@ -116495,7 +116493,7 @@ hjk
oTD
loO
oTD
-leg
+cNO
kFN
uYh
hvz
@@ -116532,7 +116530,7 @@ vOW
dSw
qiL
msZ
-bLX
+gHA
oaF
gLK
vQf
@@ -116540,7 +116538,7 @@ vOW
xnU
dSt
eer
-scY
+cOt
vte
ruc
rsd
@@ -116797,7 +116795,7 @@ tdn
xWJ
cua
eer
-uXq
+hkW
jDU
apl
ivY
@@ -117538,7 +117536,7 @@ xZL
rZV
aZd
tOj
-xts
+vnj
iVn
xzI
oUz
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 2d414269001..26daa4d97b4 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -230,6 +230,16 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible,
/turf/open/floor/iron/dark/textured,
/area/station/medical/cryo)
+"aeA" = (
+/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)
"afj" = (
/obj/effect/turf_decal/trimline/red/filled/line{
dir = 1
@@ -945,8 +955,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 +4600,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 +5059,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 +6029,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 +7654,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 +8864,18 @@
/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)
+"dkj" = (
+/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)
"dkx" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/white,
@@ -9484,12 +9512,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 +9731,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 +10844,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 +13315,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 +14268,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 +14711,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 +14757,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,
@@ -16727,6 +16761,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 +20064,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 +20139,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 +24300,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 +26009,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 +28473,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
@@ -32275,6 +32295,14 @@
/obj/machinery/light/small/directional/east,
/turf/open/floor/iron/grimy,
/area/station/security/detectives_office)
+"lGI" = (
+/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)
"lGL" = (
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/iron,
@@ -39126,6 +39154,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 +39498,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 +41390,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 +44795,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 +48589,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,
@@ -51700,16 +51730,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 +53454,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 +54117,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 +55511,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 +55901,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,
@@ -61184,18 +61177,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 +61199,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 +61399,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,
@@ -66490,6 +66459,17 @@
},
/turf/open/floor/iron,
/area/station/ai_monitored/command/storage/eva)
+"xBR" = (
+/obj/machinery/power/smes/super/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)
"xBX" = (
/obj/machinery/firealarm/directional/east,
/turf/closed/wall,
@@ -82761,8 +82741,8 @@ xjH
pIU
dno
uKy
-oPY
-iOt
+lGI
+dkj
xjH
nzQ
vol
@@ -83539,7 +83519,7 @@ pWX
eYE
hcR
gqV
-syT
+aeA
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
+xBR
mCL
aWO
aYz
diff --git a/_maps/map_files/Mining/Lavaland.dmm b/_maps/map_files/Mining/Lavaland.dmm
index 6a1d703aea4..e442018be92 100644
--- a/_maps/map_files/Mining/Lavaland.dmm
+++ b/_maps/map_files/Mining/Lavaland.dmm
@@ -586,6 +586,13 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/mine/eva)
+"dO" = (
+/obj/machinery/door/airlock/maintenance{
+ name = "Mining Station Maintenance"
+ },
+/obj/effect/mapping_helpers/airlock/access/any/engineering/maintenance/departmental,
+/turf/open/floor/plating,
+/area/mine/maintenance/service)
"dP" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -639,6 +646,17 @@
},
/turf/open/misc/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"ew" = (
+/obj/machinery/door/airlock/external{
+ name = "Mining External Airlock"
+ },
+/obj/structure/disposalpipe/segment,
+/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
+ cycle_id = "lavaland_services_north"
+ },
+/obj/effect/mapping_helpers/airlock/access/any/engineering/maintenance/departmental,
+/turf/open/floor/plating,
+/area/mine/maintenance/service)
"ez" = (
/obj/structure/chair/comfy/teal{
dir = 4
@@ -870,10 +888,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)
@@ -1014,6 +1028,16 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/smooth,
/area/mine/laborcamp/quarters)
+"gw" = (
+/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/any/engineering/maintenance/departmental,
+/turf/open/floor/plating,
+/area/mine/maintenance/service/comms)
"gx" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
@@ -2834,12 +2858,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 +3434,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{
@@ -3439,6 +3448,14 @@
},
/turf/open/misc/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
+"tk" = (
+/obj/machinery/door/airlock/maintenance{
+ name = "Mining Station Maintenance"
+ },
+/obj/structure/cable,
+/obj/effect/mapping_helpers/airlock/access/any/engineering/maintenance/departmental,
+/turf/open/floor/plating,
+/area/mine/maintenance/service)
"tr" = (
/obj/structure/closet/secure_closet/brig,
/obj/effect/decal/cleanable/dirt,
@@ -3538,6 +3555,15 @@
dir = 8
},
/area/mine/laborcamp)
+"uc" = (
+/obj/structure/lattice/catwalk/mining,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/item/toy/plush/shark{
+ desc = "A plushie depicting a somewhat cartoonish shark. The tag calls it a 'hákarl', noting that it was made by an obscure furniture manufacturer in old Scandinavia. This one seems to have some cable wiring sticking out of its mouth."
+ },
+/turf/open/lava/smooth/lava_land_surface,
+/area/lavaland/surface/outdoors)
"ui" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -3670,14 +3696,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
@@ -4081,6 +4099,11 @@
"xB" = (
/turf/closed/wall,
/area/mine/maintenance/public/north)
+"xC" = (
+/obj/machinery/power/smes/super/full,
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/mine/maintenance/labor)
"xD" = (
/turf/closed/wall/r_wall,
/area/mine/maintenance/service/comms)
@@ -4107,16 +4130,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 +4177,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 +4507,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 +4982,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,
@@ -6253,14 +6273,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
@@ -6305,6 +6317,12 @@
dir = 8
},
/area/mine/lounge)
+"Mj" = (
+/obj/structure/cable,
+/obj/machinery/power/smes/super/full,
+/obj/effect/decal/cleanable/dirt,
+/turf/open/floor/plating,
+/area/mine/maintenance/service)
"Mr" = (
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plating,
@@ -7476,13 +7494,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"
@@ -7599,6 +7610,17 @@
},
/turf/open/floor/iron/freezer,
/area/mine/living_quarters)
+"UF" = (
+/obj/structure/cable,
+/obj/machinery/door/airlock/external{
+ name = "Mining External Airlock"
+ },
+/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{
+ cycle_id = "lavaland_services_north"
+ },
+/obj/effect/mapping_helpers/airlock/access/any/engineering/maintenance/departmental,
+/turf/open/floor/plating,
+/area/mine/maintenance/service)
"UK" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/siding/wideplating_new{
@@ -8292,6 +8314,15 @@
dir = 1
},
/area/mine/laborcamp/quarters)
+"Yy" = (
+/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/any/engineering/maintenance/departmental,
+/turf/open/floor/plating,
+/area/mine/maintenance/service)
"YF" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -22573,7 +22604,7 @@ uU
uU
uU
pU
-fP
+xX
pU
ff
Gf
@@ -24377,7 +24408,7 @@ Hd
Nb
NR
Kv
-LT
+Af
ff
gm
mN
@@ -28238,7 +28269,7 @@ Zt
Zt
Zt
Zt
-Ee
+xC
ve
RD
RD
@@ -29779,7 +29810,7 @@ Xw
aj
aj
aj
-cU
+uc
aj
aj
aj
@@ -37975,7 +38006,7 @@ ni
rZ
ni
ON
-TV
+dO
xD
xD
xD
@@ -38485,12 +38516,12 @@ Ue
AA
gB
ON
-ps
+Mj
gq
ER
-vc
+tk
YR
-xI
+gw
DF
Kn
xD
@@ -38998,7 +39029,7 @@ pU
Dx
cm
FL
-cm
+ew
Ao
Ao
aW
@@ -39255,7 +39286,7 @@ pU
aD
cV
fi
-cV
+UF
Jh
cr
JS
@@ -39514,7 +39545,7 @@ ON
ON
ON
ON
-tg
+Yy
ON
ON
ON
diff --git a/_maps/map_files/NSVBlueshift/Blueshift.dmm b/_maps/map_files/NSVBlueshift/Blueshift.dmm
index eb57a4f7eee..eba39bda236 100644
--- a/_maps/map_files/NSVBlueshift/Blueshift.dmm
+++ b/_maps/map_files/NSVBlueshift/Blueshift.dmm
@@ -92,17 +92,6 @@
},
/turf/open/floor/iron/dark,
/area/station/security/brig)
-"aby" = (
-/obj/machinery/conveyor{
- dir = 4;
- id = "garbage"
- },
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/machinery/door/window/right/directional/north,
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"abA" = (
/obj/effect/spawner/random/structure/crate,
/turf/open/floor/plating,
@@ -151,10 +140,6 @@
},
/turf/open/floor/iron,
/area/station/commons/fitness/recreation)
-"acp" = (
-/obj/machinery/door/window/right/directional/north,
-/turf/open/floor/iron/dark,
-/area/station/security/execution/transfer)
"acx" = (
/obj/machinery/conveyor{
dir = 1;
@@ -287,6 +272,27 @@
/obj/structure/sink/directional/east,
/turf/open/floor/iron/cafeteria,
/area/station/commons/locker)
+"adO" = (
+/obj/effect/turf_decal/stripes{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 8
+ },
+/obj/machinery/button/elevator{
+ id = "publicElevator";
+ pixel_y = 32
+ },
+/obj/machinery/lift_indicator/directional/north{
+ linked_elevator_id = "publicElevator"
+ },
+/obj/machinery/light/directional/north,
+/obj/machinery/door/window/elevator/right/directional/west{
+ elevator_mode = 1;
+ transport_linked_id = "publicElevator"
+ },
+/turf/open/floor/iron/dark,
+/area/station/hallway/primary/central)
"adQ" = (
/obj/effect/turf_decal/siding/wood,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -553,6 +559,16 @@
dir = 8
},
/area/station/security/checkpoint/supply)
+"afX" = (
+/obj/structure/bed{
+ dir = 1
+ },
+/obj/effect/spawner/random/bedsheet{
+ dir = 1
+ },
+/obj/machinery/light_switch/directional/west,
+/turf/open/floor/carpet/black,
+/area/station/commons/dorms/room5)
"aga" = (
/obj/machinery/power/shuttle_engine/heater{
dir = 1
@@ -689,6 +705,21 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/station/science/robotics)
+"ahB" = (
+/obj/machinery/door/window/brigdoor/left/directional/north{
+ name = "Creature Pen";
+ req_access = list("research")
+ },
+/obj/effect/turf_decal/delivery,
+/obj/effect/turf_decal/stripes{
+ dir = 1
+ },
+/obj/machinery/door/poddoor/preopen{
+ id = "xeno6";
+ name = "Creature Cell #6"
+ },
+/turf/open/floor/engine,
+/area/station/science/xenobiology)
"ahP" = (
/obj/structure/flora/grass/jungle,
/obj/structure/flora/bush/grassy,
@@ -788,15 +819,6 @@
/obj/item/radio/intercom/directional/north,
/turf/open/floor/iron/dark,
/area/station/security/prison/garden)
-"aiv" = (
-/obj/machinery/door/window/brigdoor/left/directional/east{
- id = "scicell";
- name = "RnD Cell";
- req_access = list("security")
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron/dark,
-/area/station/security/checkpoint/science/research)
"aiC" = (
/obj/machinery/suit_storage_unit/engine,
/turf/open/floor/iron/dark,
@@ -1617,24 +1639,6 @@
"aqy" = (
/turf/open/floor/plating,
/area/station/maintenance/department/science/lower)
-"aqz" = (
-/obj/structure/window/reinforced/spawner/directional/north,
-/obj/effect/turf_decal/stripes{
- dir = 4
- },
-/obj/machinery/disposal/delivery_chute{
- dir = 4
- },
-/obj/structure/plasticflaps,
-/obj/structure/disposalpipe/trunk{
- dir = 4
- },
-/obj/machinery/door/window/right/directional/east{
- req_access = list("cargo");
- name = "Security Deliveries"
- },
-/turf/open/floor/iron/dark,
-/area/station/cargo/sorting)
"aqB" = (
/obj/effect/turf_decal/tile/yellow{
dir = 8
@@ -1956,14 +1960,6 @@
},
/turf/open/floor/carpet,
/area/station/security/prison/rec)
-"atJ" = (
-/obj/machinery/conveyor/inverted{
- dir = 9;
- id = "garbage"
- },
-/obj/machinery/door/window/right/directional/west,
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"atW" = (
/obj/effect/turf_decal/trimline/blue/corner,
/obj/effect/landmark/start/assistant,
@@ -1972,6 +1968,18 @@
"atX" = (
/turf/closed/wall,
/area/station/medical/treatment_center)
+"atZ" = (
+/obj/structure/table/wood/fancy,
+/obj/structure/sign/painting/library_secure{
+ pixel_y = 32
+ },
+/obj/machinery/door/window/left/directional/south{
+ name = "Secure Art Exhibition";
+ req_access = list("library")
+ },
+/obj/effect/turf_decal/siding/wood,
+/turf/open/floor/carpet,
+/area/station/service/library)
"aua" = (
/obj/item/target,
/obj/item/target,
@@ -2463,17 +2471,6 @@
/obj/effect/decal/cleanable/generic,
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
-"ayJ" = (
-/obj/structure/railing{
- dir = 8
- },
-/obj/machinery/light/directional/east,
-/obj/machinery/door/window/brigdoor/right/directional/north{
- name = "Command Chair";
- req_access = list("command")
- },
-/turf/open/floor/iron/stairs,
-/area/station/command/secure_bunker)
"ayM" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -3051,20 +3048,6 @@
/obj/structure/reagent_dispensers/water_cooler,
/turf/open/floor/iron/dark,
/area/station/tcommsat/computer)
-"aFd" = (
-/obj/machinery/door/window/left/directional/south{
- name = "Deliveries";
- req_access = list("cargo")
- },
-/obj/effect/turf_decal/delivery,
-/obj/machinery/disposal/delivery_chute,
-/obj/structure/disposalpipe/trunk{
- dir = 1
- },
-/obj/structure/window/reinforced/spawner/directional/north,
-/obj/machinery/light/directional/east,
-/turf/open/floor/iron/dark,
-/area/station/cargo/office)
"aFf" = (
/obj/effect/decal/cleanable/dirt{
icon_state = "dirt-flat-1"
@@ -3263,21 +3246,6 @@
},
/turf/open/floor/iron/dark,
/area/station/command/bridge)
-"aHb" = (
-/obj/structure/table,
-/obj/structure/window/reinforced/spawner/directional/east,
-/obj/structure/window/reinforced/spawner/directional/south,
-/obj/machinery/door/window/left/directional/west{
- name = "High-Risk Modules";
- req_access = list("ai_upload")
- },
-/obj/item/ai_module/supplied/protect_station,
-/obj/item/ai_module/reset/purge{
- pixel_x = -3;
- pixel_y = -3
- },
-/turf/open/floor/iron,
-/area/station/ai_monitored/turret_protected/ai_upload)
"aHd" = (
/turf/closed/wall/rust,
/area/station/maintenance/department/security/greater)
@@ -3427,6 +3395,25 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/maintenance/department/science/xenobiology)
+"aIz" = (
+/obj/machinery/door/firedoor,
+/obj/structure/table/reinforced,
+/obj/machinery/door/window/left{
+ name = "Chemistry Desk";
+ req_access = list("pharmacy")
+ },
+/obj/machinery/door/poddoor/shutters/preopen{
+ id = "chemisttop";
+ name = "Chemistry Lobby Shutters"
+ },
+/obj/item/folder/white,
+/obj/item/reagent_containers/cup/bottle/multiver{
+ pixel_x = -7;
+ pixel_y = 1
+ },
+/obj/machinery/door/window/left/directional/north,
+/turf/open/floor/iron/dark,
+/area/station/medical/pharmacy)
"aIA" = (
/obj/effect/landmark/start/virologist,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
@@ -3503,6 +3490,20 @@
"aJr" = (
/turf/closed/wall,
/area/station/maintenance/abandon_holding_cell)
+"aJt" = (
+/obj/machinery/door/firedoor,
+/obj/structure/table/reinforced,
+/obj/item/folder/white,
+/obj/machinery/door/poddoor/shutters/preopen{
+ id = "Psychward4";
+ name = "Control Room Shutters"
+ },
+/obj/structure/cable,
+/obj/machinery/door/window/left/directional/west{
+ req_access = list("psychology")
+ },
+/turf/open/floor/iron/dark,
+/area/station/medical/psychology)
"aJv" = (
/obj/structure/cable,
/obj/machinery/power/apc/auto_name/directional/south,
@@ -4292,18 +4293,6 @@
/obj/structure/railing,
/turf/open/floor/plating,
/area/station/maintenance/department/science/xenobiology)
-"aRV" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/turf_decal/vg_decals/numbers/five,
-/obj/machinery/door/window/brigdoor/left/directional/east{
- req_access = list("security");
- name = "Cell 5"
- },
-/turf/open/floor/iron/dark/side{
- dir = 4
- },
-/area/station/security/brig)
"aSc" = (
/obj/effect/decal/cleanable/dirt{
icon_state = "dirt-flat-1"
@@ -4560,19 +4549,6 @@
/obj/machinery/vending/boozeomat,
/turf/closed/wall/r_wall,
/area/station/command/heads_quarters/nt_rep)
-"aUK" = (
-/obj/effect/turf_decal/stripes{
- dir = 1
- },
-/obj/effect/turf_decal/siding/thinplating/dark{
- dir = 1
- },
-/obj/machinery/door/window/brigdoor/left/directional/north{
- name = "Research Director Observation";
- req_access = list("rd")
- },
-/turf/open/floor/engine,
-/area/station/command/heads_quarters/rd)
"aUL" = (
/obj/machinery/portable_atmospherics/scrubber,
/obj/effect/turf_decal/bot,
@@ -4989,19 +4965,6 @@
/obj/effect/decal/cleanable/oil/slippery,
/turf/open/floor/plating,
/area/station/maintenance/department/science/lower)
-"aZc" = (
-/obj/machinery/door/window/brigdoor/left/directional/south{
- name = "Creature Pen";
- req_access = list("research")
- },
-/obj/effect/turf_decal/delivery,
-/obj/effect/turf_decal/stripes,
-/obj/machinery/door/poddoor/preopen{
- id = "xeno3";
- name = "Creature Cell #3"
- },
-/turf/open/floor/engine,
-/area/station/science/xenobiology)
"aZe" = (
/obj/structure/table/wood,
/obj/item/lipstick/random{
@@ -5452,6 +5415,21 @@
/obj/machinery/duct,
/turf/open/floor/iron,
/area/station/engineering/supermatter/room)
+"bcX" = (
+/obj/structure/table/reinforced,
+/obj/machinery/door/firedoor,
+/obj/item/folder/white,
+/obj/item/pen,
+/obj/machinery/door/poddoor/shutters/preopen{
+ id = "rdgene2";
+ name = "Genetics Lab Shutters"
+ },
+/obj/machinery/door/window/left/directional/east{
+ name = "Genetics Desk";
+ req_access = list("genetics")
+ },
+/turf/open/floor/iron/dark,
+/area/station/science/genetics)
"bcY" = (
/obj/structure/window/spawner/directional/east,
/obj/structure/flora/bush/grassy,
@@ -5880,11 +5858,6 @@
/obj/effect/turf_decal/tile/blue/half/contrasted,
/turf/open/floor/iron/dark,
/area/station/security/checkpoint/customs/auxiliary)
-"bis" = (
-/obj/machinery/light/directional/south,
-/obj/item/radio/intercom/directional/south,
-/turf/open/floor/iron/dark,
-/area/station/service/library/private)
"bit" = (
/obj/item/kirbyplants/random,
/obj/machinery/airalarm/directional/north{
@@ -6192,19 +6165,6 @@
},
/turf/open/floor/plating,
/area/station/maintenance/port/upper)
-"bkV" = (
-/obj/structure/table/reinforced,
-/obj/machinery/door/firedoor,
-/obj/machinery/door/window/left/directional/north{
- name = "Hydroponics Desk";
- req_access = list("hydroponics")
- },
-/obj/machinery/door/window/left/directional/south{
- name = "Kitchen Desk";
- req_access = list("kitchen")
- },
-/turf/open/floor/iron/dark,
-/area/station/service/hydroponics)
"bkZ" = (
/obj/machinery/door/airlock/public/glass{
name = "Lasertag Prep Room"
@@ -7044,15 +7004,6 @@
/obj/item/storage/box/lights/mixed,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/morgue)
-"brU" = (
-/obj/machinery/atmospherics/pipe/smart/simple/general/visible{
- dir = 10
- },
-/obj/machinery/door/window/right/directional/east{
- name = "Gas Ports"
- },
-/turf/open/floor/iron/dark,
-/area/station/security/execution/education)
"brZ" = (
/obj/structure/table/wood,
/obj/structure/window/reinforced/spawner/directional/east,
@@ -7756,6 +7707,28 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/upper)
+"byV" = (
+/obj/structure/table/reinforced,
+/obj/machinery/door/firedoor,
+/obj/machinery/door/window/left{
+ name = "Warden's Desk"
+ },
+/obj/machinery/recharger{
+ pixel_x = 8
+ },
+/obj/item/folder/red{
+ pixel_x = -5
+ },
+/obj/item/pen{
+ pixel_x = -5
+ },
+/obj/structure/cable,
+/obj/machinery/door/window/brigdoor/right/directional/north{
+ req_access = list("armory");
+ name = "Warden's Desk"
+ },
+/turf/open/floor/iron/dark,
+/area/station/security/warden)
"bzj" = (
/obj/structure/rack,
/obj/effect/turf_decal/bot,
@@ -7892,12 +7865,6 @@
},
/turf/open/floor/iron,
/area/station/security/brig)
-"bAF" = (
-/obj/effect/turf_decal/bot,
-/obj/machinery/hydroponics/constructable,
-/obj/machinery/door/window/right/directional/north,
-/turf/open/floor/iron/dark,
-/area/station/service/hydroponics)
"bAL" = (
/obj/machinery/door/poddoor/shutters{
id = "gatewayshutters";
@@ -8110,6 +8077,16 @@
},
/turf/open/floor/grass,
/area/station/security/prison/garden)
+"bCR" = (
+/obj/structure/cable,
+/obj/machinery/power/apc/auto_name/directional/west,
+/obj/structure/table,
+/obj/machinery/chem_dispenser/drinks/beer{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/bar/opposingcorners,
+/turf/open/floor/iron,
+/area/station/service/bar)
"bDe" = (
/obj/effect/turf_decal/siding/wood,
/obj/structure/cable,
@@ -8145,6 +8122,10 @@
"bDA" = (
/turf/closed/wall,
/area/station/security/checkpoint/customs)
+"bDB" = (
+/obj/machinery/door/window/right/directional/north,
+/turf/open/floor/iron/dark,
+/area/station/security/execution/transfer)
"bDD" = (
/obj/effect/turf_decal/tile/yellow/half/contrasted,
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
@@ -8200,18 +8181,6 @@
/obj/effect/landmark/start/hangover,
/turf/open/floor/light/colour_cycle/dancefloor_a,
/area/station/common/night_club)
-"bDX" = (
-/obj/machinery/door/window/brigdoor/left/directional/north{
- name = "Creature Pen";
- req_access = list("research")
- },
-/obj/effect/turf_decal/delivery,
-/obj/machinery/door/poddoor/preopen{
- id = "xeno7";
- name = "Creature Cell #7"
- },
-/turf/open/floor/engine,
-/area/station/science/xenobiology)
"bEb" = (
/obj/machinery/light/directional/west,
/obj/effect/spawner/liquids_spawner,
@@ -8521,10 +8490,6 @@
},
/turf/open/floor/iron/shuttle/arrivals/airless,
/area/space/nearstation)
-"bHE" = (
-/obj/structure/musician/piano,
-/turf/open/floor/wood,
-/area/station/service/theater)
"bHU" = (
/obj/effect/turf_decal/siding/thinplating/dark,
/obj/structure/cable,
@@ -8553,6 +8518,17 @@
},
/turf/open/floor/plating,
/area/station/maintenance/department/security/greater)
+"bIv" = (
+/obj/structure/railing{
+ dir = 8
+ },
+/obj/machinery/door/window/left/directional/south{
+ name = "Fitness Ring"
+ },
+/turf/open/floor/iron/stairs{
+ dir = 1
+ },
+/area/station/commons/fitness)
"bIw" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -8793,6 +8769,17 @@
/obj/item/clothing/head/utility/welding,
/turf/open/floor/iron/dark,
/area/station/maintenance/department/engineering/atmos_aux_port)
+"bKw" = (
+/obj/structure/table,
+/obj/structure/window/reinforced/spawner/directional/west,
+/obj/structure/window/reinforced/spawner/directional/south,
+/obj/machinery/door/window/left/directional/east{
+ name = "Core Modules";
+ req_access = list("ai_upload")
+ },
+/obj/effect/spawner/random/aimodule/harmless,
+/turf/open/floor/iron,
+/area/station/ai_monitored/turret_protected/ai_upload)
"bKy" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -9879,6 +9866,16 @@
},
/turf/open/floor/iron,
/area/station/maintenance/aft/upper)
+"bTX" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/door/window/brigdoor/right/directional/west{
+ name = "Command Chair";
+ req_access = list("command")
+ },
+/turf/open/floor/iron,
+/area/station/command/bridge)
"bUc" = (
/obj/structure/cable,
/obj/effect/decal/cleanable/dirt{
@@ -9961,6 +9958,15 @@
/obj/structure/table/glass,
/turf/open/floor/wood,
/area/station/hallway/primary/port)
+"bUG" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
+/obj/item/radio/intercom/directional/north,
+/obj/machinery/door/window/brigdoor/right/directional/south{
+ name = "Cargo Deliveries";
+ req_access = list("security")
+ },
+/turf/open/floor/iron/dark,
+/area/station/security/brig)
"bVc" = (
/obj/structure/window/spawner/directional/south,
/obj/structure/filingcabinet/chestdrawer,
@@ -10264,6 +10270,13 @@
},
/turf/open/floor/iron/dark,
/area/station/escapepodbay)
+"bXS" = (
+/obj/effect/turf_decal/siding/wood{
+ dir = 4
+ },
+/obj/machinery/door/window/right/directional/east,
+/turf/open/floor/wood,
+/area/station/command/heads_quarters/captain)
"bXX" = (
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
@@ -10551,6 +10564,24 @@
/obj/effect/spawner/random/trash/garbage,
/turf/open/floor/plating,
/area/station/maintenance/department/security/greater)
+"cbc" = (
+/obj/structure/window/reinforced/spawner/directional/south,
+/obj/machinery/disposal/delivery_chute{
+ dir = 4
+ },
+/obj/structure/plasticflaps,
+/obj/structure/disposalpipe/trunk{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes{
+ dir = 4
+ },
+/obj/machinery/door/window/right/directional/east{
+ req_access = list("cargo");
+ name = "Medbay Deliveries"
+ },
+/turf/open/floor/iron/dark,
+/area/station/cargo/sorting)
"cbl" = (
/obj/structure/window/reinforced/spawner/directional/north,
/obj/structure/window/reinforced/spawner/directional/west,
@@ -11227,23 +11258,6 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/plating,
/area/station/service/bar/atrium)
-"chI" = (
-/obj/effect/turf_decal/stripes{
- dir = 4
- },
-/obj/machinery/disposal/delivery_chute{
- dir = 4
- },
-/obj/structure/plasticflaps,
-/obj/structure/disposalpipe/trunk{
- dir = 8
- },
-/obj/machinery/door/window/right/directional/east{
- req_access = list("cargo");
- name = "Service Deliveries"
- },
-/turf/open/floor/iron/dark,
-/area/station/cargo/sorting)
"chO" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -11596,6 +11610,21 @@
initial_gas_mix = "TEMP=2.7"
},
/area/space/nearstation)
+"clj" = (
+/obj/structure/table,
+/obj/structure/window/reinforced/spawner/directional/east,
+/obj/structure/window/reinforced/spawner/directional/south,
+/obj/machinery/door/window/left/directional/west{
+ name = "High-Risk Modules";
+ req_access = list("ai_upload")
+ },
+/obj/item/ai_module/supplied/protect_station,
+/obj/item/ai_module/reset/purge{
+ pixel_x = -3;
+ pixel_y = -3
+ },
+/turf/open/floor/iron,
+/area/station/ai_monitored/turret_protected/ai_upload)
"clo" = (
/obj/structure/table,
/obj/item/storage/box/zipties{
@@ -12106,15 +12135,11 @@
/obj/effect/turf_decal/tile/blue/fourcorners,
/turf/open/floor/iron/white,
/area/station/medical/medbay/central)
-"cpT" = (
-/obj/machinery/door/airlock/maintenance_hatch{
- name = "Security Maintenance"
- },
-/obj/effect/mapping_helpers/airlock/welded,
-/obj/structure/cable,
-/obj/effect/mapping_helpers/airlock/access/all/security/general,
-/turf/open/floor/plating,
-/area/station/maintenance/department/security/lower)
+"cpO" = (
+/obj/machinery/airalarm/directional/east,
+/obj/machinery/door/window/right/directional/north,
+/turf/open/floor/wood,
+/area/station/service/theater)
"cpY" = (
/obj/structure/rack/shelf,
/obj/item/weldingtool,
@@ -13040,6 +13065,27 @@
},
/turf/open/floor/iron,
/area/station/security/lockers)
+"cxx" = (
+/obj/structure/table/reinforced,
+/obj/item/storage/medkit/fire{
+ pixel_x = 6;
+ pixel_y = 6
+ },
+/obj/item/storage/medkit/fire{
+ pixel_x = 3;
+ pixel_y = 3
+ },
+/obj/item/storage/medkit/regular,
+/obj/item/storage/medkit/fire{
+ pixel_x = -3;
+ pixel_y = -3
+ },
+/obj/machinery/door/window/right/directional/south{
+ req_access = list("medical");
+ name = "First-Aid Supplies"
+ },
+/turf/open/floor/iron,
+/area/station/medical/storage)
"cxL" = (
/obj/effect/turf_decal/trimline/blue/line{
dir = 1
@@ -13127,27 +13173,6 @@
},
/turf/open/floor/iron,
/area/station/engineering/atmos/test_chambers)
-"cyD" = (
-/obj/machinery/light/directional/north,
-/obj/effect/turf_decal/stripes{
- dir = 8
- },
-/obj/effect/turf_decal/stripes/white/line{
- dir = 8
- },
-/obj/machinery/button/elevator{
- id = "publicElevator";
- pixel_y = 32
- },
-/obj/machinery/lift_indicator/directional/north{
- linked_elevator_id = "publicElevator"
- },
-/obj/machinery/door/window/elevator/right/directional/west{
- elevator_mode = 1;
- transport_linked_id = "publicElevator"
- },
-/turf/open/floor/iron/dark,
-/area/station/hallway/primary/upper)
"cyE" = (
/obj/effect/decal/cleanable/glass,
/obj/item/clothing/shoes/magboots,
@@ -14480,6 +14505,18 @@
/obj/machinery/light_switch/directional/east,
/turf/open/floor/iron/dark,
/area/station/security/checkpoint/supply)
+"cJl" = (
+/obj/machinery/door/window/brigdoor/left/directional/north{
+ name = "Creature Pen";
+ req_access = list("research")
+ },
+/obj/effect/turf_decal/stripes{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/smart/simple/dark/visible,
+/obj/structure/disposalpipe/segment,
+/turf/open/floor/engine,
+/area/station/science/xenobiology)
"cJv" = (
/obj/structure/flora/rock/pile/jungle,
/obj/structure/window/reinforced/spawner/directional/south,
@@ -15642,6 +15679,23 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/maintenance/department/engineering/atmos_aux_port)
+"cVx" = (
+/obj/machinery/door/firedoor,
+/obj/structure/table/reinforced,
+/obj/item/folder/blue,
+/obj/machinery/door/poddoor/preopen{
+ id = "hopblast";
+ name = "HoP Blast Door"
+ },
+/obj/machinery/door/window/right/directional/east{
+ name = "Access Queue"
+ },
+/obj/machinery/door/window/brigdoor/left/directional/west{
+ name = "Access Desk";
+ req_access = list("hop")
+ },
+/turf/open/floor/iron/dark,
+/area/station/command/heads_quarters/hop)
"cVz" = (
/turf/closed/wall,
/area/station/cargo/lobby)
@@ -16154,13 +16208,6 @@
/obj/structure/cable,
/turf/open/floor/carpet,
/area/station/maintenance/abandon_psych)
-"daQ" = (
-/obj/structure/chair/office{
- dir = 1
- },
-/obj/machinery/door/window/left/directional/west,
-/turf/open/floor/iron/dark,
-/area/station/security/execution/education)
"daW" = (
/obj/machinery/griddle,
/obj/machinery/button/door{
@@ -16407,6 +16454,16 @@
/obj/effect/spawner/random/trash/moisture_trap,
/turf/open/floor/plating,
/area/station/maintenance/fore/upper)
+"dea" = (
+/obj/machinery/door/window/left/directional/north{
+ name = "Interior Door";
+ req_access = list("lawyer")
+ },
+/obj/effect/turf_decal/siding/wood{
+ dir = 9
+ },
+/turf/open/floor/carpet/blue,
+/area/station/service/lawoffice)
"deb" = (
/obj/effect/turf_decal/stripes/end{
dir = 4
@@ -17250,6 +17307,13 @@
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/plating/airless,
/area/space/nearstation)
+"dlU" = (
+/obj/structure/cable,
+/obj/machinery/power/smes/super/full{
+ name = "ai power storage unit"
+ },
+/turf/open/floor/circuit,
+/area/station/ai_monitored/turret_protected/ai)
"dlY" = (
/obj/effect/turf_decal/trimline/purple/filled/corner{
dir = 1
@@ -17778,27 +17842,6 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
/area/station/maintenance/aft/upper)
-"drM" = (
-/obj/effect/turf_decal/stripes{
- dir = 8
- },
-/obj/effect/turf_decal/stripes/white/line{
- dir = 8
- },
-/obj/machinery/button/elevator{
- id = "publicElevator";
- pixel_y = 32
- },
-/obj/machinery/lift_indicator/directional/north{
- linked_elevator_id = "publicElevator"
- },
-/obj/machinery/light/directional/north,
-/obj/machinery/door/window/elevator/right/directional/west{
- elevator_mode = 1;
- transport_linked_id = "publicElevator"
- },
-/turf/open/floor/iron/dark,
-/area/station/hallway/primary/central)
"drQ" = (
/obj/machinery/door/airlock/bathroom{
name = "Restroom"
@@ -17889,18 +17932,6 @@
/obj/effect/mapping_helpers/airlock/access/all/service/general,
/turf/open/floor/plating,
/area/station/maintenance/disposal)
-"dsL" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/turf_decal/vg_decals/numbers/six,
-/obj/machinery/door/window/brigdoor/left/directional/east{
- req_access = list("security");
- name = "Cell 6"
- },
-/turf/open/floor/iron/dark/side{
- dir = 4
- },
-/area/station/security/brig)
"dsM" = (
/obj/structure/disposalpipe/segment,
/obj/structure/cable,
@@ -17977,20 +18008,6 @@
/obj/item/kirbyplants/organic/plant22,
/turf/open/floor/iron/dark,
/area/station/command/heads_quarters/hos)
-"dtv" = (
-/obj/machinery/door/firedoor,
-/obj/structure/table/reinforced,
-/obj/item/folder/white,
-/obj/machinery/door/poddoor/shutters/preopen{
- id = "Psychward4";
- name = "Control Room Shutters"
- },
-/obj/structure/cable,
-/obj/machinery/door/window/left/directional/east{
- req_access = list("psychology")
- },
-/turf/open/floor/iron/dark,
-/area/station/medical/psychology)
"dtw" = (
/obj/structure/table/wood,
/obj/structure/showcase/machinery/microwave{
@@ -18380,6 +18397,20 @@
/obj/machinery/light/small/directional/west,
/turf/open/floor/iron/cafeteria,
/area/station/commons/toilet/auxiliary)
+"dxT" = (
+/obj/machinery/door/firedoor/border_only{
+ dir = 4
+ },
+/obj/effect/turf_decal/box,
+/obj/machinery/atmospherics/components/unary/portables_connector/visible/layer4{
+ dir = 1
+ },
+/obj/machinery/door/window/right/directional/east{
+ name = "Ordnance Freezer Chamber Access"
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/iron/dark,
+/area/station/science/ordnance)
"dyh" = (
/obj/effect/decal/cleanable/dirt{
icon_state = "dirt-flat-1"
@@ -18531,15 +18562,21 @@
},
/turf/open/floor/plating/airless,
/area/station/maintenance/port/upper)
-"dzM" = (
-/obj/structure/flora/bush/sparsegrass,
-/obj/machinery/door/window/left/directional/south{
- name = "Monkey Pen";
- req_access = list("virology")
+"dzF" = (
+/obj/effect/turf_decal/delivery,
+/obj/machinery/navbeacon{
+ codes_txt = "delivery;dir=8";
+ location = "Medbay"
},
-/obj/effect/turf_decal/siding/thinplating/light,
-/turf/open/floor/grass,
-/area/station/medical/virology/isolation)
+/obj/structure/disposalpipe/segment{
+ dir = 10
+ },
+/obj/machinery/door/window/right/directional/east{
+ name = "Medical Delivery";
+ req_access = list("medical")
+ },
+/turf/open/floor/iron/dark,
+/area/station/medical/medbay/central)
"dzO" = (
/obj/effect/turf_decal/siding/thinplating/dark/corner{
dir = 8
@@ -18729,13 +18766,6 @@
/obj/effect/mapping_helpers/airlock/access/all/supply/general,
/turf/open/floor/plating,
/area/station/maintenance/department/crew_quarters/bar)
-"dBt" = (
-/obj/effect/turf_decal/siding/wood{
- dir = 4
- },
-/obj/machinery/door/window/right/directional/east,
-/turf/open/floor/wood,
-/area/station/command/heads_quarters/captain)
"dBv" = (
/obj/effect/turf_decal/bot,
/obj/machinery/field/generator,
@@ -18903,17 +18933,6 @@
/obj/effect/turf_decal/tile/neutral/half/contrasted,
/turf/open/floor/iron,
/area/station/hallway/primary/port)
-"dDb" = (
-/obj/machinery/door/window/left/directional/south{
- name = "Library Desk";
- req_access = list("library")
- },
-/obj/machinery/power/apc/auto_name/directional/west,
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/wood,
-/area/station/service/library)
"dDf" = (
/turf/open/floor/iron/dark/side{
dir = 10
@@ -19062,6 +19081,21 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron,
/area/station/hallway/primary/upper)
+"dEC" = (
+/obj/machinery/door/firedoor,
+/obj/structure/table/reinforced,
+/obj/machinery/door/poddoor/shutters/preopen{
+ id = "roboticsprivacy";
+ name = "Robotics Shutters"
+ },
+/obj/item/folder,
+/obj/item/pen,
+/obj/machinery/door/window/left/directional/east{
+ name = "Robotics Desk";
+ req_access = list("robotics")
+ },
+/turf/open/floor/iron/dark,
+/area/station/science/robotics/lab)
"dEF" = (
/obj/machinery/atmospherics/pipe/smart/simple/supply/visible/layer4{
dir = 5
@@ -19122,29 +19156,6 @@
/obj/structure/cable,
/turf/open/floor/iron/smooth,
/area/station/cargo/power_station/upper)
-"dFq" = (
-/obj/machinery/door/window/brigdoor/left/directional/east{
- id = "medcell";
- name = "Medical Cell";
- req_access = list("security")
- },
-/obj/effect/turf_decal/delivery,
-/obj/effect/turf_decal/trimline/blue/filled/warning{
- dir = 4
- },
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/effect/turf_decal/tile/blue{
- dir = 1
- },
-/obj/effect/turf_decal/tile/blue{
- dir = 8
- },
-/turf/open/floor/iron/white/side{
- dir = 4
- },
-/area/station/security/checkpoint/medical)
"dFr" = (
/obj/machinery/atmospherics/pipe/smart/simple/pink/visible{
dir = 8
@@ -20146,6 +20157,15 @@
dir = 4
},
/area/station/security/prison/workout)
+"dOL" = (
+/obj/machinery/door/window/brigdoor/left/directional/south{
+ id = "cargocell";
+ name = "Cargo Cell";
+ req_access = list("security")
+ },
+/obj/machinery/light/directional/north,
+/turf/open/floor/iron,
+/area/station/security/checkpoint/supply)
"dOT" = (
/obj/effect/decal/cleanable/dirt{
icon_state = "dirt-flat-1"
@@ -20313,21 +20333,6 @@
"dRu" = (
/turf/open/floor/iron/dark,
/area/station/service/barber)
-"dRv" = (
-/obj/machinery/door/firedoor,
-/obj/structure/table/reinforced,
-/obj/machinery/door/poddoor/shutters/preopen{
- id = "roboticsprivacy";
- name = "Robotics Shutters"
- },
-/obj/item/folder,
-/obj/item/pen,
-/obj/machinery/door/window/left/directional/east{
- name = "Robotics Desk";
- req_access = list("robotics")
- },
-/turf/open/floor/iron/dark,
-/area/station/science/robotics/lab)
"dRI" = (
/obj/effect/turf_decal/bot,
/obj/effect/turf_decal/loading_area{
@@ -20707,6 +20712,19 @@
dir = 1
},
/area/station/hallway/primary/central/aft)
+"dUi" = (
+/obj/effect/turf_decal/stripes{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes/red/line{
+ dir = 4
+ },
+/obj/machinery/door/window/left/directional/east{
+ name = "Mech Bay";
+ req_access = list("robotics")
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/station/science/robotics/lab)
"dUl" = (
/obj/effect/turf_decal/stripes{
dir = 6
@@ -21076,19 +21094,6 @@
/obj/machinery/light/directional/west,
/turf/open/floor/iron,
/area/station/common/wrestling/lobby)
-"dYh" = (
-/obj/effect/turf_decal/stripes{
- dir = 4
- },
-/obj/effect/turf_decal/stripes/red/line{
- dir = 4
- },
-/obj/machinery/door/window/left/directional/east{
- name = "Mech Bay";
- req_access = list("robotics")
- },
-/turf/open/floor/mineral/plastitanium/red,
-/area/station/science/robotics/lab)
"dYj" = (
/obj/machinery/holopad,
/obj/structure/cable,
@@ -21163,23 +21168,6 @@
/obj/structure/lattice/catwalk,
/turf/open/space/basic,
/area/space/nearstation)
-"dZn" = (
-/obj/machinery/door/firedoor,
-/obj/structure/table/reinforced,
-/obj/item/folder/blue,
-/obj/item/folder/blue,
-/obj/item/folder/blue,
-/obj/item/pen,
-/obj/machinery/door/window/left/directional/east{
- name = "Jetpack Storage";
- req_access = list("eva")
- },
-/obj/machinery/door/window/brigdoor/right/directional/west{
- name = "Customs Desk";
- req_access = list("command")
- },
-/turf/open/floor/iron/dark,
-/area/station/security/checkpoint/customs)
"dZo" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -21278,28 +21266,6 @@
/obj/machinery/light/directional/east,
/turf/open/floor/iron/white,
/area/station/science/genetics)
-"eap" = (
-/obj/structure/table/reinforced,
-/obj/machinery/door/firedoor,
-/obj/machinery/door/window/left{
- name = "Warden's Desk"
- },
-/obj/machinery/recharger{
- pixel_x = 8
- },
-/obj/item/folder/red{
- pixel_x = -5
- },
-/obj/item/pen{
- pixel_x = -5
- },
-/obj/structure/cable,
-/obj/machinery/door/window/brigdoor/right/directional/north{
- req_access = list("armory");
- name = "Warden's Desk"
- },
-/turf/open/floor/iron/dark,
-/area/station/security/warden)
"eau" = (
/obj/machinery/atmospherics/components/unary/portables_connector/visible{
dir = 1
@@ -21493,15 +21459,18 @@
/obj/machinery/newscaster/directional/south,
/turf/open/floor/iron,
/area/station/medical/virology)
-"edu" = (
-/obj/machinery/firealarm/directional/south,
+"edo" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/door/window/brigdoor/right/directional/west{
- name = "Prisoner Transfer";
- req_access = list("security")
+/obj/effect/turf_decal/vg_decals/numbers/six,
+/obj/machinery/door/window/brigdoor/left/directional/east{
+ req_access = list("security");
+ name = "Cell 6"
},
-/turf/open/floor/iron,
-/area/station/security/checkpoint/escape)
+/turf/open/floor/iron/dark/side{
+ dir = 4
+ },
+/area/station/security/brig)
"edv" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/cable,
@@ -21569,6 +21538,13 @@
dir = 1
},
/area/station/hallway/primary/port)
+"eeB" = (
+/obj/machinery/door/window/brigdoor/right/directional/east{
+ name = "Cargo Deliveries";
+ req_access = list("security")
+ },
+/turf/open/floor/iron/dark,
+/area/station/security/brig)
"eeD" = (
/obj/item/beacon,
/obj/structure/cable,
@@ -21727,6 +21703,21 @@
},
/turf/open/space/basic,
/area/space/nearstation)
+"efG" = (
+/obj/machinery/door/firedoor,
+/obj/structure/table/reinforced,
+/obj/machinery/door/poddoor/preopen{
+ id = "atmoslock";
+ name = "Atmospherics Lockdown Blast Door"
+ },
+/obj/item/paper_bin,
+/obj/item/pen,
+/obj/machinery/door/window/right/directional/east{
+ name = "Atmospherics Desk";
+ req_access = list("atmospherics")
+ },
+/turf/open/floor/iron/dark,
+/area/station/engineering/atmos/office)
"efJ" = (
/turf/closed/wall,
/area/station/service/library/lounge)
@@ -21734,16 +21725,6 @@
/obj/effect/turf_decal/siding/wood,
/turf/open/floor/wood,
/area/station/command/captain_dining)
-"efS" = (
-/obj/machinery/door/window/left/directional/south{
- name = "Law Office Front Desk"
- },
-/obj/machinery/camera/directional/west{
- c_tag = "Law Lobby";
- dir = 10
- },
-/turf/open/floor/wood,
-/area/station/service/lawoffice)
"efW" = (
/obj/structure/toilet{
dir = 1
@@ -22565,33 +22546,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/plating,
/area/station/maintenance/central)
-"eoK" = (
-/obj/structure/table/wood,
-/obj/item/folder/blue{
- pixel_x = 3;
- pixel_y = 3
- },
-/obj/item/folder/blue,
-/obj/item/stamp/denied{
- pixel_x = -6;
- pixel_y = 4
- },
-/obj/item/stamp/head/captain{
- pixel_x = 5;
- pixel_y = 2
- },
-/obj/item/stamp{
- pixel_x = -6
- },
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/machinery/door/window/brigdoor/right/directional/west{
- name = "Captain's Desk";
- req_access = list("captain")
- },
-/turf/open/floor/carpet/blue,
-/area/station/command/heads_quarters/captain/private)
"eoO" = (
/obj/item/stack/sheet/iron{
amount = 10
@@ -23010,24 +22964,6 @@
/obj/machinery/digital_clock/directional/east,
/turf/open/floor/iron,
/area/station/service/hydroponics)
-"esT" = (
-/obj/structure/table/reinforced,
-/obj/machinery/door/window/left/directional/west{
- name = "Secure Tech Cabinet"
- },
-/obj/machinery/camera/directional/east{
- c_tag = "Engineering - Secure tech storage";
- name = "engineering camera"
- },
-/obj/structure/cable,
-/obj/item/ai_module/reset{
- pixel_y = 8
- },
-/obj/item/ai_module/core/full/custom{
- pixel_y = -4
- },
-/turf/open/floor/iron/dark,
-/area/station/engineering/storage/tech)
"esV" = (
/obj/machinery/door/airlock/engineering{
name = "Auxillary Base Construction"
@@ -23369,6 +23305,19 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/white,
/area/station/science/research)
+"evl" = (
+/obj/machinery/door/window/left/directional/east{
+ name = "Deliveries";
+ req_access = list("cargo")
+ },
+/obj/effect/turf_decal/delivery,
+/obj/effect/turf_decal/tile/brown/anticorner/contrasted,
+/obj/structure/cable,
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 8
+ },
+/turf/open/floor/iron,
+/area/station/cargo/office)
"evn" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -24298,19 +24247,6 @@
/obj/structure/window/reinforced/spawner/directional/east,
/turf/open/floor/plating,
/area/station/maintenance/aft/upper)
-"eEk" = (
-/obj/structure/flora/bush/lavendergrass,
-/obj/effect/turf_decal/siding/thinplating/light{
- dir = 4
- },
-/obj/machinery/door/poddoor/shutters/preopen{
- id = "rdgene";
- name = "Genetics Lab Shutters"
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/door/window/left/directional/east,
-/turf/open/floor/grass,
-/area/station/science/genetics)
"eEq" = (
/obj/structure/railing{
dir = 4
@@ -25037,18 +24973,6 @@
"eKU" = (
/turf/closed/wall/r_wall,
/area/station/security/prison/visit)
-"eKX" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/turf_decal/vg_decals/numbers/three,
-/obj/machinery/door/window/brigdoor/right/directional/west{
- req_access = list("security");
- name = "Cell 3"
- },
-/turf/open/floor/iron/dark/side{
- dir = 8
- },
-/area/station/security/brig)
"eKZ" = (
/obj/effect/turf_decal/bot,
/obj/structure/rack,
@@ -25103,6 +25027,18 @@
/obj/machinery/light/small/directional/west,
/turf/open/floor/iron/freezer,
/area/station/command/heads_quarters/blueshield)
+"eLq" = (
+/obj/effect/turf_decal/bot,
+/obj/machinery/hydroponics/constructable,
+/obj/structure/window/spawner/directional/north,
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 10
+ },
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/turf/open/floor/iron/dark,
+/area/station/service/hydroponics)
"eLv" = (
/obj/machinery/computer/mech_bay_power_console{
dir = 1
@@ -25418,6 +25354,33 @@
dir = 10
},
/area/station/engineering/storage)
+"eOf" = (
+/obj/machinery/camera/directional/north{
+ c_tag = "AI Chamber - Core";
+ network = list("aicore")
+ },
+/obj/effect/turf_decal/tile/neutral{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/neutral,
+/obj/effect/turf_decal/tile/neutral{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral{
+ dir = 8
+ },
+/obj/machinery/requests_console/directional/north{
+ department = "AI";
+ name = "AI Requests Console"
+ },
+/obj/effect/mapping_helpers/requests_console/information,
+/obj/effect/mapping_helpers/requests_console/assistance,
+/obj/machinery/door/window/brigdoor/left/directional/east{
+ name = "Primary AI Core Acces Door";
+ req_access = list("ai_upload")
+ },
+/turf/open/floor/iron/dark,
+/area/station/ai_monitored/turret_protected/ai)
"eOg" = (
/obj/structure/closet/crate/bin,
/turf/open/floor/wood,
@@ -25685,6 +25648,21 @@
initial_gas_mix = "TEMP=2.7"
},
/area/station/science/ordnance/bomb)
+"eQk" = (
+/obj/machinery/door/window/brigdoor/left/directional/north{
+ name = "Creature Pen";
+ req_access = list("research")
+ },
+/obj/effect/turf_decal/delivery,
+/obj/effect/turf_decal/stripes{
+ dir = 1
+ },
+/obj/machinery/door/poddoor/preopen{
+ id = "xeno5";
+ name = "Creature Cell #5"
+ },
+/turf/open/floor/engine,
+/area/station/science/xenobiology)
"eQp" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/structure/disposalpipe/segment,
@@ -26062,6 +26040,18 @@
dir = 8
},
/area/station/commons/fitness/recreation)
+"eUl" = (
+/obj/effect/turf_decal/bot,
+/obj/machinery/hydroponics/constructable,
+/obj/structure/window/spawner/directional/south,
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 1
+ },
+/obj/machinery/door/window/right/directional/west{
+ pixel_x = -3
+ },
+/turf/open/floor/iron/dark,
+/area/station/service/hydroponics)
"eUo" = (
/obj/effect/turf_decal/trimline/blue/filled/line,
/obj/effect/turf_decal/trimline/blue/corner{
@@ -26201,20 +26191,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/dark,
/area/station/ai_monitored/turret_protected/aisat_interior)
-"eVA" = (
-/obj/machinery/status_display/evac/directional/north,
-/obj/machinery/light/directional/north,
-/obj/machinery/camera/directional/north{
- c_tag = "Bridge - E.V.A. Fore";
- name = "command camera"
- },
-/obj/machinery/door/window/left/directional/west{
- req_access = list("eva")
- },
-/turf/open/floor/iron/stairs{
- dir = 4
- },
-/area/station/ai_monitored/command/storage/eva/upper)
"eVK" = (
/obj/structure/table,
/obj/item/folder/blue{
@@ -26791,21 +26767,6 @@
/obj/structure/bodycontainer/morgue,
/turf/open/floor/iron/dark,
/area/station/service/chapel)
-"faM" = (
-/obj/machinery/door/firedoor,
-/obj/structure/table/reinforced,
-/obj/machinery/door/poddoor/preopen{
- id = "atmoslock";
- name = "Atmospherics Lockdown Blast Door"
- },
-/obj/item/paper_bin,
-/obj/item/pen,
-/obj/machinery/door/window/right/directional/east{
- name = "Atmospherics Desk";
- req_access = list("atmospherics")
- },
-/turf/open/floor/iron/dark,
-/area/station/engineering/atmos/office)
"faR" = (
/obj/effect/decal/cleanable/dirt{
icon_state = "dirt-flat-1"
@@ -27019,6 +26980,14 @@
},
/turf/open/floor/iron/dark,
/area/station/security/execution/education)
+"fcO" = (
+/obj/machinery/door/window/left/directional/north,
+/obj/effect/turf_decal/siding/wood{
+ dir = 1
+ },
+/obj/machinery/airalarm/directional/west,
+/turf/open/floor/wood/parquet,
+/area/station/common/arcade)
"fcP" = (
/turf/open/floor/carpet,
/area/station/security/courtroom)
@@ -28063,6 +28032,20 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/ai_monitored/command/storage/eva/upper)
+"fnJ" = (
+/obj/machinery/door/firedoor,
+/obj/structure/table/reinforced,
+/obj/item/folder,
+/obj/item/food/grown/apple,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/door/window/left/directional/east{
+ name = "Hydroponics Desk";
+ req_access = list("hydroponics")
+ },
+/turf/open/floor/iron/dark,
+/area/station/service/hydroponics)
"fnL" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -28387,27 +28370,6 @@
/obj/machinery/light/directional/north,
/turf/open/floor/iron,
/area/station/service/chapel)
-"fqz" = (
-/obj/structure/railing{
- dir = 8
- },
-/obj/machinery/door/window/left/directional/south{
- name = "Fitness Ring"
- },
-/turf/open/floor/iron/stairs{
- dir = 1
- },
-/area/station/commons/fitness)
-"fqB" = (
-/obj/structure/cable,
-/obj/machinery/power/apc/auto_name/directional/west,
-/obj/structure/table,
-/obj/machinery/chem_dispenser/drinks/beer{
- dir = 4
- },
-/obj/effect/turf_decal/tile/bar/opposingcorners,
-/turf/open/floor/iron,
-/area/station/service/bar)
"fqD" = (
/obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/co2{
dir = 4
@@ -29044,6 +29006,29 @@
dir = 4
},
/area/station/hallway/secondary/command)
+"fxv" = (
+/obj/effect/turf_decal/tile/neutral{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/neutral,
+/obj/effect/turf_decal/tile/neutral{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral{
+ dir = 8
+ },
+/obj/machinery/holopad/secure,
+/obj/machinery/flasher/directional/west{
+ id = "AI";
+ pixel_y = -26
+ },
+/obj/structure/cable,
+/obj/machinery/door/window/brigdoor/left/directional/east{
+ name = "Secondary AI Core Acces Door";
+ req_access = list("ai_upload")
+ },
+/turf/open/floor/iron/dark,
+/area/station/ai_monitored/turret_protected/ai)
"fxw" = (
/obj/machinery/button/door/directional/south{
id = "gatewayshutters";
@@ -29515,6 +29500,17 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/plating,
/area/station/science/ordnance/freezerchamber)
+"fCT" = (
+/obj/structure/table,
+/obj/structure/window/reinforced/spawner/directional/west,
+/obj/structure/window/reinforced/spawner/directional/north,
+/obj/machinery/door/window/left/directional/east{
+ name = "Core Modules";
+ req_access = list("ai_upload")
+ },
+/obj/effect/spawner/random/aimodule/neutral,
+/turf/open/floor/iron,
+/area/station/ai_monitored/turret_protected/ai_upload)
"fCU" = (
/turf/open/floor/carpet,
/area/station/service/lawoffice)
@@ -30982,29 +30978,6 @@
/obj/item/toy/figure/engineer,
/turf/open/floor/iron,
/area/station/engineering/break_room)
-"fSn" = (
-/obj/effect/turf_decal/tile/neutral{
- dir = 1
- },
-/obj/effect/turf_decal/tile/neutral,
-/obj/effect/turf_decal/tile/neutral{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 8
- },
-/obj/machinery/holopad/secure,
-/obj/machinery/flasher/directional/west{
- id = "AI";
- pixel_y = -26
- },
-/obj/structure/cable,
-/obj/machinery/door/window/brigdoor/left/directional/east{
- name = "Secondary AI Core Acces Door";
- req_access = list("ai_upload")
- },
-/turf/open/floor/iron/dark,
-/area/station/ai_monitored/turret_protected/ai)
"fSo" = (
/obj/structure/lattice,
/obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible{
@@ -31157,12 +31130,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/upper)
-"fTY" = (
-/obj/structure/cable,
-/obj/item/radio/intercom/directional/north,
-/obj/machinery/door/window/brigdoor/right/directional/west,
-/turf/open/floor/iron,
-/area/station/security/checkpoint/escape)
"fUa" = (
/obj/machinery/door/airlock/captain{
name = "Captain's Quarters"
@@ -32078,18 +32045,6 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron,
/area/station/hallway/primary/central/fore)
-"gdb" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/structure/disposalpipe/segment,
-/obj/machinery/door/firedoor/border_only{
- dir = 1
- },
-/obj/effect/landmark/start/hangover,
-/obj/machinery/door/window/right/directional/north,
-/turf/open/floor/wood,
-/area/station/service/cafeteria)
"gdj" = (
/turf/closed/wall/r_wall,
/area/station/security/lockers)
@@ -32359,6 +32314,15 @@
/obj/structure/cable,
/turf/open/floor/plating/airless,
/area/space/nearstation)
+"gga" = (
+/obj/machinery/door/firedoor/border_only{
+ dir = 1
+ },
+/obj/machinery/door/window/right/directional/north{
+ name = "Ordnance Freezer Chamber Access"
+ },
+/turf/open/floor/iron/dark,
+/area/station/science/ordnance)
"ggh" = (
/obj/effect/turf_decal/stripes{
dir = 4
@@ -32553,14 +32517,6 @@
},
/turf/open/floor/mineral/plastitanium,
/area/station/science/robotics/mechbay)
-"gis" = (
-/obj/effect/turf_decal/delivery,
-/obj/machinery/door/window/left/directional/north{
- name = "Bar Delivery";
- req_access = list("bar")
- },
-/turf/open/floor/iron/dark,
-/area/station/hallway/secondary/service)
"git" = (
/obj/effect/turf_decal/siding/wood{
dir = 8
@@ -32751,34 +32707,6 @@
/obj/machinery/light/small/directional/east,
/turf/open/floor/iron/dark,
/area/station/medical/medbay/central)
-"gkD" = (
-/obj/machinery/turretid{
- icon_state = "control_stun";
- name = "AI Chamber turret control";
- pixel_x = 3;
- pixel_y = -23
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 1
- },
-/obj/effect/turf_decal/tile/neutral,
-/obj/effect/turf_decal/tile/neutral{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 8
- },
-/obj/machinery/power/apc/auto_name/directional/north,
-/obj/structure/cable,
-/obj/machinery/airalarm/directional/north{
- pixel_y = 33
- },
-/obj/machinery/door/window/brigdoor/left/directional/west{
- name = "Primary AI Core Acces Door";
- req_access = list("ai_upload")
- },
-/turf/open/floor/iron/dark,
-/area/station/ai_monitored/turret_protected/ai)
"gkL" = (
/obj/structure/railing{
dir = 4
@@ -34428,6 +34356,10 @@
/obj/machinery/duct,
/turf/open/floor/iron/white,
/area/station/medical/medbay/central)
+"gzV" = (
+/obj/structure/window/reinforced/spawner/directional/north,
+/turf/open/floor/wood,
+/area/station/hallway/primary/central)
"gAc" = (
/obj/effect/turf_decal/stripes{
dir = 1
@@ -34903,27 +34835,6 @@
/obj/machinery/light/directional/west,
/turf/open/floor/iron/dark,
/area/station/ai_monitored/command/nuke_storage)
-"gFj" = (
-/obj/structure/table/reinforced,
-/obj/item/storage/medkit/fire{
- pixel_x = 6;
- pixel_y = 6
- },
-/obj/item/storage/medkit/fire{
- pixel_x = 3;
- pixel_y = 3
- },
-/obj/item/storage/medkit/regular,
-/obj/item/storage/medkit/fire{
- pixel_x = -3;
- pixel_y = -3
- },
-/obj/machinery/door/window/right/directional/south{
- req_access = list("medical");
- name = "First-Aid Supplies"
- },
-/turf/open/floor/iron,
-/area/station/medical/storage)
"gFA" = (
/obj/structure/chair/plastic{
dir = 4
@@ -35113,6 +35024,28 @@
/obj/effect/spawner/random/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/fore/upper)
+"gHC" = (
+/obj/machinery/flasher/directional/east{
+ id = "AI";
+ pixel_y = 26
+ },
+/obj/effect/turf_decal/tile/neutral{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/neutral,
+/obj/effect/turf_decal/tile/neutral{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral{
+ dir = 8
+ },
+/obj/machinery/holopad/secure,
+/obj/machinery/door/window/brigdoor/left/directional/west{
+ name = "Tertiary AI Core Acces Door";
+ req_access = list("ai_upload")
+ },
+/turf/open/floor/iron/dark,
+/area/station/ai_monitored/turret_protected/ai)
"gHH" = (
/obj/structure/table/wood,
/obj/item/reagent_containers/cup/bottle/syrup_bottle/liqueur{
@@ -35523,6 +35456,17 @@
dir = 8
},
/area/station/service/hydroponics)
+"gLX" = (
+/obj/machinery/conveyor{
+ dir = 4;
+ id = "garbage"
+ },
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/door/window/right/directional/north,
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"gLY" = (
/obj/structure/mirror{
pixel_y = 32
@@ -36142,13 +36086,6 @@
/obj/effect/landmark/start/assistant,
/turf/open/floor/carpet,
/area/station/service/library/lounge)
-"gSe" = (
-/obj/machinery/door/window/brigdoor/right/directional/east{
- name = "Cargo Deliveries";
- req_access = list("security")
- },
-/turf/open/floor/iron/dark,
-/area/station/security/brig)
"gSg" = (
/obj/structure/lattice,
/obj/machinery/atmospherics/pipe/smart/simple/green/visible{
@@ -36515,6 +36452,18 @@
},
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
+"gVW" = (
+/obj/machinery/door/firedoor,
+/obj/structure/table/reinforced,
+/obj/item/folder/red,
+/obj/item/pen,
+/obj/structure/disposalpipe/segment,
+/obj/machinery/door/window/brigdoor/right/directional/north{
+ name = "Security Desk";
+ req_access = list("security")
+ },
+/turf/open/floor/iron/dark,
+/area/station/security/checkpoint/escape)
"gWc" = (
/obj/effect/turf_decal/stripes{
dir = 8
@@ -37203,11 +37152,6 @@
},
/turf/open/floor/iron,
/area/station/maintenance/starboard/fore)
-"hdT" = (
-/obj/machinery/airalarm/directional/east,
-/obj/machinery/door/window/right/directional/north,
-/turf/open/floor/wood,
-/area/station/service/theater)
"hdU" = (
/obj/structure/table/wood/fancy/blue,
/obj/effect/turf_decal/siding/wood{
@@ -37260,28 +37204,6 @@
/obj/item/plate,
/turf/open/floor/carpet/blue,
/area/station/command/captain_dining)
-"heu" = (
-/obj/machinery/flasher/directional/east{
- id = "AI";
- pixel_y = 26
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 1
- },
-/obj/effect/turf_decal/tile/neutral,
-/obj/effect/turf_decal/tile/neutral{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 8
- },
-/obj/machinery/holopad/secure,
-/obj/machinery/door/window/brigdoor/left/directional/west{
- name = "Tertiary AI Core Acces Door";
- req_access = list("ai_upload")
- },
-/turf/open/floor/iron/dark,
-/area/station/ai_monitored/turret_protected/ai)
"hey" = (
/obj/effect/turf_decal/tile/yellow/half/contrasted{
dir = 8
@@ -38015,22 +37937,6 @@
},
/turf/open/floor/iron/dark,
/area/station/hallway/primary/central)
-"hlQ" = (
-/obj/machinery/power/smes{
- charge = 5e+006
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 1
- },
-/obj/effect/turf_decal/tile/neutral,
-/obj/effect/turf_decal/tile/neutral{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 8
- },
-/turf/open/floor/iron/dark,
-/area/station/ai_monitored/turret_protected/aisat_interior)
"hlR" = (
/obj/structure/chair/sofa/bench/right{
dir = 4;
@@ -38203,6 +38109,10 @@
"hnC" = (
/turf/open/floor/plating,
/area/station/maintenance/department/science/upper)
+"hnD" = (
+/obj/structure/musician/piano,
+/turf/open/floor/wood,
+/area/station/service/bar/atrium)
"hnI" = (
/obj/machinery/door/firedoor,
/obj/effect/turf_decal/stripes{
@@ -38625,6 +38535,14 @@
},
/turf/open/floor/carpet/purple,
/area/station/common/night_club/back_stage)
+"hsJ" = (
+/obj/effect/turf_decal/delivery,
+/obj/machinery/door/window/left/directional/north{
+ name = "Bar Delivery";
+ req_access = list("bar")
+ },
+/turf/open/floor/iron/dark,
+/area/station/hallway/secondary/service)
"hsN" = (
/obj/structure/railing/corner{
dir = 1
@@ -38720,22 +38638,6 @@
/obj/effect/mapping_helpers/airlock/access/all/medical/virology,
/turf/open/floor/iron,
/area/station/medical/virology)
-"htu" = (
-/obj/structure/window/reinforced/spawner/directional/north,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/turf_decal/vg_decals/numbers/one,
-/obj/effect/turf_decal/tile/red/half/contrasted{
- dir = 8
- },
-/obj/machinery/door/window/brigdoor/right/directional/west{
- req_access = list("security");
- name = "Cell 1"
- },
-/turf/open/floor/iron/dark/side{
- dir = 8
- },
-/area/station/security/brig)
"htw" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/door/poddoor/shutters/preopen{
@@ -39157,6 +39059,19 @@
/obj/item/folder/red,
/turf/open/floor/plating,
/area/station/maintenance/abandon_holding_cell)
+"hym" = (
+/obj/structure/table/reinforced,
+/obj/machinery/door/firedoor,
+/obj/machinery/door/window/left/directional/north{
+ name = "Hydroponics Desk";
+ req_access = list("hydroponics")
+ },
+/obj/machinery/door/window/left/directional/south{
+ name = "Kitchen Desk";
+ req_access = list("kitchen")
+ },
+/turf/open/floor/iron/dark,
+/area/station/service/hydroponics)
"hyp" = (
/obj/machinery/portable_atmospherics/pump,
/turf/open/floor/plating,
@@ -39205,17 +39120,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/openspace,
/area/station/maintenance/department/medical/central)
-"hyU" = (
-/obj/structure/table,
-/obj/structure/window/reinforced/spawner/directional/west,
-/obj/structure/window/reinforced/spawner/directional/north,
-/obj/machinery/door/window/left/directional/east{
- name = "Core Modules";
- req_access = list("ai_upload")
- },
-/obj/effect/spawner/random/aimodule/neutral,
-/turf/open/floor/iron,
-/area/station/ai_monitored/turret_protected/ai_upload)
"hyY" = (
/obj/effect/turf_decal/tile/brown/half/contrasted,
/turf/open/floor/iron,
@@ -40720,6 +40624,27 @@
/obj/machinery/shower/directional/west,
/turf/open/floor/iron/freezer,
/area/station/commons/toilet/restrooms)
+"hNA" = (
+/obj/machinery/light/directional/north,
+/obj/effect/turf_decal/stripes{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes/white/line{
+ dir = 8
+ },
+/obj/machinery/button/elevator{
+ id = "publicElevator";
+ pixel_y = 32
+ },
+/obj/machinery/lift_indicator/directional/north{
+ linked_elevator_id = "publicElevator"
+ },
+/obj/machinery/door/window/elevator/right/directional/west{
+ elevator_mode = 1;
+ transport_linked_id = "publicElevator"
+ },
+/turf/open/floor/iron/dark,
+/area/station/hallway/primary/upper)
"hNB" = (
/obj/machinery/duct,
/turf/open/floor/iron,
@@ -42058,6 +41983,19 @@
/obj/effect/spawner/random/trash/graffiti,
/turf/closed/wall,
/area/station/maintenance/department/security/greater)
+"ibj" = (
+/obj/structure/table/reinforced,
+/obj/machinery/door/firedoor,
+/obj/machinery/door/window/right/directional/west{
+ req_access = list("armory");
+ name = "Armoury Desk"
+ },
+/obj/machinery/door/window/right/directional/east{
+ name = "Armoury Desk";
+ req_access = list("armory")
+ },
+/turf/open/floor/iron/dark,
+/area/station/ai_monitored/security/armory)
"ibk" = (
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
@@ -42401,18 +42339,6 @@
},
/turf/open/floor/iron/dark,
/area/station/security/brig)
-"iep" = (
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/turf_decal/vg_decals/numbers/two,
-/obj/machinery/door/window/brigdoor/right/directional/west{
- req_access = list("security");
- name = "Cell 2"
- },
-/turf/open/floor/iron/dark/side{
- dir = 8
- },
-/area/station/security/brig)
"ies" = (
/obj/effect/turf_decal/siding/wood{
dir = 9
@@ -43102,6 +43028,29 @@
/obj/structure/extinguisher_cabinet/directional/east,
/turf/open/floor/iron,
/area/station/commons/dorms)
+"ils" = (
+/obj/structure/table/reinforced,
+/obj/machinery/door/firedoor,
+/obj/machinery/door/poddoor/shutters/preopen{
+ id = "roboticsprivacy";
+ name = "Robotics Shutters"
+ },
+/obj/item/folder,
+/obj/item/folder,
+/obj/item/folder,
+/obj/item/pen,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/door/window/left/directional/west{
+ req_access = list("robotics");
+ name = "Robotics Desk"
+ },
+/obj/machinery/door/window/left/directional/east{
+ name = "Robotics Desk"
+ },
+/turf/open/floor/iron/dark,
+/area/station/science/robotics)
"ilB" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -43263,19 +43212,6 @@
},
/turf/open/floor/wood,
/area/station/commons/dorms/room1)
-"imX" = (
-/obj/structure/table/reinforced,
-/obj/machinery/door/firedoor,
-/obj/machinery/door/window/right/directional/west{
- req_access = list("armory");
- name = "Armoury Desk"
- },
-/obj/machinery/door/window/right/directional/east{
- name = "Armoury Desk";
- req_access = list("armory")
- },
-/turf/open/floor/iron/dark,
-/area/station/ai_monitored/security/armory)
"inc" = (
/obj/effect/decal/cleanable/oil/streak,
/turf/open/floor/iron/dark,
@@ -43719,6 +43655,13 @@
/obj/effect/landmark/start/hangover,
/turf/open/floor/wood,
/area/station/hallway/primary/port)
+"irB" = (
+/obj/structure/chair/office{
+ dir = 1
+ },
+/obj/machinery/door/window/left/directional/west,
+/turf/open/floor/iron/dark,
+/area/station/security/execution/education)
"irC" = (
/obj/structure/closet/firecloset,
/turf/open/floor/plating,
@@ -44557,6 +44500,10 @@
},
/turf/open/floor/iron/dark,
/area/station/security/brig)
+"iAk" = (
+/obj/machinery/door/window/right/directional/north,
+/turf/open/floor/iron/dark,
+/area/station/science/xenobiology)
"iAl" = (
/obj/structure/closet/cardboard,
/obj/effect/spawner/random/maintenance/two,
@@ -44871,6 +44818,17 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central)
+"iDh" = (
+/obj/machinery/door/window/left/directional/south{
+ name = "Library Desk";
+ req_access = list("library")
+ },
+/obj/machinery/power/apc/auto_name/directional/west,
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/wood,
+/area/station/service/library)
"iDw" = (
/obj/machinery/door/airlock/maintenance,
/obj/effect/decal/cleanable/dirt{
@@ -45432,20 +45390,6 @@
/obj/effect/spawner/structure/window,
/turf/open/floor/plating,
/area/station/hallway/secondary/entry)
-"iIO" = (
-/obj/structure/table/wood,
-/obj/item/coin/adamantine{
- pixel_x = -4;
- pixel_y = 4
- },
-/obj/item/hand_tele,
-/obj/item/melee/chainofcommand,
-/obj/machinery/door/window/brigdoor/left/directional/west{
- name = "Captain's Desk";
- req_access = list("captain")
- },
-/turf/open/floor/carpet/blue,
-/area/station/command/heads_quarters/captain/private)
"iIZ" = (
/obj/structure/window/reinforced/spawner/directional/east,
/obj/effect/turf_decal/trimline/blue/line,
@@ -45831,6 +45775,14 @@
dir = 1
},
/area/station/hallway/secondary/exit)
+"iNe" = (
+/obj/effect/turf_decal/delivery,
+/obj/machinery/door/window/right/directional/north{
+ name = "Hydroponics Delivery";
+ req_access = list("hydroponics")
+ },
+/turf/open/floor/iron/dark,
+/area/station/service/hydroponics)
"iNf" = (
/obj/structure/disposalpipe/segment{
dir = 5
@@ -46068,6 +46020,21 @@
/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/abandon_exam/cat)
+"iQM" = (
+/obj/machinery/door/window/brigdoor/left/directional/north{
+ name = "Creature Pen";
+ req_access = list("research")
+ },
+/obj/effect/turf_decal/delivery,
+/obj/effect/turf_decal/stripes{
+ dir = 1
+ },
+/obj/machinery/door/poddoor/preopen{
+ id = "xeno9";
+ name = "Creature Cell #9"
+ },
+/turf/open/floor/engine,
+/area/station/science/xenobiology)
"iQN" = (
/obj/structure/chair/office/light{
dir = 1
@@ -46166,17 +46133,6 @@
},
/turf/open/floor/iron/dark,
/area/station/security/execution/transfer)
-"iRK" = (
-/obj/structure/table,
-/obj/structure/window/reinforced/spawner/directional/west,
-/obj/structure/window/reinforced/spawner/directional/south,
-/obj/machinery/door/window/left/directional/east{
- name = "Core Modules";
- req_access = list("ai_upload")
- },
-/obj/effect/spawner/random/aimodule/harmless,
-/turf/open/floor/iron,
-/area/station/ai_monitored/turret_protected/ai_upload)
"iRO" = (
/obj/structure/railing{
dir = 4
@@ -46296,6 +46252,20 @@
/obj/effect/mapping_helpers/burnt_floor,
/turf/open/floor/plating/airless,
/area/space/nearstation)
+"iTD" = (
+/obj/structure/table/wood,
+/obj/item/coin/adamantine{
+ pixel_x = -4;
+ pixel_y = 4
+ },
+/obj/item/hand_tele,
+/obj/item/melee/chainofcommand,
+/obj/machinery/door/window/brigdoor/left/directional/west{
+ name = "Captain's Desk";
+ req_access = list("captain")
+ },
+/turf/open/floor/carpet/blue,
+/area/station/command/heads_quarters/captain/private)
"iTI" = (
/obj/machinery/suit_storage_unit/open,
/turf/open/floor/iron/dark,
@@ -47356,15 +47326,6 @@
},
/turf/open/floor/grass,
/area/station/medical/exam_room)
-"jcF" = (
-/obj/machinery/conveyor{
- dir = 4;
- id = "garbage"
- },
-/obj/machinery/door/window/right/directional/north,
-/obj/machinery/door/window/right/directional/south,
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"jcN" = (
/obj/machinery/rnd/production/techfab/department/service,
/obj/effect/turf_decal/bot,
@@ -47538,6 +47499,11 @@
/obj/effect/turf_decal/tile/bar/opposingcorners,
/turf/open/floor/iron,
/area/station/service/bar)
+"jeX" = (
+/obj/machinery/light/directional/south,
+/obj/item/radio/intercom/directional/south,
+/turf/open/floor/iron/dark,
+/area/station/service/library/private)
"jfa" = (
/obj/effect/spawner/random/trash/graffiti,
/turf/closed/wall,
@@ -48771,21 +48737,6 @@
/obj/item/surgery_tray/full/morgue,
/turf/open/floor/iron/white,
/area/station/medical/morgue)
-"jqO" = (
-/obj/effect/turf_decal/delivery,
-/obj/machinery/navbeacon{
- codes_txt = "delivery;dir=8";
- location = "Medbay"
- },
-/obj/structure/disposalpipe/segment{
- dir = 10
- },
-/obj/machinery/door/window/right/directional/east{
- name = "Medical Delivery";
- req_access = list("medical")
- },
-/turf/open/floor/iron/dark,
-/area/station/medical/medbay/central)
"jqP" = (
/obj/structure/sink/directional/west,
/obj/machinery/camera/directional/west{
@@ -48897,6 +48848,22 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/circuit,
/area/station/command/gateway)
+"jrJ" = (
+/obj/structure/window/reinforced/spawner/directional/north,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/turf_decal/vg_decals/numbers/one,
+/obj/effect/turf_decal/tile/red/half/contrasted{
+ dir = 8
+ },
+/obj/machinery/door/window/brigdoor/right/directional/west{
+ req_access = list("security");
+ name = "Cell 1"
+ },
+/turf/open/floor/iron/dark/side{
+ dir = 8
+ },
+/area/station/security/brig)
"jrL" = (
/obj/effect/turf_decal/stripes{
dir = 6
@@ -49816,12 +49783,6 @@
},
/turf/open/floor/iron/white,
/area/station/science/tele_sci)
-"jAH" = (
-/obj/structure/cable,
-/obj/machinery/power/apc/auto_name/directional/west,
-/obj/machinery/door/window/right/directional/north,
-/turf/open/floor/wood,
-/area/station/service/theater)
"jAO" = (
/obj/structure/railing/corner{
dir = 8
@@ -50072,6 +50033,14 @@
/obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible,
/turf/open/floor/iron,
/area/station/engineering/atmos)
+"jDk" = (
+/obj/effect/turf_decal/delivery,
+/obj/machinery/door/window/left/directional/north{
+ name = "Kitchen Delivery";
+ req_access = list("kitchen")
+ },
+/turf/open/floor/iron/freezer,
+/area/station/service/kitchen/coldroom)
"jDp" = (
/obj/machinery/atmospherics/pipe/layer_manifold/brown/visible,
/obj/effect/spawner/structure/window/reinforced/plasma,
@@ -50224,23 +50193,6 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/iron/white,
/area/station/medical/virology)
-"jEK" = (
-/obj/effect/turf_decal/stripes{
- dir = 4
- },
-/obj/machinery/disposal/delivery_chute{
- dir = 4
- },
-/obj/structure/plasticflaps,
-/obj/structure/disposalpipe/trunk{
- dir = 8
- },
-/obj/machinery/door/window/right/directional/east{
- req_access = list("cargo");
- name = "Science Deliveries"
- },
-/turf/open/floor/iron/dark,
-/area/station/cargo/sorting)
"jEP" = (
/obj/effect/turf_decal/stripes{
dir = 8
@@ -51288,18 +51240,6 @@
/obj/machinery/duct,
/turf/open/floor/iron/grimy,
/area/station/command/heads_quarters/captain)
-"jOL" = (
-/obj/effect/turf_decal/bot,
-/obj/machinery/hydroponics/constructable,
-/obj/structure/window/spawner/directional/north,
-/obj/effect/turf_decal/trimline/green/filled/line{
- dir = 10
- },
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/turf/open/floor/iron/dark,
-/area/station/service/hydroponics)
"jOV" = (
/obj/effect/turf_decal/stripes{
dir = 8
@@ -51842,19 +51782,22 @@
/obj/machinery/duct,
/turf/open/floor/iron,
/area/station/commons/fitness)
-"jTE" = (
-/obj/effect/turf_decal/bot,
-/obj/machinery/hydroponics/constructable,
-/obj/structure/window/spawner/directional/north,
-/obj/effect/turf_decal/trimline/green/filled/line,
-/obj/structure/disposalpipe/segment{
+"jTG" = (
+/obj/structure/window/reinforced/spawner/directional/north,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/turf_decal/vg_decals/numbers/four,
+/obj/effect/turf_decal/tile/red/half/contrasted{
dir = 4
},
-/obj/machinery/door/window/left/directional/west{
- pixel_x = -3
+/obj/machinery/door/window/brigdoor/left/directional/east{
+ req_access = list("security");
+ name = "Cell 4"
},
-/turf/open/floor/iron/dark,
-/area/station/service/hydroponics)
+/turf/open/floor/iron/dark/side{
+ dir = 4
+ },
+/area/station/security/brig)
"jTH" = (
/obj/effect/turf_decal/bot,
/obj/structure/closet/firecloset,
@@ -52300,16 +52243,6 @@
dir = 4
},
/area/station/security/prison/visit)
-"jWX" = (
-/obj/effect/turf_decal/bot,
-/obj/machinery/hydroponics/constructable,
-/obj/structure/window/spawner/directional/north,
-/obj/effect/turf_decal/trimline/green/filled/line,
-/obj/machinery/door/window/left/directional/west{
- pixel_x = -3
- },
-/turf/open/floor/iron/dark,
-/area/station/service/hydroponics)
"jXa" = (
/obj/machinery/computer/records/medical{
dir = 8
@@ -52319,14 +52252,6 @@
},
/turf/open/floor/iron/dark,
/area/station/command/heads_quarters/hos)
-"jXd" = (
-/obj/machinery/door/window/left/directional/north,
-/obj/effect/turf_decal/siding/wood{
- dir = 1
- },
-/obj/machinery/airalarm/directional/west,
-/turf/open/floor/wood/parquet,
-/area/station/common/arcade)
"jXA" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment,
@@ -52731,14 +52656,6 @@
},
/turf/open/floor/iron,
/area/station/commons/dorms)
-"kaB" = (
-/obj/effect/turf_decal/delivery,
-/obj/machinery/door/window/right/directional/north{
- name = "Hydroponics Delivery";
- req_access = list("hydroponics")
- },
-/turf/open/floor/iron/dark,
-/area/station/service/hydroponics)
"kaK" = (
/obj/structure/grille/broken,
/obj/effect/spawner/random/trash/mess,
@@ -52945,21 +52862,6 @@
/obj/machinery/duct,
/turf/open/floor/iron/white,
/area/station/science/genetics)
-"kdq" = (
-/obj/machinery/door/window/brigdoor/left/directional/north{
- name = "Creature Pen";
- req_access = list("research")
- },
-/obj/effect/turf_decal/delivery,
-/obj/effect/turf_decal/stripes{
- dir = 1
- },
-/obj/machinery/door/poddoor/preopen{
- id = "xeno6";
- name = "Creature Cell #6"
- },
-/turf/open/floor/engine,
-/area/station/science/xenobiology)
"kdw" = (
/obj/machinery/firealarm/directional/south,
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
@@ -53216,18 +53118,6 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/iron,
/area/station/hallway/secondary/exit/departure_lounge)
-"kfH" = (
-/obj/effect/turf_decal/bot,
-/obj/machinery/hydroponics/constructable,
-/obj/structure/window/spawner/directional/north,
-/obj/effect/turf_decal/trimline/green/filled/line{
- dir = 6
- },
-/obj/machinery/door/window/left/directional/west{
- pixel_x = -3
- },
-/turf/open/floor/iron/dark,
-/area/station/service/hydroponics)
"kfJ" = (
/obj/effect/turf_decal/siding/wood,
/obj/structure/chair/wood{
@@ -54295,19 +54185,6 @@
dir = 1
},
/area/station/hallway/primary/starboard)
-"kpk" = (
-/obj/machinery/door/window/brigdoor/left/directional/south{
- name = "Creature Pen";
- req_access = list("research")
- },
-/obj/effect/turf_decal/delivery,
-/obj/effect/turf_decal/stripes,
-/obj/machinery/door/poddoor/preopen{
- id = "xeno1";
- name = "Creature Cell #1"
- },
-/turf/open/floor/engine,
-/area/station/science/xenobiology)
"kpo" = (
/obj/structure/window/reinforced/spawner/directional/east,
/obj/structure/window/reinforced/spawner/directional/west,
@@ -54668,6 +54545,23 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/engine,
/area/station/ai_monitored/turret_protected/aisat/hallway)
+"ksx" = (
+/obj/effect/turf_decal/stripes{
+ dir = 4
+ },
+/obj/machinery/disposal/delivery_chute{
+ dir = 4
+ },
+/obj/structure/plasticflaps,
+/obj/structure/disposalpipe/trunk{
+ dir = 8
+ },
+/obj/machinery/door/window/right/directional/east{
+ req_access = list("cargo");
+ name = "Service Deliveries"
+ },
+/turf/open/floor/iron/dark,
+/area/station/cargo/sorting)
"ksJ" = (
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 9
@@ -55512,6 +55406,16 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/dark,
/area/station/security/office)
+"kAn" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/door/window/brigdoor/right/directional/east{
+ name = "Security Desk";
+ req_access = list("security")
+ },
+/turf/open/floor/iron,
+/area/station/security/checkpoint/escape)
"kAp" = (
/obj/structure/showcase/machinery/cloning_pod{
desc = "An old prototype cloning pod, permanently decommissioned following the incident.";
@@ -55624,6 +55528,14 @@
},
/turf/open/floor/wood,
/area/station/service/abandoned_gambling_den)
+"kBE" = (
+/obj/effect/turf_decal/delivery,
+/obj/machinery/door/window/brigdoor/left/directional/east{
+ name = "Xenobiology Deliveries";
+ req_access = list("research")
+ },
+/turf/open/floor/iron/dark,
+/area/station/science/xenobiology/control)
"kBG" = (
/obj/structure/fans/tiny/forcefield,
/obj/machinery/light/directional/east,
@@ -55987,6 +55899,21 @@
/obj/machinery/light_switch/directional/east,
/turf/open/floor/carpet/blue,
/area/station/command/heads_quarters/cmo)
+"kFy" = (
+/obj/machinery/door/firedoor,
+/obj/structure/table/reinforced,
+/obj/item/folder/red,
+/obj/item/pen,
+/obj/machinery/door/window/left/directional/east{
+ name = "Jetpack Storage";
+ req_access = list("eva")
+ },
+/obj/machinery/door/window/brigdoor/right/directional/west{
+ name = "Security Customs";
+ req_access = list("security")
+ },
+/turf/open/floor/iron/dark,
+/area/station/security/checkpoint)
"kFL" = (
/obj/structure/railing{
dir = 10
@@ -56861,6 +56788,12 @@
"kPg" = (
/turf/open/floor/iron/dark/small,
/area/station/cargo/storage)
+"kPl" = (
+/obj/structure/flora/bush/grassy,
+/obj/structure/flora/bush/flowers_br,
+/obj/machinery/door/window/left/directional/east,
+/turf/open/floor/grass,
+/area/station/medical/aslyum)
"kPo" = (
/obj/structure/cable,
/obj/item/kirbyplants/random,
@@ -57292,6 +57225,13 @@
},
/turf/open/floor/iron,
/area/station/science/ordnance)
+"kUv" = (
+/obj/machinery/airalarm/directional/north,
+/obj/machinery/newscaster/directional/east,
+/obj/machinery/light/directional/north,
+/obj/machinery/smartfridge/organ,
+/turf/open/floor/iron/dark/small,
+/area/station/medical/morgue)
"kUx" = (
/obj/effect/turf_decal/siding/wood/corner{
dir = 4
@@ -57516,6 +57456,29 @@
/obj/structure/cable,
/turf/open/floor/carpet/purple,
/area/station/science/breakroom)
+"kYa" = (
+/obj/machinery/door/window/brigdoor/left/directional/east{
+ id = "medcell";
+ name = "Medical Cell";
+ req_access = list("security")
+ },
+/obj/effect/turf_decal/delivery,
+/obj/effect/turf_decal/trimline/blue/filled/warning{
+ dir = 4
+ },
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/effect/turf_decal/tile/blue{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/blue{
+ dir = 8
+ },
+/turf/open/floor/iron/white/side{
+ dir = 4
+ },
+/area/station/security/checkpoint/medical)
"kYe" = (
/obj/effect/turf_decal/stripes{
dir = 10
@@ -58493,17 +58456,6 @@
/obj/item/clothing/mask/gas,
/turf/open/floor/plating,
/area/station/maintenance/department/science/xenobiology)
-"lgU" = (
-/obj/machinery/conveyor{
- dir = 4;
- id = "packageSort2"
- },
-/obj/machinery/door/window/left/directional/east{
- name = "Crate Security Door";
- req_access = list("cargo")
- },
-/turf/open/floor/iron/dark,
-/area/station/cargo/sorting)
"lgV" = (
/obj/machinery/shower/directional/west,
/obj/machinery/light/small/directional/north,
@@ -58591,6 +58543,13 @@
},
/turf/open/floor/plating,
/area/station/maintenance/department/security/upper)
+"lhM" = (
+/obj/machinery/door/window/brigdoor/left/directional/south{
+ name = "Creature Pen";
+ req_access = list("research")
+ },
+/turf/open/floor/engine,
+/area/station/science/xenobiology)
"lhN" = (
/obj/effect/turf_decal/bot,
/obj/effect/turf_decal/tile/brown{
@@ -59195,6 +59154,24 @@
},
/turf/open/floor/iron/dark,
/area/station/engineering/supermatter/room)
+"loc" = (
+/obj/structure/table/wood,
+/obj/item/paper_bin,
+/obj/item/pen,
+/obj/effect/turf_decal/tile/neutral{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/neutral,
+/obj/effect/turf_decal/tile/neutral{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral{
+ dir = 8
+ },
+/obj/machinery/newscaster/directional/south,
+/obj/item/folder,
+/turf/open/floor/iron/dark,
+/area/station/service/library/private)
"lor" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -59306,13 +59283,6 @@
"lpf" = (
/turf/closed/wall,
/area/station/maintenance/abandon_surgery)
-"lph" = (
-/obj/machinery/airalarm/directional/north,
-/obj/machinery/newscaster/directional/east,
-/obj/machinery/light/directional/north,
-/obj/machinery/smartfridge/organ,
-/turf/open/floor/iron/dark/small,
-/area/station/medical/morgue)
"lpi" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -59985,6 +59955,14 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/hallway/primary/aft)
+"lwm" = (
+/obj/machinery/conveyor/inverted{
+ dir = 9;
+ id = "garbage"
+ },
+/obj/machinery/door/window/right/directional/west,
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"lwo" = (
/obj/effect/turf_decal/trimline/blue/line{
dir = 8;
@@ -60086,6 +60064,18 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/port)
+"lxB" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/structure/disposalpipe/segment,
+/obj/machinery/door/firedoor/border_only{
+ dir = 1
+ },
+/obj/effect/landmark/start/hangover,
+/obj/machinery/door/window/right/directional/north,
+/turf/open/floor/wood,
+/area/station/service/cafeteria)
"lxF" = (
/obj/machinery/power/apc/auto_name/directional/south,
/obj/structure/cable,
@@ -60585,6 +60575,19 @@
/obj/machinery/duct,
/turf/open/floor/wood,
/area/station/command/heads_quarters/rd)
+"lCP" = (
+/obj/effect/turf_decal/bot,
+/obj/machinery/hydroponics/constructable,
+/obj/structure/window/spawner/directional/north,
+/obj/effect/turf_decal/trimline/green/filled/line,
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/door/window/left/directional/west{
+ pixel_x = -3
+ },
+/turf/open/floor/iron/dark,
+/area/station/service/hydroponics)
"lCR" = (
/obj/effect/turf_decal/tile/red,
/obj/machinery/newscaster/directional/east,
@@ -60987,19 +60990,6 @@
/obj/machinery/duct,
/turf/open/floor/carpet/red,
/area/station/commons/dorms/room6)
-"lGL" = (
-/obj/effect/turf_decal/tile/yellow/opposingcorners{
- dir = 8
- },
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 8
- },
-/obj/machinery/door/window/left/directional/north{
- name = "Engineering Deliveries";
- req_access = list("engineering")
- },
-/turf/open/floor/iron/checker,
-/area/station/engineering/lobby)
"lGO" = (
/obj/machinery/camera/directional/east{
c_tag = "Security - Shooting Range"
@@ -61090,16 +61080,6 @@
},
/turf/open/floor/plating,
/area/station/maintenance/port/fore)
-"lHR" = (
-/obj/structure/bed{
- dir = 1
- },
-/obj/effect/spawner/random/bedsheet{
- dir = 1
- },
-/obj/effect/landmark/start/hangover,
-/turf/open/floor/carpet/black,
-/area/station/commons/dorms/room5)
"lHT" = (
/obj/effect/turf_decal/tile/dark_blue/anticorner/contrasted,
/obj/machinery/recharge_station,
@@ -61523,6 +61503,13 @@
},
/turf/open/floor/iron/white,
/area/station/medical/virology/isolation)
+"lLv" = (
+/obj/machinery/door/window/brigdoor/left/directional/north{
+ name = "Creature Pen";
+ req_access = list("research")
+ },
+/turf/open/floor/engine,
+/area/station/science/xenobiology)
"lLC" = (
/obj/structure/table/wood,
/obj/item/folder{
@@ -61595,6 +61582,10 @@
/obj/structure/cable,
/turf/open/floor/iron/dark,
/area/station/command/bridge)
+"lMu" = (
+/obj/machinery/door/window/right/directional/north,
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"lMx" = (
/obj/effect/turf_decal/stripes,
/obj/structure/table/reinforced,
@@ -63101,6 +63092,24 @@
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
/turf/open/floor/iron/freezer,
/area/station/maintenance/abandon_kitchen_upper)
+"mbb" = (
+/obj/structure/window/reinforced/spawner/directional/north,
+/obj/effect/turf_decal/stripes{
+ dir = 4
+ },
+/obj/machinery/disposal/delivery_chute{
+ dir = 4
+ },
+/obj/structure/plasticflaps,
+/obj/structure/disposalpipe/trunk{
+ dir = 4
+ },
+/obj/machinery/door/window/right/directional/east{
+ req_access = list("cargo");
+ name = "Security Deliveries"
+ },
+/turf/open/floor/iron/dark,
+/area/station/cargo/sorting)
"mbg" = (
/obj/machinery/light/directional/north,
/turf/open/floor/carpet/red,
@@ -63534,6 +63543,24 @@
/obj/machinery/newscaster/directional/west,
/turf/open/floor/iron/dark,
/area/station/science/server)
+"mfp" = (
+/obj/structure/table/reinforced,
+/obj/machinery/door/window/left/directional/west{
+ name = "Secure Tech Cabinet"
+ },
+/obj/machinery/camera/directional/east{
+ c_tag = "Engineering - Secure tech storage";
+ name = "engineering camera"
+ },
+/obj/structure/cable,
+/obj/item/ai_module/reset{
+ pixel_y = 8
+ },
+/obj/item/ai_module/core/full/custom{
+ pixel_y = -4
+ },
+/turf/open/floor/iron/dark,
+/area/station/engineering/storage/tech)
"mfw" = (
/obj/machinery/flasher/portable,
/turf/open/floor/iron/dark/side{
@@ -63810,20 +63837,6 @@
dir = 8
},
/area/station/hallway/primary/central)
-"miq" = (
-/obj/machinery/door/firedoor,
-/obj/structure/table/reinforced,
-/obj/item/folder,
-/obj/item/food/grown/apple,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/machinery/door/window/left/directional/east{
- name = "Hydroponics Desk";
- req_access = list("hydroponics")
- },
-/turf/open/floor/iron/dark,
-/area/station/service/hydroponics)
"miw" = (
/obj/structure/table,
/obj/item/weldingtool/largetank{
@@ -64149,13 +64162,6 @@
/obj/machinery/duct,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/morgue)
-"mmr" = (
-/obj/machinery/door/window/brigdoor/left/directional/south{
- name = "Creature Pen";
- req_access = list("research")
- },
-/turf/open/floor/engine,
-/area/station/science/xenobiology)
"mmu" = (
/obj/effect/turf_decal/tile/dark_blue/half/contrasted{
dir = 1
@@ -64247,6 +64253,18 @@
/obj/machinery/light/directional/east,
/turf/open/floor/iron/freezer,
/area/station/science/xenobiology)
+"mnv" = (
+/obj/effect/turf_decal/bot,
+/obj/machinery/hydroponics/constructable,
+/obj/structure/window/spawner/directional/north,
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 6
+ },
+/obj/machinery/door/window/left/directional/west{
+ pixel_x = -3
+ },
+/turf/open/floor/iron/dark,
+/area/station/service/hydroponics)
"mnw" = (
/obj/effect/turf_decal/bot,
/obj/machinery/atmospherics/components/binary/pump{
@@ -64411,6 +64429,20 @@
dir = 8
},
/area/station/escapepodbay)
+"mpE" = (
+/obj/machinery/door/firedoor,
+/obj/structure/table/reinforced,
+/obj/item/folder/white,
+/obj/machinery/door/poddoor/shutters/preopen{
+ id = "Psychward4";
+ name = "Control Room Shutters"
+ },
+/obj/structure/cable,
+/obj/machinery/door/window/left/directional/east{
+ req_access = list("psychology")
+ },
+/turf/open/floor/iron/dark,
+/area/station/medical/psychology)
"mpJ" = (
/obj/effect/turf_decal/delivery,
/obj/effect/spawner/random/structure/crate,
@@ -64700,19 +64732,6 @@
/obj/effect/mapping_helpers/airlock/access/all/engineering/external,
/turf/open/floor/plating,
/area/station/maintenance/aft/upper)
-"msO" = (
-/obj/machinery/door/window/brigdoor/left/directional/south{
- name = "Creature Pen";
- req_access = list("research")
- },
-/obj/effect/turf_decal/delivery,
-/obj/effect/turf_decal/stripes,
-/obj/machinery/door/poddoor/preopen{
- id = "xeno2";
- name = "Creature Cell #2"
- },
-/turf/open/floor/engine,
-/area/station/science/xenobiology)
"msQ" = (
/obj/structure/cable,
/obj/effect/turf_decal/tile/red/half/contrasted{
@@ -66479,13 +66498,6 @@
/obj/item/stack/medical/gauze,
/turf/open/floor/iron/white,
/area/station/medical/treatment_center)
-"mKw" = (
-/obj/machinery/door/window/brigdoor/right/directional/north{
- name = "Shooting Range";
- req_access = list("security")
- },
-/turf/open/floor/iron/dark,
-/area/station/security/range)
"mKz" = (
/obj/machinery/door/poddoor/shutters{
id = "custodialshutters";
@@ -66767,19 +66779,6 @@
/obj/machinery/light/broken/directional/west,
/turf/open/floor/plating,
/area/station/maintenance/abandon_art_studio)
-"mNh" = (
-/obj/machinery/door/window/left/directional/east{
- name = "Deliveries";
- req_access = list("cargo")
- },
-/obj/effect/turf_decal/delivery,
-/obj/effect/turf_decal/tile/brown/anticorner/contrasted,
-/obj/structure/cable,
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
- dir = 8
- },
-/turf/open/floor/iron,
-/area/station/cargo/office)
"mNk" = (
/obj/effect/turf_decal/tile/neutral{
dir = 1
@@ -67863,21 +67862,6 @@
},
/turf/open/floor/iron,
/area/station/security/execution/transfer)
-"mXQ" = (
-/obj/effect/turf_decal/stripes{
- dir = 4
- },
-/obj/effect/turf_decal/stripes/red/line{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/door/window/right/directional/east{
- name = "Mech Bay";
- req_access = list("robotics")
- },
-/turf/open/floor/mineral/plastitanium/red,
-/area/station/science/robotics/lab)
"mYc" = (
/obj/effect/decal/cleanable/glass,
/obj/item/shard,
@@ -67983,6 +67967,15 @@
dir = 8
},
/area/station/hallway/primary/central)
+"mYU" = (
+/obj/structure/flora/bush/sparsegrass,
+/obj/machinery/door/window/left/directional/south{
+ name = "Monkey Pen";
+ req_access = list("virology")
+ },
+/obj/effect/turf_decal/siding/thinplating/light,
+/turf/open/floor/grass,
+/area/station/medical/virology/isolation)
"mYV" = (
/obj/item/stack/sheet/cardboard,
/obj/structure/cable,
@@ -68329,6 +68322,19 @@
/obj/effect/decal/cleanable/oil,
/turf/open/floor/plating,
/area/station/maintenance/fore/upper)
+"ncE" = (
+/obj/machinery/door/window/brigdoor/left/directional/south{
+ name = "Creature Pen";
+ req_access = list("research")
+ },
+/obj/effect/turf_decal/delivery,
+/obj/effect/turf_decal/stripes,
+/obj/machinery/door/poddoor/preopen{
+ id = "xeno4";
+ name = "Creature Cell #4"
+ },
+/turf/open/floor/engine,
+/area/station/science/xenobiology)
"ncH" = (
/obj/effect/turf_decal/stripes{
dir = 8
@@ -68472,6 +68478,16 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/security/corrections_officer)
+"net" = (
+/obj/machinery/atmospherics/components/binary/pump{
+ dir = 4;
+ name = "justice gas pump"
+ },
+/obj/machinery/door/window/left/directional/east{
+ name = "Gas Ports"
+ },
+/turf/open/floor/iron/dark,
+/area/station/security/execution/education)
"neu" = (
/obj/structure/table_frame,
/obj/effect/decal/cleanable/dirt{
@@ -68520,18 +68536,6 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron,
/area/station/hallway/primary/upper)
-"neT" = (
-/obj/machinery/door/firedoor,
-/obj/structure/table/reinforced,
-/obj/item/folder/red,
-/obj/item/pen,
-/obj/structure/disposalpipe/segment,
-/obj/machinery/door/window/brigdoor/right/directional/north{
- name = "Security Desk";
- req_access = list("security")
- },
-/turf/open/floor/iron/dark,
-/area/station/security/checkpoint/escape)
"neV" = (
/obj/effect/turf_decal/stripes/red/line{
dir = 8
@@ -68544,13 +68548,6 @@
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/medical/storage)
-"nfd" = (
-/obj/effect/turf_decal/siding/wood{
- dir = 4
- },
-/obj/machinery/door/window/left/directional/east,
-/turf/open/floor/wood,
-/area/station/command/heads_quarters/captain)
"nff" = (
/obj/effect/turf_decal/stripes{
dir = 9
@@ -68886,6 +68883,19 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/science/ordnance/storage)
+"nid" = (
+/obj/machinery/door/window/brigdoor/left/directional/south{
+ name = "Creature Pen";
+ req_access = list("research")
+ },
+/obj/effect/turf_decal/delivery,
+/obj/effect/turf_decal/stripes,
+/obj/machinery/door/poddoor/preopen{
+ id = "xeno3";
+ name = "Creature Cell #3"
+ },
+/turf/open/floor/engine,
+/area/station/science/xenobiology)
"nih" = (
/obj/effect/turf_decal/stripes{
dir = 8
@@ -69673,21 +69683,6 @@
/obj/effect/mapping_helpers/broken_floor,
/turf/open/floor/plating,
/area/station/maintenance/department/engineering/atmos_aux_port)
-"nrK" = (
-/obj/machinery/door/firedoor,
-/obj/structure/table/reinforced,
-/obj/item/folder/red,
-/obj/item/pen,
-/obj/machinery/door/window/left/directional/east{
- name = "Jetpack Storage";
- req_access = list("eva")
- },
-/obj/machinery/door/window/brigdoor/right/directional/west{
- name = "Security Customs";
- req_access = list("security")
- },
-/turf/open/floor/iron/dark,
-/area/station/security/checkpoint)
"nrS" = (
/obj/machinery/telecomms/server/presets/engineering,
/obj/effect/turf_decal/trimline/yellow/filled/line{
@@ -70545,6 +70540,18 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/plating,
/area/station/maintenance/central)
+"nAb" = (
+/obj/effect/turf_decal/delivery,
+/obj/structure/cable,
+/obj/structure/disposalpipe/segment{
+ dir = 5
+ },
+/obj/machinery/door/window/right/directional/west{
+ name = "Research Delivery";
+ req_access = list("research")
+ },
+/turf/open/floor/iron/dark,
+/area/station/science/research)
"nAl" = (
/obj/machinery/airalarm/directional/south,
/obj/machinery/light/directional/south,
@@ -71458,6 +71465,19 @@
/obj/effect/mapping_helpers/airlock/access/all/security/general,
/turf/open/floor/iron,
/area/station/security/execution/transfer)
+"nJg" = (
+/obj/effect/turf_decal/tile/yellow/opposingcorners{
+ dir = 8
+ },
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 8
+ },
+/obj/machinery/door/window/left/directional/north{
+ name = "Engineering Deliveries";
+ req_access = list("engineering")
+ },
+/turf/open/floor/iron/checker,
+/area/station/engineering/lobby)
"nJh" = (
/obj/structure/chair/sofa/corp{
dir = 1
@@ -71680,6 +71700,18 @@
},
/turf/open/floor/iron/dark,
/area/station/engineering/atmos/pumproom)
+"nLk" = (
+/obj/effect/turf_decal/bot,
+/obj/machinery/hydroponics/constructable,
+/obj/structure/window/spawner/directional/south,
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 5
+ },
+/obj/machinery/door/window/right/directional/west{
+ pixel_x = -3
+ },
+/turf/open/floor/iron/dark,
+/area/station/service/hydroponics)
"nLl" = (
/obj/structure/girder/displaced,
/obj/structure/grille/broken,
@@ -71793,10 +71825,6 @@
},
/turf/open/floor/carpet/blue,
/area/station/command/heads_quarters/captain)
-"nMJ" = (
-/obj/structure/window/reinforced/spawner/directional/north,
-/turf/open/floor/wood,
-/area/station/hallway/primary/central)
"nMN" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/curtain/bounty,
@@ -71967,6 +71995,21 @@
/obj/item/clothing/accessory/medal/gold/ordom,
/turf/open/floor/carpet/green,
/area/station/command/heads_quarters/nt_rep)
+"nOD" = (
+/obj/effect/turf_decal/bot,
+/obj/machinery/hydroponics/constructable,
+/obj/structure/window/spawner/directional/north,
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 6
+ },
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/door/window/left/directional/west{
+ pixel_x = -3
+ },
+/turf/open/floor/iron/dark,
+/area/station/service/hydroponics)
"nOE" = (
/obj/structure/barricade/security,
/obj/effect/turf_decal/stripes,
@@ -72205,18 +72248,6 @@
},
/turf/open/floor/iron/dark,
/area/station/security/execution/education)
-"nQN" = (
-/obj/effect/turf_decal/bot,
-/obj/machinery/hydroponics/constructable,
-/obj/structure/window/spawner/directional/south,
-/obj/effect/turf_decal/trimline/green/filled/line{
- dir = 5
- },
-/obj/machinery/door/window/right/directional/west{
- pixel_x = -3
- },
-/turf/open/floor/iron/dark,
-/area/station/service/hydroponics)
"nQX" = (
/obj/structure/railing,
/obj/structure/table,
@@ -73521,6 +73552,12 @@
/obj/effect/spawner/random/entertainment/gambling,
/turf/open/floor/wood,
/area/station/service/abandoned_gambling_den)
+"odJ" = (
+/obj/structure/cable,
+/obj/item/radio/intercom/directional/north,
+/obj/machinery/door/window/brigdoor/right/directional/west,
+/turf/open/floor/iron,
+/area/station/security/checkpoint/escape)
"odL" = (
/obj/structure/cable,
/turf/open/floor/iron/dark/side{
@@ -74147,6 +74184,15 @@
/obj/docking_port/stationary/escape_pod,
/turf/open/space/basic,
/area/space)
+"oiv" = (
+/obj/machinery/door/window/brigdoor/left/directional/east{
+ id = "scicell";
+ name = "RnD Cell";
+ req_access = list("security")
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/turf/open/floor/iron/dark,
+/area/station/security/checkpoint/science/research)
"oiz" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/wood,
@@ -74903,6 +74949,39 @@
/obj/structure/curtain/bounty/start_closed,
/turf/open/floor/iron/dark/herringbone,
/area/station/cargo/bitrunning/den)
+"opw" = (
+/obj/structure/window/reinforced/spawner/directional/north{
+ pixel_y = 1
+ },
+/obj/structure/rack,
+/obj/item/clothing/shoes/magboots{
+ pixel_x = -4;
+ pixel_y = 3
+ },
+/obj/item/clothing/shoes/magboots,
+/obj/item/clothing/shoes/magboots{
+ pixel_x = 4;
+ pixel_y = -3
+ },
+/obj/effect/turf_decal/tile/neutral{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/neutral,
+/obj/effect/turf_decal/tile/neutral{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes{
+ dir = 4
+ },
+/obj/machinery/door/window/left/directional/east{
+ name = "Magboot Storage";
+ req_access = list("eva")
+ },
+/turf/open/floor/iron/dark,
+/area/station/ai_monitored/command/storage/eva)
"opJ" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/dark/side{
@@ -75306,6 +75385,24 @@
/obj/effect/decal/cleanable/blood/old,
/turf/open/floor/mineral/plastitanium,
/area/station/maintenance/cult_chapel_maint)
+"otE" = (
+/obj/structure/table/reinforced,
+/obj/machinery/door/firedoor,
+/obj/machinery/door/window/left/directional/west{
+ name = "Law Desk";
+ req_access = list("lawyer")
+ },
+/obj/machinery/door/poddoor/shutters/preopen{
+ id = "lawyerprivacy";
+ name = "Lawyer's Privacy Shutter"
+ },
+/obj/item/folder{
+ pixel_x = 2;
+ pixel_y = 2
+ },
+/obj/item/folder,
+/turf/open/floor/iron/dark,
+/area/station/service/lawoffice)
"otN" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -76179,14 +76276,6 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/dark,
/area/station/command/bridge)
-"oBX" = (
-/obj/effect/turf_decal/delivery,
-/obj/machinery/door/window/brigdoor/left/directional/east{
- name = "Xenobiology Deliveries";
- req_access = list("research")
- },
-/turf/open/floor/iron/dark,
-/area/station/science/xenobiology/control)
"oCa" = (
/obj/item/chair,
/obj/effect/decal/cleanable/dirt{
@@ -77210,39 +77299,6 @@
},
/turf/open/floor/iron/kitchen,
/area/station/service/kitchen/diner)
-"oMx" = (
-/obj/structure/window/reinforced/spawner/directional/north{
- pixel_y = 1
- },
-/obj/structure/rack,
-/obj/item/clothing/shoes/magboots{
- pixel_x = -4;
- pixel_y = 3
- },
-/obj/item/clothing/shoes/magboots,
-/obj/item/clothing/shoes/magboots{
- pixel_x = 4;
- pixel_y = -3
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 1
- },
-/obj/effect/turf_decal/tile/neutral,
-/obj/effect/turf_decal/tile/neutral{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 8
- },
-/obj/effect/turf_decal/stripes{
- dir = 4
- },
-/obj/machinery/door/window/left/directional/east{
- name = "Magboot Storage";
- req_access = list("eva")
- },
-/turf/open/floor/iron/dark,
-/area/station/ai_monitored/command/storage/eva)
"oMC" = (
/obj/structure/bed,
/obj/item/bedsheet/mime,
@@ -77385,14 +77441,6 @@
/obj/machinery/vending/boozeomat,
/turf/closed/wall,
/area/station/command/heads_quarters/captain)
-"oNM" = (
-/obj/effect/turf_decal/delivery,
-/obj/machinery/door/window/left/directional/north{
- name = "Kitchen Delivery";
- req_access = list("kitchen")
- },
-/turf/open/floor/iron/freezer,
-/area/station/service/kitchen/coldroom)
"oNT" = (
/obj/effect/spawner/random/trash/mess,
/obj/structure/cable,
@@ -77639,15 +77687,6 @@
},
/turf/open/floor/iron/dark,
/area/station/service/barber)
-"oQp" = (
-/obj/machinery/door/window/brigdoor/left/directional/south{
- id = "cargocell";
- name = "Cargo Cell";
- req_access = list("security")
- },
-/obj/machinery/light/directional/north,
-/turf/open/floor/iron,
-/area/station/security/checkpoint/supply)
"oQq" = (
/obj/structure/table/wood,
/obj/item/flashlight/lamp/bananalamp{
@@ -77750,19 +77789,6 @@
/obj/effect/landmark/start/assistant,
/turf/open/floor/iron,
/area/station/commons/fitness/recreation)
-"oRk" = (
-/obj/machinery/door/poddoor/preopen{
- id = "xenosecure";
- name = "Secure Pen Shutters"
- },
-/obj/machinery/door/window/brigdoor/left/directional/south{
- name = "Creature Pen";
- req_access = list("research")
- },
-/obj/machinery/atmospherics/pipe/smart/simple/dark/visible,
-/obj/structure/disposalpipe/segment,
-/turf/open/floor/engine,
-/area/station/science/xenobiology)
"oRn" = (
/obj/structure/hedge/opaque,
/obj/structure/railing{
@@ -78761,18 +78787,6 @@
},
/turf/open/floor/iron/kitchen,
/area/station/service/kitchen/diner)
-"pbz" = (
-/obj/structure/table/reinforced,
-/obj/item/folder,
-/obj/item/folder/yellow,
-/obj/item/pen,
-/obj/machinery/door/firedoor,
-/obj/machinery/door/window/right/directional/north{
- name = "Cargo Desk";
- req_access = list("cargo")
- },
-/turf/open/floor/iron/dark,
-/area/station/cargo/office)
"pbB" = (
/obj/effect/decal/cleanable/dirt{
icon_state = "dirt-flat-1"
@@ -78992,6 +79006,12 @@
/obj/item/storage/crayons,
/turf/open/floor/iron,
/area/station/commons/fitness/recreation)
+"pey" = (
+/obj/structure/cable,
+/obj/machinery/power/apc/auto_name/directional/west,
+/obj/machinery/door/window/right/directional/north,
+/turf/open/floor/wood,
+/area/station/service/theater)
"peD" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/effect/turf_decal/tile/bar/opposingcorners,
@@ -79150,6 +79170,15 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/wood,
/area/station/security/courtroom)
+"pgm" = (
+/obj/machinery/door/airlock/maintenance_hatch{
+ name = "Security Maintenance"
+ },
+/obj/effect/mapping_helpers/airlock/welded,
+/obj/structure/cable,
+/obj/effect/mapping_helpers/airlock/access/all/security/general,
+/turf/open/floor/plating,
+/area/station/maintenance/department/security/lower)
"pgs" = (
/obj/structure/window/reinforced/spawner/directional/east,
/obj/structure/rack,
@@ -79430,12 +79459,6 @@
/obj/structure/window/reinforced/spawner/directional/east,
/turf/open/floor/iron/dark,
/area/station/security/brig)
-"piP" = (
-/obj/structure/flora/bush/grassy,
-/obj/structure/flora/bush/flowers_br,
-/obj/machinery/door/window/left/directional/east,
-/turf/open/floor/grass,
-/area/station/medical/aslyum)
"piQ" = (
/obj/structure/chair/office,
/turf/open/floor/iron/dark,
@@ -79795,18 +79818,6 @@
/obj/effect/turf_decal/tile/green/tram,
/turf/open/floor/iron,
/area/station/service/hydroponics)
-"pmu" = (
-/obj/effect/turf_decal/delivery,
-/obj/structure/cable,
-/obj/structure/disposalpipe/segment{
- dir = 5
- },
-/obj/machinery/door/window/right/directional/west{
- name = "Research Delivery";
- req_access = list("research")
- },
-/turf/open/floor/iron/dark,
-/area/station/science/research)
"pmD" = (
/obj/structure/chair/wood{
dir = 8
@@ -79854,37 +79865,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/white,
/area/station/science/xenobiology/control)
-"pna" = (
-/obj/structure/window/reinforced/spawner/directional/south,
-/obj/structure/rack,
-/obj/item/tank/jetpack/carbondioxide{
- pixel_x = 4;
- pixel_y = -1
- },
-/obj/item/tank/jetpack/carbondioxide,
-/obj/item/tank/jetpack/carbondioxide{
- pixel_x = -4;
- pixel_y = 1
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 1
- },
-/obj/effect/turf_decal/tile/neutral,
-/obj/effect/turf_decal/tile/neutral{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 8
- },
-/obj/effect/turf_decal/stripes{
- dir = 4
- },
-/obj/machinery/door/window/left/directional/east{
- name = "Jetpack Storage";
- req_access = list("eva")
- },
-/turf/open/floor/iron/dark,
-/area/station/ai_monitored/command/storage/eva)
"pnd" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/command/glass{
@@ -80549,6 +80529,19 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/maintenance/fore/upper)
+"pux" = (
+/obj/machinery/door/poddoor/preopen{
+ id = "xenosecure";
+ name = "Secure Pen Shutters"
+ },
+/obj/machinery/door/window/brigdoor/left/directional/south{
+ name = "Creature Pen";
+ req_access = list("research")
+ },
+/obj/machinery/atmospherics/pipe/smart/simple/dark/visible,
+/obj/structure/disposalpipe/segment,
+/turf/open/floor/engine,
+/area/station/science/xenobiology)
"puy" = (
/obj/item/radio/intercom/directional/east,
/turf/open/floor/iron/dark/side{
@@ -81251,6 +81244,16 @@
/obj/structure/extinguisher_cabinet/directional/west,
/turf/open/floor/iron/white,
/area/station/science)
+"pAI" = (
+/obj/machinery/door/window/left/directional/south{
+ name = "Law Office Front Desk"
+ },
+/obj/machinery/camera/directional/west{
+ c_tag = "Law Lobby";
+ dir = 10
+ },
+/turf/open/floor/wood,
+/area/station/service/lawoffice)
"pAO" = (
/obj/structure/chair/office{
dir = 8
@@ -81499,6 +81502,19 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/station/common/night_club/back_stage)
+"pEJ" = (
+/obj/effect/turf_decal/stripes{
+ dir = 1
+ },
+/obj/effect/turf_decal/siding/thinplating/dark{
+ dir = 1
+ },
+/obj/machinery/door/window/brigdoor/left/directional/north{
+ name = "Research Director Observation";
+ req_access = list("rd")
+ },
+/turf/open/floor/engine,
+/area/station/command/heads_quarters/rd)
"pEL" = (
/obj/structure/window/reinforced/spawner/directional/north,
/obj/structure/window/reinforced/spawner/directional/west,
@@ -81757,15 +81773,6 @@
/obj/machinery/light/small/broken/directional/west,
/turf/open/floor/plating,
/area/station/service/abandoned_gambling_den)
-"pHF" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4,
-/obj/item/radio/intercom/directional/north,
-/obj/machinery/door/window/brigdoor/right/directional/south{
- name = "Cargo Deliveries";
- req_access = list("security")
- },
-/turf/open/floor/iron/dark,
-/area/station/security/brig)
"pHH" = (
/obj/structure/table/reinforced,
/obj/machinery/cell_charger,
@@ -82429,24 +82436,6 @@
/obj/structure/window/reinforced/spawner/directional/south,
/turf/open/floor/grass,
/area/station/hallway/secondary/exit)
-"pNp" = (
-/obj/structure/table/wood,
-/obj/item/paper_bin,
-/obj/item/pen,
-/obj/effect/turf_decal/tile/neutral{
- dir = 1
- },
-/obj/effect/turf_decal/tile/neutral,
-/obj/effect/turf_decal/tile/neutral{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 8
- },
-/obj/machinery/newscaster/directional/south,
-/obj/item/folder,
-/turf/open/floor/iron/dark,
-/area/station/service/library/private)
"pNw" = (
/obj/structure/lattice/catwalk,
/obj/machinery/atmospherics/pipe/smart/simple/cyan/visible,
@@ -82622,6 +82611,13 @@
/obj/effect/turf_decal/tile/bar/opposingcorners,
/turf/open/floor/iron,
/area/station/service/bar/atrium)
+"pPz" = (
+/obj/effect/turf_decal/siding/wood{
+ dir = 4
+ },
+/obj/machinery/door/window/left/directional/east,
+/turf/open/floor/wood,
+/area/station/command/heads_quarters/captain)
"pPD" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -82660,10 +82656,6 @@
/obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance,
/turf/open/floor/plating,
/area/station/maintenance/library/lower)
-"pQh" = (
-/obj/machinery/door/window/right/directional/north,
-/turf/open/floor/iron/dark,
-/area/station/science/xenobiology)
"pQr" = (
/obj/structure/cable,
/turf/open/floor/iron/dark/side{
@@ -82750,6 +82742,21 @@
/obj/machinery/shower/directional/south,
/turf/open/floor/iron/freezer,
/area/station/commons/dorms/vacantroom)
+"pQX" = (
+/obj/item/radio/intercom/directional/south,
+/obj/structure/secure_safe/caps_spare{
+ pixel_x = 5;
+ pixel_y = -37
+ },
+/obj/structure/cable,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/door/window/brigdoor/right/directional/east{
+ name = "Command Chair";
+ req_access = list("command")
+ },
+/turf/open/floor/iron,
+/area/station/command/bridge)
"pQZ" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -82984,6 +82991,18 @@
/obj/structure/bookcase/random/reference,
/turf/open/floor/wood,
/area/station/security/prison/rec)
+"pTS" = (
+/obj/machinery/door/window/brigdoor/left/directional/north{
+ name = "Creature Pen";
+ req_access = list("research")
+ },
+/obj/effect/turf_decal/delivery,
+/obj/machinery/door/poddoor/preopen{
+ id = "xeno7";
+ name = "Creature Cell #7"
+ },
+/turf/open/floor/engine,
+/area/station/science/xenobiology)
"pTW" = (
/obj/effect/turf_decal/tile/neutral{
dir = 8
@@ -83438,21 +83457,6 @@
/obj/machinery/light_switch/directional/east,
/turf/open/floor/grass,
/area/station/security/prison/garden)
-"pXf" = (
-/obj/item/radio/intercom/directional/south,
-/obj/structure/secure_safe/caps_spare{
- pixel_x = 5;
- pixel_y = -37
- },
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/door/window/brigdoor/right/directional/east{
- name = "Command Chair";
- req_access = list("command")
- },
-/turf/open/floor/iron,
-/area/station/command/bridge)
"pXg" = (
/obj/effect/spawner/random/structure/crate,
/turf/open/floor/iron/dark/small,
@@ -83831,20 +83835,6 @@
/obj/structure/extinguisher_cabinet/directional/north,
/turf/open/floor/iron/dark,
/area/station/security/prison/mess)
-"qbg" = (
-/obj/effect/turf_decal/delivery,
-/obj/effect/turf_decal/stripes{
- dir = 8
- },
-/obj/machinery/computer/pod/old/mass_driver_controller/ordnancedriver/longrange{
- pixel_y = 28
- },
-/obj/machinery/door/window/left/directional/east{
- name = "Mass Driver Door";
- req_access = list("ordnance")
- },
-/turf/open/floor/iron/dark,
-/area/station/science/ordnance/testlab)
"qbj" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -83869,6 +83859,15 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/wood,
/area/station/service/electronic_marketing_den)
+"qbu" = (
+/obj/effect/turf_decal/bot,
+/obj/machinery/hydroponics/constructable,
+/obj/structure/window/spawner/directional/north,
+/obj/effect/turf_decal/trimline/green/filled/line{
+ dir = 10
+ },
+/turf/open/floor/iron/dark,
+/area/station/service/hydroponics)
"qby" = (
/obj/item/radio/intercom/directional/east,
/obj/structure/cable,
@@ -84496,21 +84495,6 @@
},
/turf/open/floor/iron/dark,
/area/station/security/brig)
-"qhs" = (
-/obj/machinery/door/window/brigdoor/left/directional/north{
- name = "Creature Pen";
- req_access = list("research")
- },
-/obj/effect/turf_decal/delivery,
-/obj/effect/turf_decal/stripes{
- dir = 1
- },
-/obj/machinery/door/poddoor/preopen{
- id = "xeno9";
- name = "Creature Cell #9"
- },
-/turf/open/floor/engine,
-/area/station/science/xenobiology)
"qht" = (
/obj/structure/railing,
/obj/structure/railing{
@@ -84921,6 +84905,59 @@
"qlU" = (
/turf/open/floor/circuit,
/area/station/tcommsat/computer)
+"qlV" = (
+/obj/structure/window/reinforced/spawner/directional/south,
+/obj/structure/rack,
+/obj/item/tank/jetpack/carbondioxide{
+ pixel_x = 4;
+ pixel_y = -1
+ },
+/obj/item/tank/jetpack/carbondioxide,
+/obj/item/tank/jetpack/carbondioxide{
+ pixel_x = -4;
+ pixel_y = 1
+ },
+/obj/effect/turf_decal/tile/neutral{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/neutral,
+/obj/effect/turf_decal/tile/neutral{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral{
+ dir = 8
+ },
+/obj/effect/turf_decal/stripes{
+ dir = 4
+ },
+/obj/machinery/door/window/left/directional/east{
+ name = "Jetpack Storage";
+ req_access = list("eva")
+ },
+/turf/open/floor/iron/dark,
+/area/station/ai_monitored/command/storage/eva)
+"qlX" = (
+/obj/structure/table/reinforced,
+/obj/item/storage/medkit/toxin{
+ pixel_x = 6;
+ pixel_y = 6
+ },
+/obj/item/storage/medkit/toxin{
+ pixel_x = 3;
+ pixel_y = 3
+ },
+/obj/item/storage/medkit/regular,
+/obj/item/storage/medkit/toxin{
+ pixel_x = -3;
+ pixel_y = -3
+ },
+/obj/machinery/newscaster/directional/south,
+/obj/machinery/door/window/right/directional/north{
+ name = "First-Aid Supplies";
+ req_access = list("medical")
+ },
+/turf/open/floor/iron,
+/area/station/medical/storage)
"qlY" = (
/turf/closed/wall,
/area/station/service/library/private)
@@ -86092,23 +86129,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/glass/reinforced,
/area/station/security/prison/safe)
-"qvV" = (
-/obj/machinery/door/firedoor,
-/obj/structure/table/reinforced,
-/obj/item/folder/blue,
-/obj/machinery/door/poddoor/preopen{
- id = "hopblast";
- name = "HoP Blast Door"
- },
-/obj/machinery/door/window/right/directional/east{
- name = "Access Queue"
- },
-/obj/machinery/door/window/brigdoor/left/directional/west{
- name = "Access Desk";
- req_access = list("hop")
- },
-/turf/open/floor/iron/dark,
-/area/station/command/heads_quarters/hop)
"qvW" = (
/obj/machinery/conveyor/inverted{
dir = 6;
@@ -86397,6 +86417,10 @@
/obj/machinery/digital_clock/directional/west,
/turf/open/floor/iron/white,
/area/station/science/lab)
+"qyJ" = (
+/obj/structure/musician/piano,
+/turf/open/floor/wood,
+/area/station/service/theater)
"qyM" = (
/obj/effect/turf_decal/bot,
/obj/effect/spawner/random/structure/crate,
@@ -86594,6 +86618,18 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron,
/area/station/service/hydroponics)
+"qAC" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/turf_decal/vg_decals/numbers/three,
+/obj/machinery/door/window/brigdoor/right/directional/west{
+ req_access = list("security");
+ name = "Cell 3"
+ },
+/turf/open/floor/iron/dark/side{
+ dir = 8
+ },
+/area/station/security/brig)
"qAE" = (
/turf/open/floor/iron/dark/side{
dir = 9
@@ -87122,18 +87158,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/upper)
-"qFs" = (
-/obj/effect/turf_decal/bot,
-/obj/machinery/hydroponics/constructable,
-/obj/structure/window/spawner/directional/south,
-/obj/effect/turf_decal/trimline/green/filled/line{
- dir = 1
- },
-/obj/machinery/door/window/right/directional/west{
- pixel_x = -3
- },
-/turf/open/floor/iron/dark,
-/area/station/service/hydroponics)
"qFt" = (
/obj/effect/decal/cleanable/oil,
/obj/structure/sign/warning/vacuum/external/directional/west,
@@ -87841,6 +87865,26 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central)
+"qMO" = (
+/obj/machinery/firealarm/directional/south,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/door/window/brigdoor/right/directional/west{
+ name = "Prisoner Transfer";
+ req_access = list("security")
+ },
+/turf/open/floor/iron,
+/area/station/security/checkpoint/escape)
+"qMV" = (
+/obj/structure/railing{
+ dir = 8
+ },
+/obj/machinery/light/directional/east,
+/obj/machinery/door/window/brigdoor/right/directional/north{
+ name = "Command Chair";
+ req_access = list("command")
+ },
+/turf/open/floor/iron/stairs,
+/area/station/command/secure_bunker)
"qMW" = (
/obj/structure/cable,
/obj/effect/turf_decal/tile/neutral{
@@ -90691,16 +90735,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/medbay/lobby)
-"rpc" = (
-/obj/machinery/atmospherics/components/binary/pump{
- dir = 4;
- name = "justice gas pump"
- },
-/obj/machinery/door/window/left/directional/east{
- name = "Gas Ports"
- },
-/turf/open/floor/iron/dark,
-/area/station/security/execution/education)
"rpj" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -91460,6 +91494,22 @@
dir = 8
},
/area/station/hallway/primary/port)
+"rvH" = (
+/obj/effect/turf_decal/tile/neutral{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/neutral,
+/obj/effect/turf_decal/tile/neutral{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral{
+ dir = 8
+ },
+/obj/machinery/power/smes/super/full{
+ name = "ai power storage unit"
+ },
+/turf/open/floor/iron/dark,
+/area/station/ai_monitored/turret_protected/aisat_interior)
"rvL" = (
/obj/structure/cable,
/turf/open/floor/iron/dark,
@@ -91729,17 +91779,6 @@
/obj/structure/chair/pew/right,
/turf/open/floor/wood,
/area/station/command/heads_quarters/captain/private)
-"ryw" = (
-/obj/structure/cable,
-/obj/machinery/status_display/ai/directional/south,
-/obj/machinery/light/directional/south,
-/obj/machinery/door/window/left/directional/west{
- req_access = list("eva")
- },
-/turf/open/floor/iron/stairs{
- dir = 4
- },
-/area/station/ai_monitored/command/storage/eva/upper)
"ryz" = (
/obj/machinery/vending/wardrobe/sec_wardrobe,
/turf/open/floor/iron,
@@ -92197,21 +92236,6 @@
},
/turf/open/floor/iron,
/area/station/maintenance/starboard/fore)
-"rDH" = (
-/obj/effect/turf_decal/bot,
-/obj/machinery/hydroponics/constructable,
-/obj/structure/window/spawner/directional/north,
-/obj/effect/turf_decal/trimline/green/filled/line{
- dir = 6
- },
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/machinery/door/window/left/directional/west{
- pixel_x = -3
- },
-/turf/open/floor/iron/dark,
-/area/station/service/hydroponics)
"rDK" = (
/obj/structure/table/wood,
/obj/item/paper_bin{
@@ -93207,35 +93231,6 @@
/obj/effect/turf_decal/tile/blue/fourcorners,
/turf/open/floor/iron/white,
/area/station/medical/medbay/central)
-"rNM" = (
-/obj/machinery/door/firedoor,
-/obj/structure/table/reinforced,
-/obj/machinery/door/poddoor/preopen{
- id = "brigwindows";
- name = "Brig Front Blast Door"
- },
-/obj/item/folder/red,
-/obj/item/pen,
-/obj/machinery/door/window/right{
- name = "Security Desk"
- },
-/obj/effect/turf_decal/tile/red{
- dir = 1
- },
-/obj/effect/turf_decal/tile/red,
-/obj/effect/turf_decal/tile/red{
- dir = 4
- },
-/obj/effect/turf_decal/tile/red{
- dir = 8
- },
-/obj/structure/cable,
-/obj/machinery/door/window/brigdoor/right/directional/north{
- name = "Security Desk";
- req_access = list("security")
- },
-/turf/open/floor/iron,
-/area/station/security/brig)
"rNT" = (
/obj/structure/cable,
/turf/open/floor/iron,
@@ -93636,6 +93631,19 @@
/obj/structure/sign/poster/contraband/icebox_moment/directional/west,
/turf/open/floor/iron,
/area/station/maintenance/starboard/fore)
+"rSx" = (
+/obj/machinery/door/window/brigdoor/left/directional/south{
+ name = "Creature Pen";
+ req_access = list("research")
+ },
+/obj/effect/turf_decal/delivery,
+/obj/effect/turf_decal/stripes,
+/obj/machinery/door/poddoor/preopen{
+ id = "xeno1";
+ name = "Creature Cell #1"
+ },
+/turf/open/floor/engine,
+/area/station/science/xenobiology)
"rSz" = (
/obj/machinery/conveyor{
dir = 8;
@@ -93720,6 +93728,19 @@
/obj/effect/mapping_helpers/airlock/access/all/security/general,
/turf/open/floor/iron/dark,
/area/station/security/office)
+"rTs" = (
+/obj/structure/flora/bush/lavendergrass,
+/obj/effect/turf_decal/siding/thinplating/light{
+ dir = 4
+ },
+/obj/machinery/door/poddoor/shutters/preopen{
+ id = "rdgene";
+ name = "Genetics Lab Shutters"
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/door/window/left/directional/east,
+/turf/open/floor/grass,
+/area/station/science/genetics)
"rTv" = (
/obj/structure/table/reinforced,
/obj/structure/window/reinforced/spawner/directional/west,
@@ -93830,15 +93851,6 @@
},
/turf/open/floor/plating/airless,
/area/space/nearstation)
-"rUU" = (
-/obj/structure/table,
-/obj/machinery/door/poddoor/shutters{
- id = "visitation";
- name = "Visitation Shutters"
- },
-/obj/machinery/door/window/left/directional/west,
-/turf/open/floor/iron/dark,
-/area/station/security/prison/visit)
"rVd" = (
/obj/machinery/power/shuttle_engine/heater{
dir = 1
@@ -94048,13 +94060,6 @@
/obj/structure/window/reinforced/spawner/directional/north,
/turf/open/floor/iron/dark,
/area/station/service/chapel)
-"rXc" = (
-/obj/machinery/power/smes{
- charge = 5e+006
- },
-/obj/structure/cable,
-/turf/open/floor/circuit,
-/area/station/ai_monitored/turret_protected/ai)
"rXe" = (
/obj/structure/bed/medical/emergency,
/obj/machinery/iv_drip,
@@ -94090,21 +94095,6 @@
},
/turf/open/floor/iron/freezer,
/area/station/science/xenobiology)
-"rXo" = (
-/obj/structure/table/reinforced,
-/obj/machinery/door/firedoor,
-/obj/item/folder/white,
-/obj/item/pen,
-/obj/machinery/door/poddoor/shutters/preopen{
- id = "rdgene2";
- name = "Genetics Lab Shutters"
- },
-/obj/machinery/door/window/left/directional/east{
- name = "Genetics Desk";
- req_access = list("genetics")
- },
-/turf/open/floor/iron/dark,
-/area/station/science/genetics)
"rXp" = (
/obj/machinery/camera{
c_tag = "Command Hallway - Lower Port";
@@ -95257,6 +95247,23 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/engine,
/area/station/command/secure_bunker)
+"siQ" = (
+/obj/machinery/door/firedoor,
+/obj/structure/table/reinforced,
+/obj/machinery/door/poddoor/shutters/preopen{
+ id = "chemistbot";
+ name = "Chemistry Side Shutters"
+ },
+/obj/item/folder/white,
+/obj/machinery/door/window/left/directional/west{
+ name = "Chemistry Desk";
+ req_access = list("pharmacy")
+ },
+/obj/machinery/door/window/left/directional/east{
+ name = "Chemistry Desk"
+ },
+/turf/open/floor/iron/dark,
+/area/station/medical/pharmacy)
"siV" = (
/obj/effect/landmark/event_spawn,
/obj/machinery/camera/directional/south{
@@ -95398,6 +95405,21 @@
/obj/machinery/digital_clock/directional/west,
/turf/open/floor/iron/dark,
/area/station/command/heads_quarters/hop)
+"skg" = (
+/obj/structure/table,
+/obj/structure/window/reinforced/spawner/directional/east,
+/obj/structure/window/reinforced/spawner/directional/north,
+/obj/machinery/door/window/left/directional/west{
+ name = "High-Risk Modules";
+ req_access = list("ai_upload")
+ },
+/obj/item/ai_module/zeroth/onehuman,
+/obj/item/ai_module/supplied/oxygen{
+ pixel_x = -3;
+ pixel_y = -3
+ },
+/turf/open/floor/iron,
+/area/station/ai_monitored/turret_protected/ai_upload)
"skh" = (
/obj/machinery/door/airlock/maintenance,
/turf/open/floor/plating,
@@ -95688,6 +95710,23 @@
/obj/effect/decal/remains/human,
/turf/open/floor/plating,
/area/station/maintenance/abandon_holding_cell)
+"snt" = (
+/obj/machinery/door/firedoor,
+/obj/structure/table/reinforced,
+/obj/item/folder/blue,
+/obj/item/folder/blue,
+/obj/item/folder/blue,
+/obj/item/pen,
+/obj/machinery/door/window/left/directional/east{
+ name = "Jetpack Storage";
+ req_access = list("eva")
+ },
+/obj/machinery/door/window/brigdoor/right/directional/west{
+ name = "Customs Desk";
+ req_access = list("command")
+ },
+/turf/open/floor/iron/dark,
+/area/station/security/checkpoint/customs)
"snu" = (
/turf/closed/wall,
/area/station/service/library/printer)
@@ -95834,15 +95873,6 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/maintenance/port/upper)
-"spa" = (
-/obj/effect/turf_decal/bot,
-/obj/machinery/hydroponics/constructable,
-/obj/structure/window/spawner/directional/north,
-/obj/effect/turf_decal/trimline/green/filled/line{
- dir = 10
- },
-/turf/open/floor/iron/dark,
-/area/station/service/hydroponics)
"spb" = (
/obj/machinery/door/airlock/security/old{
name = "Jail Cell"
@@ -96084,18 +96114,6 @@
/obj/machinery/duct,
/turf/open/floor/wood/parquet,
/area/station/command/heads_quarters/nt_rep)
-"srN" = (
-/obj/structure/table/wood/fancy,
-/obj/structure/sign/painting/library_secure{
- pixel_y = 32
- },
-/obj/machinery/door/window/left/directional/south{
- name = "Secure Art Exhibition";
- req_access = list("library")
- },
-/obj/effect/turf_decal/siding/wood,
-/turf/open/floor/carpet,
-/area/station/service/library)
"srR" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/atmospherics/pipe/smart/simple/purple/visible,
@@ -96708,6 +96726,13 @@
/obj/effect/spawner/random/decoration/glowstick,
/turf/open/floor/iron,
/area/station/maintenance/department/medical/central)
+"sxj" = (
+/obj/machinery/door/window/brigdoor/right/directional/north{
+ name = "Shooting Range";
+ req_access = list("security")
+ },
+/turf/open/floor/iron/dark,
+/area/station/security/range)
"sxk" = (
/obj/effect/turf_decal/bot,
/obj/structure/training_machine,
@@ -96771,13 +96796,6 @@
},
/turf/open/floor/iron/dark,
/area/station/science/server)
-"sxE" = (
-/obj/machinery/door/window/brigdoor/right/directional/east{
- name = "Crematorium";
- req_access = list("security")
- },
-/turf/open/floor/iron/dark,
-/area/station/security/prison)
"sxF" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -97046,21 +97064,6 @@
},
/turf/open/floor/iron/dark,
/area/station/security/execution/transfer)
-"sAV" = (
-/obj/machinery/door/window/brigdoor/left/directional/north{
- name = "Creature Pen";
- req_access = list("research")
- },
-/obj/effect/turf_decal/delivery,
-/obj/effect/turf_decal/stripes{
- dir = 1
- },
-/obj/machinery/door/poddoor/preopen{
- id = "xeno5";
- name = "Creature Cell #5"
- },
-/turf/open/floor/engine,
-/area/station/science/xenobiology)
"sAW" = (
/obj/structure/railing{
dir = 8
@@ -97252,19 +97255,6 @@
},
/turf/open/floor/iron/white,
/area/station/command/heads_quarters/rd)
-"sCA" = (
-/obj/machinery/door/window/brigdoor/left/directional/south{
- name = "Creature Pen";
- req_access = list("research")
- },
-/obj/effect/turf_decal/delivery,
-/obj/effect/turf_decal/stripes,
-/obj/machinery/door/poddoor/preopen{
- id = "xeno4";
- name = "Creature Cell #4"
- },
-/turf/open/floor/engine,
-/area/station/science/xenobiology)
"sCB" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -97888,29 +97878,6 @@
/obj/effect/decal/cleanable/cobweb,
/turf/open/floor/plating,
/area/station/maintenance/department/medical)
-"sIV" = (
-/obj/structure/table/reinforced,
-/obj/machinery/door/firedoor,
-/obj/machinery/door/poddoor/shutters/preopen{
- id = "roboticsprivacy";
- name = "Robotics Shutters"
- },
-/obj/item/folder,
-/obj/item/folder,
-/obj/item/folder,
-/obj/item/pen,
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/machinery/door/window/left/directional/west{
- req_access = list("robotics");
- name = "Robotics Desk"
- },
-/obj/machinery/door/window/left/directional/east{
- name = "Robotics Desk"
- },
-/turf/open/floor/iron/dark,
-/area/station/science/robotics)
"sJb" = (
/obj/machinery/door/airlock/silver{
name = "Locker Room"
@@ -98192,25 +98159,6 @@
/obj/effect/turf_decal/bot,
/turf/open/floor/iron/white,
/area/station/medical/medbay/lobby)
-"sKU" = (
-/obj/machinery/door/firedoor,
-/obj/structure/table/reinforced,
-/obj/machinery/door/window/left{
- name = "Chemistry Desk";
- req_access = list("pharmacy")
- },
-/obj/machinery/door/poddoor/shutters/preopen{
- id = "chemisttop";
- name = "Chemistry Lobby Shutters"
- },
-/obj/item/folder/white,
-/obj/item/reagent_containers/cup/bottle/multiver{
- pixel_x = -7;
- pixel_y = 1
- },
-/obj/machinery/door/window/left/directional/north,
-/turf/open/floor/iron/dark,
-/area/station/medical/pharmacy)
"sKW" = (
/obj/structure/grille/broken,
/turf/open/floor/plating,
@@ -98785,6 +98733,21 @@
/obj/structure/grille/broken,
/turf/open/floor/plating,
/area/station/maintenance/aft/upper)
+"sQJ" = (
+/obj/machinery/door/window/brigdoor/left/directional/north{
+ name = "Creature Pen";
+ req_access = list("research")
+ },
+/obj/effect/turf_decal/delivery,
+/obj/effect/turf_decal/stripes{
+ dir = 1
+ },
+/obj/machinery/door/poddoor/preopen{
+ id = "xeno8";
+ name = "Creature Cell #8"
+ },
+/turf/open/floor/engine,
+/area/station/science/xenobiology)
"sQO" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -100634,6 +100597,15 @@
/obj/machinery/smartfridge,
/turf/open/floor/plating,
/area/station/maintenance/abandon_kitchen_upper)
+"thx" = (
+/obj/structure/window/reinforced/spawner/directional/east,
+/obj/structure/cable,
+/obj/machinery/door/window/right/directional/north{
+ name = "Robotics Deliveries";
+ req_access = list("robotics")
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/station/science/robotics/lab)
"thz" = (
/obj/structure/window/reinforced/spawner/directional/south,
/obj/structure/window/reinforced/spawner/directional/west,
@@ -101617,6 +101589,20 @@
},
/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
+"tsu" = (
+/obj/machinery/door/window/left/directional/south{
+ name = "Deliveries";
+ req_access = list("cargo")
+ },
+/obj/effect/turf_decal/delivery,
+/obj/machinery/disposal/delivery_chute,
+/obj/structure/disposalpipe/trunk{
+ dir = 1
+ },
+/obj/structure/window/reinforced/spawner/directional/north,
+/obj/machinery/light/directional/east,
+/turf/open/floor/iron/dark,
+/area/station/cargo/office)
"tsB" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/door/poddoor/shutters/preopen{
@@ -102993,22 +102979,6 @@
},
/turf/open/floor/plating,
/area/station/medical/surgery)
-"tFk" = (
-/obj/structure/window/reinforced/spawner/directional/north,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/effect/turf_decal/vg_decals/numbers/four,
-/obj/effect/turf_decal/tile/red/half/contrasted{
- dir = 4
- },
-/obj/machinery/door/window/brigdoor/left/directional/east{
- req_access = list("security");
- name = "Cell 4"
- },
-/turf/open/floor/iron/dark/side{
- dir = 4
- },
-/area/station/security/brig)
"tFl" = (
/turf/closed/wall,
/area/station/maintenance/pool_maintenance)
@@ -103040,6 +103010,23 @@
},
/turf/open/floor/iron/freezer,
/area/station/service/kitchen/coldroom)
+"tFP" = (
+/obj/effect/turf_decal/stripes{
+ dir = 4
+ },
+/obj/machinery/disposal/delivery_chute{
+ dir = 4
+ },
+/obj/structure/plasticflaps,
+/obj/structure/disposalpipe/trunk{
+ dir = 8
+ },
+/obj/machinery/door/window/right/directional/east{
+ req_access = list("cargo");
+ name = "Science Deliveries"
+ },
+/turf/open/floor/iron/dark,
+/area/station/cargo/sorting)
"tFQ" = (
/obj/structure/bed,
/obj/effect/landmark/start/hangover,
@@ -103290,16 +103277,6 @@
},
/turf/open/floor/iron/kitchen,
/area/station/service/kitchen/diner)
-"tIz" = (
-/obj/machinery/door/window/left/directional/north{
- name = "Interior Door";
- req_access = list("lawyer")
- },
-/obj/effect/turf_decal/siding/wood{
- dir = 9
- },
-/turf/open/floor/carpet/blue,
-/area/station/service/lawoffice)
"tID" = (
/obj/effect/turf_decal/tile/brown/anticorner/contrasted{
dir = 8
@@ -103335,25 +103312,6 @@
},
/turf/open/floor/plating,
/area/station/maintenance/starboard/fore)
-"tJk" = (
-/obj/machinery/door/window/brigdoor/left/directional/south{
- name = "Justice Chamber";
- req_access = list("armory")
- },
-/obj/structure/window/reinforced/spawner/directional/west,
-/obj/structure/window/reinforced/spawner/directional/east,
-/obj/machinery/door/window/brigdoor/left/directional/north{
- name = "Justice Chamber";
- req_access = list("armory")
- },
-/obj/machinery/door/firedoor,
-/obj/effect/turf_decal/delivery,
-/obj/machinery/door/poddoor/preopen{
- id = "executionfireblast"
- },
-/obj/machinery/atmospherics/pipe/smart/simple/general/visible,
-/turf/open/floor/iron/dark,
-/area/station/security/execution/education)
"tJn" = (
/obj/structure/chair{
dir = 8
@@ -103587,16 +103545,6 @@
},
/turf/open/floor/iron/white,
/area/station/medical/aslyum)
-"tLP" = (
-/obj/structure/bed{
- dir = 1
- },
-/obj/effect/spawner/random/bedsheet{
- dir = 1
- },
-/obj/machinery/light_switch/directional/west,
-/turf/open/floor/carpet/black,
-/area/station/commons/dorms/room5)
"tMc" = (
/obj/machinery/camera/directional/south{
c_tag = "Security - Perma Airlock";
@@ -103610,6 +103558,16 @@
dir = 5
},
/area/station/security/prison)
+"tMh" = (
+/obj/structure/bed{
+ dir = 1
+ },
+/obj/effect/spawner/random/bedsheet{
+ dir = 1
+ },
+/obj/effect/landmark/start/hangover,
+/turf/open/floor/carpet/black,
+/area/station/commons/dorms/room5)
"tMn" = (
/obj/structure/table/glass,
/obj/machinery/cell_charger,
@@ -103888,13 +103846,6 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/central/fore)
-"tOw" = (
-/obj/machinery/door/window/brigdoor/left/directional/north{
- name = "Creature Pen";
- req_access = list("research")
- },
-/turf/open/floor/engine,
-/area/station/science/xenobiology)
"tOB" = (
/obj/effect/turf_decal/siding/wood{
dir = 8
@@ -104049,15 +104000,6 @@
/obj/effect/turf_decal/bot,
/turf/open/floor/iron,
/area/station/science/breakroom)
-"tPz" = (
-/obj/structure/window/reinforced/spawner/directional/east,
-/obj/structure/cable,
-/obj/machinery/door/window/right/directional/north{
- name = "Robotics Deliveries";
- req_access = list("robotics")
- },
-/turf/open/floor/mineral/plastitanium/red,
-/area/station/science/robotics/lab)
"tPF" = (
/obj/effect/turf_decal/tile/red{
dir = 1
@@ -104809,6 +104751,23 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/plating,
/area/station/security/brig)
+"tWY" = (
+/obj/effect/turf_decal/stripes{
+ dir = 4
+ },
+/obj/machinery/disposal/delivery_chute{
+ dir = 4
+ },
+/obj/structure/plasticflaps,
+/obj/structure/disposalpipe/trunk{
+ dir = 8
+ },
+/obj/machinery/door/window/right/directional/east{
+ req_access = list("cargo");
+ name = "Engineering Deliveries"
+ },
+/turf/open/floor/iron/dark,
+/area/station/cargo/sorting)
"tXj" = (
/obj/effect/turf_decal/stripes{
dir = 8
@@ -105155,6 +105114,12 @@
/obj/structure/reagent_dispensers/beerkeg,
/turf/open/floor/plating,
/area/station/maintenance/aft/upper)
+"ubt" = (
+/obj/effect/turf_decal/bot,
+/obj/machinery/hydroponics/constructable,
+/obj/machinery/door/window/right/directional/north,
+/turf/open/floor/iron/dark,
+/area/station/service/hydroponics)
"ubC" = (
/obj/effect/decal/cleanable/dirt{
icon_state = "dirt-flat-1"
@@ -106030,21 +105995,6 @@
/obj/effect/turf_decal/bot_white,
/turf/open/floor/iron/dark,
/area/station/security/prison/shower)
-"ujI" = (
-/obj/machinery/door/window/brigdoor/left/directional/north{
- name = "Creature Pen";
- req_access = list("research")
- },
-/obj/effect/turf_decal/delivery,
-/obj/effect/turf_decal/stripes{
- dir = 1
- },
-/obj/machinery/door/poddoor/preopen{
- id = "xeno8";
- name = "Creature Cell #8"
- },
-/turf/open/floor/engine,
-/area/station/science/xenobiology)
"ujK" = (
/obj/effect/turf_decal/siding/blue{
dir = 4
@@ -106742,18 +106692,6 @@
/obj/effect/landmark/navigate_destination,
/turf/open/floor/iron/dark,
/area/station/common/pool)
-"upc" = (
-/obj/machinery/door/window/brigdoor/left/directional/north{
- name = "Creature Pen";
- req_access = list("research")
- },
-/obj/effect/turf_decal/stripes{
- dir = 1
- },
-/obj/machinery/atmospherics/pipe/smart/simple/dark/visible,
-/obj/structure/disposalpipe/segment,
-/turf/open/floor/engine,
-/area/station/science/xenobiology)
"upg" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/obj/structure/chair/stool/bar/directional{
@@ -107160,6 +107098,18 @@
/obj/structure/extinguisher_cabinet/directional/east,
/turf/open/floor/iron/white,
/area/station/science/research)
+"uth" = (
+/obj/structure/table/reinforced,
+/obj/item/folder,
+/obj/item/folder/yellow,
+/obj/item/pen,
+/obj/machinery/door/firedoor,
+/obj/machinery/door/window/right/directional/north{
+ name = "Cargo Desk";
+ req_access = list("cargo")
+ },
+/turf/open/floor/iron/dark,
+/area/station/cargo/office)
"utj" = (
/turf/open/floor/iron/shuttle/evac/airless,
/area/station/maintenance/department/medical)
@@ -108072,6 +108022,16 @@
/obj/structure/lattice/catwalk,
/turf/open/openspace,
/area/station/maintenance/fore/upper)
+"uCL" = (
+/obj/effect/turf_decal/bot,
+/obj/machinery/hydroponics/constructable,
+/obj/structure/window/spawner/directional/north,
+/obj/effect/turf_decal/trimline/green/filled/line,
+/obj/machinery/door/window/left/directional/west{
+ pixel_x = -3
+ },
+/turf/open/floor/iron/dark,
+/area/station/service/hydroponics)
"uCP" = (
/obj/machinery/oven/range,
/turf/open/floor/iron/cafeteria,
@@ -108875,6 +108835,35 @@
/obj/machinery/light/directional/south,
/turf/open/floor/iron/dark,
/area/station/ai_monitored/security/armory)
+"uLb" = (
+/obj/machinery/door/firedoor,
+/obj/structure/table/reinforced,
+/obj/machinery/door/poddoor/preopen{
+ id = "brigwindows";
+ name = "Brig Front Blast Door"
+ },
+/obj/item/folder/red,
+/obj/item/pen,
+/obj/machinery/door/window/right{
+ name = "Security Desk"
+ },
+/obj/effect/turf_decal/tile/red{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/red,
+/obj/effect/turf_decal/tile/red{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/red{
+ dir = 8
+ },
+/obj/structure/cable,
+/obj/machinery/door/window/brigdoor/right/directional/north{
+ name = "Security Desk";
+ req_access = list("security")
+ },
+/turf/open/floor/iron,
+/area/station/security/brig)
"uLe" = (
/obj/structure/chair{
dir = 1
@@ -110315,28 +110304,6 @@
/obj/structure/window/reinforced/spawner/directional/east,
/turf/open/floor/iron/dark,
/area/station/ai_monitored/aisat/exterior)
-"vas" = (
-/obj/structure/table/reinforced,
-/obj/item/storage/medkit/toxin{
- pixel_x = 6;
- pixel_y = 6
- },
-/obj/item/storage/medkit/toxin{
- pixel_x = 3;
- pixel_y = 3
- },
-/obj/item/storage/medkit/regular,
-/obj/item/storage/medkit/toxin{
- pixel_x = -3;
- pixel_y = -3
- },
-/obj/machinery/newscaster/directional/south,
-/obj/machinery/door/window/right/directional/north{
- name = "First-Aid Supplies";
- req_access = list("medical")
- },
-/turf/open/floor/iron,
-/area/station/medical/storage)
"vaB" = (
/obj/structure/disposalpipe/segment,
/obj/structure/sign/departments/botany/directional/east,
@@ -110755,24 +110722,6 @@
},
/turf/open/floor/wood,
/area/station/security/courtroom)
-"vfJ" = (
-/obj/structure/table/reinforced,
-/obj/machinery/door/firedoor,
-/obj/machinery/door/window/left/directional/west{
- name = "Law Desk";
- req_access = list("lawyer")
- },
-/obj/machinery/door/poddoor/shutters/preopen{
- id = "lawyerprivacy";
- name = "Lawyer's Privacy Shutter"
- },
-/obj/item/folder{
- pixel_x = 2;
- pixel_y = 2
- },
-/obj/item/folder,
-/turf/open/floor/iron/dark,
-/area/station/service/lawoffice)
"vfL" = (
/obj/structure/water_source/puddle,
/obj/structure/flora/bush/reed{
@@ -110872,6 +110821,17 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/dark,
/area/station/security/brig)
+"vgE" = (
+/obj/structure/cable,
+/obj/machinery/status_display/ai/directional/south,
+/obj/machinery/light/directional/south,
+/obj/machinery/door/window/left/directional/west{
+ req_access = list("eva")
+ },
+/turf/open/floor/iron/stairs{
+ dir = 4
+ },
+/area/station/ai_monitored/command/storage/eva/upper)
"vgG" = (
/obj/structure/trash_pile,
/obj/effect/decal/cleanable/dirt{
@@ -111390,6 +111350,33 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/white,
/area/station/science/research)
+"vlf" = (
+/obj/structure/table/wood,
+/obj/item/folder/blue{
+ pixel_x = 3;
+ pixel_y = 3
+ },
+/obj/item/folder/blue,
+/obj/item/stamp/denied{
+ pixel_x = -6;
+ pixel_y = 4
+ },
+/obj/item/stamp/head/captain{
+ pixel_x = 5;
+ pixel_y = 2
+ },
+/obj/item/stamp{
+ pixel_x = -6
+ },
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/door/window/brigdoor/right/directional/west{
+ name = "Captain's Desk";
+ req_access = list("captain")
+ },
+/turf/open/floor/carpet/blue,
+/area/station/command/heads_quarters/captain/private)
"vlo" = (
/obj/structure/table,
/turf/open/floor/iron/dark,
@@ -112470,17 +112457,6 @@
/obj/machinery/duct,
/turf/open/floor/iron/white/smooth_large,
/area/station/command/heads_quarters/ce)
-"vvq" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
- dir = 4
- },
-/obj/machinery/door/window/left/directional/west{
- name = "Security Mech Recharge Dock";
- req_access = list("security")
- },
-/turf/open/floor/iron,
-/area/station/ai_monitored/security/armory)
"vvr" = (
/obj/machinery/camera/directional/west{
c_tag = "Security Post - Medbay"
@@ -112591,6 +112567,18 @@
/obj/effect/landmark/start/hangover,
/turf/open/floor/iron,
/area/station/hallway/primary/upper)
+"vww" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/turf_decal/vg_decals/numbers/five,
+/obj/machinery/door/window/brigdoor/left/directional/east{
+ req_access = list("security");
+ name = "Cell 5"
+ },
+/turf/open/floor/iron/dark/side{
+ dir = 4
+ },
+/area/station/security/brig)
"vwE" = (
/obj/structure/cable,
/obj/machinery/firealarm/directional/west,
@@ -113563,6 +113551,15 @@
},
/turf/open/floor/iron/dark,
/area/station/hallway/secondary/entry)
+"vFh" = (
+/obj/structure/table,
+/obj/machinery/door/poddoor/shutters{
+ id = "visitation";
+ name = "Visitation Shutters"
+ },
+/obj/machinery/door/window/left/directional/west,
+/turf/open/floor/iron/dark,
+/area/station/security/prison/visit)
"vFi" = (
/turf/open/floor/plating,
/area/station/maintenance/department/security/lesser)
@@ -114179,10 +114176,6 @@
},
/turf/open/floor/iron/dark,
/area/station/hallway/secondary/service)
-"vLf" = (
-/obj/structure/musician/piano,
-/turf/open/floor/wood,
-/area/station/service/bar/atrium)
"vLj" = (
/turf/open/floor/engine/air,
/area/station/engineering/atmos)
@@ -114845,15 +114838,6 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
-"vRC" = (
-/obj/machinery/door/firedoor/border_only{
- dir = 1
- },
-/obj/machinery/door/window/right/directional/north{
- name = "Ordnance Freezer Chamber Access"
- },
-/turf/open/floor/iron/dark,
-/area/station/science/ordnance)
"vRE" = (
/obj/effect/turf_decal/tile/neutral{
dir = 1
@@ -115702,6 +115686,34 @@
/obj/structure/cable,
/turf/open/floor/plating,
/area/station/security/prison/visit)
+"wbd" = (
+/obj/machinery/turretid{
+ icon_state = "control_stun";
+ name = "AI Chamber turret control";
+ pixel_x = 3;
+ pixel_y = -23
+ },
+/obj/effect/turf_decal/tile/neutral{
+ dir = 1
+ },
+/obj/effect/turf_decal/tile/neutral,
+/obj/effect/turf_decal/tile/neutral{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/neutral{
+ dir = 8
+ },
+/obj/machinery/power/apc/auto_name/directional/north,
+/obj/structure/cable,
+/obj/machinery/airalarm/directional/north{
+ pixel_y = 33
+ },
+/obj/machinery/door/window/brigdoor/left/directional/west{
+ name = "Primary AI Core Acces Door";
+ req_access = list("ai_upload")
+ },
+/turf/open/floor/iron/dark,
+/area/station/ai_monitored/turret_protected/ai)
"wbe" = (
/obj/machinery/conveyor{
dir = 8;
@@ -115870,6 +115882,17 @@
},
/turf/open/floor/plating,
/area/station/maintenance/department/science/lower)
+"wcy" = (
+/obj/machinery/conveyor{
+ dir = 4;
+ id = "packageSort2"
+ },
+/obj/machinery/door/window/left/directional/east{
+ name = "Crate Security Door";
+ req_access = list("cargo")
+ },
+/turf/open/floor/iron/dark,
+/area/station/cargo/sorting)
"wcz" = (
/obj/effect/landmark/start/hangover,
/turf/open/floor/iron,
@@ -116765,21 +116788,6 @@
},
/turf/open/floor/plating,
/area/station/maintenance/port/upper)
-"wkd" = (
-/obj/structure/table,
-/obj/structure/window/reinforced/spawner/directional/east,
-/obj/structure/window/reinforced/spawner/directional/north,
-/obj/machinery/door/window/left/directional/west{
- name = "High-Risk Modules";
- req_access = list("ai_upload")
- },
-/obj/item/ai_module/zeroth/onehuman,
-/obj/item/ai_module/supplied/oxygen{
- pixel_x = -3;
- pixel_y = -3
- },
-/turf/open/floor/iron,
-/area/station/ai_monitored/turret_protected/ai_upload)
"wks" = (
/obj/effect/turf_decal/trimline/purple/filled/corner{
dir = 4
@@ -117095,6 +117103,19 @@
/obj/structure/table/glass,
/turf/open/floor/wood,
/area/station/hallway/primary/central)
+"wmZ" = (
+/obj/machinery/door/window/brigdoor/left/directional/south{
+ name = "Creature Pen";
+ req_access = list("research")
+ },
+/obj/effect/turf_decal/delivery,
+/obj/effect/turf_decal/stripes,
+/obj/machinery/door/poddoor/preopen{
+ id = "xeno2";
+ name = "Creature Cell #2"
+ },
+/turf/open/floor/engine,
+/area/station/science/xenobiology)
"wna" = (
/obj/structure/table/reinforced,
/obj/machinery/door/firedoor,
@@ -119770,16 +119791,6 @@
},
/turf/open/floor/plating/airless,
/area/station/maintenance/port/upper)
-"wMW" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/door/window/brigdoor/right/directional/east{
- name = "Security Desk";
- req_access = list("security")
- },
-/turf/open/floor/iron,
-/area/station/security/checkpoint/escape)
"wNn" = (
/obj/structure/rack,
/obj/effect/turf_decal/bot,
@@ -120554,6 +120565,21 @@
/obj/item/storage/box/mousetraps,
/turf/open/floor/iron/dark/side,
/area/station/hallway/primary/port)
+"wVc" = (
+/obj/effect/turf_decal/stripes{
+ dir = 4
+ },
+/obj/effect/turf_decal/stripes/red/line{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/machinery/door/window/right/directional/east{
+ name = "Mech Bay";
+ req_access = list("robotics")
+ },
+/turf/open/floor/mineral/plastitanium/red,
+/area/station/science/robotics/lab)
"wVe" = (
/obj/effect/turf_decal/weather/sand{
dir = 4
@@ -120746,6 +120772,20 @@
/obj/effect/landmark/start/coroner,
/turf/open/floor/iron/dark/small,
/area/station/medical/morgue)
+"wXt" = (
+/obj/effect/turf_decal/delivery,
+/obj/effect/turf_decal/stripes{
+ dir = 8
+ },
+/obj/machinery/computer/pod/old/mass_driver_controller/ordnancedriver/longrange{
+ pixel_y = 28
+ },
+/obj/machinery/door/window/left/directional/east{
+ name = "Mass Driver Door";
+ req_access = list("ordnance")
+ },
+/turf/open/floor/iron/dark,
+/area/station/science/ordnance/testlab)
"wXw" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -121421,6 +121461,25 @@
/obj/item/radio/intercom/directional/south,
/turf/open/floor/circuit,
/area/station/command/gateway)
+"xez" = (
+/obj/machinery/door/window/brigdoor/left/directional/south{
+ name = "Justice Chamber";
+ req_access = list("armory")
+ },
+/obj/structure/window/reinforced/spawner/directional/west,
+/obj/structure/window/reinforced/spawner/directional/east,
+/obj/machinery/door/window/brigdoor/left/directional/north{
+ name = "Justice Chamber";
+ req_access = list("armory")
+ },
+/obj/machinery/door/firedoor,
+/obj/effect/turf_decal/delivery,
+/obj/machinery/door/poddoor/preopen{
+ id = "executionfireblast"
+ },
+/obj/machinery/atmospherics/pipe/smart/simple/general/visible,
+/turf/open/floor/iron/dark,
+/area/station/security/execution/education)
"xeE" = (
/obj/item/trash/syndi_cakes,
/obj/structure/cable,
@@ -121836,6 +121895,18 @@
/obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible,
/turf/open/floor/plating,
/area/station/engineering/atmos/hfr_room)
+"xiJ" = (
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
+/obj/effect/turf_decal/vg_decals/numbers/two,
+/obj/machinery/door/window/brigdoor/right/directional/west{
+ req_access = list("security");
+ name = "Cell 2"
+ },
+/turf/open/floor/iron/dark/side{
+ dir = 8
+ },
+/area/station/security/brig)
"xiN" = (
/obj/structure/chair/sofa/right/brown,
/turf/open/floor/carpet,
@@ -122070,43 +122141,12 @@
/obj/effect/mapping_helpers/airlock/access/all/security/general,
/turf/open/floor/plating,
/area/station/maintenance/department/security/greater)
-"xle" = (
-/obj/machinery/door/firedoor/border_only{
- dir = 4
- },
-/obj/effect/turf_decal/box,
-/obj/machinery/atmospherics/components/unary/portables_connector/visible/layer4{
- dir = 1
- },
-/obj/machinery/door/window/right/directional/east{
- name = "Ordnance Freezer Chamber Access"
- },
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/turf/open/floor/iron/dark,
-/area/station/science/ordnance)
"xli" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
dir = 8
},
/turf/open/floor/iron,
/area/station/hallway/primary/central)
-"xll" = (
-/obj/machinery/door/firedoor,
-/obj/structure/table/reinforced,
-/obj/machinery/door/poddoor/shutters/preopen{
- id = "chemistbot";
- name = "Chemistry Side Shutters"
- },
-/obj/item/folder/white,
-/obj/machinery/door/window/left/directional/west{
- name = "Chemistry Desk";
- req_access = list("pharmacy")
- },
-/obj/machinery/door/window/left/directional/east{
- name = "Chemistry Desk"
- },
-/turf/open/floor/iron/dark,
-/area/station/medical/pharmacy)
"xlq" = (
/obj/structure/chair/stool/directional/west,
/obj/machinery/light/small/red/dim/directional/west,
@@ -122515,6 +122555,15 @@
},
/turf/open/floor/iron,
/area/station/science/explab)
+"xpC" = (
+/obj/machinery/conveyor{
+ dir = 4;
+ id = "garbage"
+ },
+/obj/machinery/door/window/right/directional/north,
+/obj/machinery/door/window/right/directional/south,
+/turf/open/floor/plating,
+/area/station/maintenance/disposal)
"xpM" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -123098,6 +123147,20 @@
},
/turf/open/floor/iron,
/area/station/hallway/primary/upper)
+"xvb" = (
+/obj/machinery/status_display/evac/directional/north,
+/obj/machinery/light/directional/north,
+/obj/machinery/camera/directional/north{
+ c_tag = "Bridge - E.V.A. Fore";
+ name = "command camera"
+ },
+/obj/machinery/door/window/left/directional/west{
+ req_access = list("eva")
+ },
+/turf/open/floor/iron/stairs{
+ dir = 4
+ },
+/area/station/ai_monitored/command/storage/eva/upper)
"xvc" = (
/obj/effect/spawner/random/trash/moisture_trap,
/turf/open/floor/plating,
@@ -123325,24 +123388,6 @@
/obj/machinery/duct,
/turf/open/floor/iron,
/area/station/commons/dorms)
-"xxK" = (
-/obj/structure/window/reinforced/spawner/directional/south,
-/obj/machinery/disposal/delivery_chute{
- dir = 4
- },
-/obj/structure/plasticflaps,
-/obj/structure/disposalpipe/trunk{
- dir = 4
- },
-/obj/effect/turf_decal/stripes{
- dir = 4
- },
-/obj/machinery/door/window/right/directional/east{
- req_access = list("cargo");
- name = "Medbay Deliveries"
- },
-/turf/open/floor/iron/dark,
-/area/station/cargo/sorting)
"xxN" = (
/obj/structure/window/reinforced/spawner/directional/north,
/obj/structure/window/reinforced/spawner/directional/south,
@@ -124335,10 +124380,6 @@
dir = 4
},
/area/station/hallway/secondary/command)
-"xHZ" = (
-/obj/machinery/door/window/right/directional/north,
-/turf/open/floor/plating,
-/area/station/maintenance/disposal)
"xIa" = (
/obj/structure/railing{
dir = 4
@@ -124772,6 +124813,15 @@
/obj/effect/decal/cleanable/blood,
/turf/open/floor/plating,
/area/station/maintenance/department/science/xenobiology)
+"xMz" = (
+/obj/machinery/atmospherics/pipe/smart/simple/general/visible{
+ dir = 10
+ },
+/obj/machinery/door/window/right/directional/east{
+ name = "Gas Ports"
+ },
+/turf/open/floor/iron/dark,
+/area/station/security/execution/education)
"xME" = (
/obj/machinery/power/port_gen/pacman/pre_loaded,
/turf/open/floor/plating,
@@ -125115,16 +125165,6 @@
},
/turf/open/floor/plating,
/area/station/maintenance/abandon_art_studio)
-"xPJ" = (
-/obj/structure/cable,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/machinery/door/window/brigdoor/right/directional/west{
- name = "Command Chair";
- req_access = list("command")
- },
-/turf/open/floor/iron,
-/area/station/command/bridge)
"xPO" = (
/obj/structure/disposalpipe/segment{
dir = 5
@@ -125189,20 +125229,6 @@
/obj/machinery/light_switch/directional/south,
/turf/open/floor/circuit,
/area/station/ai_monitored/command/nuke_storage)
-"xQT" = (
-/obj/machinery/door/firedoor,
-/obj/structure/table/reinforced,
-/obj/item/folder/white,
-/obj/machinery/door/poddoor/shutters/preopen{
- id = "Psychward4";
- name = "Control Room Shutters"
- },
-/obj/structure/cable,
-/obj/machinery/door/window/left/directional/west{
- req_access = list("psychology")
- },
-/turf/open/floor/iron/dark,
-/area/station/medical/psychology)
"xQY" = (
/obj/effect/decal/cleanable/dirt{
icon_state = "dirt-flat-1"
@@ -125399,6 +125425,17 @@
},
/turf/open/floor/iron/dark,
/area/station/security/office)
+"xTz" = (
+/obj/structure/cable,
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 4
+ },
+/obj/machinery/door/window/left/directional/west{
+ name = "Security Mech Recharge Dock";
+ req_access = list("security")
+ },
+/turf/open/floor/iron,
+/area/station/ai_monitored/security/armory)
"xTA" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -125482,23 +125519,6 @@
},
/turf/open/floor/iron,
/area/station/medical/patients_rooms)
-"xUG" = (
-/obj/effect/turf_decal/stripes{
- dir = 4
- },
-/obj/machinery/disposal/delivery_chute{
- dir = 4
- },
-/obj/structure/plasticflaps,
-/obj/structure/disposalpipe/trunk{
- dir = 8
- },
-/obj/machinery/door/window/right/directional/east{
- req_access = list("cargo");
- name = "Engineering Deliveries"
- },
-/turf/open/floor/iron/dark,
-/area/station/cargo/sorting)
"xUL" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -127273,6 +127293,13 @@
/obj/effect/spawner/random/trash/grille_or_waste,
/turf/open/floor/plating,
/area/station/maintenance/department/medical/central)
+"yjZ" = (
+/obj/machinery/door/window/brigdoor/right/directional/east{
+ name = "Crematorium";
+ req_access = list("security")
+ },
+/turf/open/floor/iron/dark,
+/area/station/security/prison)
"ykd" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment{
@@ -127423,33 +127450,6 @@
/obj/machinery/firealarm/directional/south,
/turf/open/floor/iron/dark/side,
/area/station/security/checkpoint/customs/auxiliary)
-"ylA" = (
-/obj/machinery/camera/directional/north{
- c_tag = "AI Chamber - Core";
- network = list("aicore")
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 1
- },
-/obj/effect/turf_decal/tile/neutral,
-/obj/effect/turf_decal/tile/neutral{
- dir = 4
- },
-/obj/effect/turf_decal/tile/neutral{
- dir = 8
- },
-/obj/machinery/requests_console/directional/north{
- department = "AI";
- name = "AI Requests Console"
- },
-/obj/effect/mapping_helpers/requests_console/information,
-/obj/effect/mapping_helpers/requests_console/assistance,
-/obj/machinery/door/window/brigdoor/left/directional/east{
- name = "Primary AI Core Acces Door";
- req_access = list("ai_upload")
- },
-/turf/open/floor/iron/dark,
-/area/station/ai_monitored/turret_protected/ai)
"ylQ" = (
/obj/machinery/light/directional/west,
/obj/item/radio/intercom/directional/west,
@@ -146148,10 +146148,10 @@ kuh
cFU
cFU
cFU
-fTY
+odJ
hro
oGo
-edu
+qMO
cFU
cFU
use
@@ -146883,7 +146883,7 @@ uVc
ewE
xoK
uEt
-jXd
+fcO
iKV
mWh
pCR
@@ -147178,7 +147178,7 @@ cFU
cFU
tIo
nZM
-wMW
+kAn
nZM
cFU
cFU
@@ -147694,7 +147694,7 @@ cLd
vCP
lpe
mLd
-neT
+gVW
wPU
hKt
kfF
@@ -148175,7 +148175,7 @@ pCR
wTv
pBo
mDo
-fqz
+bIv
uDU
uDU
uDU
@@ -148368,7 +148368,7 @@ mjE
mjE
mjE
mjE
-cpT
+pgm
mjE
ltN
cDn
@@ -153059,7 +153059,7 @@ jwJ
kro
mUP
bWr
-tIz
+dea
fHr
fHr
rJj
@@ -153771,7 +153771,7 @@ hZI
osb
hZI
pPF
-acp
+bDB
hxO
tMz
mjE
@@ -153842,7 +153842,7 @@ oHU
qlY
sJE
jzJ
-pNp
+loc
qlY
tbS
oMk
@@ -154099,7 +154099,7 @@ kWy
qlY
qfV
jbI
-bis
+jeX
qlY
snu
gbw
@@ -154343,7 +154343,7 @@ qku
cST
lAZ
lAZ
-vfJ
+otE
lAZ
sXk
jgg
@@ -154601,12 +154601,12 @@ ofm
lAZ
tiZ
uNw
-efS
+pAI
qUR
nRk
eNd
uuF
-srN
+atZ
sMu
iFl
xLo
@@ -154810,7 +154810,7 @@ hGf
mZP
hGf
piO
-gSe
+eeB
hGf
bii
bii
@@ -155128,7 +155128,7 @@ kty
kqE
uND
lkV
-dDb
+iDh
sHp
uSe
hpb
@@ -155824,7 +155824,7 @@ lJt
lJt
lJt
vcQ
-mKw
+sxj
sjd
lJt
lJt
@@ -157743,7 +157743,7 @@ oqz
nFl
mze
nPr
-lGL
+nJg
oeA
maz
gKc
@@ -157996,7 +157996,7 @@ wHI
wHI
uzo
gnI
-faM
+efG
gnI
uzo
uzo
@@ -158934,7 +158934,7 @@ nJA
xXo
oSe
aqM
-rNM
+uLb
iXf
bkP
fPl
@@ -158953,7 +158953,7 @@ rig
kbZ
nRo
tpd
-gdb
+lxB
wup
wup
jKx
@@ -159437,7 +159437,7 @@ lHi
dlN
gkm
gkm
-imX
+ibj
gkm
gkm
abJ
@@ -159498,7 +159498,7 @@ qjx
aMQ
lDp
cYn
-drM
+adO
hlP
yhm
yhm
@@ -160042,7 +160042,7 @@ liN
xJH
dvB
dvB
-esT
+mfp
dvB
dvB
xJH
@@ -160465,7 +160465,7 @@ gkm
gkm
gkm
ntH
-vvq
+xTz
wne
gkm
eIM
@@ -160758,7 +160758,7 @@ inQ
qDH
mHE
kAG
-miq
+fnJ
lCe
gSl
lRu
@@ -161005,8 +161005,8 @@ ggP
vIU
mHE
kDi
-bAF
-bAF
+ubt
+ubt
anb
uuw
dqZ
@@ -161038,7 +161038,7 @@ jZJ
nge
rZM
wna
-fqB
+bCR
kGp
mQS
nYP
@@ -161053,7 +161053,7 @@ qJJ
cUu
jMU
pgb
-vLf
+hnD
oAu
vET
hPM
@@ -161248,7 +161248,7 @@ ykW
ykW
qsl
vPn
-htu
+jrJ
vPo
tNE
ykG
@@ -161280,7 +161280,7 @@ vdr
kCk
onf
aqj
-nMJ
+gzV
rNa
rNa
rNa
@@ -161507,9 +161507,9 @@ qak
cVu
qak
iEG
-iep
+xiJ
vPo
-eKX
+qAC
vPo
hGf
sXE
@@ -161759,7 +161759,7 @@ fWt
ksn
pSY
ljt
-eap
+byV
qak
qak
qak
@@ -161777,16 +161777,16 @@ dVy
ucQ
qpu
aYq
-spa
+qbu
qBg
aYq
-spa
+qbu
wba
aYq
-spa
+qbu
hdb
aYq
-jOL
+eLq
ntA
mHE
mHE
@@ -162021,9 +162021,9 @@ wvo
cVu
qak
rcC
-aRV
+vww
vPo
-dsL
+edo
vPo
hGf
gBM
@@ -162033,17 +162033,17 @@ ocl
dVy
qxf
okI
-qFs
-jWX
+eUl
+uCL
eOU
-qFs
-jWX
+eUl
+uCL
eNn
-qFs
-jWX
+eUl
+uCL
cfN
-qFs
-jTE
+eUl
+lCP
xrD
jYG
kxD
@@ -162276,7 +162276,7 @@ ykW
ykW
dKZ
nuj
-tFk
+jTG
vPo
rVq
kHM
@@ -162290,21 +162290,21 @@ xxl
dVy
sFi
okI
-nQN
-kfH
+nLk
+mnv
qBg
-nQN
-kfH
+nLk
+mnv
wba
-nQN
-kfH
+nLk
+mnv
hdb
-nQN
-rDH
+nLk
+nOD
nAE
jyy
uOJ
-bkV
+hym
gom
gWE
gWE
@@ -163041,7 +163041,7 @@ gkm
sak
tif
iLK
-pHF
+bUG
oaq
wvo
qak
@@ -163332,7 +163332,7 @@ qPh
alt
laX
okJ
-kaB
+iNe
mHE
lGz
tFN
@@ -163366,7 +163366,7 @@ wUv
xnG
bLF
hmV
-oQp
+dOL
sNu
lDc
lFy
@@ -163540,8 +163540,8 @@ cLU
cLU
cLU
cLU
-rpc
-brU
+net
+xMz
chB
cLU
cLU
@@ -163796,7 +163796,7 @@ uJO
gHt
mcE
nQK
-tJk
+xez
jsH
usE
qeT
@@ -163806,7 +163806,7 @@ nJY
pQr
uCY
rZC
-sxE
+yjZ
mzV
vxj
ssh
@@ -164107,7 +164107,7 @@ vpn
pdU
hAL
vdy
-oNM
+jDk
wZQ
kzi
ord
@@ -164569,7 +164569,7 @@ cLU
cLU
cLU
jPr
-daQ
+irB
rRU
cLU
cLU
@@ -164900,11 +164900,11 @@ wlh
hvw
odz
smr
-aqz
-chI
-xUG
-jEK
-xxK
+mbb
+ksx
+tWY
+tFP
+cbc
suZ
xti
sut
@@ -165169,7 +165169,7 @@ lNl
mcl
usq
uvM
-pbz
+uth
iVl
wgo
afC
@@ -165343,11 +165343,11 @@ caC
xJH
xJH
eKU
-rUU
+vFh
jTO
keD
sHg
-rUU
+vFh
eKU
fBz
fBz
@@ -165396,7 +165396,7 @@ qIW
ooc
tqh
kqf
-gis
+hsJ
lDB
wQt
xqh
@@ -165669,7 +165669,7 @@ tAt
jVo
uTJ
xti
-lgU
+wcy
sFt
wLn
qKF
@@ -165681,7 +165681,7 @@ kgd
teT
dyJ
voV
-mNh
+evl
hHv
rqC
bSf
@@ -165937,7 +165937,7 @@ nxW
czQ
qvv
iYm
-aFd
+tsu
mTQ
mTQ
nup
@@ -167971,7 +167971,7 @@ sWA
xIy
jUp
nPo
-jcF
+xpC
lyW
xlq
nsi
@@ -168230,7 +168230,7 @@ jUp
vEx
apo
xga
-atJ
+lwm
ycA
eFn
sIq
@@ -168488,7 +168488,7 @@ jSY
kSC
trl
sMx
-aby
+gLX
eFn
weW
vaL
@@ -169773,7 +169773,7 @@ pxb
tWP
vMy
dyT
-xHZ
+lMu
nfx
pxb
pxb
@@ -170330,11 +170330,11 @@ bDA
feL
bDA
xwK
-dZn
+snt
xwK
bDA
awV
-nrK
+kFy
awV
juF
jLb
@@ -213461,9 +213461,9 @@ cWn
hOv
gxL
iuJ
-lHR
+tMh
axm
-tLP
+afX
xPd
lDR
tEY
@@ -213745,7 +213745,7 @@ ksm
eLU
eLU
eLU
-aiv
+oiv
bHt
mjp
eLU
@@ -217867,7 +217867,7 @@ cAp
iYk
gNW
bfo
-aUK
+pEJ
uJA
aOH
pzS
@@ -218618,7 +218618,7 @@ qvX
qvX
qvX
gOY
-dRv
+dEC
gOY
eAQ
uor
@@ -219099,9 +219099,9 @@ tml
uyR
frb
jmH
-oMx
+opw
pJT
-pna
+qlV
bSS
fRy
cRb
@@ -219378,8 +219378,8 @@ ooa
jCN
ooa
uUk
-jAH
-bHE
+pey
+qyJ
sTk
qjg
aZe
@@ -220406,7 +220406,7 @@ qvs
fCd
exn
mzM
-hdT
+cpO
dGB
sTk
lIZ
@@ -220929,10 +220929,10 @@ niB
wAk
quF
dkX
-tPz
-dYh
+thx
+dUi
scI
-mXQ
+wVc
mpe
gCg
hbU
@@ -221455,7 +221455,7 @@ bDH
uor
hJR
dfN
-pmu
+nAb
eIC
hJR
uJL
@@ -221750,8 +221750,8 @@ fDT
mBc
mOS
oEB
-upc
-oRk
+cJl
+pux
mzy
qaH
lXo
@@ -222000,7 +222000,7 @@ uTg
cmJ
kpH
cWg
-pQh
+iAk
rYe
bSd
fDT
@@ -222478,7 +222478,7 @@ xKX
nrx
lir
sXt
-sIV
+ils
sXt
lir
lir
@@ -223017,7 +223017,7 @@ soz
soz
jYw
irI
-oBX
+kBE
rJT
byl
nsB
@@ -223030,12 +223030,12 @@ omW
gDN
hog
euU
-mmr
-kpk
+lhM
+rSx
bOU
mya
-sAV
-tOw
+eQk
+lLv
euU
pCC
fDT
@@ -223456,7 +223456,7 @@ miE
lGo
xai
xai
-qvV
+cVx
jYP
xai
jYP
@@ -223696,9 +223696,9 @@ syx
wFN
iig
jiu
-hyU
+fCT
eNV
-iRK
+bKw
jiu
jiu
soz
@@ -223801,12 +223801,12 @@ xAB
gDN
jQV
euU
-mmr
-msO
+lhM
+wmZ
bOU
mya
-kdq
-tOw
+ahB
+lLv
euU
aYz
fDT
@@ -223847,7 +223847,7 @@ dFU
psD
cKf
hOo
-fSn
+fxv
nxU
ivJ
oOq
@@ -223950,7 +223950,7 @@ kzz
dep
xIf
wzY
-xPJ
+bTX
jiu
jiu
gBh
@@ -224360,7 +224360,7 @@ gEo
tYH
qNB
dFU
-gkD
+wbd
dFU
dFU
dFU
@@ -224576,8 +224576,8 @@ nsB
nsB
qii
lhr
-bDX
-tOw
+pTS
+lLv
euU
aYz
fDT
@@ -224620,7 +224620,7 @@ pIo
uMb
fdi
aka
-rXc
+dlU
mkC
gHe
dFU
@@ -224874,7 +224874,7 @@ svu
heN
wYe
dFU
-ylA
+eOf
dFU
dFU
dFU
@@ -224978,7 +224978,7 @@ jmZ
dep
nLV
gmt
-pXf
+pQX
jiu
jiu
gBh
@@ -225034,7 +225034,7 @@ mMJ
xtV
eUH
pKz
-cyD
+hNA
uol
lcX
mCP
@@ -225238,9 +225238,9 @@ fwu
wFN
uPf
jiu
-wkd
+skg
bSa
-aHb
+clj
jiu
jiu
soz
@@ -225343,12 +225343,12 @@ cZU
gDN
hog
euU
-mmr
-aZc
+lhM
+nid
eUV
kzI
-qhs
-tOw
+iQM
+lLv
euU
pCC
fDT
@@ -225389,7 +225389,7 @@ dFU
vJL
scw
bsA
-heu
+gHC
ogx
aFk
oOq
@@ -225632,7 +225632,7 @@ mpb
mpb
gLc
fge
-hlQ
+rvH
ybB
yap
fge
@@ -226114,12 +226114,12 @@ bWW
gDN
jQV
euU
-mmr
-sCA
+lhM
+ncE
eUV
kzI
-ujI
-tOw
+sQJ
+lLv
euU
aYz
fDT
@@ -226341,7 +226341,7 @@ wae
xKN
lqk
cIt
-eEk
+rTs
xFq
xFq
xFq
@@ -226594,7 +226594,7 @@ aMt
whu
lqk
pYm
-rXo
+bcX
pYm
lqk
oEx
@@ -227340,7 +227340,7 @@ pyI
qYp
vqm
xMH
-sKU
+aIz
evg
vUe
spp
@@ -228349,7 +228349,7 @@ vHK
kAM
cjD
vHK
-lph
+kUv
fhS
gxq
vHK
@@ -228374,7 +228374,7 @@ dnN
nRp
cra
eFU
-xll
+siQ
uTU
cra
aMt
@@ -228572,11 +228572,11 @@ loJ
soz
kaj
kaj
-eVA
+xvb
kcj
oeq
tsb
-ryw
+vgE
kaj
kaj
hIx
@@ -228848,8 +228848,8 @@ jOx
vtt
oNL
vtt
-nfd
-dBt
+pPz
+bXS
vtt
rRM
gfL
@@ -229165,7 +229165,7 @@ jHY
jHY
aQc
xWZ
-piP
+kPl
jHY
jHY
jHY
@@ -229444,7 +229444,7 @@ wsk
evv
yjD
kUp
-vRC
+gga
dEY
uiY
ofB
@@ -229628,7 +229628,7 @@ vnC
isF
isF
tCr
-dFq
+kYa
tCr
isF
uzK
@@ -229658,10 +229658,10 @@ oiF
omQ
qdq
ggp
-gFj
+cxx
uGK
xAA
-vas
+qlX
pLB
crS
tYD
@@ -229703,7 +229703,7 @@ yjD
hJE
lrX
leC
-xle
+dxT
xbd
xDl
iZs
@@ -230904,8 +230904,8 @@ fUa
gTZ
gTZ
aOC
-eoK
-iIO
+vlf
+iTD
iZC
gTZ
gTZ
@@ -230963,7 +230963,7 @@ eEJ
uwy
aQY
jsj
-dtv
+mpE
jsj
aQY
xIX
@@ -231209,7 +231209,7 @@ dBC
sZB
pVw
aEa
-jqO
+dzF
iUQ
kfe
tlC
@@ -231991,7 +231991,7 @@ jrg
oXE
aQY
jsj
-xQT
+aJt
jsj
aQY
aBK
@@ -232789,7 +232789,7 @@ ulx
ulx
ulx
lLn
-qbg
+wXt
eQK
lLn
lLn
@@ -233973,7 +233973,7 @@ qNP
iUS
jNU
cab
-ayJ
+qMV
rXy
xbB
mTZ
@@ -237603,7 +237603,7 @@ lGd
lkh
sPm
ele
-dzM
+mYU
qoY
viC
viC
diff --git a/_maps/map_files/NorthStar/north_star.dmm b/_maps/map_files/NorthStar/north_star.dmm
index 2e62e13527d..ba6a7fc1758 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,
@@ -8993,6 +8989,31 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/smooth,
/area/station/construction)
+"cjz" = (
+/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)
"cjB" = (
/obj/effect/turf_decal/stripes/line,
/obj/effect/decal/cleanable/dirt,
@@ -12183,7 +12204,7 @@
/obj/machinery/camera/motion/directional/north{
c_tag = "Minisat North"
},
-/obj/machinery/power/smes/full,
+/obj/machinery/power/smes/super/full,
/obj/structure/cable,
/turf/open/floor/circuit,
/area/station/ai_monitored/turret_protected/aisat/service)
@@ -19511,15 +19532,6 @@
},
/turf/open/openspace,
/area/station/science/xenobiology/hallway)
-"fbl" = (
-/obj/machinery/power/smes,
-/obj/effect/turf_decal/stripes/line{
- dir = 4
- },
-/obj/structure/cable,
-/obj/machinery/light/small/directional/west,
-/turf/open/floor/plating,
-/area/station/engineering/gravity_generator)
"fbo" = (
/obj/effect/turf_decal/tile/red/opposingcorners{
dir = 1
@@ -24752,12 +24764,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{
@@ -36847,6 +36853,15 @@
},
/turf/open/floor/iron/dark,
/area/station/hallway/floor1/aft)
+"jCk" = (
+/obj/effect/turf_decal/stripes/line{
+ dir = 4
+ },
+/obj/structure/cable,
+/obj/machinery/light/small/directional/west,
+/obj/machinery/power/smes/full,
+/turf/open/floor/plating,
+/area/station/engineering/gravity_generator)
"jCz" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -40338,6 +40353,14 @@
},
/turf/open/floor/iron/chapel,
/area/station/service/chapel)
+"kvW" = (
+/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)
"kwc" = (
/obj/effect/turf_decal/trimline/green/filled/line{
dir = 8
@@ -44192,6 +44215,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 +48628,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,
@@ -61920,7 +61943,7 @@
/turf/open/floor/iron/white,
/area/station/science/lobby)
"pUB" = (
-/obj/machinery/power/smes/full,
+/obj/machinery/power/smes/super/full,
/obj/structure/cable,
/turf/open/floor/circuit,
/area/station/ai_monitored/turret_protected/aisat/service)
@@ -63807,6 +63830,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{
@@ -72945,31 +72978,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 +76638,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{
@@ -79799,7 +79799,7 @@
/area/station/maintenance/solars/starboard/fore)
"uDR" = (
/obj/machinery/firealarm/directional/west,
-/obj/machinery/power/smes/full,
+/obj/machinery/power/smes/super/full,
/obj/structure/cable,
/turf/open/floor/circuit,
/area/station/ai_monitored/turret_protected/aisat_interior)
@@ -143683,7 +143683,7 @@ lEI
aVc
dEc
dFq
-fbl
+jCk
oHx
dEc
vYD
@@ -195562,7 +195562,7 @@ mqc
mRQ
dVV
xNy
-sPp
+cjz
mcI
rPC
sJn
@@ -196076,7 +196076,7 @@ iOA
utl
doh
gJz
-tKr
+kvW
hwQ
piz
aWO
@@ -196590,7 +196590,7 @@ iOA
dfU
pZm
wJy
-tKr
+kvW
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
diff --git a/_maps/map_files/VoidRaptor/VoidRaptor.dmm b/_maps/map_files/VoidRaptor/VoidRaptor.dmm
index 35c6b42f083..e077f65f4b0 100644
--- a/_maps/map_files/VoidRaptor/VoidRaptor.dmm
+++ b/_maps/map_files/VoidRaptor/VoidRaptor.dmm
@@ -7570,16 +7570,6 @@
"cnC" = (
/turf/closed/wall,
/area/station/maintenance/port/central)
-"coc" = (
-/obj/structure/sign/nanotrasen{
- pixel_y = -32
- },
-/obj/machinery/power/smes{
- charge = 5e+006
- },
-/obj/structure/cable,
-/turf/open/floor/vault,
-/area/station/ai_monitored/turret_protected/ai)
"cog" = (
/obj/machinery/light/floor,
/turf/open/floor/engine/co2,
@@ -23052,6 +23042,19 @@
/obj/structure/sign/calendar/directional/south,
/turf/open/floor/wood/large,
/area/station/command/heads_quarters/blueshield)
+"gHF" = (
+/obj/effect/turf_decal/trimline/brown/filled/line{
+ dir = 1
+ },
+/obj/machinery/navbeacon{
+ codes_txt = "delivery;dir=2";
+ dir = 4;
+ location = "QM #1"
+ },
+/obj/effect/turf_decal/box,
+/mob/living/simple_animal/bot/mulebot,
+/turf/open/floor/iron/smooth_edge,
+/area/station/cargo/storage)
"gHG" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -62150,6 +62153,20 @@
/obj/structure/window/spawner/directional/north,
/turf/open/floor/grass,
/area/station/service/hydroponics/garden)
+"roC" = (
+/obj/effect/turf_decal/trimline/brown/filled/line{
+ dir = 1
+ },
+/obj/machinery/firealarm/directional/north,
+/obj/machinery/navbeacon{
+ codes_txt = "delivery;dir=2";
+ dir = 4;
+ location = "QM #4"
+ },
+/obj/effect/turf_decal/box,
+/mob/living/simple_animal/bot/mulebot,
+/turf/open/floor/iron/smooth_edge,
+/area/station/cargo/storage)
"roK" = (
/obj/machinery/newscaster/directional/west,
/obj/structure/table/wood/fancy,
@@ -70742,20 +70759,6 @@
},
/turf/open/floor/plating,
/area/station/science/ordnance/storage)
-"tEH" = (
-/obj/effect/turf_decal/trimline/brown/filled/line{
- dir = 1
- },
-/obj/machinery/firealarm/directional/north,
-/obj/machinery/navbeacon{
- codes_txt = "delivery;dir=2";
- dir = 4;
- location = "QM #4"
- },
-/obj/effect/turf_decal/box,
-/mob/living/simple_animal/bot/mulebot,
-/turf/open/floor/iron/smooth_edge,
-/area/station/cargo/storage)
"tEI" = (
/obj/structure/table,
/obj/item/food/ready_donk/mac_n_cheese{
@@ -82959,19 +82962,6 @@
/obj/item/reagent_containers/spray/cleaner,
/turf/open/floor/iron/dark,
/area/station/medical/break_room)
-"wVQ" = (
-/obj/effect/turf_decal/trimline/brown/filled/line{
- dir = 1
- },
-/obj/machinery/navbeacon{
- codes_txt = "delivery;dir=2";
- dir = 4;
- location = "QM #1"
- },
-/obj/effect/turf_decal/box,
-/mob/living/simple_animal/bot/mulebot,
-/turf/open/floor/iron/smooth_edge,
-/area/station/cargo/storage)
"wWw" = (
/obj/structure/window/reinforced/spawner/directional/west,
/obj/structure/chair/office{
@@ -84354,6 +84344,16 @@
dir = 8
},
/area/station/service/hydroponics)
+"xsi" = (
+/obj/structure/sign/nanotrasen{
+ pixel_y = -32
+ },
+/obj/structure/cable,
+/obj/machinery/power/smes/super/full{
+ name = "ai power storage unit"
+ },
+/turf/open/floor/vault,
+/area/station/ai_monitored/turret_protected/ai)
"xsj" = (
/obj/effect/turf_decal/trimline/yellow/filled/line{
dir = 4
@@ -102018,7 +102018,7 @@ dYb
uQi
bWK
lvx
-coc
+xsi
rDp
rDp
xMq
@@ -129610,7 +129610,7 @@ gjq
nyf
gZb
wuW
-wVQ
+gHF
udn
aRn
fun
@@ -130381,7 +130381,7 @@ aUA
pjT
xMq
sFi
-tEH
+roC
udn
cLG
sny
diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm
index 456cf46196e..82a1cda8daf 100644
--- a/_maps/map_files/tramstation/tramstation.dmm
+++ b/_maps/map_files/tramstation/tramstation.dmm
@@ -7418,14 +7418,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
/turf/open/floor/iron/white,
/area/station/medical/pharmacy)
-"bzP" = (
-/obj/effect/turf_decal/trimline/neutral/filled/line,
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
- dir = 8
- },
-/obj/structure/cable,
-/turf/open/floor/iron,
-/area/station/engineering/gravity_generator)
"bAj" = (
/obj/machinery/door/airlock/engineering/glass{
name = "Tram Mechanical Room"
@@ -9879,6 +9871,14 @@
},
/turf/open/floor/iron/white,
/area/station/science/lab)
+"crm" = (
+/obj/machinery/airalarm/directional/east,
+/obj/structure/table,
+/obj/item/storage/toolbox/electrical{
+ pixel_y = 5
+ },
+/turf/open/floor/iron,
+/area/station/engineering/gravity_generator)
"crz" = (
/obj/effect/turf_decal/trimline/yellow/filled/line{
dir = 1
@@ -19590,6 +19590,12 @@
},
/turf/open/floor/wood,
/area/station/service/library)
+"fTF" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
+ dir = 4
+ },
+/turf/open/floor/iron,
+/area/station/engineering/gravity_generator)
"fTI" = (
/obj/structure/railing{
dir = 1
@@ -22970,6 +22976,11 @@
"hhc" = (
/turf/open/floor/iron/dark,
/area/station/command/bridge)
+"hhf" = (
+/obj/machinery/power/smes/super/full,
+/obj/structure/cable,
+/turf/open/floor/circuit,
+/area/station/ai_monitored/turret_protected/ai)
"hht" = (
/obj/effect/landmark/event_spawn,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
@@ -28799,15 +28810,6 @@
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/white,
/area/station/medical/medbay/lobby)
-"joq" = (
-/obj/effect/turf_decal/trimline/neutral/filled/line{
- dir = 6
- },
-/obj/structure/table,
-/obj/machinery/firealarm/directional/east,
-/obj/machinery/light/directional/east,
-/turf/open/floor/iron,
-/area/station/engineering/gravity_generator)
"jos" = (
/obj/effect/turf_decal/trimline/neutral/filled/line{
dir = 9
@@ -32489,6 +32491,11 @@
},
/turf/open/space/openspace,
/area/space)
+"kzf" = (
+/obj/effect/turf_decal/trimline/neutral/filled/line,
+/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
+/turf/open/floor/iron,
+/area/station/engineering/gravity_generator)
"kzg" = (
/obj/structure/table,
/obj/machinery/recharger,
@@ -33445,16 +33452,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
@@ -33880,11 +33877,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/station/security/brig)
-"kWp" = (
-/obj/effect/turf_decal/trimline/neutral/filled/line,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
-/turf/open/floor/iron,
-/area/station/engineering/gravity_generator)
"kWq" = (
/obj/effect/turf_decal/trimline/purple/filled/corner,
/obj/effect/turf_decal/trimline/purple/filled/corner{
@@ -33966,13 +33958,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 +34712,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)
@@ -37312,6 +37292,20 @@
},
/turf/open/floor/iron/dark,
/area/station/ai_monitored/turret_protected/aisat/foyer)
+"mds" = (
+/obj/effect/turf_decal/trimline/neutral/filled/line{
+ dir = 6
+ },
+/obj/machinery/firealarm/directional/east,
+/obj/machinery/light/directional/east,
+/obj/structure/table,
+/obj/item/book/manual/wiki/engineering_guide{
+ pixel_x = -2
+ },
+/obj/item/radio/off,
+/obj/item/radio/intercom/directional/south,
+/turf/open/floor/iron,
+/area/station/engineering/gravity_generator)
"mdD" = (
/obj/effect/turf_decal/siding/thinplating,
/obj/effect/turf_decal/siding/thinplating{
@@ -41946,6 +41940,14 @@
/obj/item/radio/intercom/directional/north,
/turf/open/floor/engine,
/area/station/engineering/supermatter/room)
+"nNa" = (
+/obj/effect/turf_decal/trimline/neutral/filled/line,
+/obj/machinery/power/terminal{
+ dir = 8
+ },
+/obj/structure/cable,
+/turf/open/floor/iron,
+/area/station/engineering/gravity_generator)
"nNh" = (
/obj/structure/flora/bush/sunny/style_random,
/turf/open/misc/grass/jungle,
@@ -42898,6 +42900,14 @@
/obj/machinery/reagentgrinder,
/turf/open/floor/wood,
/area/station/service/bar/backroom)
+"ocw" = (
+/obj/effect/turf_decal/trimline/neutral/filled/line{
+ dir = 10
+ },
+/obj/machinery/light/directional/west,
+/obj/machinery/power/smes/engineering,
+/turf/open/floor/iron,
+/area/station/engineering/gravity_generator)
"ocK" = (
/obj/effect/turf_decal/trimline/yellow/filled/line,
/obj/structure/sign/warning/secure_area{
@@ -46389,6 +46399,14 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/plating,
/area/station/maintenance/tram/mid)
+"pwj" = (
+/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)
"pwm" = (
/obj/structure/railing{
dir = 10
@@ -48309,16 +48327,6 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/plating,
/area/station/maintenance/tram/right)
-"qeq" = (
-/obj/effect/turf_decal/trimline/neutral/filled/line{
- dir = 10
- },
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{
- dir = 4
- },
-/obj/machinery/light/directional/west,
-/turf/open/floor/iron,
-/area/station/engineering/gravity_generator)
"qes" = (
/obj/machinery/door/airlock/grunge{
name = "Entertainment Center"
@@ -54737,6 +54745,16 @@
/obj/structure/sign/calendar/directional/north,
/turf/open/floor/carpet,
/area/station/command/heads_quarters/hop)
+"srx" = (
+/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)
"srz" = (
/obj/effect/turf_decal/trimline/neutral/filled/line{
dir = 6
@@ -62205,12 +62223,6 @@
/obj/machinery/atmospherics/pipe/bridge_pipe/green/visible,
/turf/open/floor/iron,
/area/station/engineering/atmos)
-"uPi" = (
-/obj/effect/turf_decal/trimline/neutral/filled/line,
-/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
-/obj/structure/cable,
-/turf/open/floor/iron,
-/area/station/engineering/gravity_generator)
"uPo" = (
/obj/structure/table/glass,
/obj/effect/turf_decal/trimline/blue/filled/line,
@@ -64125,14 +64137,6 @@
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/station/science/lobby)
-"vyD" = (
-/obj/machinery/power/smes{
- charge = 5e+06
- },
-/obj/machinery/airalarm/directional/east,
-/obj/structure/cable,
-/turf/open/floor/iron,
-/area/station/engineering/gravity_generator)
"vyG" = (
/obj/machinery/door/airlock/command{
name = "Head of Security"
@@ -65311,6 +65315,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;
@@ -66590,13 +66601,6 @@
/obj/structure/flora/coconuts,
/turf/open/misc/grass/jungle,
/area/station/science/explab)
-"wtS" = (
-/obj/machinery/power/terminal{
- dir = 4
- },
-/obj/structure/cable,
-/turf/open/floor/iron,
-/area/station/engineering/gravity_generator)
"wuc" = (
/obj/effect/turf_decal/trimline/yellow/filled/corner{
dir = 1
@@ -67094,14 +67098,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{
@@ -67324,6 +67320,13 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron/white,
/area/station/medical/medbay/central)
+"wGQ" = (
+/obj/effect/turf_decal/trimline/neutral/filled/line,
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
+ dir = 8
+ },
+/turf/open/floor/iron,
+/area/station/engineering/gravity_generator)
"wGU" = (
/obj/machinery/door/window/brigdoor/right/directional/east{
name = "Medical Cell";
@@ -102972,7 +102975,7 @@ bVW
xdC
uKK
nFu
-qeq
+ocw
fal
akJ
tbc
@@ -103228,8 +103231,8 @@ pcO
iKr
ofZ
uKK
-ajF
-kWp
+fTF
+nNa
fal
akK
rvY
@@ -103743,7 +103746,7 @@ mIU
hmI
uKK
ajF
-uPi
+kzf
fal
akK
ixT
@@ -103999,8 +104002,8 @@ bKu
bVW
swg
uKK
-wtS
-bzP
+ajF
+wGQ
fal
aks
lJv
@@ -104256,8 +104259,8 @@ fal
fal
eSU
wSh
-vyD
-joq
+crm
+mds
fal
akI
pib
@@ -172639,7 +172642,7 @@ bWk
svF
xrG
kow
-wDt
+pwj
jqY
jqY
jqY
@@ -173147,7 +173150,7 @@ whz
aaa
aaa
ugt
-kOL
+srx
vrJ
aPS
tMb
@@ -185801,7 +185804,7 @@ jLx
ffe
mgi
pIQ
-llW
+hhf
xZx
rSB
dVM
@@ -186314,7 +186317,7 @@ mYB
njC
aoh
iUO
-kXq
+vTD
lxi
njC
mEb
diff --git a/_maps/shuttles/arrival_birdshot.dmm b/_maps/shuttles/arrival_birdshot.dmm
index 2288db6bbe2..d884c22d8db 100644
--- a/_maps/shuttles/arrival_birdshot.dmm
+++ b/_maps/shuttles/arrival_birdshot.dmm
@@ -62,6 +62,11 @@
/obj/machinery/light/cold/directional/north,
/turf/open/floor/mineral/titanium/blue,
/area/shuttle/arrival)
+"x" = (
+/obj/effect/spawner/structure/window/reinforced/shuttle,
+/obj/structure/fans/tiny/invisible,
+/turf/open/floor/plating,
+/area/shuttle/arrival)
"B" = (
/turf/open/floor/mineral/titanium/blue,
/area/shuttle/arrival)
@@ -69,6 +74,7 @@
/obj/machinery/door/airlock/titanium{
name = "Arrivals Shuttle Airlock"
},
+/obj/structure/fans/tiny,
/turf/open/floor/mineral/titanium/blue,
/area/shuttle/arrival)
"J" = (
@@ -128,20 +134,20 @@
(1,1,1) = {"
a
-Q
-Q
-Q
-Q
-Q
+x
+x
+x
+x
+x
a
"}
(2,1,1) = {"
a
-Q
+x
f
n
R
-Q
+x
a
"}
(3,1,1) = {"
@@ -172,22 +178,22 @@ B
F
"}
(6,1,1) = {"
-Q
+x
U
B
U
B
U
-Q
+x
"}
(7,1,1) = {"
-Q
+x
U
B
U
B
U
-Q
+x
"}
(8,1,1) = {"
V
@@ -204,7 +210,7 @@ Q
L
q
w
-Q
+x
a
"}
(10,1,1) = {"
@@ -217,22 +223,22 @@ q
V
"}
(11,1,1) = {"
-Q
+x
U
B
U
B
U
-Q
+x
"}
(12,1,1) = {"
-Q
+x
U
B
U
B
U
-Q
+x
"}
(13,1,1) = {"
F
diff --git a/_maps/shuttles/arrival_box.dmm b/_maps/shuttles/arrival_box.dmm
index 3d4a8769d4c..53d704515bb 100644
--- a/_maps/shuttles/arrival_box.dmm
+++ b/_maps/shuttles/arrival_box.dmm
@@ -9,10 +9,12 @@
/obj/machinery/door/airlock/titanium{
name = "Arrivals Shuttle Airlock"
},
+/obj/structure/fans/tiny,
/turf/open/floor/plating,
/area/shuttle/arrival)
"d" = (
/obj/effect/spawner/structure/window/reinforced/shuttle,
+/obj/structure/fans/tiny/invisible,
/turf/open/floor/plating,
/area/shuttle/arrival)
"e" = (
diff --git a/_maps/shuttles/arrival_delta.dmm b/_maps/shuttles/arrival_delta.dmm
index 649c16bdcf4..527b50f66c3 100644
--- a/_maps/shuttles/arrival_delta.dmm
+++ b/_maps/shuttles/arrival_delta.dmm
@@ -39,6 +39,7 @@
/area/shuttle/arrival)
"ah" = (
/obj/effect/spawner/structure/window/reinforced/shuttle,
+/obj/structure/fans/tiny/invisible,
/turf/open/floor/plating,
/area/shuttle/arrival)
"ai" = (
@@ -156,6 +157,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 4
},
+/obj/structure/fans/tiny,
/turf/open/floor/iron/white,
/area/shuttle/arrival)
"ap" = (
diff --git a/_maps/shuttles/arrival_donut.dmm b/_maps/shuttles/arrival_donut.dmm
index e8ff316a69e..e8947674b7c 100644
--- a/_maps/shuttles/arrival_donut.dmm
+++ b/_maps/shuttles/arrival_donut.dmm
@@ -38,6 +38,7 @@
/area/shuttle/arrival)
"k" = (
/obj/machinery/door/airlock/titanium,
+/obj/structure/fans/tiny,
/turf/open/floor/plating,
/area/shuttle/arrival)
"l" = (
@@ -55,6 +56,7 @@
/area/shuttle/arrival)
"o" = (
/obj/effect/spawner/structure/window/reinforced/shuttle,
+/obj/structure/fans/tiny/invisible,
/turf/open/floor/plating,
/area/shuttle/arrival)
"p" = (
diff --git a/_maps/shuttles/arrival_kilo.dmm b/_maps/shuttles/arrival_kilo.dmm
index 3fd328965de..b59cf8d160d 100644
--- a/_maps/shuttles/arrival_kilo.dmm
+++ b/_maps/shuttles/arrival_kilo.dmm
@@ -16,6 +16,7 @@
/obj/effect/turf_decal/stripes/line{
dir = 1
},
+/obj/structure/fans/tiny,
/turf/open/floor/mineral/plastitanium,
/area/shuttle/arrival)
"ae" = (
@@ -99,6 +100,7 @@
dir = 8
},
/obj/effect/spawner/structure/window/reinforced/shuttle,
+/obj/structure/fans/tiny/invisible,
/turf/open/floor/plating,
/area/shuttle/arrival)
"ap" = (
@@ -298,6 +300,11 @@
},
/turf/open/floor/mineral/plastitanium,
/area/shuttle/arrival)
+"lA" = (
+/obj/effect/spawner/structure/window/reinforced/shuttle,
+/obj/structure/fans/tiny/invisible,
+/turf/open/floor/plating,
+/area/shuttle/arrival)
"rV" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -349,7 +356,7 @@ aX
aW
aQ
aY
-af
+lA
"}
(5,1,1) = {"
ae
@@ -367,7 +374,7 @@ rV
ay
aV
aN
-af
+lA
"}
(7,1,1) = {"
af
@@ -376,7 +383,7 @@ rV
az
aV
aN
-af
+lA
"}
(8,1,1) = {"
af
@@ -385,7 +392,7 @@ rV
ab
aV
aN
-af
+lA
"}
(9,1,1) = {"
ac
@@ -435,9 +442,9 @@ ag
(14,1,1) = {"
ag
ac
-af
-af
-af
+lA
+lA
+lA
ac
ag
"}
diff --git a/_maps/shuttles/arrival_northstar.dmm b/_maps/shuttles/arrival_northstar.dmm
index 888a497bc58..fadde8f9df4 100644
--- a/_maps/shuttles/arrival_northstar.dmm
+++ b/_maps/shuttles/arrival_northstar.dmm
@@ -12,6 +12,7 @@
/obj/machinery/door/airlock/survival_pod/glass{
name = "Arrivals Shuttle Airlock"
},
+/obj/structure/fans/tiny,
/turf/open/floor/plating,
/area/shuttle/arrival)
"d" = (
@@ -183,6 +184,7 @@
/area/shuttle/arrival)
"Z" = (
/obj/effect/spawner/structure/window/survival_pod,
+/obj/structure/fans/tiny/invisible,
/turf/open/floor/plating,
/area/shuttle/arrival)
diff --git a/_maps/shuttles/arrival_pubby.dmm b/_maps/shuttles/arrival_pubby.dmm
index 8f2ecdab58c..e534fd01a40 100644
--- a/_maps/shuttles/arrival_pubby.dmm
+++ b/_maps/shuttles/arrival_pubby.dmm
@@ -9,10 +9,12 @@
/obj/machinery/door/airlock/titanium{
name = "Arrivals Shuttle Airlock"
},
+/obj/structure/fans/tiny,
/turf/open/floor/plating,
/area/shuttle/arrival)
"d" = (
/obj/effect/spawner/structure/window/reinforced/shuttle,
+/obj/structure/fans/tiny/invisible,
/turf/open/floor/plating,
/area/shuttle/arrival)
"e" = (
@@ -53,6 +55,7 @@
name = "Ship Shutters"
},
/obj/effect/spawner/structure/window/reinforced/shuttle,
+/obj/structure/fans/tiny/invisible,
/turf/open/floor/plating,
/area/shuttle/arrival)
"n" = (
diff --git a/_maps/shuttles/infiltrator_advanced.dmm b/_maps/shuttles/infiltrator_advanced.dmm
index 1f048327921..c9123066874 100644
--- a/_maps/shuttles/infiltrator_advanced.dmm
+++ b/_maps/shuttles/infiltrator_advanced.dmm
@@ -1935,7 +1935,7 @@
/turf/open/floor/mineral/plastitanium,
/area/shuttle/syndicate/armory)
"tP" = (
-/obj/machinery/power/smes/full,
+/obj/machinery/power/smes/super/full,
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/delivery,
/obj/structure/sign/warning/electric_shock/directional/north,
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/_maps/shuttles/ruin_pirate_cutter.dmm b/_maps/shuttles/ruin_pirate_cutter.dmm
index f09f996426d..425bdef5e08 100644
--- a/_maps/shuttles/ruin_pirate_cutter.dmm
+++ b/_maps/shuttles/ruin_pirate_cutter.dmm
@@ -14,20 +14,6 @@
/obj/effect/turf_decal/tile/red/half/contrasted,
/turf/open/floor/iron,
/area/shuttle/ruin/caravan/pirate)
-"cI" = (
-/obj/structure/bed{
- dir = 4
- },
-/obj/item/bedsheet/pirate{
- dir = 4
- },
-/obj/machinery/airalarm/directional/west,
-/obj/effect/mapping_helpers/airalarm/all_access,
-/obj/effect/turf_decal/tile/red{
- dir = 8
- },
-/turf/open/floor/iron/dark,
-/area/shuttle/ruin/caravan/pirate)
"dS" = (
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
@@ -52,12 +38,6 @@
/obj/item/reagent_containers/cup/glass/bottle/rum,
/turf/open/floor/iron/dark,
/area/shuttle/ruin/caravan/pirate)
-"fO" = (
-/obj/machinery/light/small/directional/south,
-/obj/structure/bed,
-/obj/item/bedsheet/pirate,
-/turf/open/floor/iron/dark,
-/area/shuttle/ruin/caravan/pirate)
"ge" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on,
/obj/effect/decal/cleanable/dirt,
@@ -249,12 +229,6 @@
},
/turf/open/floor/plating,
/area/shuttle/ruin/caravan/pirate)
-"qL" = (
-/obj/machinery/light/small/directional/north,
-/obj/structure/bed,
-/obj/item/bedsheet/pirate,
-/turf/open/floor/iron/dark,
-/area/shuttle/ruin/caravan/pirate)
"qU" = (
/obj/structure/table,
/obj/machinery/light/small/directional/west,
@@ -318,15 +292,6 @@
},
/turf/open/floor/plating,
/area/shuttle/ruin/caravan/pirate)
-"vt" = (
-/obj/structure/table,
-/obj/machinery/door/window/right/directional/south{
- name = "Weapon Storage"
- },
-/obj/item/gun/energy/laser,
-/obj/effect/turf_decal/tile/neutral/fourcorners,
-/turf/open/floor/iron/dark,
-/area/shuttle/ruin/caravan/pirate)
"vT" = (
/obj/structure/table,
/obj/item/circular_saw,
@@ -376,6 +341,12 @@
},
/turf/closed/wall/mineral/plastitanium,
/area/shuttle/ruin/caravan/pirate)
+"wV" = (
+/obj/machinery/light/small/directional/north,
+/obj/structure/bed,
+/obj/item/bedsheet/pirate,
+/turf/open/floor/iron/dark,
+/area/shuttle/ruin/caravan/pirate)
"xb" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on{
dir = 4
@@ -526,6 +497,26 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/shuttle/ruin/caravan/pirate)
+"GL" = (
+/obj/structure/bed{
+ dir = 4
+ },
+/obj/item/bedsheet/pirate{
+ dir = 4
+ },
+/obj/machinery/airalarm/directional/west,
+/obj/effect/mapping_helpers/airalarm/all_access,
+/obj/effect/turf_decal/tile/red{
+ dir = 8
+ },
+/turf/open/floor/iron/dark,
+/area/shuttle/ruin/caravan/pirate)
+"Ha" = (
+/obj/machinery/light/small/directional/south,
+/obj/structure/bed,
+/obj/item/bedsheet/pirate,
+/turf/open/floor/iron/dark,
+/area/shuttle/ruin/caravan/pirate)
"Hb" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
dir = 5
@@ -533,6 +524,14 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron,
/area/shuttle/ruin/caravan/pirate)
+"Hj" = (
+/obj/machinery/power/smes/super/full,
+/obj/effect/turf_decal/stripes/line{
+ dir = 5
+ },
+/obj/structure/cable,
+/turf/open/floor/plating,
+/area/shuttle/ruin/caravan/pirate)
"Hl" = (
/obj/machinery/porta_turret/syndicate/pod{
dir = 6;
@@ -558,6 +557,15 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/shuttle/ruin/caravan/pirate)
+"Iu" = (
+/obj/structure/table,
+/obj/machinery/door/window/right/directional/south{
+ name = "Weapon Storage"
+ },
+/obj/item/gun/energy/laser,
+/obj/effect/turf_decal/tile/neutral/fourcorners,
+/turf/open/floor/iron/dark,
+/area/shuttle/ruin/caravan/pirate)
"Jv" = (
/turf/template_noop,
/area/template_noop)
@@ -752,14 +760,6 @@
dir = 9
},
/area/shuttle/ruin/caravan/pirate)
-"We" = (
-/obj/machinery/power/smes/full,
-/obj/effect/turf_decal/stripes/line{
- dir = 5
- },
-/obj/structure/cable,
-/turf/open/floor/plating,
-/area/shuttle/ruin/caravan/pirate)
"Wi" = (
/obj/effect/mapping_helpers/airlock/cyclelink_helper{
dir = 1
@@ -820,18 +820,6 @@
},
/turf/open/floor/plating,
/area/shuttle/ruin/caravan/pirate)
-"Yu" = (
-/obj/structure/bed{
- dir = 4
- },
-/obj/item/bedsheet/pirate{
- dir = 4
- },
-/obj/machinery/firealarm/directional/west,
-/turf/open/floor/iron/dark/side{
- dir = 6
- },
-/area/shuttle/ruin/caravan/pirate)
"Yy" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
dir = 8
@@ -844,6 +832,18 @@
/obj/effect/turf_decal/bot,
/turf/open/floor/plating,
/area/shuttle/ruin/caravan/pirate)
+"Zq" = (
+/obj/structure/bed{
+ dir = 4
+ },
+/obj/item/bedsheet/pirate{
+ dir = 4
+ },
+/obj/machinery/firealarm/directional/west,
+/turf/open/floor/iron/dark/side{
+ dir = 6
+ },
+/area/shuttle/ruin/caravan/pirate)
"ZU" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
dir = 5
@@ -889,7 +889,7 @@ uV
DQ
xb
Kc
-We
+Hj
PC
es
Kc
@@ -994,7 +994,7 @@ Ns
Hb
wP
Kc
-vt
+Iu
AW
jc
jx
@@ -1022,9 +1022,9 @@ Jv
Kc
gS
Po
-Yu
+Zq
Wo
-cI
+GL
Mk
pg
Kc
@@ -1035,13 +1035,13 @@ Jv
Jv
Jv
Kc
-qL
+wV
Ye
nT
wh
Ir
CI
-fO
+Ha
Kc
Jv
Jv
diff --git a/_maps/shuttles/ruin_syndicate_dropship.dmm b/_maps/shuttles/ruin_syndicate_dropship.dmm
index 449c21eb56a..dc3e7b68a7b 100644
--- a/_maps/shuttles/ruin_syndicate_dropship.dmm
+++ b/_maps/shuttles/ruin_syndicate_dropship.dmm
@@ -376,7 +376,7 @@
/turf/open/floor/pod/dark,
/area/shuttle/ruin/caravan/syndicate3)
"Oe" = (
-/obj/machinery/power/smes/full,
+/obj/machinery/power/smes/super/full,
/obj/effect/turf_decal/stripes/line{
dir = 5
},
diff --git a/code/__DEFINES/_flags.dm b/code/__DEFINES/_flags.dm
index cdad8bba52a..09f2e040bd3 100644
--- a/code/__DEFINES/_flags.dm
+++ b/code/__DEFINES/_flags.dm
@@ -317,3 +317,5 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define EMOTE_VISIBLE (1<<1)
/// Is it an emote that should be shown regardless of blindness/deafness
#define EMOTE_IMPORTANT (1<<2)
+/// Emote only prints to runechat, not to the chat window
+#define EMOTE_RUNECHAT (1<<3)
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/say.dm b/code/__DEFINES/say.dm
index f82f4af2ddd..75366f07d48 100644
--- a/code/__DEFINES/say.dm
+++ b/code/__DEFINES/say.dm
@@ -119,5 +119,10 @@
-//Used in visible_message_flags, audible_message_flags and runechat_flags
+// Used in visible_message_flags, audible_message_flags and runechat_flags
+/// Automatically applies emote related spans/fonts/formatting to the message
#define EMOTE_MESSAGE (1<<0)
+/// By default, self_message will respect the visual / audible component of the message.
+/// Meaning that if the message is visual, and sourced from a blind mob, they will not see it.
+/// This flag skips that behavior, and will always show the self message to the mob.
+#define ALWAYS_SHOW_SELF_MESSAGE (1<<1)
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/subsystems.dm b/code/__DEFINES/subsystems.dm
index d7ec3e4669c..4281fba00cb 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -190,8 +190,8 @@
#define INIT_ORDER_PATH -50
#define INIT_ORDER_MATURITY_GUARD -60 //SKYRAT EDIT ADDITION
#define INIT_ORDER_DECAY -61 //SKYRAT EDIT ADDITION
+#define INIT_ORDER_POWERATOR_PENALITY -62 // SKYRAT EDIT ADDITION
#define INIT_ORDER_EXPLOSIONS -69
-#define INIT_ORDER_LOOT -70
#define INIT_ORDER_STATPANELS -97
#define INIT_ORDER_BAN_CACHE -98
#define INIT_ORDER_INIT_PROFILER -99 //Near the end, logs the costs of initialize
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 f1335f8ff58..4f67591f13c 100644
--- a/code/__DEFINES/traits/declarations.dm
+++ b/code/__DEFINES/traits/declarations.dm
@@ -522,6 +522,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/files.dm b/code/__HELPERS/files.dm
index f8cb06fd762..1cdf2efa896 100644
--- a/code/__HELPERS/files.dm
+++ b/code/__HELPERS/files.dm
@@ -33,6 +33,8 @@ GLOBAL_VAR_INIT(fileaccess_timer, 0)
var/confirmation = input(src, "Are you SURE you want to download all the files in this folder? (This will open [length(comp_flist)] prompt[length(comp_flist) == 1 ? "" : "s"])", "Confirmation") in list("Yes", "No")
if(confirmation != "Yes")
continue
+ log_admin("[key_name(src)] is downloading [length(comp_flist)] files from [path]") // SKYRAT EDIT -- ADDITION
+ message_admins("Admin [key_name_admin(src)] is downloading [length(comp_flist)] files from [path]") // SKYRAT EDIT -- ADDITION
for(var/file in comp_flist)
src << ftp(path + file)
return
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
index 7ae0feadea7..89a666093ee 100644
--- a/code/__HELPERS/global_lists.dm
+++ b/code/__HELPERS/global_lists.dm
@@ -172,8 +172,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/logging/_logging.dm b/code/__HELPERS/logging/_logging.dm
index 1c3e342428a..48780b36d3d 100644
--- a/code/__HELPERS/logging/_logging.dm
+++ b/code/__HELPERS/logging/_logging.dm
@@ -70,7 +70,7 @@ GLOBAL_LIST_INIT(testing_global_profiler, list("_PROFILE_NAME" = "Global"))
SEND_TEXT(world.log, text)
#endif
-#if defined(REFERENCE_DOING_IT_LIVE)
+#if defined(REFERENCE_TRACKING_LOG_APART)
#define log_reftracker(msg) log_harddel("## REF SEARCH [msg]")
/proc/log_harddel(text)
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/_compile_options.dm b/code/_compile_options.dm
index 8768a1e3622..0dcefa7a809 100644
--- a/code/_compile_options.dm
+++ b/code/_compile_options.dm
@@ -34,6 +34,8 @@
#define FIND_REF_NO_CHECK_TICK
#endif //ifdef GC_FAILURE_HARD_LOOKUP
+// Log references in their own file, rather then in runtimes.log
+//#define REFERENCE_TRACKING_LOG_APART
#endif //ifdef REFERENCE_TRACKING
/*
@@ -60,8 +62,24 @@
#define REFERENCE_TRACKING
// actually look for refs
#define GC_FAILURE_HARD_LOOKUP
+// Log references in their own file
+#define REFERENCE_TRACKING_LOG_APART
#endif // REFERENCE_DOING_IT_LIVE
+/// Sets up the reftracker to be used locally, to hunt for hard deletions
+/// Errors are logged to [log_dir]/harddels.log
+//#define REFERENCE_TRACKING_STANDARD
+#ifdef REFERENCE_TRACKING_STANDARD
+// compile the backend
+#define REFERENCE_TRACKING
+// actually look for refs
+#define GC_FAILURE_HARD_LOOKUP
+// spend ALL our time searching, not just part of it
+#define FIND_REF_NO_CHECK_TICK
+// Log references in their own file
+#define REFERENCE_TRACKING_LOG_APART
+#endif // REFERENCE_TRACKING_STANDARD
+
// If this is uncommented, we do a single run though of the game setup and tear down process with unit tests in between
// #define UNIT_TESTS
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index cce0793a5b1..a6e6003bd9b 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -344,6 +344,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/logging.dm b/code/_globalvars/logging.dm
index d91116cedd1..2f05cedf316 100644
--- a/code/_globalvars/logging.dm
+++ b/code/_globalvars/logging.dm
@@ -33,7 +33,7 @@ GLOBAL_PROTECT(##log_var_name);\
DECLARE_LOG(config_error_log, DONT_START_LOG)
DECLARE_LOG(perf_log, DONT_START_LOG) // Declared here but name is set in time_track subsystem
-#ifdef REFERENCE_DOING_IT_LIVE
+#ifdef REFERENCE_TRACKING_LOG_APART
DECLARE_LOG_NAMED(harddel_log, "harddels", START_LOG)
#endif
diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm
index 749dfd49b21..469cbcee76d 100644
--- a/code/_globalvars/traits/_traits.dm
+++ b/code/_globalvars/traits/_traits.dm
@@ -499,6 +499,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 5af3477435b..549d33ac7b3 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/dynamic/dynamic_rulesets_midround.dm b/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm
index a5600e16a3c..f6db90b5854 100644
--- a/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm
+++ b/code/controllers/subsystem/dynamic/dynamic_rulesets_midround.dm
@@ -305,25 +305,29 @@
cost = 10
required_type = /mob/living/silicon/ai
blocking_rules = list(/datum/dynamic_ruleset/roundstart/malf_ai)
+ // AIs are technically considered "Ghost roles" as far as candidate selection are concerned
+ // So we need to allow it here. We filter of actual ghost role AIs (charlie) via trim_candidates ourselves
+ restrict_ghost_roles = FALSE
/datum/dynamic_ruleset/midround/malf/trim_candidates()
..()
- candidates = living_players
- for(var/mob/living/player in candidates)
- if(!isAI(player))
- candidates -= player
+ candidates = list()
+ for(var/mob/living/silicon/ai/player in living_players)
+ if(!is_station_level(player.z))
continue
-
- if(is_centcom_level(player.z))
- candidates -= player
+ if(isnull(player.mind))
continue
+ if(player.mind.special_role || length(player.mind.antag_datums))
+ continue
+ candidates += player
- if(player.mind && (player.mind.special_role || player.mind.antag_datums?.len > 0))
- candidates -= player
+/datum/dynamic_ruleset/midround/malf/ready(forced)
+ if(!check_candidates())
+ log_dynamic("FAIL: No valid AI found for the Malfunctioning AI ruleset.")
+ return FALSE
+ return ..()
/datum/dynamic_ruleset/midround/malf/execute()
- if(!candidates || !candidates.len)
- return FALSE
var/mob/living/silicon/ai/new_malf_ai = pick_n_take(candidates)
assigned += new_malf_ai.mind
var/datum/antagonist/malf_ai/malf_antag_datum = new
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/pai.dm b/code/controllers/subsystem/pai.dm
index 58f4eda0a05..e3d47a5c0cd 100644
--- a/code/controllers/subsystem/pai.dm
+++ b/code/controllers/subsystem/pai.dm
@@ -17,6 +17,11 @@ SUBSYSTEM_DEF(pai)
ui.open()
ui.set_autoupdate(FALSE)
+/datum/controller/subsystem/pai/Recover()
+ . = ..()
+ candidates = SSpai.candidates
+ pai_card_list = SSpai.pai_card_list
+
/datum/controller/subsystem/pai/ui_state(mob/user)
return GLOB.observer_state
@@ -35,13 +40,14 @@ SUBSYSTEM_DEF(pai)
. = ..()
if(.)
return TRUE
- var/datum/pai_candidate/candidate = candidates[usr.ckey]
- if(is_banned_from(usr.ckey, ROLE_PAI))
- to_chat(usr, span_warning("You are banned from playing pAI!"))
+ var/mob/user = ui.user
+ var/datum/pai_candidate/candidate = candidates[user.ckey]
+ if(is_banned_from(user.ckey, ROLE_PAI))
+ to_chat(user, span_warning("You are banned from playing pAI!"))
ui.close()
return FALSE
if(isnull(candidate))
- to_chat(usr, span_warning("There was an error. Please resubmit."))
+ to_chat(user, span_warning("There was an error. Please resubmit."))
ui.close()
return FALSE
switch(action)
@@ -49,19 +55,19 @@ SUBSYSTEM_DEF(pai)
candidate.comments = trim(params["comments"], MAX_BROADCAST_LEN)
candidate.description = trim(params["description"], MAX_BROADCAST_LEN)
candidate.name = trim(params["name"], MAX_NAME_LEN)
- candidate.ckey = usr.ckey
+ candidate.ckey = user.ckey
candidate.ready = TRUE
ui.close()
- submit_alert()
+ submit_alert(user)
return TRUE
if("save")
candidate.comments = params["comments"]
candidate.description = params["description"]
candidate.name = params["name"]
- candidate.savefile_save(usr)
+ candidate.savefile_save(user)
return TRUE
if("load")
- candidate.savefile_load(usr)
+ candidate.savefile_load(user)
ui.send_full_update()
return TRUE
return FALSE
@@ -84,14 +90,14 @@ SUBSYSTEM_DEF(pai)
/**
* Pings all pAI cards on the station that new candidates are available.
*/
-/datum/controller/subsystem/pai/proc/submit_alert()
+/datum/controller/subsystem/pai/proc/submit_alert(mob/user)
if(submit_spam)
- to_chat(usr, span_warning("Your candidacy has been submitted, but pAI cards have been alerted too recently."))
+ to_chat(user, span_warning("Your candidacy has been submitted, but pAI cards have been alerted too recently."))
return FALSE
submit_spam = TRUE
for(var/obj/item/pai_card/pai_card as anything in pai_card_list)
if(!pai_card.pai)
pai_card.alert_update()
- to_chat(usr, span_notice("Your pAI candidacy has been submitted!"))
- addtimer(VARSET_CALLBACK(src, submit_spam, FALSE), PAI_SPAM_TIME, TIMER_UNIQUE | TIMER_STOPPABLE | TIMER_CLIENT_TIME | TIMER_DELETE_ME)
+ to_chat(user, span_notice("Your pAI candidacy has been submitted!"))
+ addtimer(VARSET_CALLBACK(src, submit_spam, FALSE), PAI_SPAM_TIME, TIMER_UNIQUE|TIMER_DELETE_ME)
return TRUE
diff --git a/code/controllers/subsystem/polling.dm b/code/controllers/subsystem/polling.dm
index 724651ebed7..7a74c344f60 100644
--- a/code/controllers/subsystem/polling.dm
+++ b/code/controllers/subsystem/polling.dm
@@ -79,13 +79,13 @@ SUBSYSTEM_DEF(polling)
for(var/mob/candidate_mob as anything in group)
if(!candidate_mob.client)
continue
- // Universal opt-out for all players if it's for a role.
- if(role && (!candidate_mob.client.prefs.read_preference(/datum/preference/toggle/ghost_roles)))
+ // Universal opt-out for all players.
+ if(!candidate_mob.client.prefs.read_preference(/datum/preference/toggle/ghost_roles))
continue
// Opt-out for admins whom are currently adminned.
- if(role && (!candidate_mob.client.prefs.read_preference(/datum/preference/toggle/ghost_roles_as_admin)) && candidate_mob.client.holder)
+ if((!candidate_mob.client.prefs.read_preference(/datum/preference/toggle/ghost_roles_as_admin)) && candidate_mob.client.holder)
continue
- if(role && !is_eligible(candidate_mob, role, check_jobban, ignore_category))
+ if(!is_eligible(candidate_mob, role, check_jobban, ignore_category))
continue
if(start_signed_up)
diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm
index 733b94d582a..dcca82fe6d8 100644
--- a/code/controllers/subsystem/statpanel.dm
+++ b/code/controllers/subsystem/statpanel.dm
@@ -192,6 +192,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..29250d16125 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++
@@ -72,7 +72,8 @@
/datum/ai_movement/proc/post_move(datum/move_loop/source, succeeded)
SIGNAL_HANDLER
var/datum/ai_controller/controller = source.extra_info
- if(succeeded != MOVELOOP_FAILURE)
- reset_pathing_failures(controller)
- return
- increment_pathing_failures(controller)
+ switch(succeeded)
+ if(MOVELOOP_SUCCESS)
+ reset_pathing_failures(controller)
+ if(MOVELOOP_FAILURE)
+ increment_pathing_failures(controller)
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/sisyphus_awarder.dm b/code/datums/components/sisyphus_awarder.dm
index 36fc344c746..2a18a2889fc 100644
--- a/code/datums/components/sisyphus_awarder.dm
+++ b/code/datums/components/sisyphus_awarder.dm
@@ -5,6 +5,8 @@
/datum/component/sisyphus_awarder
/// What poor sap is hauling this rock?
var/mob/living/sisyphus
+ /// Reference to a place where it all started.
+ var/turf/bottom_of_the_hill
/datum/component/sisyphus_awarder/Initialize()
if (!istype(parent, /obj/item/boulder))
@@ -30,6 +32,7 @@
RegisterSignal(the_taker, COMSIG_ENTER_AREA, PROC_REF(on_bearer_changed_area))
RegisterSignal(the_taker, COMSIG_QDELETING, PROC_REF(on_dropped))
sisyphus = the_taker
+ bottom_of_the_hill = get_turf(the_taker)
/// If you ever drop this shit you fail the challenge
/datum/component/sisyphus_awarder/proc/on_dropped()
@@ -45,5 +48,21 @@
return
if (entered_area.type != /area/centcom/central_command_areas/evacuation)
return // Don't istype because taking pods doesn't count
+
chosen_one.client?.give_award(/datum/award/achievement/misc/sisyphus, chosen_one)
+ play_reward_scene()
+
qdel(src)
+
+/// Sends the player back to the Lavaland and plays a funny sound
+/datum/component/sisyphus_awarder/proc/play_reward_scene()
+ if(isnull(bottom_of_the_hill))
+ return // This probably shouldn't happen, but...
+
+ podspawn(list(
+ "path" = /obj/structure/closet/supplypod/centcompod/sisyphus,
+ "target" = get_turf(sisyphus),
+ "reverse_dropoff_coords" = list(bottom_of_the_hill.x, bottom_of_the_hill.y, bottom_of_the_hill.z),
+ ))
+
+ SEND_SOUND(sisyphus, 'sound/ambience/music/sisyphus/sisyphus.ogg')
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/eigenstate.dm b/code/datums/eigenstate.dm
index 3bba7463209..b25fa657eb6 100644
--- a/code/datums/eigenstate.dm
+++ b/code/datums/eigenstate.dm
@@ -119,8 +119,7 @@ GLOBAL_DATUM_INIT(eigenstate_manager, /datum/eigenstate_manager, new)
spark_time = world.time
//Calls a special proc for the atom if needed (closets use bust_open())
SEND_SIGNAL(eigen_target, COMSIG_EIGENSTATE_ACTIVATE)
- if(!subtle)
- return COMPONENT_CLOSET_INSERT_INTERRUPT
+ return COMPONENT_CLOSET_INSERT_INTERRUPT
///Prevents tool use on the item
/datum/eigenstate_manager/proc/tool_interact(atom/source, mob/user, obj/item/item)
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/emotes.dm b/code/datums/emotes.dm
index e384aa1bcce..e10f4478cbf 100644
--- a/code/datums/emotes.dm
+++ b/code/datums/emotes.dm
@@ -88,25 +88,19 @@
* Returns TRUE if it was able to run the emote, FALSE otherwise.
*/
/datum/emote/proc/run_emote(mob/user, params, type_override, intentional = FALSE)
- . = TRUE
if(!can_run_emote(user, TRUE, intentional))
return FALSE
if(SEND_SIGNAL(user, COMSIG_MOB_PRE_EMOTED, key, params, type_override, intentional) & COMPONENT_CANT_EMOTE)
- return // We don't return FALSE because the error output would be incorrect, provide your own if necessary.
+ return TRUE // We don't return FALSE because the error output would be incorrect, provide your own if necessary.
var/msg = select_message_type(user, message, intentional)
if(params && message_param)
msg = select_param(user, params)
msg = replace_pronoun(user, msg)
-
if(!msg)
- return
+ return TRUE
user.log_message(msg, LOG_EMOTE)
- // SKYRAT EDIT START - Better emotes - Original: var/dchatmsg = "[user] [msg]"
- var/space = should_have_space_before_emote(html_decode(msg)[1]) ? " " : ""
- var/dchatmsg = "[user] [space][msg]"
- // SKYRAT EDIT END
var/tmp_sound = get_sound(user)
if(tmp_sound && should_play_sound(user, intentional) && TIMER_COOLDOWN_FINISHED(user, type))
@@ -119,38 +113,143 @@
playsound(user, tmp_sound, sound_volume, vary)
//SKYRAT EDIT CHANGE END
- var/user_turf = get_turf(user)
- if (user.client)
- for(var/mob/ghost as anything in GLOB.dead_mob_list)
- if(!ghost.client || isnewplayer(ghost))
+ var/is_important = emote_type & EMOTE_IMPORTANT
+ var/is_visual = emote_type & EMOTE_VISIBLE
+ var/is_audible = emote_type & EMOTE_AUDIBLE
+ var/space = should_have_space_before_emote(html_decode(msg)[1]) ? " " : "" // SKYRAT EDIT ADDITION
+
+ // Emote doesn't get printed to chat, runechat only
+ if(emote_type & EMOTE_RUNECHAT)
+ for(var/mob/viewer as anything in viewers(user))
+ if(isnull(viewer.client))
continue
- if(get_chat_toggles(ghost.client) & CHAT_GHOSTSIGHT && !(ghost in viewers(user_turf, null)))
- if(pref_check_emote(ghost)) // SKYRAT EDIT ADDITION - Pref checked emotes
- ghost.show_message("[FOLLOW_LINK(ghost, user)] [dchatmsg] ") // SKYRAT EDIT CHANGE - Indented
- if(emote_type & (EMOTE_AUDIBLE | EMOTE_VISIBLE)) //emote is audible and visible
- user.audible_message(msg, deaf_message = "You see how [user] [space][msg] ", audible_message_flags = EMOTE_MESSAGE, separation = space, pref_to_check = pref_to_check) // SKYRAT EDIT - Better emotes - ORIGINAL: user.audible_message(msg, deaf_message = "You see how [user] [msg] ", audible_message_flags = EMOTE_MESSAGE)
- else if(emote_type & EMOTE_VISIBLE) //emote is only visible
- user.visible_message(msg, visible_message_flags = EMOTE_MESSAGE, separation = space, pref_to_check = pref_to_check) // SKYRAT EDIT - Better emotes - ORIGINAL: user.visible_message(msg, visible_message_flags = EMOTE_MESSAGE)
- if(emote_type & EMOTE_IMPORTANT)
- for(var/mob/living/viewer in viewers())
- if(viewer.is_blind() && !viewer.can_hear())
- if(pref_check_emote(viewer)) // SKYRAT EDIT ADDITION - Pref checked emotes
- to_chat(viewer, msg) // SKYRAT EDIT CHANGE - Indented
+ if(!is_important && viewer != user && (!is_visual || !is_audible))
+ if(is_audible && !viewer.can_hear())
+ continue
+ if(is_visual && viewer.is_blind())
+ continue
+ // SKYRAT EDIT BEGIN - Pref checked emotes
+ if(!pref_check_emote(viewer))
+ continue
+ // SKYRAT EDIT END
+ if(user.runechat_prefs_check(viewer, EMOTE_MESSAGE))
+ viewer.create_chat_message(
+ speaker = user,
+ raw_message = msg,
+ runechat_flags = EMOTE_MESSAGE,
+ )
+ else if(is_important)
+ to_chat(viewer, "[user] [msg] ")
+ else if(is_audible && is_visual)
+ viewer.show_message(
+ "[user] [msg] ", MSG_AUDIBLE,
+ "You see how [user] [msg] ", MSG_VISUAL,
+ )
+ else if(is_audible)
+ viewer.show_message("[user] [msg] ", MSG_AUDIBLE)
+ else if(is_visual)
+ viewer.show_message("[user] [msg] ", MSG_VISUAL)
+ return TRUE // Early exit so no dchat message
+
+ // The emote has some important information, and should always be shown to the user
+ else if(is_important)
+ for(var/mob/viewer as anything in viewers(user))
+ // SKYRAT EDIT BEGIN - Pref checked emotes
+ if(!pref_check_emote(viewer))
+ continue
+ // SKYRAT EDIT END
+ to_chat(viewer, "[user] [msg] ")
+ if(user.runechat_prefs_check(viewer, EMOTE_MESSAGE))
+ viewer.create_chat_message(
+ speaker = user,
+ raw_message = msg,
+ runechat_flags = EMOTE_MESSAGE,
+ )
+ // Emotes has both an audible and visible component
+ // Prioritize audible, and provide a visible message if the user is deaf
+ else if(is_visual && is_audible)
+ user.audible_message(
+ message = msg,
+ deaf_message = "You see how [user] [msg] ",
+ self_message = msg,
+ audible_message_flags = EMOTE_MESSAGE|ALWAYS_SHOW_SELF_MESSAGE,
+ separation = space, // SKYRAT EDIT ADDITION
+ pref_to_check = pref_to_check // SKYRAT EDIT ADDITION - Pref checked emotes
+ )
+ // Emote is entirely audible, no visible component
+ else if(is_audible)
+ user.audible_message(
+ message = msg,
+ self_message = msg,
+ audible_message_flags = EMOTE_MESSAGE,
+ separation = space, // SKYRAT EDIT ADDITION
+ pref_to_check = pref_to_check // SKYRAT EDIT ADDITION - Pref checked emotes
+ )
+ // Emote is entirely visible, no audible component
+ else if(is_visual)
+ user.visible_message(
+ message = msg,
+ self_message = msg,
+ visible_message_flags = EMOTE_MESSAGE|ALWAYS_SHOW_SELF_MESSAGE,
+ separation = space, // SKYRAT EDIT ADDITION
+ pref_to_check = pref_to_check // SKYRAT EDIT ADDITION - Pref checked emotes
+ )
+ else
+ CRASH("Emote [type] has no valid emote type set!")
// SKYRAT EDIT -- BEGIN -- ADDITION -- AI QOL - RELAY EMOTES OVER HOLOPADS
var/obj/effect/overlay/holo_pad_hologram/hologram = GLOB.hologram_impersonators[user]
if(hologram)
- if(emote_type & (EMOTE_AUDIBLE | EMOTE_VISIBLE))
- hologram.audible_message(msg, deaf_message = span_emote("You see how [user] [msg]"), audible_message_flags = EMOTE_MESSAGE, pref_to_check = pref_to_check)
- else if(emote_type & EMOTE_VISIBLE)
- hologram.visible_message(msg, visible_message_flags = EMOTE_MESSAGE, pref_to_check = pref_to_check)
- if(emote_type & EMOTE_IMPORTANT)
+ if(is_important)
for(var/mob/living/viewer in viewers(world.view, hologram))
- if(viewer.is_blind() && !viewer.can_hear())
- if(pref_check_emote(viewer))
- to_chat(viewer, msg)
+ if(!pref_check_emote(viewer))
+ continue
+ to_chat(viewer, msg)
+ else if(is_visual && is_audible)
+ hologram.audible_message(
+ message = msg,
+ deaf_message = "You see how [user] [msg] ",
+ self_message = msg,
+ audible_message_flags = EMOTE_MESSAGE|ALWAYS_SHOW_SELF_MESSAGE,
+ separation = space,
+ pref_to_check = pref_to_check,
+ )
+ else if(is_audible)
+ hologram.audible_message(
+ message = msg,
+ self_message = msg,
+ audible_message_flags = EMOTE_MESSAGE,
+ separation = space,
+ pref_to_check = pref_to_check,
+ )
+ else if(is_visual)
+ hologram.visible_message(
+ message = msg,
+ self_message = msg,
+ visible_message_flags = EMOTE_MESSAGE|ALWAYS_SHOW_SELF_MESSAGE,
+ separation = space,
+ pref_to_check = pref_to_check,
+ )
// SKYRAT EDIT -- END
+ if(!isnull(user.client))
+ var/dchatmsg = "[user] [space][msg]" // SKYRAT EDIT - Better emotes - Original: var/dchatmsg = "[user] [msg]"
+ for(var/mob/ghost as anything in GLOB.dead_mob_list - viewers(get_turf(user)))
+ if(isnull(ghost.client) || isnewplayer(ghost))
+ continue
+ if(!(get_chat_toggles(ghost.client) & CHAT_GHOSTSIGHT))
+ continue
+ // SKYRAT EDIT BEGIN - Pref checked emotes
+ if(!pref_check_emote(ghost))
+ continue
+ // SKYRAT EDIT END
+ ghost.show_message("[FOLLOW_LINK(ghost, user)] [dchatmsg] ") // SKYRAT EDIT CHANGE - Indented
+
+
+ return TRUE
+
+
+
/**
* For handling emote cooldown, return true to allow the emote to happen.
*
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/computer/orders/order_items/mining/order_toys.dm b/code/game/machinery/computer/orders/order_items/mining/order_toys.dm
index 7ee4c6cfba8..fab03cabaa4 100644
--- a/code/game/machinery/computer/orders/order_items/mining/order_toys.dm
+++ b/code/game/machinery/computer/orders/order_items/mining/order_toys.dm
@@ -25,7 +25,7 @@
item_path = /obj/item/mine_bot_upgrade/regnerative_shield
cost_per_order = 500
-/datum/orderable_item/toys_drones/drone_shield
+/datum/orderable_item/toys_drones/drone_remote
item_path = /obj/item/minebot_remote_control
cost_per_order = 500
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 0ff933cc9b1..d166d06fa7f 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -889,7 +889,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 e6c3e80c575..3d92ccd437e 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -229,6 +229,8 @@
var/current_skin
///// List of options to reskin.
var/list/unique_reskin
+ /// Do we apply a click cooldown when resisting this object if it is restraining them?
+ var/resist_cooldown = CLICK_CD_BREAKOUT
/obj/item/Initialize(mapload)
if(attack_verb_continuous)
@@ -921,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/circuitboards/machines/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm
index faf7c76e502..bc6076fe028 100644
--- a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm
+++ b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm
@@ -349,6 +349,9 @@
greyscale_colors = CIRCUIT_COLOR_ENGINEERING
build_path = /obj/machinery/rnd/production/techfab/department/engineering
+/obj/item/circuitboard/machine/smes/super
+ def_components = list(/obj/item/stock_parts/cell = /obj/item/stock_parts/cell/super/empty)
+
/obj/item/circuitboard/machine/thermomachine
name = "Thermomachine"
greyscale_colors = CIRCUIT_COLOR_ENGINEERING
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index 4cb077808a8..6e4dbd233ba 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)
. = ..()
@@ -775,7 +775,7 @@
/obj/item/toy/crayon/spraycan/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
. = ..()
- if(!user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS))
+ if(!user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS|SILENT_ADJACENCY))
return .
if(has_cap)
@@ -786,7 +786,7 @@
/obj/item/toy/crayon/spraycan/add_item_context(datum/source, list/context, atom/target, mob/living/user)
. = ..()
- if(!user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS))
+ if(!user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS|SILENT_ADJACENCY))
return .
context[SCREENTIP_CONTEXT_LMB] = "Paint"
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 2d8912fb242..cfa3bafbc64 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/handcuffs.dm b/code/game/objects/items/handcuffs.dm
index 1d8adbbb278..192842e6447 100644
--- a/code/game/objects/items/handcuffs.dm
+++ b/code/game/objects/items/handcuffs.dm
@@ -175,6 +175,7 @@
desc = "Fake handcuffs meant for gag purposes."
breakouttime = 1 SECONDS
restraint_strength = HANDCUFFS_TYPE_WEAK
+ resist_cooldown = CLICK_CD_SLOW
/**
* # Cable restraints
@@ -356,6 +357,7 @@
name = "fake zipties"
desc = "Fake zipties meant for gag purposes."
breakouttime = 1 SECONDS
+ resist_cooldown = CLICK_CD_SLOW
/obj/item/restraints/handcuffs/cable/zipties/fake/used
desc = "A pair of broken fake zipties."
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 bdb8387d95f..5956c04eaf3 100644
--- a/code/game/objects/items/robot/items/hypo.dm
+++ b/code/game/objects/items/robot/items/hypo.dm
@@ -108,7 +108,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)
@@ -309,7 +309,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
@@ -322,7 +322,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
@@ -394,7 +394,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 d0fd45064d2..f1f922ba5a6 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 02cbd3f7239..3dd2dbb3490 100644
--- a/code/game/objects/items/spear.dm
+++ b/code/game/objects/items/spear.dm
@@ -213,6 +213,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..48fae041de4 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)
@@ -291,7 +294,7 @@
/// Make our arm do slashing effects
/datum/status_effect/golem/diamond/proc/set_arm_fluff(obj/item/bodypart/arm/arm)
- arm.unarmed_attack_verb = "slash"
+ arm.unarmed_attack_verbs = list("slash")
arm.grappled_attack_verb = "lacerate"
arm.unarmed_attack_effect = ATTACK_EFFECT_CLAW
arm.unarmed_attack_sound = 'sound/weapons/slash.ogg'
@@ -312,7 +315,7 @@
/datum/status_effect/golem/diamond/proc/reset_arm_fluff(obj/item/bodypart/arm/arm)
if (!arm)
return
- arm.unarmed_attack_verb = initial(arm.unarmed_attack_verb)
+ arm.unarmed_attack_verbs = initial(arm.unarmed_attack_verbs)
arm.unarmed_attack_effect = initial(arm.unarmed_attack_effect)
arm.unarmed_attack_sound = initial(arm.unarmed_attack_sound)
arm.unarmed_miss_sound = initial(arm.unarmed_miss_sound)
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/ai_core.dm b/code/game/objects/structures/ai_core.dm
index 6207a4031c1..5c219aaa4a9 100644
--- a/code/game/objects/structures/ai_core.dm
+++ b/code/game/objects/structures/ai_core.dm
@@ -12,6 +12,8 @@
var/datum/ai_laws/laws
var/obj/item/circuitboard/aicore/circuit
var/obj/item/mmi/core_mmi
+ /// only used in cases of AIs piloting mechs or shunted malf AIs, possible later use cases
+ var/mob/living/silicon/ai/remote_ai = null
/obj/structure/ai_core/Initialize(mapload)
. = ..()
@@ -58,11 +60,20 @@
update_appearance()
/obj/structure/ai_core/Destroy()
+ if(istype(remote_ai))
+ remote_ai.break_core_link()
+ remote_ai = null
QDEL_NULL(circuit)
QDEL_NULL(core_mmi)
QDEL_NULL(laws)
return ..()
+/obj/structure/ai_core/take_damage(damage_amount, damage_type, damage_flag, sound_effect, attack_dir, armour_penetration)
+ . = ..()
+ if(. > 0 && istype(remote_ai))
+ to_chat(remote_ai, span_danger("Your core is under attack!"))
+
+
/obj/structure/ai_core/deactivated
icon_state = "ai-empty"
anchored = TRUE
@@ -157,6 +168,8 @@
return ITEM_INTERACT_SUCCESS
/obj/structure/ai_core/attackby(obj/item/tool, mob/living/user, params)
+ if(remote_ai)
+ to_chat(remote_ai, span_danger("CORE TAMPERING DETECTED!"))
if(!anchored)
if(tool.tool_behaviour == TOOL_WELDER)
if(state != EMPTY_CORE)
@@ -295,8 +308,17 @@
if(tool.tool_behaviour == TOOL_CROWBAR && core_mmi)
tool.play_tool_sound(src)
balloon_alert(user, "removed [AI_CORE_BRAIN(core_mmi)]")
- core_mmi.forceMove(loc)
- return
+ if(remote_ai)
+ var/mob/living/silicon/ai/remoted_ai = remote_ai
+ remoted_ai.break_core_link()
+ if(!IS_MALF_AI(remoted_ai))
+ //don't pull back shunted malf AIs
+ remoted_ai.death(gibbed = TRUE, drop_mmi = FALSE)
+ ///the drop_mmi param determines whether the MMI is dropped at their current location
+ ///which in this case would be somewhere else, so we drop their MMI at the core instead
+ remoted_ai.make_mmi_drop_and_transfer(core_mmi, src)
+ core_mmi.forceMove(loc) //if they're malf, just drops a blank MMI, or if it's an incomplete shell
+ return //it drops the mmi that was put in before it was finished
if(GLASS_CORE)
if(tool.tool_behaviour == TOOL_CROWBAR)
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 d456a32b8d5..e8b99157465 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/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 731de224f8d..0f7d7a3f39b 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -593,6 +593,7 @@ ADMIN_VERB(debug_spell_requirements, R_DEBUG, "Debug Spell Requirements", "View
ADMIN_VERB(load_lazy_template, R_ADMIN, "Load/Jump Lazy Template", "Loads a lazy template and/or jumps to it.", ADMIN_CATEGORY_EVENTS)
var/list/choices = LAZY_TEMPLATE_KEY_LIST_ALL()
var/choice = tgui_input_list(user, "Key?", "Lazy Loader", choices)
+ var/teleport_to_template = tgui_input_list(user, "Jump to template after loading?", "Where to?", list("Yes", "No"))
if(!choice)
return
@@ -611,12 +612,13 @@ ADMIN_VERB(load_lazy_template, R_ADMIN, "Load/Jump Lazy Template", "Loads a lazy
to_chat(user, span_boldwarning("Failed to load template!"))
return
- if(!isobserver(user.mob))
- SSadmin_verbs.dynamic_invoke_verb(user, /datum/admin_verb/admin_ghost)
- user.mob.forceMove(reservation.bottom_left_turfs[1])
+ if(teleport_to_template == "Yes")
+ if(!isobserver(user.mob))
+ SSadmin_verbs.dynamic_invoke_verb(user, /datum/admin_verb/admin_ghost)
+ user.mob.forceMove(reservation.bottom_left_turfs[1])
+ to_chat(user, span_boldnicegreen("Template loaded, you have been moved to the bottom left of the reservation."))
message_admins("[key_name_admin(user)] has loaded lazy template '[choice]'")
- to_chat(user, span_boldnicegreen("Template loaded, you have been moved to the bottom left of the reservation."))
ADMIN_VERB(library_control, R_BAN, "Library Management", "List and manage the Library.", ADMIN_CATEGORY_MAIN)
if(!user.holder.library_manager)
diff --git a/code/modules/admin/sql_ban_system.dm b/code/modules/admin/sql_ban_system.dm
index 30c657e6ab5..407f321a470 100644
--- a/code/modules/admin/sql_ban_system.dm
+++ b/code/modules/admin/sql_ban_system.dm
@@ -428,6 +428,7 @@
ROLE_REV_HEAD,
ROLE_SENTIENT_DISEASE,
ROLE_SPIDER,
+ ROLE_SPY,
ROLE_SYNDICATE,
ROLE_TRAITOR,
ROLE_WIZARD,
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/verbs/getlogs.dm b/code/modules/admin/verbs/getlogs.dm
index bceac01cbe0..7dc1493e75b 100644
--- a/code/modules/admin/verbs/getlogs.dm
+++ b/code/modules/admin/verbs/getlogs.dm
@@ -12,6 +12,7 @@ ADMIN_VERB(get_current_logs, R_ADMIN, "Get Current Logs", "View or retrieve logf
if(file_spam_check())
return
+ log_admin("[key_name(src)] accessed file: [path]") // SKYRAT EDIT -- ADDITION
message_admins("[key_name_admin(src)] accessed file: [path]")
switch(tgui_alert(usr,"View (in game), Open (in your system's text editor), or Download?", path, list("View", "Open", "Download")))
if ("View")
diff --git a/code/modules/admin/verbs/possess.dm b/code/modules/admin/verbs/possess.dm
index a7e50840f5e..2949447b2ef 100644
--- a/code/modules/admin/verbs/possess.dm
+++ b/code/modules/admin/verbs/possess.dm
@@ -1,5 +1,5 @@
-ADMIN_VERB(possess, R_POSSESS, "Possess Obj", "Possess an object.", ADMIN_CATEGORY_OBJECT, obj/target in world)
+ADMIN_VERB_AND_CONTEXT_MENU(possess, R_POSSESS, "Possess Obj", "Possess an object.", ADMIN_CATEGORY_OBJECT, obj/target in world)
var/result = user.mob.AddComponent(/datum/component/object_possession, target)
if(isnull(result)) // trigger a safety movement just in case we yonk
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 "(READ ONLY) [var_name] = [_debug_variable_value(var_name, value, 0, src, sanitize = TRUE, display_flags = NONE)] "
+
+/mutable_appearance/appearance_mirror/vv_get_dropdown()
+ SHOULD_CALL_PARENT(FALSE)
+
+ . = list()
+ VV_DROPDOWN_OPTION("", "---")
+ VV_DROPDOWN_OPTION(VV_HK_CALLPROC, "Call Proc")
+ VV_DROPDOWN_OPTION(VV_HK_MARK, "Mark Object")
+ VV_DROPDOWN_OPTION(VV_HK_TAG, "Tag Datum")
+ VV_DROPDOWN_OPTION(VV_HK_DELETE, "Delete")
+ VV_DROPDOWN_OPTION(VV_HK_EXPOSE, "Show VV To Player")
+
+/proc/get_vv_appearance(mutable_appearance/appearance) // actually appearance yadeeyada
+ return new /mutable_appearance/appearance_mirror(appearance)
diff --git a/code/modules/admin/view_variables/debug_variables.dm b/code/modules/admin/view_variables/debug_variables.dm
index 8aea000a1a6..a4035acd014 100644
--- a/code/modules/admin/view_variables/debug_variables.dm
+++ b/code/modules/admin/view_variables/debug_variables.dm
@@ -30,6 +30,9 @@
// This is split into a seperate proc mostly to make errors that happen not break things too much
/proc/_debug_variable_value(name, value, level, datum/owner, sanitize, display_flags)
+ if(isappearance(value))
+ value = get_vv_appearance(value)
+
. = "DISPLAY_ERROR: ([value] [REF(value)])" // Make sure this line can never runtime
if(isnull(value))
@@ -49,10 +52,6 @@
return "/icon ([value] )"
#endif
- if(isappearance(value))
- var/image/actually_an_appearance = value
- return "/appearance ([actually_an_appearance.icon] )"
-
if(isfilter(value))
var/datum/filter_value = value
return "/filter ([filter_value.type] [REF(filter_value)] )"
diff --git a/code/modules/admin/view_variables/view_variables.dm b/code/modules/admin/view_variables/view_variables.dm
index b139ec9d488..37bf0911c60 100644
--- a/code/modules/admin/view_variables/view_variables.dm
+++ b/code/modules/admin/view_variables/view_variables.dm
@@ -1,7 +1,10 @@
+#define ICON_STATE_CHECKED 1 /// this dmi is checked. We don't check this one anymore.
+#define ICON_STATE_NULL 2 /// this dmi has null-named icon_state, allowing it to show a sprite on vv editor.
+
ADMIN_VERB_AND_CONTEXT_MENU(debug_variables, R_NONE, "View Variables", "View the variables of a datum.", ADMIN_CATEGORY_DEBUG, datum/thing in world)
user.debug_variables(thing)
-
// This is kept as a seperate proc because admins are able to show VV to non-admins
+
/client/proc/debug_variables(datum/thing in world)
set category = "Debug"
set name = "View Variables"
@@ -18,6 +21,8 @@ ADMIN_VERB_AND_CONTEXT_MENU(debug_variables, R_NONE, "View Variables", "View the
var/datum/asset/asset_cache_datum = get_asset_datum(/datum/asset/simple/vv)
asset_cache_datum.send(usr)
+ if(isappearance(thing))
+ thing = get_vv_appearance(thing) // this is /mutable_appearance/our_bs_subtype
var/islist = islist(thing) || (!isdatum(thing) && hascall(thing, "Cut")) // Some special lists dont count as lists, but can be detected by if they have list procs
if(!islist && !isdatum(thing))
return
@@ -27,7 +32,7 @@ ADMIN_VERB_AND_CONTEXT_MENU(debug_variables, R_NONE, "View Variables", "View the
var/icon/sprite
var/hash
- var/type = islist? /list : thing.type
+ var/type = islist ? /list : thing.type
var/no_icon = FALSE
if(isatom(thing))
@@ -36,8 +41,25 @@ ADMIN_VERB_AND_CONTEXT_MENU(debug_variables, R_NONE, "View Variables", "View the
no_icon = TRUE
else if(isimage(thing))
+ // icon_state=null shows first image even if dmi has no icon_state for null name.
+ // This list remembers which dmi has null icon_state, to determine if icon_state=null should display a sprite
+ // (NOTE: icon_state="" is correct, but saying null is obvious)
+ var/static/list/dmi_nullstate_checklist = list()
var/image/image_object = thing
- sprite = icon(image_object.icon, image_object.icon_state)
+ var/icon_filename_text = "[image_object.icon]" // "icon(null)" type can exist. textifying filters it.
+ if(icon_filename_text)
+ if(image_object.icon_state)
+ sprite = icon(image_object.icon, image_object.icon_state)
+
+ else // it means: icon_state=""
+ if(!dmi_nullstate_checklist[icon_filename_text])
+ dmi_nullstate_checklist[icon_filename_text] = ICON_STATE_CHECKED
+ if("" in icon_states(image_object.icon))
+ // this dmi has nullstate. We'll allow "icon_state=null" to show image.
+ dmi_nullstate_checklist[icon_filename_text] = ICON_STATE_NULL
+
+ if(dmi_nullstate_checklist[icon_filename_text] == ICON_STATE_NULL)
+ sprite = icon(image_object.icon, image_object.icon_state)
var/sprite_text
if(sprite)
@@ -285,3 +307,6 @@ datumrefresh=[refid];[HrefToken()]'>Refresh
/client/proc/vv_update_display(datum/thing, span, content)
src << output("[span]:[content]", "variables[REF(thing)].browser:replace_span")
+
+#undef ICON_STATE_CHECKED
+#undef ICON_STATE_NULL
diff --git a/code/modules/antagonists/malf_ai/malf_ai.dm b/code/modules/antagonists/malf_ai/malf_ai.dm
index 095ccbc1b75..d44403df84a 100644
--- a/code/modules/antagonists/malf_ai/malf_ai.dm
+++ b/code/modules/antagonists/malf_ai/malf_ai.dm
@@ -173,6 +173,8 @@
to_chat(malf_ai, "Your radio has been upgraded! Use :t to speak on an encrypted channel with Syndicate Agents!")
+ if(malf_ai.malf_picker)
+ return
malf_ai.add_malf_picker()
diff --git a/code/modules/antagonists/malf_ai/malf_ai_modules.dm b/code/modules/antagonists/malf_ai/malf_ai_modules.dm
index 099ed86044e..073d905646d 100644
--- a/code/modules/antagonists/malf_ai/malf_ai_modules.dm
+++ b/code/modules/antagonists/malf_ai/malf_ai_modules.dm
@@ -945,6 +945,8 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module))
var/prev_verbs
/// Saved span state, used to restore after a voice change
var/prev_span
+ /// The list of available voices
+ var/static/list/voice_options = list("normal", SPAN_ROBOT, SPAN_YELL, SPAN_CLOWN)
/obj/machinery/ai_voicechanger/Initialize(mapload)
. = ..()
@@ -972,11 +974,12 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module))
/obj/machinery/ai_voicechanger/ui_data(mob/user)
var/list/data = list()
- data["voices"] = list("normal", SPAN_ROBOT, SPAN_YELL, SPAN_CLOWN) //manually adding this since i dont see other option
+ data["voices"] = voice_options
data["loud"] = loudvoice
data["on"] = changing_voice
data["say_verb"] = say_verb
data["name"] = say_name
+ data["selected"] = say_span || owner.speech_span
return data
/obj/machinery/ai_voicechanger/ui_act(action, params)
@@ -1010,9 +1013,23 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module))
if(changing_voice)
owner.radio.use_command = loudvoice
if("look")
- say_span = params["look"]
+ var/selection = params["look"]
+ if(isnull(selection))
+ return FALSE
+
+ var/found = FALSE
+ for(var/option in voice_options)
+ if(option == selection)
+ found = TRUE
+ break
+ if(!found)
+ stack_trace("User attempted to select an unavailable voice option")
+ return FALSE
+
+ say_span = selection
if(changing_voice)
owner.speech_span = say_span
+ to_chat(usr, span_notice("Voice set to [selection]."))
if("verb")
say_verb = params["verb"]
if(changing_voice)
diff --git a/code/modules/antagonists/ninja/ninjaDrainAct.dm b/code/modules/antagonists/ninja/ninjaDrainAct.dm
index c50df819e0d..403da2327a2 100644
--- a/code/modules/antagonists/ninja/ninjaDrainAct.dm
+++ b/code/modules/antagonists/ninja/ninjaDrainAct.dm
@@ -1,3 +1,8 @@
+/// Minimum amount of energy we can drain in a single drain action
+#define NINJA_MIN_DRAIN (0.2 * STANDARD_CELL_CHARGE)
+/// Maximum amount of energy we can drain in a single drain action
+#define NINJA_MAX_DRAIN (0.4 * STANDARD_CELL_CHARGE)
+
/**
* Atom level proc for space ninja's glove interactions.
*
@@ -26,7 +31,7 @@
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread()
spark_system.set_up(5, 0, loc)
while(cell.charge> 0 && !maxcapacity)
- drain = rand(hacking_module.mindrain, hacking_module.maxdrain)
+ drain = rand(NINJA_MIN_DRAIN, NINJA_MAX_DRAIN)
if(cell.charge < drain)
drain = cell.charge
if(hacking_module.mod.get_charge() + drain > hacking_module.mod.get_max_charge())
@@ -62,7 +67,7 @@
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread()
spark_system.set_up(5, 0, loc)
while(charge > 0 && !maxcapacity)
- drain = rand(hacking_module.mindrain, hacking_module.maxdrain)
+ drain = rand(NINJA_MIN_DRAIN, NINJA_MAX_DRAIN)
if(charge < drain)
drain = charge
if(hacking_module.mod.get_charge() + drain > hacking_module.mod.get_max_charge())
@@ -228,7 +233,7 @@
var/drain_total = 0
var/datum/powernet/wire_powernet = powernet
while(!maxcapacity && src)
- drain = (round((rand(hacking_module.mindrain, hacking_module.maxdrain))/2))
+ drain = (round((rand(NINJA_MIN_DRAIN, NINJA_MAX_DRAIN))/2))
var/drained = 0
if(wire_powernet && do_after(ninja, 1 SECONDS, target = src, hidden = TRUE))
drained = min(drain, delayed_surplus())
@@ -264,7 +269,7 @@
var/drain_total = 0
if(get_charge())
while(cell.charge > 0 && !maxcapacity)
- drain = rand(hacking_module.mindrain, hacking_module.maxdrain)
+ drain = rand(NINJA_MIN_DRAIN, NINJA_MAX_DRAIN)
if(cell.charge < drain)
drain = cell.charge
if(hacking_module.mod.get_charge() + drain > hacking_module.mod.get_max_charge())
@@ -477,3 +482,6 @@
//FIRELOCKS//
/obj/machinery/door/firedoor/ninjadrain_act(mob/living/carbon/human/ninja, obj/item/mod/module/hacker/hacking_module)
crack_open()
+
+#undef NINJA_MIN_DRAIN
+#undef NINJA_MAX_DRAIN
diff --git a/code/modules/antagonists/nukeop/equipment/borgchameleon.dm b/code/modules/antagonists/nukeop/equipment/borgchameleon.dm
index a2a072f02e2..9b536066843 100644
--- a/code/modules/antagonists/nukeop/equipment/borgchameleon.dm
+++ b/code/modules/antagonists/nukeop/equipment/borgchameleon.dm
@@ -1,5 +1,5 @@
-#define ACTIVATION_COST (300 KILO JOULES)
-#define ACTIVATION_UP_KEEP (25 KILO WATTS)
+#define ACTIVATION_COST (0.3 * STANDARD_CELL_CHARGE)
+#define ACTIVATION_UP_KEEP (0.025 * STANDARD_CELL_RATE)
/obj/item/borg_chameleon
name = "cyborg chameleon projector"
diff --git a/code/modules/antagonists/nukeop/outfits.dm b/code/modules/antagonists/nukeop/outfits.dm
index eb251bcc363..e8ae07ffdde 100644
--- a/code/modules/antagonists/nukeop/outfits.dm
+++ b/code/modules/antagonists/nukeop/outfits.dm
@@ -120,10 +120,7 @@
head = /obj/item/clothing/head/helmet/space/plasmaman/syndie
uniform = /obj/item/clothing/under/plasmaman/syndicate
glasses = /obj/item/clothing/glasses/overwatch
- suit = /obj/item/clothing/suit/jacket/letterman_syndie
r_hand = /obj/item/tank/internals/plasmaman/belt/full
- command_radio = TRUE
- tc = 0
/datum/outfit/syndicate/reinforcement/gorlex
name = "Syndicate Operative - Gorlex Reinforcement"
@@ -212,3 +209,4 @@
shoes = /obj/item/clothing/shoes/sandal
command_radio = TRUE
tc = 0
+ uplink_type = null
diff --git a/code/modules/antagonists/pirate/pirate_event.dm b/code/modules/antagonists/pirate/pirate_event.dm
index e4a14182d0e..40cf038a214 100644
--- a/code/modules/antagonists/pirate/pirate_event.dm
+++ b/code/modules/antagonists/pirate/pirate_event.dm
@@ -42,7 +42,7 @@
priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", SSstation.announcer.get_rand_report_sound())
threat.answer_callback = CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(pirates_answered), threat, chosen_gang, payoff, world.time)
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(spawn_pirates), threat, chosen_gang), RESPONSE_MAX_TIME)
- SScommunications.send_message(threat, unique = TRUE)
+ DScommunications.send_message(threat, unique = TRUE)
/proc/pirates_answered(datum/comm_message/threat, datum/pirate_gang/chosen_gang, payoff, initial_send_time)
if(world.time > initial_send_time + RESPONSE_MAX_TIME)
diff --git a/code/modules/antagonists/pirate/pirate_gangs.dm b/code/modules/antagonists/pirate/pirate_gangs.dm
index d3bc0968a12..cb2f5fc1428 100644
--- a/code/modules/antagonists/pirate/pirate_gangs.dm
+++ b/code/modules/antagonists/pirate/pirate_gangs.dm
@@ -206,3 +206,25 @@ GLOBAL_LIST_INIT(heavy_pirate_gangs, init_pirate_gangs(is_heavy = TRUE))
response_too_late = "You were not ready then, and now that time has passed. We can only go forward, never back."
response_not_enough = "You have insulted us, but there shall be no feud, only swift justice!"
announcement_color = "purple"
+
+//medieval militia, from OUTER SPACE!
+/datum/pirate_gang/medieval
+ name = "Medieval Warmongers"
+
+ is_heavy_threat = TRUE
+ ship_template_id = "medieval"
+ ship_name_pool = "medieval_names"
+
+ threat_title = "HOMAGE PAYMENT REQUEST"
+ threat_content = "SALUTATIONS, THIS IS %SHIPNAME AND WE ARE COLLECTING MONEY \
+ FROM THE VASSALS IN OUR TERRITORY, YOU JUST SO HAPPEN TO BE IN IT TOO!! NORMALLY \
+ WE SLAUGHTER WEAKLINGS LIKE YOU FOR TRESPASING ON OUR LAND, BUT WE ARE WILLING \
+ TO WELCOME YOU INTO OUR SPACE IF YOU PAY %PAYOFF AS HOMAGE TO OUR LAW. BE WISE ON YOUR CHOICE!! \
+ (send message. send message. why message not sent?)."
+ arrival_announcement = "I FIGURED OUT HOW TO FLY MY SHIP, WE WILL BE DOCKING NEXT TO YOU IN A MINUTE!!"
+ possible_answers = list("Please don't hurt me.","You are dumb, go larp somewhere else.")
+
+ response_received = "THIS WILL SUFFICE, REMEMBER WHO OWNS YOU!!"
+ response_rejected = "FOOLISH DECISION, I'LL MAKE AN EXAMPLE OUT OF YOUR CARCASS!! (does anyone remember how to pilot our ship?)"
+ response_too_late = "YOU ARE ALREADY UNDER SIEGE YOU BUFFON, ARE YOU BRAINSICK OR IGNORANT?!!"
+ response_not_enough = "DO THINK OF ME AS A JESTER? YOU ARE DEAD MEAT!! (i forgot how to fly the ship, tarnation.)"
diff --git a/code/modules/antagonists/pirate/pirate_outfits.dm b/code/modules/antagonists/pirate/pirate_outfits.dm
index 4c73cac107f..15a3d4fe2dc 100644
--- a/code/modules/antagonists/pirate/pirate_outfits.dm
+++ b/code/modules/antagonists/pirate/pirate_outfits.dm
@@ -148,3 +148,34 @@
glasses = null
suit = /obj/item/clothing/suit/jacket/oversized
head = /obj/item/clothing/head/costume/crown
+
+/datum/outfit/pirate/medieval
+ name = "Medieval Warmonger"
+
+ id = null
+ glasses = null
+ uniform = /obj/item/clothing/under/costume/gamberson/military
+ suit = /obj/item/clothing/suit/armor/vest/military
+ suit_store = /obj/item/spear/military
+ back = /obj/item/storage/backpack/satchel/leather
+ gloves = /obj/item/clothing/gloves/color/brown
+ head = /obj/item/clothing/head/helmet/military
+ mask = /obj/item/clothing/mask/balaclava
+ shoes = /obj/item/clothing/shoes/workboots
+ belt = /obj/item/claymore/shortsword
+ l_pocket = /obj/item/flashlight/flare/torch
+
+/datum/outfit/pirate/medieval/warlord
+ name = "Medieval Warlord"
+
+ neck = /obj/item/bedsheet/pirate
+ suit = /obj/item/clothing/suit/armor/riot/knight/warlord
+ suit_store = null
+ back = /obj/item/fireaxe/boardingaxe
+ gloves = /obj/item/clothing/gloves/combat
+ head = /obj/item/clothing/head/helmet/knight/warlord
+ mask = /obj/item/clothing/mask/breath
+ shoes = /obj/item/clothing/shoes/bronze
+ belt = /obj/item/gun/magic/hook
+ l_pocket = /obj/item/tank/internals/emergency_oxygen
+ r_pocket = /obj/item/flashlight/lantern
diff --git a/code/modules/antagonists/pirate/pirate_roles.dm b/code/modules/antagonists/pirate/pirate_roles.dm
index 64baa724db1..78a3d3fd12a 100644
--- a/code/modules/antagonists/pirate/pirate_roles.dm
+++ b/code/modules/antagonists/pirate/pirate_roles.dm
@@ -191,3 +191,33 @@
/obj/effect/mob_spawn/ghost_role/human/pirate/lustrous/gunner
rank = "Coruscant"
+
+/obj/effect/mob_spawn/ghost_role/human/pirate/medieval
+ name = "\improper Improvised sleeper"
+ desc = "A body bag poked with holes, currently being used as a sleeping bag. Someone seems to be sleeping inside of it."
+ density = FALSE
+ you_are_text = "You were a nobody before, until you were given a sword and the opportunity to rise up in ranks. If you put some effort, you can make it big!"
+ flavour_text = "Raiding some cretins while engaging in bloodsport and violence? what a deal. Stay together and pillage everything!"
+ icon = 'icons/obj/medical/bodybag.dmi'
+ icon_state = "bodybag"
+ fluff_spawn = null
+ prompt_name = "a medieval warmonger"
+ outfit = /datum/outfit/pirate/medieval
+ rank = "Footsoldier"
+
+/obj/effect/mob_spawn/ghost_role/human/pirate/medieval/special(mob/living/carbon/spawned_mob)
+ . = ..()
+ if(rank == "Footsoldier")
+ ADD_TRAIT(spawned_mob, TRAIT_NOGUNS, INNATE_TRAIT)
+ spawned_mob.AddComponent(/datum/component/unbreakable)
+ var/datum/action/cooldown/mob_cooldown/dash/dodge = new(spawned_mob)
+ dodge.Grant(spawned_mob)
+
+/obj/effect/mob_spawn/ghost_role/human/pirate/medieval/warlord
+ rank = "Warlord"
+ outfit = /datum/outfit/pirate/medieval/warlord
+
+/obj/effect/mob_spawn/ghost_role/human/pirate/medieval/warlord/special(mob/living/carbon/spawned_mob)
+ . = ..()
+ spawned_mob.dna.add_mutation(/datum/mutation/human/hulk/superhuman)
+ spawned_mob.dna.add_mutation(/datum/mutation/human/gigantism)
diff --git a/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm b/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm
index 04ebab73cbd..eaa1de48b58 100644
--- a/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm
+++ b/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm
@@ -96,6 +96,9 @@
light_color = COLOR_SOFT_RED
possible_destinations = "pirate_away;pirate_home;pirate_custom"
+/obj/machinery/computer/shuttle/pirate/drop_pod
+ possible_destinations = "null"
+
/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate/pirate
name = "pirate shuttle navigation computer"
desc = "Used to designate a precise transit location for the pirate shuttle."
diff --git a/code/modules/antagonists/space_dragon/carp_rift.dm b/code/modules/antagonists/space_dragon/carp_rift.dm
index e003bf76e4d..8a74d4b63da 100644
--- a/code/modules/antagonists/space_dragon/carp_rift.dm
+++ b/code/modules/antagonists/space_dragon/carp_rift.dm
@@ -160,7 +160,7 @@
newcarp.faction = dragon.owner.current.faction.Copy()
if(SPT_PROB(1.5, seconds_per_tick))
var/rand_dir = pick(GLOB.cardinals)
- SSmove_manager.move_to(src, get_step(src, rand_dir), 1)
+ DSmove_manager.move_to(src, get_step(src, rand_dir), 1)
return
// Increase time trackers and check for any updated states.
diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm
index 44d00f3c170..222fcb39d16 100644
--- a/code/modules/antagonists/wizard/equipment/artefact.dm
+++ b/code/modules/antagonists/wizard/equipment/artefact.dm
@@ -362,7 +362,7 @@
qdel(src)
return
RegisterSignal(src, COMSIG_MOVABLE_CROSS_OVER, PROC_REF(check_teleport))
- SSmove_manager.move_towards(src, get_turf(whistle.whistler))
+ DSmove_manager.move_towards(src, get_turf(whistle.whistler))
/// Check if anything the tornado crosses is the creator.
/obj/effect/temp_visual/teleporting_tornado/proc/check_teleport(datum/source, atom/movable/crossed)
diff --git a/code/modules/antagonists/wizard/equipment/spellbook_entries/assistance.dm b/code/modules/antagonists/wizard/equipment/spellbook_entries/assistance.dm
index aece8d6741b..69c33e751ec 100644
--- a/code/modules/antagonists/wizard/equipment/spellbook_entries/assistance.dm
+++ b/code/modules/antagonists/wizard/equipment/spellbook_entries/assistance.dm
@@ -1,44 +1,45 @@
+#define SPELLBOOK_CATEGORY_ASSISTANCE "Assistance"
// Wizard spells that assist the caster in some way
/datum/spellbook_entry/summonitem
name = "Summon Item"
desc = "Recalls a previously marked item to your hand from anywhere in the universe."
spell_type = /datum/action/cooldown/spell/summonitem
- category = "Assistance"
+ category = SPELLBOOK_CATEGORY_ASSISTANCE
cost = 1
/datum/spellbook_entry/charge
name = "Charge"
desc = "This spell can be used to recharge a variety of things in your hands, from magical artifacts to electrical components. A creative wizard can even use it to grant magical power to a fellow magic user."
spell_type = /datum/action/cooldown/spell/charge
- category = "Assistance"
+ category = SPELLBOOK_CATEGORY_ASSISTANCE
cost = 1
/datum/spellbook_entry/shapeshift
name = "Wild Shapeshift"
desc = "Take on the shape of another for a time to use their natural abilities. Once you've made your choice it cannot be changed."
spell_type = /datum/action/cooldown/spell/shapeshift/wizard
- category = "Assistance"
+ category = SPELLBOOK_CATEGORY_ASSISTANCE
cost = 1
/datum/spellbook_entry/tap
name = "Soul Tap"
desc = "Fuel your spells using your own soul!"
spell_type = /datum/action/cooldown/spell/tap
- category = "Assistance"
+ category = SPELLBOOK_CATEGORY_ASSISTANCE
cost = 1
/datum/spellbook_entry/item/staffanimation
name = "Staff of Animation"
desc = "An arcane staff capable of shooting bolts of eldritch energy which cause inanimate objects to come to life. This magic doesn't affect machines."
item_path = /obj/item/gun/magic/staff/animate
- category = "Assistance"
+ category = SPELLBOOK_CATEGORY_ASSISTANCE
/datum/spellbook_entry/item/soulstones
name = "Soulstone Shard Kit"
desc = "Soul Stone Shards are ancient tools capable of capturing and harnessing the spirits of the dead and dying. \
The spell Artificer allows you to create arcane machines for the captured souls to pilot."
item_path = /obj/item/storage/belt/soulstone/full
- category = "Assistance"
+ category = SPELLBOOK_CATEGORY_ASSISTANCE
/datum/spellbook_entry/item/soulstones/try_equip_item(mob/living/carbon/human/user, obj/item/to_equip)
var/was_equipped = user.equip_to_slot_if_possible(to_equip, ITEM_SLOT_BELT, disable_warning = TRUE)
@@ -56,13 +57,13 @@
name = "A Necromantic Stone"
desc = "A Necromantic stone is able to resurrect three dead individuals as skeletal thralls for you to command."
item_path = /obj/item/necromantic_stone
- category = "Assistance"
+ category = SPELLBOOK_CATEGORY_ASSISTANCE
/datum/spellbook_entry/item/contract
name = "Contract of Apprenticeship"
desc = "A magical contract binding an apprentice wizard to your service, using it will summon them to your side."
item_path = /obj/item/antag_spawner/contract
- category = "Assistance"
+ category = SPELLBOOK_CATEGORY_ASSISTANCE
refundable = TRUE
/datum/spellbook_entry/item/guardian
@@ -70,7 +71,7 @@
desc = "A deck of guardian tarot cards, capable of binding a personal guardian to your body. There are multiple types of guardian available, but all of them will transfer some amount of damage to you. \
It would be wise to avoid buying these with anything capable of causing you to swap bodies with others."
item_path = /obj/item/guardian_creator/wizard
- category = "Assistance"
+ category = SPELLBOOK_CATEGORY_ASSISTANCE
/datum/spellbook_entry/item/bloodbottle
name = "Bottle of Blood"
@@ -80,7 +81,7 @@
in their killing, and you yourself may become a victim."
item_path = /obj/item/antag_spawner/slaughter_demon
limit = 3
- category = "Assistance"
+ category = SPELLBOOK_CATEGORY_ASSISTANCE
refundable = TRUE
/datum/spellbook_entry/item/hugbottle
@@ -95,7 +96,7 @@
item_path = /obj/item/antag_spawner/slaughter_demon/laughter
cost = 1 //non-destructive; it's just a jape, sibling!
limit = 3
- category = "Assistance"
+ category = SPELLBOOK_CATEGORY_ASSISTANCE
refundable = TRUE
/datum/spellbook_entry/item/vendormancer
@@ -105,4 +106,6 @@
throw around to squash oponents or be directly detonated. When out of \
charges a long channel will restore the charges."
item_path = /obj/item/runic_vendor_scepter
- category = "Assistance"
+ category = SPELLBOOK_CATEGORY_ASSISTANCE
+
+#undef SPELLBOOK_CATEGORY_ASSISTANCE
diff --git a/code/modules/antagonists/wizard/equipment/spellbook_entries/defensive.dm b/code/modules/antagonists/wizard/equipment/spellbook_entries/defensive.dm
index 1ffac3cf3af..a66d99c21c8 100644
--- a/code/modules/antagonists/wizard/equipment/spellbook_entries/defensive.dm
+++ b/code/modules/antagonists/wizard/equipment/spellbook_entries/defensive.dm
@@ -1,49 +1,50 @@
+#define SPELLBOOK_CATEGORY_DEFENSIVE "Defensive"
// Defensive wizard spells
/datum/spellbook_entry/magicm
name = "Magic Missile"
desc = "Fires several, slow moving, magic projectiles at nearby targets."
spell_type = /datum/action/cooldown/spell/aoe/magic_missile
- category = "Defensive"
+ category = SPELLBOOK_CATEGORY_DEFENSIVE
/datum/spellbook_entry/disabletech
name = "Disable Tech"
desc = "Disables all weapons, cameras and most other technology in range."
spell_type = /datum/action/cooldown/spell/emp/disable_tech
- category = "Defensive"
+ category = SPELLBOOK_CATEGORY_DEFENSIVE
cost = 1
/datum/spellbook_entry/repulse
name = "Repulse"
desc = "Throws everything around the user away."
spell_type = /datum/action/cooldown/spell/aoe/repulse/wizard
- category = "Defensive"
+ category = SPELLBOOK_CATEGORY_DEFENSIVE
/datum/spellbook_entry/lightning_packet
name = "Thrown Lightning"
desc = "Forged from eldrich energies, a packet of pure power, \
known as a spell packet will appear in your hand, that when thrown will stun the target."
spell_type = /datum/action/cooldown/spell/conjure_item/spellpacket
- category = "Defensive"
+ category = SPELLBOOK_CATEGORY_DEFENSIVE
/datum/spellbook_entry/timestop
name = "Time Stop"
desc = "Stops time for everyone except for you, allowing you to move freely \
while your enemies and even projectiles are frozen."
spell_type = /datum/action/cooldown/spell/timestop
- category = "Defensive"
+ category = SPELLBOOK_CATEGORY_DEFENSIVE
/datum/spellbook_entry/smoke
name = "Smoke"
desc = "Spawns a cloud of choking smoke at your location."
spell_type = /datum/action/cooldown/spell/smoke
- category = "Defensive"
+ category = SPELLBOOK_CATEGORY_DEFENSIVE
cost = 1
/datum/spellbook_entry/forcewall
name = "Force Wall"
desc = "Create a magical barrier that only you can pass through."
spell_type = /datum/action/cooldown/spell/forcewall
- category = "Defensive"
+ category = SPELLBOOK_CATEGORY_DEFENSIVE
cost = 1
/datum/spellbook_entry/lichdom
@@ -53,28 +54,28 @@
no matter the circumstances. Be wary - with each revival, your body will become weaker, and \
it will become easier for others to find your item of power."
spell_type = /datum/action/cooldown/spell/lichdom
- category = "Defensive"
+ category = SPELLBOOK_CATEGORY_DEFENSIVE
no_coexistance_typecache = list(/datum/action/cooldown/spell/splattercasting)
/datum/spellbook_entry/chuunibyou
name = "Chuuni Invocations"
desc = "Makes all your spells shout invocations, and the invocations become... stupid. You heal slightly after casting a spell."
spell_type = /datum/action/cooldown/spell/chuuni_invocations
- category = "Defensive"
+ category = SPELLBOOK_CATEGORY_DEFENSIVE
/datum/spellbook_entry/spacetime_dist
name = "Spacetime Distortion"
desc = "Entangle the strings of space-time in an area around you, \
randomizing the layout and making proper movement impossible. The strings vibrate..."
spell_type = /datum/action/cooldown/spell/spacetime_dist
- category = "Defensive"
+ category = SPELLBOOK_CATEGORY_DEFENSIVE
cost = 1
/datum/spellbook_entry/the_traps
name = "The Traps!"
desc = "Summon a number of traps around you. They will damage and enrage any enemies that step on them."
spell_type = /datum/action/cooldown/spell/conjure/the_traps
- category = "Defensive"
+ category = SPELLBOOK_CATEGORY_DEFENSIVE
cost = 1
/datum/spellbook_entry/bees
@@ -82,7 +83,7 @@
desc = "This spell magically kicks a transdimensional beehive, \
instantly summoning a swarm of bees to your location. These bees are NOT friendly to anyone."
spell_type = /datum/action/cooldown/spell/conjure/bee
- category = "Defensive"
+ category = SPELLBOOK_CATEGORY_DEFENSIVE
/datum/spellbook_entry/duffelbag
name = "Bestow Cursed Duffel Bag"
@@ -91,7 +92,7 @@
if it is not fed regularly, and regardless of whether or not it's been fed, \
it will slow the person wearing it down significantly."
spell_type = /datum/action/cooldown/spell/touch/duffelbag
- category = "Defensive"
+ category = SPELLBOOK_CATEGORY_DEFENSIVE
cost = 1
/datum/spellbook_entry/item/staffhealing
@@ -99,26 +100,26 @@
desc = "An altruistic staff that can heal the lame and raise the dead."
item_path = /obj/item/gun/magic/staff/healing
cost = 1
- category = "Defensive"
+ category = SPELLBOOK_CATEGORY_DEFENSIVE
/datum/spellbook_entry/item/lockerstaff
name = "Staff of the Locker"
desc = "A staff that shoots lockers. It eats anyone it hits on its way, leaving a welded locker with your victims behind."
item_path = /obj/item/gun/magic/staff/locker
- category = "Defensive"
+ category = SPELLBOOK_CATEGORY_DEFENSIVE
/datum/spellbook_entry/item/scryingorb
name = "Scrying Orb"
desc = "An incandescent orb of crackling energy. Using it will allow you to release your ghost while alive, allowing you to spy upon the station and talk to the deceased. In addition, buying it will permanently grant you X-ray vision."
item_path = /obj/item/scrying
- category = "Defensive"
+ category = SPELLBOOK_CATEGORY_DEFENSIVE
/datum/spellbook_entry/item/wands
name = "Wand Assortment"
desc = "A collection of wands that allow for a wide variety of utility. \
Wands have a limited number of charges, so be conservative with their use. Comes in a handy belt."
item_path = /obj/item/storage/belt/wands/full
- category = "Defensive"
+ category = SPELLBOOK_CATEGORY_DEFENSIVE
/datum/spellbook_entry/item/wands/try_equip_item(mob/living/carbon/human/user, obj/item/to_equip)
var/was_equipped = user.equip_to_slot_if_possible(to_equip, ITEM_SLOT_BELT, disable_warning = TRUE)
@@ -130,7 +131,7 @@
while providing more protection against attacks and the void of space. \
Also grants a battlemage shield."
item_path = /obj/item/mod/control/pre_equipped/enchanted
- category = "Defensive"
+ category = SPELLBOOK_CATEGORY_DEFENSIVE
/datum/spellbook_entry/item/armor/try_equip_item(mob/living/carbon/human/user, obj/item/to_equip)
var/obj/item/mod/control/mod = to_equip
@@ -151,5 +152,7 @@
name = "Battlemage Armour Charges"
desc = "A powerful defensive rune, it will grant eight additional charges to a battlemage shield."
item_path = /obj/item/wizard_armour_charge
- category = "Defensive"
+ category = SPELLBOOK_CATEGORY_DEFENSIVE
cost = 1
+
+#undef SPELLBOOK_CATEGORY_DEFENSIVE
diff --git a/code/modules/antagonists/wizard/equipment/spellbook_entries/mobility.dm b/code/modules/antagonists/wizard/equipment/spellbook_entries/mobility.dm
index 6a8f322a3a5..bc09b092f6c 100644
--- a/code/modules/antagonists/wizard/equipment/spellbook_entries/mobility.dm
+++ b/code/modules/antagonists/wizard/equipment/spellbook_entries/mobility.dm
@@ -1,47 +1,48 @@
+#define SPELLBOOK_CATEGORY_MOBILITY "Mobility"
// Wizard spells that aid mobiilty(or stealth?)
/datum/spellbook_entry/mindswap
name = "Mindswap"
desc = "Allows you to switch bodies with a target next to you. You will both fall asleep when this happens, and it will be quite obvious that you are the target's body if someone watches you do it."
spell_type = /datum/action/cooldown/spell/pointed/mind_transfer
- category = "Mobility"
+ category = SPELLBOOK_CATEGORY_MOBILITY
/datum/spellbook_entry/knock
name = "Knock"
desc = "Opens nearby doors and closets."
spell_type = /datum/action/cooldown/spell/aoe/knock
- category = "Mobility"
+ category = SPELLBOOK_CATEGORY_MOBILITY
cost = 1
/datum/spellbook_entry/blink
name = "Blink"
desc = "Randomly teleports you a short distance."
spell_type = /datum/action/cooldown/spell/teleport/radius_turf/blink
- category = "Mobility"
+ category = SPELLBOOK_CATEGORY_MOBILITY
/datum/spellbook_entry/teleport
name = "Teleport"
desc = "Teleports you to an area of your selection."
spell_type = /datum/action/cooldown/spell/teleport/area_teleport/wizard
- category = "Mobility"
+ category = SPELLBOOK_CATEGORY_MOBILITY
/datum/spellbook_entry/jaunt
name = "Ethereal Jaunt"
desc = "Turns your form ethereal, temporarily making you invisible and able to pass through walls."
spell_type = /datum/action/cooldown/spell/jaunt/ethereal_jaunt
- category = "Mobility"
+ category = SPELLBOOK_CATEGORY_MOBILITY
/datum/spellbook_entry/swap
name = "Swap"
desc = "Switch places with any living target within nine tiles. Right click to mark a secondary target. You will always swap to your primary target."
spell_type = /datum/action/cooldown/spell/pointed/swap
- category = "Mobility"
+ category = SPELLBOOK_CATEGORY_MOBILITY
cost = 1
/datum/spellbook_entry/item/warpwhistle
name = "Warp Whistle"
desc = "A strange whistle that will transport you to a distant safe place on the station. There is a window of vulnerability at the beginning of every use."
item_path = /obj/item/warp_whistle
- category = "Mobility"
+ category = SPELLBOOK_CATEGORY_MOBILITY
cost = 1
/datum/spellbook_entry/item/staffdoor
@@ -49,11 +50,13 @@
desc = "A particular staff that can mold solid walls into ornate doors. Useful for getting around in the absence of other transportation. Does not work on glass."
item_path = /obj/item/gun/magic/staff/door
cost = 1
- category = "Mobility"
+ category = SPELLBOOK_CATEGORY_MOBILITY
/datum/spellbook_entry/item/teleport_rod
name = /obj/item/teleport_rod::name
desc = /obj/item/teleport_rod::desc
item_path = /obj/item/teleport_rod
cost = 2 // Puts it at 3 cost if you go for safety instant summons, but teleporting anywhere on screen is pretty good.
- category = "Mobility"
+ category = SPELLBOOK_CATEGORY_MOBILITY
+
+#undef SPELLBOOK_CATEGORY_MOBILITY
diff --git a/code/modules/antagonists/wizard/equipment/spellbook_entries/offensive.dm b/code/modules/antagonists/wizard/equipment/spellbook_entries/offensive.dm
index b23de0aa6b0..d919c5e768f 100644
--- a/code/modules/antagonists/wizard/equipment/spellbook_entries/offensive.dm
+++ b/code/modules/antagonists/wizard/equipment/spellbook_entries/offensive.dm
@@ -1,27 +1,28 @@
+#define SPELLBOOK_CATEGORY_OFFENSIVE "Offensive"
// Offensive wizard spells
/datum/spellbook_entry/fireball
name = "Fireball"
desc = "Fires an explosive fireball at a target. Considered a classic among all wizards."
spell_type = /datum/action/cooldown/spell/pointed/projectile/fireball
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
/datum/spellbook_entry/spell_cards
name = "Spell Cards"
desc = "Blazing hot rapid-fire homing cards. Send your foes to the shadow realm with their mystical power!"
spell_type = /datum/action/cooldown/spell/pointed/projectile/spell_cards
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
/datum/spellbook_entry/rod_form
name = "Rod Form"
desc = "Take on the form of an immovable rod, destroying all in your path. Purchasing this spell multiple times will also increase the rod's damage and travel range."
spell_type = /datum/action/cooldown/spell/rod_form
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
/datum/spellbook_entry/disintegrate
name = "Smite"
desc = "Charges your hand with an unholy energy that can be used to cause a touched victim to violently explode."
spell_type = /datum/action/cooldown/spell/touch/smite
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
/datum/spellbook_entry/summon_simians
name = "Summon Simians"
@@ -29,45 +30,45 @@
summons primal monkeys and lesser gorillas that will promptly flip out and attack everything in sight. Fun! \
Their lesser, easily manipulable minds will be convinced you are one of their allies, but only for a minute. Unless you also are a monkey."
spell_type = /datum/action/cooldown/spell/conjure/simian
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
/datum/spellbook_entry/blind
name = "Blind"
desc = "Temporarily blinds a single target."
spell_type = /datum/action/cooldown/spell/pointed/blind
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
cost = 1
/datum/spellbook_entry/mutate
name = "Mutate"
desc = "Causes you to turn into a hulk and gain laser vision for a short while."
spell_type = /datum/action/cooldown/spell/apply_mutations/mutate
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
/datum/spellbook_entry/fleshtostone
name = "Flesh to Stone"
desc = "Charges your hand with the power to turn victims into inert statues for a long period of time."
spell_type = /datum/action/cooldown/spell/touch/flesh_to_stone
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
/datum/spellbook_entry/teslablast
name = "Tesla Blast"
desc = "Charge up a tesla arc and release it at a random nearby target! You can move freely while it charges. The arc jumps between targets and can knock them down."
spell_type = /datum/action/cooldown/spell/charged/beam/tesla
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
/datum/spellbook_entry/lightningbolt
name = "Lightning Bolt"
desc = "Fire a lightning bolt at your foes! It will jump between targets, but can't knock them down."
spell_type = /datum/action/cooldown/spell/pointed/projectile/lightningbolt
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
cost = 1
/datum/spellbook_entry/infinite_guns
name = "Lesser Summon Guns"
desc = "Why reload when you have infinite guns? Summons an unending stream of bolt action rifles that deal little damage, but will knock targets down. Requires both hands free to use. Learning this spell makes you unable to learn Arcane Barrage."
spell_type = /datum/action/cooldown/spell/conjure_item/infinite_guns/gun
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
cost = 3
no_coexistance_typecache = list(/datum/action/cooldown/spell/conjure_item/infinite_guns/arcane_barrage)
@@ -75,7 +76,7 @@
name = "Arcane Barrage"
desc = "Fire a torrent of arcane energy at your foes with this (powerful) spell. Deals much more damage than Lesser Summon Guns, but won't knock targets down. Requires both hands free to use. Learning this spell makes you unable to learn Lesser Summon Gun."
spell_type = /datum/action/cooldown/spell/conjure_item/infinite_guns/arcane_barrage
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
cost = 3
no_coexistance_typecache = list(/datum/action/cooldown/spell/conjure_item/infinite_guns/gun)
@@ -83,68 +84,70 @@
name = "Barnyard Curse"
desc = "This spell dooms an unlucky soul to possess the speech and facial attributes of a barnyard animal."
spell_type = /datum/action/cooldown/spell/pointed/barnyardcurse
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
/datum/spellbook_entry/splattercasting
name = "Splattercasting"
desc = "Dramatically lowers the cooldown on all spells, but each one will cost blood, as well as it naturally \
draining from you over time. You can replenish it from your victims, specifically their necks."
spell_type = /datum/action/cooldown/spell/splattercasting
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
no_coexistance_typecache = list(/datum/action/cooldown/spell/lichdom)
/datum/spellbook_entry/sanguine_strike
name = "Exsanguinating Strike"
desc = "Sanguine spell that enchants your next weapon strike to deal more damage, heal you for damage dealt, and refill blood."
spell_type = /datum/action/cooldown/spell/sanguine_strike
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
/datum/spellbook_entry/scream_for_me
name = "Scream For Me"
desc = "Sadistic sanguine spell that inflicts numerous severe blood wounds all over the victim's body."
spell_type = /datum/action/cooldown/spell/touch/scream_for_me
cost = 1
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
/datum/spellbook_entry/item/staffchaos
name = "Staff of Chaos"
desc = "A caprious tool that can fire all sorts of magic without any rhyme or reason. Using it on people you care about is not recommended."
item_path = /obj/item/gun/magic/staff/chaos
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
/datum/spellbook_entry/item/staffchange
name = "Staff of Change"
desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself."
item_path = /obj/item/gun/magic/staff/change
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
/datum/spellbook_entry/item/mjolnir
name = "Mjolnir"
desc = "A mighty hammer on loan from Thor, God of Thunder. It crackles with barely contained power."
item_path = /obj/item/mjollnir
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
/datum/spellbook_entry/item/singularity_hammer
name = "Singularity Hammer"
desc = "A hammer that creates an intensely powerful field of gravity where it strikes, pulling everything nearby to the point of impact."
item_path = /obj/item/singularityhammer
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
/datum/spellbook_entry/item/spellblade
name = "Spellblade"
desc = "A sword capable of firing blasts of energy which rip targets limb from limb."
item_path = /obj/item/gun/magic/staff/spellblade
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
/datum/spellbook_entry/item/highfrequencyblade
name = "High Frequency Blade"
desc = "An incredibly swift enchanted blade resonating at a frequency high enough to be able to slice through anything."
item_path = /obj/item/highfrequencyblade/wizard
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
cost = 3
/datum/spellbook_entry/item/frog_contract
name = "Frog Contract"
desc = "Sign a pact with the frogs to have your own destructive pet guardian!"
item_path = /obj/item/frog_contract
- category = "Offensive"
+ category = SPELLBOOK_CATEGORY_OFFENSIVE
+
+#undef SPELLBOOK_CATEGORY_OFFENSIVE
diff --git a/code/modules/antagonists/xeno/xeno.dm b/code/modules/antagonists/xeno/xeno.dm
index 115e40ca595..d2e0bddd0dd 100644
--- a/code/modules/antagonists/xeno/xeno.dm
+++ b/code/modules/antagonists/xeno/xeno.dm
@@ -87,7 +87,7 @@
explanation_text = "Escape from captivity."
/datum/objective/escape_captivity/check_completion()
- if(!istype(get_area(owner), SScommunications.captivity_area))
+ if(!istype(get_area(owner), DScommunications.captivity_area))
return TRUE
/datum/objective/advance_hive
@@ -146,7 +146,7 @@
if(!captive_alien || captive_alien.stat == DEAD)
return CAPTIVE_XENO_DEAD
- if(istype(get_area(captive_alien), SScommunications.captivity_area))
+ if(istype(get_area(captive_alien), DScommunications.captivity_area))
return CAPTIVE_XENO_FAIL
return CAPTIVE_XENO_PASS
@@ -155,7 +155,7 @@
/mob/living/carbon/alien/mind_initialize()
..()
if(!mind.has_antag_datum(/datum/antagonist/xeno))
- if(SScommunications.xenomorph_egg_delivered && istype(get_area(src), SScommunications.captivity_area))
+ if(DScommunications.xenomorph_egg_delivered && istype(get_area(src), DScommunications.captivity_area))
mind.add_antag_datum(/datum/antagonist/xeno/captive)
else
mind.add_antag_datum(/datum/antagonist/xeno)
diff --git a/code/modules/asset_cache/assets/tgui.dm b/code/modules/asset_cache/assets/tgui.dm
index 9c79925602c..4b31d93e037 100644
--- a/code/modules/asset_cache/assets/tgui.dm
+++ b/code/modules/asset_cache/assets/tgui.dm
@@ -1,3 +1,23 @@
+// If you use a file(...) object, instead of caching the asset it will be loaded from disk every time it's requested.
+// This is useful for development, but not recommended for production.
+// And if TGS is defined, we're being run in a production environment.
+
+#ifdef TGS
+/datum/asset/simple/tgui
+ keep_local_name = FALSE
+ assets = list(
+ "tgui.bundle.js" = "tgui/public/tgui.bundle.js",
+ "tgui.bundle.css" = "tgui/public/tgui.bundle.css",
+ )
+
+/datum/asset/simple/tgui_panel
+ keep_local_name = FALSE
+ assets = list(
+ "tgui-panel.bundle.js" = "tgui/public/tgui-panel.bundle.js",
+ "tgui-panel.bundle.css" = "tgui/public/tgui-panel.bundle.css",
+ )
+
+#else
/datum/asset/simple/tgui
keep_local_name = TRUE
assets = list(
@@ -11,3 +31,5 @@
"tgui-panel.bundle.js" = file("tgui/public/tgui-panel.bundle.js"),
"tgui-panel.bundle.css" = file("tgui/public/tgui-panel.bundle.css"),
)
+
+#endif
diff --git a/code/modules/atmospherics/machinery/air_alarm/air_alarm_interact.dm b/code/modules/atmospherics/machinery/air_alarm/air_alarm_interact.dm
index bb45d1f8c1f..f7eaf5788c9 100644
--- a/code/modules/atmospherics/machinery/air_alarm/air_alarm_interact.dm
+++ b/code/modules/atmospherics/machinery/air_alarm/air_alarm_interact.dm
@@ -140,7 +140,7 @@
if(istype(W, /obj/item/electroadaptive_pseudocircuit))
var/obj/item/electroadaptive_pseudocircuit/P = W
- if(!P.adapt_circuit(user, circuit_cost = 25 KILO JOULES))
+ if(!P.adapt_circuit(user, circuit_cost = 0.025 * STANDARD_CELL_CHARGE))
return
user.visible_message(span_notice("[user] fabricates a circuit and places it into [src]."), \
span_notice("You adapt an air alarm circuit and slot it into the assembly."))
diff --git a/code/modules/atmospherics/machinery/components/electrolyzer/electrolyzer.dm b/code/modules/atmospherics/machinery/components/electrolyzer/electrolyzer.dm
index 56ee3c6039d..2da9ac752b5 100644
--- a/code/modules/atmospherics/machinery/components/electrolyzer/electrolyzer.dm
+++ b/code/modules/atmospherics/machinery/components/electrolyzer/electrolyzer.dm
@@ -127,7 +127,7 @@
if(anchored)
use_energy(power_to_use)
else
- cell.use(power_to_use KILO JOULES)
+ cell.use(power_to_use)
/obj/machinery/electrolyzer/proc/call_reactions(datum/gas_mixture/env)
for(var/reaction in GLOB.electrolyzer_reactions)
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/machine_connector.dm b/code/modules/atmospherics/machinery/components/unary_devices/machine_connector.dm
index dc1c2d6282f..157cbae9af0 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/machine_connector.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/machine_connector.dm
@@ -5,14 +5,12 @@
var/obj/machinery/atmospherics/components/unary/gas_connector
/datum/gas_machine_connector/New(location, obj/machinery/connecting_machine = null, direction = SOUTH, gas_volume)
- gas_connector = new(location)
-
connected_machine = connecting_machine
if(!connected_machine)
- QDEL_NULL(gas_connector)
qdel(src)
return
+ gas_connector = new(location)
gas_connector.dir = connected_machine.dir
gas_connector.airs[1].volume = gas_volume
@@ -41,7 +39,8 @@
RegisterSignal(connected_machine, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(pre_move_connected_machine))
RegisterSignal(connected_machine, COMSIG_MOVABLE_MOVED, PROC_REF(moved_connected_machine))
RegisterSignal(connected_machine, COMSIG_MACHINERY_DEFAULT_ROTATE_WRENCH, PROC_REF(wrenched_connected_machine))
- RegisterSignal(connected_machine, COMSIG_QDELETING, PROC_REF(deconstruct_connected_machine))
+ RegisterSignal(connected_machine, COMSIG_OBJ_DECONSTRUCT, PROC_REF(deconstruct_connected_machine))
+ RegisterSignal(connected_machine, COMSIG_QDELETING, PROC_REF(destroy_connected_machine))
/**
* Unregister the signals previously registered
@@ -51,7 +50,8 @@
COMSIG_MOVABLE_MOVED,
COMSIG_MOVABLE_PRE_MOVE,
COMSIG_MACHINERY_DEFAULT_ROTATE_WRENCH,
- COMSIG_QDELETING,
+ COMSIG_OBJ_DECONSTRUCT,
+ COMSIG_QDELETING
))
/**
@@ -82,12 +82,18 @@
*/
/datum/gas_machine_connector/proc/deconstruct_connected_machine()
SIGNAL_HANDLER
+
relocate_airs()
+
+/**
+ * Called when the machine has been destroyed
+ */
+/datum/gas_machine_connector/proc/destroy_connected_machine()
+ SIGNAL_HANDLER
+
disconnect_connector()
SSair.stop_processing_machine(connected_machine)
unregister_from_machine()
- connected_machine = null
- QDEL_NULL(gas_connector)
qdel(src)
/**
diff --git a/code/modules/atmospherics/machinery/pipes/pipes.dm b/code/modules/atmospherics/machinery/pipes/pipes.dm
index 574daa2af3a..40258db903f 100644
--- a/code/modules/atmospherics/machinery/pipes/pipes.dm
+++ b/code/modules/atmospherics/machinery/pipes/pipes.dm
@@ -35,7 +35,12 @@
AddElement(/datum/element/undertile, TRAIT_T_RAY_VISIBLE) //if changing this, change the subtypes RemoveElements too, because thats how bespoke works
/obj/machinery/atmospherics/pipe/on_deconstruction(disassembled)
- releaseAirToTurf()
+ //we delete the parent here so it initializes air_temporary for us. See /datum/pipeline/Destroy() which calls temporarily_store_air()
+ QDEL_NULL(parent)
+
+ if(air_temporary)
+ var/turf/T = loc
+ T.assume_air(air_temporary)
return ..()
@@ -61,11 +66,6 @@
replace_pipenet(parent, new /datum/pipeline)
return list(parent)
-/obj/machinery/atmospherics/pipe/proc/releaseAirToTurf()
- if(air_temporary)
- var/turf/T = loc
- T.assume_air(air_temporary)
-
/obj/machinery/atmospherics/pipe/return_air()
if(air_temporary)
return air_temporary
diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm
index 75152798bba..6d4a8ad714a 100644
--- a/code/modules/atmospherics/machinery/portable/canister.dm
+++ b/code/modules/atmospherics/machinery/portable/canister.dm
@@ -483,7 +483,7 @@
var/energy_consumed = energy_factor * 250 * seconds_per_tick
if(powered(AREA_USAGE_EQUIP, ignore_use_power = TRUE))
use_energy(energy_consumed, channel = AREA_USAGE_EQUIP)
- else if(!internal_cell?.use(energy_consumed * 0.025 KILO JOULES))
+ else if(!internal_cell?.use(energy_consumed * 0.025))
shielding_powered = FALSE
SSair.start_processing_machine(src)
investigate_log("shielding turned off due to power loss")
diff --git a/code/modules/bitrunning/antagonists/netguardian.dm b/code/modules/bitrunning/antagonists/netguardian.dm
index 39d64675334..f0ea7822985 100644
--- a/code/modules/bitrunning/antagonists/netguardian.dm
+++ b/code/modules/bitrunning/antagonists/netguardian.dm
@@ -45,12 +45,17 @@
speech_span = SPAN_ROBOT
death_message = "malfunctions!"
+ lighting_cutoff_red = 30
+ lighting_cutoff_green = 5
+ lighting_cutoff_blue = 20
+
habitable_atmos = null
minimum_survivable_temperature = TCMB
ai_controller = /datum/ai_controller/basic_controller/netguardian
/mob/living/basic/netguardian/Initialize(mapload)
. = ..()
+ ADD_TRAIT(src, TRAIT_NO_FLOATING_ANIM, INNATE_TRAIT)
AddComponent(/datum/component/ranged_attacks, \
casing_type = /obj/item/ammo_casing/c46x30mm, \
projectile_sound = 'sound/weapons/gun/smg/shot.ogg', \
@@ -62,12 +67,19 @@
ai_controller.set_blackboard_key(BB_NETGUARDIAN_ROCKET_ABILITY, rockets)
AddElement(/datum/element/simple_flying)
+ update_appearance(UPDATE_OVERLAYS)
/mob/living/basic/netguardian/death(gibbed)
do_sparks(number = 3, cardinal_only = TRUE, source = src)
playsound(src, 'sound/mecha/weapdestr.ogg', 100)
return ..()
+/mob/living/basic/netguardian/update_overlays()
+ . = ..()
+ if (stat == DEAD)
+ return
+ . += emissive_appearance(icon, "netguardian_emissive", src)
+
/datum/action/cooldown/mob_cooldown/projectile_attack/rapid_fire/netguardian
name = "2E Rocket Launcher"
button_icon = 'icons/obj/weapons/guns/ammo.dmi'
@@ -82,9 +94,11 @@
playsound(player, 'sound/mecha/skyfall_power_up.ogg', 120)
player.say("target acquired.", "machine")
- var/mutable_appearance/scan_effect = mutable_appearance('icons/mob/nonhuman-player/netguardian.dmi', "scan")
- var/mutable_appearance/rocket_effect = mutable_appearance('icons/mob/nonhuman-player/netguardian.dmi', "rockets")
- var/list/overlays = list(scan_effect, rocket_effect)
+ var/overlay_icon = 'icons/mob/nonhuman-player/netguardian.dmi'
+ var/list/overlays = list()
+ overlays += mutable_appearance(overlay_icon, "scan")
+ overlays += mutable_appearance(overlay_icon, "rockets")
+ overlays += emissive_appearance(overlay_icon, "scan", player)
player.add_overlay(overlays)
StartCooldown()
diff --git a/code/modules/cards/deck/deck.dm b/code/modules/cards/deck/deck.dm
index 54f8a5feba6..ccce3560249 100644
--- a/code/modules/cards/deck/deck.dm
+++ b/code/modules/cards/deck/deck.dm
@@ -11,7 +11,7 @@
hitsound = null
attack_verb_continuous = list("attacks")
attack_verb_simple = list("attack")
- interaction_flags_click = NEED_DEXTERITY|FORBID_TELEKINESIS_REACH
+ interaction_flags_click = NEED_DEXTERITY|FORBID_TELEKINESIS_REACH|ALLOW_RESTING
/// The amount of time it takes to shuffle
var/shuffle_time = DECK_SHUFFLE_TIME
/// Deck shuffling cooldown.
diff --git a/code/modules/cards/singlecard.dm b/code/modules/cards/singlecard.dm
index e03c5800346..0c228fbbb17 100644
--- a/code/modules/cards/singlecard.dm
+++ b/code/modules/cards/singlecard.dm
@@ -14,7 +14,7 @@
throw_range = 7
attack_verb_continuous = list("attacks")
attack_verb_simple = list("attack")
- interaction_flags_click = NEED_DEXTERITY|FORBID_TELEKINESIS_REACH
+ interaction_flags_click = NEED_DEXTERITY|FORBID_TELEKINESIS_REACH|ALLOW_RESTING
/// Artistic style of the deck
var/deckstyle = "nanotrasen"
/// If the cards in the deck have different icon states (blank and CAS decks do not)
diff --git a/code/modules/cargo/supplypod.dm b/code/modules/cargo/supplypod.dm
index b36a3b59942..3be58d8a3c9 100644
--- a/code/modules/cargo/supplypod.dm
+++ b/code/modules/cargo/supplypod.dm
@@ -99,6 +99,23 @@
delays = list(POD_TRANSIT = 20, POD_FALLING = 4, POD_OPENING = 30, POD_LEAVING = 30)
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
+/obj/structure/closet/supplypod/centcompod/sisyphus
+ delays = list(POD_TRANSIT = 0, POD_FALLING = 0, POD_OPENING = 0, POD_LEAVING = 0.2)
+ reverse_delays = list(POD_TRANSIT = 0, POD_FALLING = 1.5 SECONDS, POD_OPENING = 0.6 SECONDS, POD_LEAVING = 0)
+ custom_rev_delay = TRUE
+ effectStealth = TRUE
+ reversing = TRUE
+ reverse_option_list = list(
+ "Mobs" = TRUE,
+ "Objects" = FALSE,
+ "Anchored" = FALSE,
+ "Underfloor" = FALSE,
+ "Wallmounted" = FALSE,
+ "Floors" = FALSE,
+ "Walls" = FALSE,
+ "Mecha" = TRUE,
+ )
+
/obj/structure/closet/supplypod/back_to_station
name = "blood-red supply pod"
desc = "An intimidating supply pod, covered in the blood-red markings"
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index 4473f8663b2..4e0a38b2186 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -8,11 +8,11 @@
///What level of bright light protection item has.
var/flash_protect = FLASH_PROTECTION_NONE
var/tint = 0 //Sets the item's level of visual impairment tint, normally set to the same as flash_protect
- var/up = 0 //but separated to allow items to protect but not impair vision, like space helmets
- var/visor_flags = 0 //flags that are added/removed when an item is adjusted up/down
- var/visor_flags_inv = 0 //same as visor_flags, but for flags_inv
- var/visor_flags_cover = 0 //same as above, but for flags_cover
- ///What to toggle when toggled with weldingvisortoggle()
+ var/up = FALSE //but separated to allow items to protect but not impair vision, like space helmets
+ var/visor_flags = NONE //flags that are added/removed when an item is adjusted up/down
+ var/visor_flags_inv = NONE //same as visor_flags, but for flags_inv
+ var/visor_flags_cover = NONE //same as above, but for flags_cover
+ ///What to toggle when toggled with adjust_visor()
var/visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT | VISOR_VISIONFLAGS | VISOR_INVISVIEW
var/clothing_flags = NONE
@@ -233,7 +233,9 @@
UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
for(var/trait in clothing_traits)
REMOVE_CLOTHING_TRAIT(user, trait)
-
+ if(iscarbon(user) && tint)
+ var/mob/living/carbon/carbon_user = user
+ carbon_user.update_tint()
if(LAZYLEN(user_vars_remembered))
for(var/variable in user_vars_remembered)
if(variable in user.vars)
@@ -250,6 +252,9 @@
RegisterSignal(user, COMSIG_MOVABLE_MOVED, PROC_REF(bristle), override = TRUE)
for(var/trait in clothing_traits)
ADD_CLOTHING_TRAIT(user, trait)
+ if(iscarbon(user) && tint)
+ var/mob/living/carbon/carbon_user = user
+ carbon_user.update_tint()
if (LAZYLEN(user_vars_to_edit))
for(var/variable in user_vars_to_edit)
if(variable in user.vars)
@@ -465,18 +470,30 @@ BLIND // can't see anything
female_clothing_icon = fcopy_rsc(female_clothing_icon)
GLOB.female_clothing_icons[index] = female_clothing_icon
-/obj/item/clothing/proc/weldingvisortoggle(mob/user) //proc to toggle welding visors on helmets, masks, goggles, etc.
+/// Proc that adjusts the clothing item, used by things like breathing masks, welding helmets, welding goggles etc.
+/obj/item/clothing/proc/adjust_visor(mob/living/user)
if(!can_use(user))
return FALSE
visor_toggling()
- to_chat(user, span_notice("You adjust \the [src] [up ? "up" : "down"]."))
+ to_chat(user, span_notice("You adjust [src] [up ? "up" : "down"]."))
- if(iscarbon(user))
- var/mob/living/carbon/C = user
- C.head_update(src, forced = 1)
update_item_action_buttons()
+
+ if(user.is_holding(src))
+ user.update_held_items()
+ return TRUE
+ if(up)
+ user.update_obscured_slots(visor_flags_inv)
+ user.update_clothing(slot_flags)
+ if(!iscarbon(user))
+ return TRUE
+ var/mob/living/carbon/carbon_user = user
+ if(visor_vars_to_toggle & VISOR_TINT)
+ carbon_user.update_tint()
+ if((visor_flags & (MASKINTERNALS|HEADINTERNALS)) && carbon_user.invalid_internals())
+ carbon_user.cutoff_internals()
return TRUE
/obj/item/clothing/proc/visor_toggling() //handles all the actual toggling of flags
@@ -484,31 +501,17 @@ BLIND // can't see anything
SEND_SIGNAL(src, COMSIG_CLOTHING_VISOR_TOGGLE, up)
clothing_flags ^= visor_flags
flags_inv ^= visor_flags_inv
- flags_cover ^= initial(flags_cover)
- icon_state = "[initial(icon_state)][up ? "up" : ""]"
- if(visor_vars_to_toggle & VISOR_FLASHPROTECT)
- flash_protect ^= initial(flash_protect)
- if(visor_vars_to_toggle & VISOR_TINT)
- tint ^= initial(tint)
-
-/obj/item/clothing/head/helmet/space/plasmaman/visor_toggling() //handles all the actual toggling of flags
- up = !up
- SEND_SIGNAL(src, COMSIG_CLOTHING_VISOR_TOGGLE, up)
- clothing_flags ^= visor_flags
- flags_inv ^= visor_flags_inv
- icon_state = "[initial(icon_state)]"
+ flags_cover ^= visor_flags_cover
if(visor_vars_to_toggle & VISOR_FLASHPROTECT)
flash_protect ^= initial(flash_protect)
if(visor_vars_to_toggle & VISOR_TINT)
tint ^= initial(tint)
+ update_appearance() //most of the time the sprite changes
/obj/item/clothing/proc/can_use(mob/user)
- if(user && ismob(user))
- if(!user.incapacitated())
- return 1
- return 0
+ return istype(user) && !user.incapacitated()
-/obj/item/clothing/proc/_spawn_shreds()
+/obj/item/clothing/proc/spawn_shreds()
new /obj/effect/decal/cleanable/shreds(get_turf(src), name)
/obj/item/clothing/atom_destruction(damage_flag)
@@ -516,7 +519,7 @@ BLIND // can't see anything
return ..()
if(damage_flag == BOMB)
//so the shred survives potential turf change from the explosion.
- addtimer(CALLBACK(src, PROC_REF(_spawn_shreds)), 0.1 SECONDS)
+ addtimer(CALLBACK(src, PROC_REF(spawn_shreds)), 0.1 SECONDS)
deconstruct(FALSE)
if(damage_flag == CONSUME) //This allows for moths to fully consume clothing, rather than damaging it like other sources like brute
var/turf/current_position = get_turf(src)
diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm
index c44d5be4ef8..98bb6f56fc6 100644
--- a/code/modules/clothing/glasses/_glasses.dm
+++ b/code/modules/clothing/glasses/_glasses.dm
@@ -37,20 +37,17 @@
. += span_notice("Alt-click to toggle [p_their()] colors.")
/obj/item/clothing/glasses/visor_toggling()
- ..()
+ . = ..()
+ alternate_worn_layer = up ? ABOVE_BODY_FRONT_HEAD_LAYER : initial(alternate_worn_layer) // SKYRAT EDIT CHANGE - ORIGINAL : alternate_worn_layer = up ? ABOVE_BODY_FRONT_HEAD_LAYER : null
if(visor_vars_to_toggle & VISOR_VISIONFLAGS)
vision_flags ^= initial(vision_flags)
if(visor_vars_to_toggle & VISOR_INVISVIEW)
invis_view ^= initial(invis_view)
-/obj/item/clothing/glasses/weldingvisortoggle(mob/user)
+/obj/item/clothing/glasses/adjust_visor(mob/living/user)
. = ..()
- alternate_worn_layer = up ? ABOVE_BODY_FRONT_HEAD_LAYER : initial(alternate_worn_layer) // SKYRAT EDIT - ORIGINAL : alternate_worn_layer = up ? ABOVE_BODY_FRONT_HEAD_LAYER : null
- if(. && user)
+ if(. && !user.is_holding(src) && (visor_vars_to_toggle & (VISOR_VISIONFLAGS|VISOR_INVISVIEW)))
user.update_sight()
- if(iscarbon(user))
- var/mob/living/carbon/carbon_user = user
- carbon_user.head_update(src, forced = TRUE)
//called when thermal glasses are emped.
/obj/item/clothing/glasses/proc/thermal_overload()
@@ -452,7 +449,11 @@
alternate_worn_layer = ABOVE_BODY_FRONT_HEAD_LAYER // SKYRAT EDIT - Just so it works until I make the change upstream
/obj/item/clothing/glasses/welding/attack_self(mob/user)
- weldingvisortoggle(user)
+ adjust_visor(user)
+
+/obj/item/clothing/glasses/welding/update_icon_state()
+ . = ..()
+ icon_state = "[initial(icon_state)][up ? "up" : ""]"
/obj/item/clothing/glasses/welding/up/Initialize(mapload)
. = ..()
diff --git a/code/modules/clothing/gloves/boxing.dm b/code/modules/clothing/gloves/boxing.dm
index deed90b1696..03b1cbb5bf7 100644
--- a/code/modules/clothing/gloves/boxing.dm
+++ b/code/modules/clothing/gloves/boxing.dm
@@ -6,6 +6,25 @@
equip_delay_other = 60
species_exception = list(/datum/species/golem) // now you too can be a golem boxing champion
clothing_traits = list(TRAIT_CHUNKYFINGERS)
+ /// Determines the version of boxing (or any martial art for that matter) that the boxing gloves gives
+ var/style_to_give = /datum/martial_art/boxing
+
+/obj/item/clothing/gloves/boxing/Initialize(mapload)
+ . = ..()
+ var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/extendohand_l, /datum/crafting_recipe/extendohand_r)
+
+ AddComponent(
+ /datum/component/slapcrafting,\
+ slapcraft_recipes = slapcraft_recipe_list,\
+ )
+
+ AddComponent(/datum/component/martial_art_giver, style_to_give)
+
+/obj/item/clothing/gloves/boxing/evil
+ name = "evil boxing gloves"
+ desc = "These strange gloves radiate an unsually evil aura."
+ greyscale_colors = "#21211f"
+ style_to_give = /datum/martial_art/boxing/evil
/obj/item/clothing/gloves/boxing/green
icon_state = "boxinggreen"
@@ -18,3 +37,16 @@
/obj/item/clothing/gloves/boxing/yellow
icon_state = "boxingyellow"
greyscale_colors = "#d2a800"
+
+/obj/item/clothing/gloves/boxing/golden
+ name = "golden gloves"
+ desc = "The reigning champ of the station!"
+ icon_state = "boxinggold"
+ custom_materials = list(/datum/material/gold = SHEET_MATERIAL_AMOUNT*1) //LITERALLY GOLD
+ material_flags = MATERIAL_EFFECTS | MATERIAL_AFFECT_STATISTICS
+ equip_delay_other = 120
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE
+
+/obj/item/clothing/gloves/boxing/golden/Initialize(mapload)
+ . = ..()
+ AddElement(/datum/element/skill_reward, /datum/skill/athletics)
diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm
index c5b25166c09..4d9ec24e335 100644
--- a/code/modules/clothing/head/hardhat.dm
+++ b/code/modules/clothing/head/hardhat.dm
@@ -129,32 +129,21 @@
visor_flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF
///Icon state of the welding visor.
var/visor_state = "weldvisor"
- var/visor_sprite_path //SKYRAT EDIT --- Lets the visor not smush the snout
-
-/obj/item/clothing/head/utility/hardhat/welding/Initialize(mapload)
- . = ..()
- update_appearance()
/obj/item/clothing/head/utility/hardhat/welding/attack_self_secondary(mob/user, modifiers)
- toggle_welding_screen(user)
+ adjust_visor(user)
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
/obj/item/clothing/head/utility/hardhat/welding/ui_action_click(mob/user, actiontype)
if(istype(actiontype, /datum/action/item_action/toggle_welding_screen))
- toggle_welding_screen(user)
+ adjust_visor(user)
return
-
return ..()
-/obj/item/clothing/head/utility/hardhat/welding/proc/toggle_welding_screen(mob/living/user)
- if(weldingvisortoggle(user))
- playsound(src, 'sound/mecha/mechmove03.ogg', 50, TRUE) //Visors don't just come from nothing
- var/mob/living/carbon/carbon_user = user //SKYRAT EDIT --- Lets the visor not smush the snout
- if(carbon_user.dna.species.mutant_bodyparts["snout"])
- visor_sprite_path = 'modular_skyrat/master_files/icons/mob/clothing/head_muzzled.dmi'
- else
- visor_sprite_path = 'icons/mob/clothing/head/utility.dmi' //END SKYRAT EDIT
- update_appearance()
+/obj/item/clothing/head/utility/hardhat/welding/adjust_visor(mob/living/user)
+ . = ..()
+ if(.)
+ playsound(src, 'sound/mecha/mechmove03.ogg', 50, TRUE)
/obj/item/clothing/head/utility/hardhat/welding/worn_overlays(mutable_appearance/standing, isinhands)
. = ..()
@@ -162,9 +151,7 @@
return
if(!up)
- // SKYRAT EDIT: ORIGINAL - . += mutable_appearance('icons/mob/clothing/head/utility.dmi', visor_state)
- // SKYRAT EDIT: WELDING MUZZLES
- . += mutable_appearance(visor_sprite_path, visor_state)
+ . += mutable_appearance(visor_sprite_path, visor_state) //SKYRAT EDIT CHANGE - WELDING MUZZLES - ORIGINAL: . += mutable_appearance('icons/mob/clothing/head/utility.dmi', visor_state)
/obj/item/clothing/head/utility/hardhat/welding/update_overlays()
. = ..()
@@ -207,7 +194,8 @@
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF
visor_flags_cover = NONE
- flags_inv = HIDEEARS|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT
+ flags_inv = HIDEEARS|HIDEHAIR|HIDEFACE|HIDEFACIALHAIR|HIDESNOUT
+ transparent_protection = HIDEMASK|HIDEEYES
visor_flags_inv = NONE
visor_state = "weldvisor_atmos"
diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm
index 236d94c39fa..0122cda3978 100644
--- a/code/modules/clothing/head/helmet.dm
+++ b/code/modules/clothing/head/helmet.dm
@@ -142,6 +142,7 @@
/obj/item/clothing/head/helmet/toggleable
+ visor_vars_to_toggle = NONE
dog_fashion = null
///chat message when the visor is toggled down.
var/toggle_message
@@ -149,26 +150,11 @@
var/alt_toggle_message
/obj/item/clothing/head/helmet/toggleable/attack_self(mob/user)
+ adjust_visor(user)
+
+/obj/item/clothing/head/helmet/toggleable/update_icon_state()
. = ..()
- if(.)
- return
- if(user.incapacitated() || !try_toggle())
- return
- up = !up
- flags_1 ^= visor_flags
- flags_inv ^= visor_flags_inv
- flags_cover ^= visor_flags_cover
icon_state = "[initial(icon_state)][up ? "up" : ""]"
- to_chat(user, span_notice("[up ? alt_toggle_message : toggle_message] \the [src]."))
-
- user.update_worn_head()
- if(iscarbon(user))
- var/mob/living/carbon/carbon_user = user
- carbon_user.head_update(src, forced = TRUE)
-
-///Attempt to toggle the visor. Returns true if it does the thing.
-/obj/item/clothing/head/helmet/toggleable/proc/try_toggle()
- return TRUE
/obj/item/clothing/head/helmet/toggleable/riot
name = "riot helmet"
@@ -223,11 +209,18 @@
///Looping sound datum for the siren helmet
var/datum/looping_sound/siren/weewooloop
-/obj/item/clothing/head/helmet/toggleable/justice/try_toggle()
+/obj/item/clothing/head/helmet/toggleable/justice/adjust_visor(mob/living/user)
if(!COOLDOWN_FINISHED(src, visor_toggle_cooldown))
return FALSE
COOLDOWN_START(src, visor_toggle_cooldown, 2 SECONDS)
- return TRUE
+ return ..()
+
+/obj/item/clothing/head/helmet/toggleable/justice/visor_toggling()
+ . = ..()
+ if(up)
+ weewooloop.start()
+ else
+ weewooloop.stop()
/obj/item/clothing/head/helmet/toggleable/justice/Initialize(mapload)
. = ..()
@@ -237,13 +230,6 @@
QDEL_NULL(weewooloop)
return ..()
-/obj/item/clothing/head/helmet/toggleable/justice/attack_self(mob/user)
- . = ..()
- if(up)
- weewooloop.start()
- else
- weewooloop.stop()
-
/obj/item/clothing/head/helmet/toggleable/justice/escape
name = "alarm helmet"
desc = "WEEEEOOO. WEEEEEOOO. STOP THAT MONKEY. WEEEOOOO."
@@ -538,3 +524,48 @@
fire = 65
acid = 40
wound = 15
+
+/obj/item/clothing/head/helmet/military
+ name = "Crude Helmet"
+ desc = "A cheaply made kettle helmet with an added faceplate to protect your eyes and mouth."
+ icon_state = "military"
+ inhand_icon_state = "knight_helmet"
+ flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT
+ flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF
+ strip_delay = 80
+ dog_fashion = null
+ armor_type = /datum/armor/helmet_military
+
+/datum/armor/helmet_military
+ melee = 45
+ bullet = 25
+ laser = 25
+ energy = 25
+ bomb = 25
+ fire = 10
+ acid = 50
+ wound = 20
+
+/obj/item/clothing/head/helmet/military/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/clothing_fov_visor, FOV_90_DEGREES)
+
+/obj/item/clothing/head/helmet/knight/warlord
+ name = "golden barbute helmet"
+ desc = "There is no man behind the helmet, only a terrible thought."
+ icon_state = "warlord"
+ inhand_icon_state = null
+ armor_type = /datum/armor/helmet_warlord
+ flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEMASK|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT
+ flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF
+ slowdown = 0.2
+
+/datum/armor/helmet_warlord
+ melee = 70
+ bullet = 60
+ laser = 70
+ energy = 70
+ bomb = 40
+ fire = 50
+ acid = 50
+ wound = 30
diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm
index c212481453b..97c0093c599 100644
--- a/code/modules/clothing/head/jobs.dm
+++ b/code/modules/clothing/head/jobs.dm
@@ -173,7 +173,7 @@
armor_type = /datum/armor/fedora_det_hat
icon_state = "detective"
inhand_icon_state = "det_hat"
- interaction_flags_click = NEED_DEXTERITY|NEED_HANDS
+ interaction_flags_click = NEED_DEXTERITY|NEED_HANDS|ALLOW_RESTING
/// Cooldown for retrieving precious candy corn on alt click
var/candy_cooldown = 0
dog_fashion = /datum/dog_fashion/head/detective
@@ -222,7 +222,7 @@
icon_state = "detective"
inhand_icon_state = "det_hat"
dog_fashion = /datum/dog_fashion/head/detective
- interaction_flags_click = FORBID_TELEKINESIS_REACH
+ interaction_flags_click = FORBID_TELEKINESIS_REACH|ALLOW_RESTING
///prefix our phrases must begin with
var/prefix = "go go gadget"
///an assoc list of phrase = item (like gun = revolver)
diff --git a/code/modules/clothing/head/soft_caps.dm b/code/modules/clothing/head/soft_caps.dm
index 92517d4a7dd..3003e9a76ee 100644
--- a/code/modules/clothing/head/soft_caps.dm
+++ b/code/modules/clothing/head/soft_caps.dm
@@ -5,7 +5,7 @@
worn_icon = 'icons/mob/clothing/head/hats.dmi'
icon_state = "cargosoft"
inhand_icon_state = "greyscale_softcap" //todo wip
- interaction_flags_click = NEED_DEXTERITY
+ interaction_flags_click = NEED_DEXTERITY|ALLOW_RESTING
/// For setting icon archetype
var/soft_type = "cargo"
/// If there is a suffix to append
diff --git a/code/modules/clothing/head/welding.dm b/code/modules/clothing/head/welding.dm
index bccb1d4524d..cb785447174 100644
--- a/code/modules/clothing/head/welding.dm
+++ b/code/modules/clothing/head/welding.dm
@@ -14,6 +14,7 @@
actions_types = list(/datum/action/item_action/toggle)
visor_flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDESNOUT
visor_flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH | PEPPERPROOF
+ visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT
resistance_flags = FIRE_PROOF
clothing_flags = SNUG_FIT | STACKABLE_HELMET_EXEMPT
@@ -23,9 +24,9 @@
acid = 60
/obj/item/clothing/head/utility/welding/attack_self(mob/user)
- weldingvisortoggle(user)
+ adjust_visor(user)
-/obj/item/clothing/head/utility/welding/visor_toggling()
+/obj/item/clothing/head/utility/welding/update_icon_state()
. = ..()
+ icon_state = "[initial(icon_state)][up ? "up" : ""]"
inhand_icon_state = "[initial(inhand_icon_state)][up ? "off" : ""]"
-
diff --git a/code/modules/clothing/masks/_masks.dm b/code/modules/clothing/masks/_masks.dm
index 23fc2272229..c1d29d65c86 100644
--- a/code/modules/clothing/masks/_masks.dm
+++ b/code/modules/clothing/masks/_masks.dm
@@ -7,9 +7,8 @@
slot_flags = ITEM_SLOT_MASK
strip_delay = 40
equip_delay_other = 40
+ visor_vars_to_toggle = NONE
var/modifies_speech = FALSE
- ///Whether the mask is pushed out of the food hole or not.
- var/mask_adjusted = FALSE
var/adjusted_flags = null
///Did we install a filtering cloth?
var/has_filter = FALSE
@@ -69,33 +68,17 @@
M.update_worn_mask()
//Proc that moves gas/breath masks out of the way, disabling them and allowing pill/food consumption
-/obj/item/clothing/mask/proc/adjustmask(mob/living/carbon/user)
- if(user?.incapacitated())
- return
- mask_adjusted = !mask_adjusted
- if(!mask_adjusted)
- icon_state = initial(icon_state)
- clothing_flags |= visor_flags
- flags_inv |= visor_flags_inv
- flags_cover |= visor_flags_cover
- to_chat(user, span_notice("You push \the [src] back into place."))
- slot_flags = initial(slot_flags)
- else
- icon_state += "_up"
- to_chat(user, span_notice("You push \the [src] out of the way."))
- clothing_flags &= ~visor_flags
- flags_inv &= ~visor_flags_inv
- flags_cover &= ~visor_flags_cover
+/obj/item/clothing/mask/visor_toggling(mob/living/user)
+ . = ..()
+ if(up)
if(adjusted_flags)
slot_flags = adjusted_flags
- if(!istype(user))
- return
- // Update the mob if it's wearing the mask.
- if(user.wear_mask == src)
- user.wear_mask_update(src, toggle_off = mask_adjusted)
- if(loc == user)
- // Update action button icon for adjusted mask, if someone is holding it.
- user.update_mob_action_buttons()
+ else
+ slot_flags = initial(slot_flags)
+
+/obj/item/clothing/mask/update_icon_state()
+ . = ..()
+ icon_state = "[initial(icon_state)][up ? "_up" : ""]"
/**
* Proc called in lungs.dm to act if wearing a mask with filters, used to reduce the filters durability, return a changed gas mixture depending on the filter status
diff --git a/code/modules/clothing/masks/bandana.dm b/code/modules/clothing/masks/bandana.dm
index cd4b3980e55..c80ad733543 100644
--- a/code/modules/clothing/masks/bandana.dm
+++ b/code/modules/clothing/masks/bandana.dm
@@ -22,7 +22,7 @@
/obj/item/clothing/mask/bandana/examine(mob/user)
. = ..()
- if(mask_adjusted)
+ if(up)
. += "Use in-hand to untie it to wear as a mask!"
return
if(slot_flags & ITEM_SLOT_NECK)
@@ -32,25 +32,25 @@
. += "Alt-click to tie it up to wear on your neck!"
/obj/item/clothing/mask/bandana/attack_self(mob/user)
+ adjust_visor(user)
+
+/obj/item/clothing/mask/bandana/adjust_visor(mob/living/user)
if(slot_flags & ITEM_SLOT_NECK)
to_chat(user, span_warning("You must undo [src] in order to push it into a hat!"))
- return
- //SKYRAT EDIT START: BANDANA HATS FOR MUTANTS
+ return FALSE
+ //SKYRAT EDIT ADDITION START: BANDANA HATS FOR MUTANTS
if(slot_flags & ITEM_SLOT_HEAD)
supports_variations_flags = NONE
if(slot_flags & ITEM_SLOT_MASK)
supports_variations_flags = initial(supports_variations_flags)
- //SKYRAT EDIT END
+ //SKYRAT EDIT ADDITION END
+ return ..()
- adjustmask(user)
-
-/obj/item/clothing/mask/bandana/adjustmask(mob/living/user)
+/obj/item/clothing/mask/bandana/visor_toggling()
. = ..()
- if(mask_adjusted)
+ if(up)
undyeable = TRUE
else
- inhand_icon_state = initial(inhand_icon_state)
- worn_icon_state = initial(worn_icon_state)
undyeable = initial(undyeable)
/obj/item/clothing/mask/bandana/click_alt(mob/user)
@@ -231,14 +231,13 @@
greyscale_config_inhand_left = /datum/greyscale_config/facescarf/inhands_left
greyscale_config_inhand_right = /datum/greyscale_config/facescarf/inhands_right
flags_1 = IS_PLAYER_COLORABLE_1
- interaction_flags_click = NEED_DEXTERITY
+ interaction_flags_click = NEED_DEXTERITY|ALLOW_RESTING
/obj/item/clothing/mask/facescarf/attack_self(mob/user)
- adjustmask(user)
-
+ adjust_visor(user)
/obj/item/clothing/mask/facescarf/click_alt(mob/user)
- adjustmask(user)
+ adjust_visor(user)
return CLICK_ACTION_SUCCESS
diff --git a/code/modules/clothing/masks/boxing.dm b/code/modules/clothing/masks/boxing.dm
index 78ba0764b81..468b1272f86 100644
--- a/code/modules/clothing/masks/boxing.dm
+++ b/code/modules/clothing/masks/boxing.dm
@@ -10,7 +10,7 @@
actions_types = list(/datum/action/item_action/adjust)
/obj/item/clothing/mask/balaclava/attack_self(mob/user)
- adjustmask(user)
+ adjust_visor(user)
/obj/item/clothing/mask/floortilebalaclava
name = "floortile balaclava"
@@ -25,7 +25,7 @@
actions_types = list(/datum/action/item_action/adjust)
/obj/item/clothing/mask/floortilebalaclava/attack_self(mob/user)
- adjustmask(user)
+ adjust_visor(user)
/obj/item/clothing/mask/luchador
name = "Luchador Mask"
diff --git a/code/modules/clothing/masks/breath.dm b/code/modules/clothing/masks/breath.dm
index 0249f0b1321..73f91f7c6b8 100644
--- a/code/modules/clothing/masks/breath.dm
+++ b/code/modules/clothing/masks/breath.dm
@@ -12,7 +12,7 @@
flags_cover = MASKCOVERSMOUTH
visor_flags_cover = MASKCOVERSMOUTH
resistance_flags = NONE
- interaction_flags_click = NEED_DEXTERITY
+ interaction_flags_click = NEED_DEXTERITY|ALLOW_RESTING
/datum/armor/mask_breath
bio = 50
@@ -22,10 +22,10 @@
return OXYLOSS
/obj/item/clothing/mask/breath/attack_self(mob/user)
- adjustmask(user)
+ adjust_visor(user)
/obj/item/clothing/mask/breath/click_alt(mob/user)
- adjustmask(user)
+ adjust_visor(user)
return CLICK_ACTION_SUCCESS
/obj/item/clothing/mask/breath/examine(mob/user)
diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm
index 5c95a4f0e44..0a40d814622 100644
--- a/code/modules/clothing/masks/gasmask.dm
+++ b/code/modules/clothing/masks/gasmask.dm
@@ -57,11 +57,11 @@ GLOBAL_LIST_INIT(clown_mask_options, list(
cig?.equipped(equipee, slot)
return ..()
-/obj/item/clothing/mask/gas/adjustmask(mob/living/carbon/user)
- if(isnull(cig))
- return ..()
- balloon_alert(user, "there's a cig in the way!")
-
+/obj/item/clothing/mask/gas/adjust_visor(mob/living/user)
+ if(!isnull(cig))
+ balloon_alert(user, "cig in the way!")
+ return FALSE
+ return ..()
/obj/item/clothing/mask/gas/examine(mob/user)
. = ..()
@@ -219,6 +219,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list(
flags_cover = MASKCOVERSEYES
visor_flags_inv = HIDEEYES
visor_flags_cover = MASKCOVERSEYES
+ visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT
resistance_flags = FIRE_PROOF
/datum/armor/gas_welding
@@ -228,10 +229,16 @@ GLOBAL_LIST_INIT(clown_mask_options, list(
acid = 55
/obj/item/clothing/mask/gas/welding/attack_self(mob/user)
- if(weldingvisortoggle(user))
+ adjust_visor(user)
+
+/obj/item/clothing/mask/gas/welding/adjust_visor(mob/living/user)
+ . = ..()
+ if(.)
playsound(src, 'sound/mecha/mechmove03.ogg', 50, TRUE)
-/obj/item/clothing/mask/gas/welding/up
+/obj/item/clothing/mask/gas/welding/update_icon_state()
+ . = ..()
+ icon_state = "[initial(icon_state)][up ? "up" : ""]"
/obj/item/clothing/mask/gas/welding/up/Initialize(mapload)
. = ..()
diff --git a/code/modules/clothing/masks/hailer.dm b/code/modules/clothing/masks/hailer.dm
index 7c351d3ad34..cbfbc166cbc 100644
--- a/code/modules/clothing/masks/hailer.dm
+++ b/code/modules/clothing/masks/hailer.dm
@@ -124,7 +124,7 @@ GLOBAL_LIST_INIT(hailer_phrases, list(
if(istype(action, /datum/action/item_action/halt))
halt()
else
- adjustmask(user)
+ adjust_visor(user)
/obj/item/clothing/mask/gas/sechailer/attack_self()
halt()
diff --git a/code/modules/clothing/masks/surgical.dm b/code/modules/clothing/masks/surgical.dm
index b754dc43014..4e8390edae7 100644
--- a/code/modules/clothing/masks/surgical.dm
+++ b/code/modules/clothing/masks/surgical.dm
@@ -15,4 +15,4 @@
bio = 100
/obj/item/clothing/mask/surgical/attack_self(mob/user)
- adjustmask(user)
+ adjust_visor(user)
diff --git a/code/modules/clothing/spacesuits/_spacesuits.dm b/code/modules/clothing/spacesuits/_spacesuits.dm
index 785ec9e26f9..7c93019cb64 100644
--- a/code/modules/clothing/spacesuits/_spacesuits.dm
+++ b/code/modules/clothing/spacesuits/_spacesuits.dm
@@ -1,5 +1,5 @@
/// Charge per tick consumed by the thermal regulator
-#define THERMAL_REGULATOR_COST (18 KILO JOULES)
+#define THERMAL_REGULATOR_COST (0.018 * STANDARD_CELL_CHARGE)
//Note: Everything in modules/clothing/spacesuits should have the entire suit grouped together.
// Meaning the the suit is defined directly after the corrisponding helmet. Just like below!
@@ -58,7 +58,7 @@
equip_delay_other = 80
resistance_flags = NONE
actions_types = list(/datum/action/item_action/toggle_spacesuit)
- interaction_flags_click = NEED_DEXTERITY
+ interaction_flags_click = NEED_DEXTERITY|ALLOW_RESTING
/// The default temperature setting
var/temperature_setting = BODYTEMP_NORMAL
/// If this is a path, this gets created as an object in Initialize.
diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm
index 02a54f194ea..bd20874f88d 100644
--- a/code/modules/clothing/spacesuits/plasmamen.dm
+++ b/code/modules/clothing/spacesuits/plasmamen.dm
@@ -88,26 +88,25 @@
. += span_notice("There's nothing placed on the helmet.")
/obj/item/clothing/head/helmet/space/plasmaman/click_alt(mob/user)
- toggle_welding_screen(user)
- return CLICK_ACTION_SUCCESS
+ if(user.can_perform_action(src))
+ adjust_visor(user)
/obj/item/clothing/head/helmet/space/plasmaman/ui_action_click(mob/user, action)
if(istype(action, /datum/action/item_action/toggle_welding_screen))
- toggle_welding_screen(user)
+ adjust_visor(user)
return
return ..()
-/obj/item/clothing/head/helmet/space/plasmaman/proc/toggle_welding_screen(mob/living/user)
- if(weldingvisortoggle(user))
- if(helmet_on)
- to_chat(user, span_notice("Your helmet's torch can't pass through your welding visor!"))
- helmet_on = FALSE
- playsound(src, 'sound/mecha/mechmove03.ogg', 50, TRUE) //Visors don't just come from nothing
- update_appearance()
- else
- playsound(src, 'sound/mecha/mechmove03.ogg', 50, TRUE) //Visors don't just come from nothing
- update_appearance()
+/obj/item/clothing/head/helmet/space/plasmaman/adjust_visor(mob/living/user)
+ . = ..()
+ if(!.)
+ return
+ if(helmet_on)
+ to_chat(user, span_notice("Your helmet's torch can't pass through your welding visor!"))
+ helmet_on = FALSE
+ playsound(src, 'sound/mecha/mechmove03.ogg', 50, TRUE) //Visors don't just come from nothing
+ update_appearance()
/obj/item/clothing/head/helmet/space/plasmaman/update_icon_state()
. = ..()
@@ -116,7 +115,8 @@
/obj/item/clothing/head/helmet/space/plasmaman/update_overlays()
. = ..()
- . += visor_icon
+ if(!up)
+ . += visor_icon
/obj/item/clothing/head/helmet/space/plasmaman/attackby(obj/item/hitting_item, mob/living/user)
. = ..()
diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm
index dcf6d502834..7367020ea04 100644
--- a/code/modules/clothing/suits/armor.dm
+++ b/code/modules/clothing/suits/armor.dm
@@ -712,3 +712,48 @@
fire = 40
acid = 50
wound = 30
+
+/obj/item/clothing/suit/armor/vest/military
+ name = "Crude chestplate"
+ desc = "It may look rough, rusty and battered, but it's also made out of junk and uncomfortable to wear."
+ icon_state = "military"
+ inhand_icon_state = "armor"
+ dog_fashion = null
+ armor_type = /datum/armor/military
+ allowed = list(
+ /obj/item/banner,
+ /obj/item/claymore/shortsword,
+ /obj/item/nullrod,
+ /obj/item/spear,
+ /obj/item/gun/ballistic/bow
+ )
+
+/datum/armor/military
+ melee = 45
+ bullet = 25
+ laser = 25
+ energy = 25
+ bomb = 25
+ fire = 10
+ acid = 50
+ wound = 20
+
+/obj/item/clothing/suit/armor/riot/knight/warlord
+ name = "golden plate armor"
+ desc = "This bulky set of armor is coated with a shiny layer of gold. It seems to almost reflect all light sources."
+ icon_state = "warlord"
+ inhand_icon_state = null
+ armor_type = /datum/armor/armor_warlord
+ w_class = WEIGHT_CLASS_BULKY
+ clothing_flags = THICKMATERIAL
+ slowdown = 0.8
+
+/datum/armor/armor_warlord
+ melee = 70
+ bullet = 60
+ laser = 70
+ energy = 70
+ bomb = 40
+ fire = 50
+ acid = 50
+ wound = 30
diff --git a/code/modules/clothing/under/costume.dm b/code/modules/clothing/under/costume.dm
index b09aaa34104..bc9aad4198a 100644
--- a/code/modules/clothing/under/costume.dm
+++ b/code/modules/clothing/under/costume.dm
@@ -431,3 +431,17 @@
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS|HEAD
flags_inv = HIDEGLOVES|HIDESHOES|HIDEEARS|HIDEEYES|HIDEHAIR
+/obj/item/clothing/under/costume/gamberson
+ name = "re-enactor's Gamberson"
+ desc = "A colorful set of clothes made to look like a medieval gamberson."
+ icon_state = "gamberson"
+ inhand_icon_state = null
+ female_sprite_flags = NO_FEMALE_UNIFORM
+ can_adjust = FALSE
+
+/obj/item/clothing/under/costume/gamberson/military
+ name = "swordsman's Gamberson"
+ desc = "A padded medieval gamberson. Has enough woolen layers to dull a strike from any small weapon."
+ armor_type = /datum/armor/clothing_under/rank_security
+ has_sensor = NO_SENSORS
+
diff --git a/code/modules/deathmatch/deathmatch_loadouts.dm b/code/modules/deathmatch/deathmatch_loadouts.dm
index 343df0a9943..a3d047c7b99 100644
--- a/code/modules/deathmatch/deathmatch_loadouts.dm
+++ b/code/modules/deathmatch/deathmatch_loadouts.dm
@@ -21,6 +21,9 @@
user.set_species(/datum/species/human)
for(var/datum/action/act as anything in granted_spells)
var/datum/action/new_ability = new act(user)
+ if(istype(new_ability, /datum/action/cooldown/spell))
+ var/datum/action/cooldown/spell/new_spell = new_ability
+ new_spell.spell_requirements = SPELL_REQUIRES_NO_ANTIMAGIC
new_ability.Grant(user)
/datum/outfit/deathmatch_loadout/naked
@@ -164,6 +167,7 @@
name = "Deathmatch: Druid"
display_name = "Druid"
desc = "How can plants help you?"
+
species_override = /datum/species/pod
l_hand = /obj/item/gun/ballistic/bow
r_hand = /obj/item/ammo_casing/arrow
@@ -259,7 +263,6 @@
l_pocket = /obj/item/melee/energy/sword/bananium
r_pocket = /obj/item/shield/energy/bananium
gloves = /obj/item/clothing/gloves/tackler/rocket
-
backpack_contents = list(
/obj/item/reagent_containers/spray/waterflower = 1,
/obj/item/instrument/bikehorn = 1,
@@ -357,3 +360,167 @@
shoes = /obj/item/clothing/shoes/cowboy
belt = /obj/item/storage/belt/holster/detective/full
head = /obj/item/clothing/head/cowboy/brown
+
+/// wizards
+
+/datum/outfit/deathmatch_loadout/wizard
+ name = "Deathmatch: Wizard"
+ display_name = "Wizard"
+ desc = "It's wizard time, motherfucker! FIREBALL!!"
+
+ l_hand = /obj/item/staff
+ uniform = /datum/outfit/wizard::uniform
+ suit = /datum/outfit/wizard::suit
+ head = /datum/outfit/wizard::head
+ shoes = /datum/outfit/wizard::shoes
+ granted_spells = list(
+ /datum/action/cooldown/spell/aoe/magic_missile,
+ /datum/action/cooldown/spell/forcewall,
+ /datum/action/cooldown/spell/jaunt/ethereal_jaunt,
+ )
+
+/datum/outfit/deathmatch_loadout/wizard/pyro
+ name = "Deathmatch: Pyromancer"
+ display_name = "Pyromancer"
+ desc = "Burninating the station-side! Burninating all the wizards!"
+
+ suit = /obj/item/clothing/suit/wizrobe/red
+ head = /obj/item/clothing/head/wizard/red
+ mask = /obj/item/clothing/mask/cigarette
+ granted_spells = list(
+ /datum/action/cooldown/spell/pointed/projectile/fireball,
+ /datum/action/cooldown/spell/smoke,
+ )
+
+/datum/outfit/deathmatch_loadout/wizard/electro
+ name = "Deathmatch: Electromancer"
+ display_name = "Electromancer"
+ desc = "Batons are so last century."
+
+ suit = /obj/item/clothing/suit/wizrobe/magusred
+ head = /obj/item/clothing/head/wizard/magus
+ granted_spells = list(
+ /datum/action/cooldown/spell/pointed/projectile/lightningbolt,
+ /datum/action/cooldown/spell/charged/beam/tesla,
+ )
+
+/datum/outfit/deathmatch_loadout/wizard/necromancer
+ name = "Deathmatch: Necromancer"
+ display_name = "Necromancer"
+ desc = "I've got a BONE to pick- Yeah, sorry."
+
+ species_override = /datum/species/skeleton
+ suit = /obj/item/clothing/suit/wizrobe/black
+ head = /obj/item/clothing/head/wizard/black
+ granted_spells = list(
+ /datum/action/cooldown/spell/touch/scream_for_me,
+ /datum/action/cooldown/spell/teleport/radius_turf/blink,
+ )
+
+/datum/outfit/deathmatch_loadout/wizard/larp
+ name = "Deathmatch: LARPer"
+ display_name = "LARPer"
+ desc = "Lightning bolt! Lightning bolt! Lightning bolt!"
+
+ l_hand = /obj/item/staff/stick
+ suit = /obj/item/clothing/suit/wizrobe/fake
+ head = /obj/item/clothing/head/wizard/fake
+ shoes = /obj/item/clothing/shoes/sandal
+ granted_spells = list(
+ /datum/action/cooldown/spell/conjure_item/spellpacket,
+ /datum/action/cooldown/spell/aoe/repulse/wizard,
+ )
+
+/datum/outfit/deathmatch_loadout/wizard/chuuni
+ name = "Deathmatch: Chuuni"
+ display_name = "Chuunibyou"
+ desc = "Darkness blacker than black and darker than dark, I beseech thee..."
+
+ l_hand = /obj/item/staff/broom
+ suit = /obj/item/clothing/suit/wizrobe/marisa
+ head = /obj/item/clothing/head/wizard/marisa
+ shoes = /obj/item/clothing/shoes/sneakers/marisa
+ granted_spells = list(
+ /datum/action/cooldown/spell/chuuni_invocations,
+ /datum/action/cooldown/spell/pointed/projectile/spell_cards,
+ )
+
+/datum/outfit/deathmatch_loadout/wizard/battle
+ name = "Deathmatch: Battlemage"
+ display_name = "Battlemage"
+ desc = "Have you heard of the High Elves?"
+
+ l_hand = /obj/item/mjollnir
+ suit = /obj/item/clothing/suit/wizrobe/magusblue
+ head = /obj/item/clothing/head/wizard/magus
+ granted_spells = list(
+ /datum/action/cooldown/spell/summonitem,
+ )
+
+/datum/outfit/deathmatch_loadout/wizard/apprentice
+ name = "Deathmatch: Apprentice"
+ display_name = "Apprentice"
+ desc = "You feel severely under-leveled for this encounter..."
+
+ l_hand = null
+ granted_spells = list(
+ /datum/action/cooldown/spell/charge,
+ )
+
+/datum/outfit/deathmatch_loadout/wizard/gunmancer
+ name = "Deathmatch: Gunmancer"
+ display_name = "Gunmancer"
+ desc = "Magic is lame."
+
+ l_hand = /obj/item/gun/ballistic/automatic/pistol/m1911
+ suit = /obj/item/clothing/suit/wizrobe/tape
+ head = /obj/item/clothing/head/wizard/tape
+ shoes = /obj/item/clothing/shoes/jackboots
+ granted_spells = list(
+ /datum/action/cooldown/spell/conjure_item/infinite_guns/gun,
+ /datum/action/cooldown/spell/aoe/knock,
+ )
+
+/datum/outfit/deathmatch_loadout/wizard/chaos
+ name = "Deathmatch: Chaos"
+ display_name = "Chaosmancer"
+ desc = "Hardcore Random Body ONLY!"
+
+ l_hand = /obj/item/gun/magic/staff/chaos
+ uniform = /obj/item/clothing/under/color/rainbow
+ suit = /obj/item/clothing/suit/costume/hawaiian
+ head = /obj/item/clothing/head/wizard/red
+ shoes = /obj/item/clothing/shoes/sneakers/marisa
+ granted_spells = list(
+ /datum/action/cooldown/spell/rod_form,
+ /datum/action/cooldown/spell/conjure/the_traps,
+ )
+
+/datum/outfit/deathmatch_loadout/wizard/clown
+ name = "Deathmatch: Clown"
+ display_name = "Funnymancer"
+ desc = "Honk NATH!"
+
+ l_hand = /obj/item/gun/magic/staff/honk
+ uniform = /obj/item/clothing/under/rank/civilian/clown
+ suit = /obj/item/clothing/suit/chaplainsuit/clownpriest
+ head = /obj/item/clothing/head/chaplain/clownmitre
+ mask = /obj/item/clothing/mask/gas/clown_hat
+ back = /obj/item/storage/backpack/clown
+ shoes = /obj/item/clothing/shoes/clown_shoes
+ granted_spells = null
+
+/datum/outfit/deathmatch_loadout/wizard/monkey
+ name = "Deathmatch: Monkey"
+ display_name = "Monkeymancer"
+ desc = "Ook eek aaa ooo eee!"
+
+ species_override = /datum/species/monkey
+ l_hand = /obj/item/food/grown/banana
+ uniform = null
+ suit = null
+ head = /obj/item/clothing/head/wizard
+ shoes = null
+ granted_spells = list(
+ /datum/action/cooldown/spell/conjure/simian,
+ )
diff --git a/code/modules/deathmatch/deathmatch_mapping.dm b/code/modules/deathmatch/deathmatch_mapping.dm
index c3e10279363..95b9f5cf278 100644
--- a/code/modules/deathmatch/deathmatch_mapping.dm
+++ b/code/modules/deathmatch/deathmatch_mapping.dm
@@ -10,3 +10,6 @@
/obj/effect/landmark/deathmatch_player_spawn
name = "Deathmatch Player Spawner"
+
+/area/deathmatch/teleport //Prevent access to cross-z teleportation in the map itself (no wands of safety/teleportation scrolls). Cordons should prevent same-z teleportations outside of the arena.
+ area_flags = UNIQUE_AREA | ABDUCTOR_PROOF | EVENT_PROTECTED | QUIET_LOGS
diff --git a/code/modules/deathmatch/deathmatch_maps.dm b/code/modules/deathmatch/deathmatch_maps.dm
index ebc3328e0ca..1abe92e7053 100644
--- a/code/modules/deathmatch/deathmatch_maps.dm
+++ b/code/modules/deathmatch/deathmatch_maps.dm
@@ -153,3 +153,25 @@
)
map_name = "backalley"
key = "backalley"
+
+/datum/lazy_template/deathmatch/raginmages
+ name = "Ragin' Mages"
+ desc = "Greetings! We're the wizards of the wizard federation!"
+ max_players = 8
+ automatic_gameend_time = 4 MINUTES // ill be surprised if this lasts more than two minutes
+ allowed_loadouts = list(
+ /datum/outfit/deathmatch_loadout/wizard,
+ /datum/outfit/deathmatch_loadout/wizard/pyro,
+ /datum/outfit/deathmatch_loadout/wizard/electro,
+ /datum/outfit/deathmatch_loadout/wizard/necromancer,
+ /datum/outfit/deathmatch_loadout/wizard/larp,
+ /datum/outfit/deathmatch_loadout/wizard/chuuni,
+ /datum/outfit/deathmatch_loadout/wizard/battle,
+ /datum/outfit/deathmatch_loadout/wizard/apprentice,
+ /datum/outfit/deathmatch_loadout/wizard/gunmancer,
+ /datum/outfit/deathmatch_loadout/wizard/monkey,
+ /datum/outfit/deathmatch_loadout/wizard/chaos,
+ /datum/outfit/deathmatch_loadout/wizard/clown,
+ )
+ map_name = "ragin_mages"
+ key = "ragin_mages"
diff --git a/code/modules/events/immovable_rod/immovable_rod.dm b/code/modules/events/immovable_rod/immovable_rod.dm
index a4cc4d4d683..658d2d07bd8 100644
--- a/code/modules/events/immovable_rod/immovable_rod.dm
+++ b/code/modules/events/immovable_rod/immovable_rod.dm
@@ -45,9 +45,9 @@
RegisterSignal(src, COMSIG_ATOM_ENTERING, PROC_REF(on_entering_atom))
if(special_target)
- SSmove_manager.home_onto(src, special_target)
+ DSmove_manager.home_onto(src, special_target)
else
- SSmove_manager.move_towards(src, real_destination)
+ DSmove_manager.move_towards(src, real_destination)
/obj/effect/immovablerod/Destroy(force)
UnregisterSignal(src, COMSIG_ATOM_ENTERING)
@@ -113,7 +113,7 @@
return
visible_message(span_danger("[src] phases into reality."))
- SSmove_manager.home_onto(src, special_target)
+ DSmove_manager.home_onto(src, special_target)
if(loc == target_turf)
complete_trajectory()
@@ -264,7 +264,7 @@
* Stops your rod's automated movement. Sit... Stay... Good rod!
*/
/obj/effect/immovablerod/proc/sit_stay_good_rod()
- SSmove_manager.stop_looping(src)
+ DSmove_manager.stop_looping(src)
/**
* Allows your rod to release restraint level zero and go for a walk.
@@ -278,7 +278,7 @@
/obj/effect/immovablerod/proc/go_for_a_walk(walkies_location = null)
if(walkies_location)
special_target = walkies_location
- SSmove_manager.home_onto(src, special_target)
+ DSmove_manager.home_onto(src, special_target)
return
complete_trajectory()
@@ -294,7 +294,7 @@
*/
/obj/effect/immovablerod/proc/walk_in_direction(direction)
destination_turf = get_edge_target_turf(src, direction)
- SSmove_manager.move_towards(src, destination_turf)
+ DSmove_manager.move_towards(src, destination_turf)
/**
* Rod will push the tram to a landmark if it hits the tram from the front/back
diff --git a/code/modules/events/shuttle_insurance.dm b/code/modules/events/shuttle_insurance.dm
index 4fce9c556b8..fed6ad9af9e 100644
--- a/code/modules/events/shuttle_insurance.dm
+++ b/code/modules/events/shuttle_insurance.dm
@@ -43,7 +43,7 @@
/datum/round_event/shuttle_insurance/start()
insurance_message = new("Shuttle Insurance", "Hey, pal, this is the [ship_name]. Can't help but notice you're rocking a wild and crazy shuttle there with NO INSURANCE! Crazy. What if something happened to it, huh?! We've done a quick evaluation on your rates in this sector and we're offering [insurance_evaluation] to cover for your shuttle in case of any disaster.", list("Purchase Insurance.","Reject Offer."))
insurance_message.answer_callback = CALLBACK(src, PROC_REF(answered))
- SScommunications.send_message(insurance_message, unique = TRUE)
+ DScommunications.send_message(insurance_message, unique = TRUE)
/datum/round_event/shuttle_insurance/proc/answered()
if(EMERGENCY_AT_LEAST_DOCKED)
diff --git a/code/modules/explorer_drone/loot.dm b/code/modules/explorer_drone/loot.dm
index 88cd5f38275..72773123968 100644
--- a/code/modules/explorer_drone/loot.dm
+++ b/code/modules/explorer_drone/loot.dm
@@ -175,7 +175,7 @@ GLOBAL_LIST_INIT(adventure_loot_generator_index,generate_generator_index())
return
if(LAZYACCESS(user.do_afters, "firelance"))
return
- if(!cell.use(200 KILO JOULES))
+ if(!cell.use(0.2 * STANDARD_CELL_CHARGE))
to_chat(user,span_warning("[src] battery ran dry!"))
return
ADD_TRAIT(user, TRAIT_IMMOBILIZED, REF(src))
diff --git a/code/modules/food_and_drinks/machinery/microwave.dm b/code/modules/food_and_drinks/machinery/microwave.dm
index 55509886a3a..0f1be89410a 100644
--- a/code/modules/food_and_drinks/machinery/microwave.dm
+++ b/code/modules/food_and_drinks/machinery/microwave.dm
@@ -15,7 +15,7 @@
#define MAX_MICROWAVE_DIRTINESS 100
/// For the wireless version, and display fluff
-#define TIER_1_CELL_CHARGE_RATE (250 KILO JOULES)
+#define TIER_1_CELL_CHARGE_RATE (0.25 * STANDARD_CELL_CHARGE)
/obj/machinery/microwave
name = "microwave oven"
diff --git a/code/modules/food_and_drinks/machinery/oven.dm b/code/modules/food_and_drinks/machinery/oven.dm
index ef9aac9a410..c997f349241 100644
--- a/code/modules/food_and_drinks/machinery/oven.dm
+++ b/code/modules/food_and_drinks/machinery/oven.dm
@@ -264,7 +264,7 @@
if(isnull(item.atom_storage))
return NONE
- if(length(contents >= max_items))
+ if(length(contents) >= max_items)
balloon_alert(user, "it's full!")
return ITEM_INTERACT_BLOCKING
diff --git a/code/modules/food_and_drinks/recipes/food_mixtures.dm b/code/modules/food_and_drinks/recipes/food_mixtures.dm
index bada60cd548..e9a9405264a 100644
--- a/code/modules/food_and_drinks/recipes/food_mixtures.dm
+++ b/code/modules/food_and_drinks/recipes/food_mixtures.dm
@@ -1,4 +1,5 @@
/datum/crafting_recipe/food
+ mass_craftable = TRUE
/datum/crafting_recipe/food/on_craft_completion(mob/user, atom/result)
SHOULD_CALL_PARENT(TRUE)
@@ -267,7 +268,7 @@
required_reagents = list(/datum/reagent/consumable/olivepaste = 4, /datum/reagent/water = 1)
reaction_flags = REACTION_INSTANT
-/datum/chemical_reaction/food/vinegar
+/datum/chemical_reaction/food/wine_vinegar
results = list(/datum/reagent/consumable/vinegar = 5)
required_reagents = list(/datum/reagent/consumable/ethanol/wine = 1, /datum/reagent/water = 1, /datum/reagent/consumable/sugar = 1)
reaction_flags = REACTION_INSTANT
@@ -285,7 +286,7 @@
mix_message = "A smooth batter forms."
reaction_flags = REACTION_INSTANT
-/datum/chemical_reaction/food/vinegar
+/datum/chemical_reaction/food/grape_vinegar
results = list(/datum/reagent/consumable/vinegar = 5)
required_reagents = list(/datum/reagent/consumable/grapejuice = 5)
required_catalysts = list(/datum/reagent/consumable/enzyme = 5)
diff --git a/code/modules/hydroponics/fermenting_barrel.dm b/code/modules/hydroponics/fermenting_barrel.dm
index a971b2b6a74..676c0cec7bb 100644
--- a/code/modules/hydroponics/fermenting_barrel.dm
+++ b/code/modules/hydroponics/fermenting_barrel.dm
@@ -163,3 +163,13 @@
/obj/structure/fermenting_barrel/gunpowder/Initialize(mapload)
. = ..()
reagents.add_reagent(/datum/reagent/gunpowder, 500)
+
+/// Medieval pirates can have a barrel as a treat
+/obj/structure/fermenting_barrel/thermite
+ name = "thermite barrel"
+ desc = "A large wooden barrel for holding thermite. Use this to make a big flipping hole on walls."
+ can_open = FALSE
+
+/obj/structure/fermenting_barrel/thermite/Initialize(mapload)
+ . = ..()
+ reagents.add_reagent(/datum/reagent/thermite, 500)
diff --git a/code/modules/hydroponics/plant_genes.dm b/code/modules/hydroponics/plant_genes.dm
index ae20edfc1d6..96e68022a78 100644
--- a/code/modules/hydroponics/plant_genes.dm
+++ b/code/modules/hydroponics/plant_genes.dm
@@ -588,7 +588,7 @@
var/obj/item/stock_parts/cell/potato/pocell = new /obj/item/stock_parts/cell/potato(user.loc)
pocell.icon = our_plant.icon // Just in case the plant icons get spread out in different files eventually, this trait won't cause error sprites (also yay downstreams)
pocell.icon_state = our_plant.icon_state
- pocell.maxcharge = our_seed.potency * 20 KILO JOULES
+ pocell.maxcharge = our_seed.potency * 0.02 * STANDARD_CELL_CHARGE
// The secret of potato supercells!
var/datum/plant_gene/trait/cell_charge/electrical_gene = our_seed.get_gene(/datum/plant_gene/trait/cell_charge)
diff --git a/code/modules/jobs/access.dm b/code/modules/jobs/access.dm
index 2055080710e..b31574bec33 100644
--- a/code/modules/jobs/access.dm
+++ b/code/modules/jobs/access.dm
@@ -19,6 +19,12 @@
if(isAdminGhostAI(accessor))
//Access can't stop the abuse
return TRUE
+ //If the mob has the simple_access component with the requried access, we let them in.
+ var/attempted_access = SEND_SIGNAL(accessor, COMSIG_MOB_TRIED_ACCESS, src)
+ if(attempted_access & ACCESS_ALLOWED)
+ return TRUE
+ if(attempted_access & ACCESS_DISALLOWED)
+ return FALSE
if(HAS_SILICON_ACCESS(accessor))
if(ispAI(accessor))
return FALSE
@@ -28,9 +34,6 @@
if(onSyndieBase() && loc != accessor)
return FALSE
return TRUE //AI can do whatever it wants
- //If the mob has the simple_access component with the requried access, we let them in.
- else if(SEND_SIGNAL(accessor, COMSIG_MOB_TRIED_ACCESS, src) & ACCESS_ALLOWED)
- return TRUE
//If the mob is holding a valid ID, we let them in. get_active_held_item() is on the mob level, so no need to copypasta everywhere.
else if(check_access(accessor.get_active_held_item()) || check_access(accessor.get_inactive_held_item()))
return TRUE
diff --git a/code/modules/lootpanel/ss_looting.dm b/code/modules/lootpanel/ss_looting.dm
index cf0882fa890..94e12f88f95 100644
--- a/code/modules/lootpanel/ss_looting.dm
+++ b/code/modules/lootpanel/ss_looting.dm
@@ -2,8 +2,9 @@
/// Queues image generation for search objects without icons
SUBSYSTEM_DEF(looting)
name = "Loot Icon Generation"
- init_order = INIT_ORDER_LOOT
+ flags = SS_NO_INIT
priority = FIRE_PRIORITY_PROCESS
+ runlevels = RUNLEVEL_LOBBY|RUNLEVELS_DEFAULT
wait = 0.5 SECONDS
/// Backlog of items. Gets put into processing
var/list/datum/lootpanel/backlog = list()
@@ -32,7 +33,7 @@ SUBSYSTEM_DEF(looting)
if(!panel.process_images())
backlog += panel
-
+
if(MC_TICK_CHECK)
return
diff --git a/code/modules/mapfluff/ruins/lavalandruin_code/biodome_winter.dm b/code/modules/mapfluff/ruins/lavalandruin_code/biodome_winter.dm
index 150b4c5e44b..55fe9e77eac 100644
--- a/code/modules/mapfluff/ruins/lavalandruin_code/biodome_winter.dm
+++ b/code/modules/mapfluff/ruins/lavalandruin_code/biodome_winter.dm
@@ -45,5 +45,5 @@
else if(isliving(hit_atom))
var/mob/living/hit_mob = hit_atom
- SSmove_manager.stop_looping(hit_mob) //stops them mid pathing even if they're stunimmune
+ DSmove_manager.stop_looping(hit_mob) //stops them mid pathing even if they're stunimmune
hit_mob.apply_status_effect(/datum/status_effect/ice_block_talisman, 3 SECONDS)
diff --git a/code/modules/mapfluff/ruins/objects_and_mobs/necropolis_gate.dm b/code/modules/mapfluff/ruins/objects_and_mobs/necropolis_gate.dm
index 6ce6056b477..8dc9cec326d 100644
--- a/code/modules/mapfluff/ruins/objects_and_mobs/necropolis_gate.dm
+++ b/code/modules/mapfluff/ruins/objects_and_mobs/necropolis_gate.dm
@@ -262,7 +262,7 @@ GLOBAL_DATUM(necropolis_gate, /obj/structure/necropolis_gate/legion_gate)
var/static/list/give_turf_traits
if(!give_turf_traits)
- give_turf_traits = string_list(list(TRAIT_LAVA_STOPPED, TRAIT_CHASM_STOPPED))
+ give_turf_traits = string_list(list(TRAIT_LAVA_STOPPED, TRAIT_CHASM_STOPPED, TRAIT_IMMERSE_STOPPED))
AddElement(/datum/element/give_turf_traits, give_turf_traits)
/obj/structure/stone_tile/singularity_pull()
diff --git a/code/modules/meteors/meteor_types.dm b/code/modules/meteors/meteor_types.dm
index 2b37a55aaa4..d7a7dd14002 100644
--- a/code/modules/meteors/meteor_types.dm
+++ b/code/modules/meteors/meteor_types.dm
@@ -76,7 +76,7 @@
/obj/effect/meteor/proc/chase_target(atom/chasing, delay, home)
if(!isatom(chasing))
return
- var/datum/move_loop/new_loop = SSmove_manager.move_towards(src, chasing, delay, home, lifetime)
+ var/datum/move_loop/new_loop = DSmove_manager.move_towards(src, chasing, delay, home, lifetime)
if(!new_loop)
return
diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm
index 4845b0f9c00..5485ce72f22 100644
--- a/code/modules/mining/equipment/explorer_gear.dm
+++ b/code/modules/mining/equipment/explorer_gear.dm
@@ -85,20 +85,20 @@
starting_filter_type = /obj/item/gas_filter/plasmaman
/obj/item/clothing/mask/gas/explorer/attack_self(mob/user)
- adjustmask(user)
+ adjust_visor(user)
-/obj/item/clothing/mask/gas/explorer/adjustmask(mob/user)
+/obj/item/clothing/mask/gas/explorer/visor_toggling()
. = ..()
// adjusted = out of the way = smaller = can fit in boxes
- update_weight_class(mask_adjusted ? WEIGHT_CLASS_SMALL : WEIGHT_CLASS_NORMAL)
- inhand_icon_state = mask_adjusted ? "[initial(inhand_icon_state)]_up" : initial(inhand_icon_state)
- if(user)
- user.update_held_items()
+ update_weight_class(up ? WEIGHT_CLASS_SMALL : WEIGHT_CLASS_NORMAL)
+/obj/item/clothing/mask/gas/explorer/update_icon_state()
+ . = ..()
+ inhand_icon_state = "[initial(inhand_icon_state)][up ? "_up" : ""]"
/obj/item/clothing/mask/gas/explorer/examine(mob/user)
. = ..()
- if(mask_adjusted || w_class == WEIGHT_CLASS_SMALL)
+ if(up || w_class == WEIGHT_CLASS_SMALL)
return
. += span_notice("You could fit this into a box if you adjusted it.")
@@ -107,7 +107,7 @@
/obj/item/clothing/mask/gas/explorer/folded/Initialize(mapload)
. = ..()
- adjustmask()
+ visor_toggling()
/obj/item/clothing/suit/hooded/cloak
icon = 'icons/obj/clothing/suits/armor.dmi'
diff --git a/code/modules/mining/equipment/vent_pointer.dm b/code/modules/mining/equipment/vent_pointer.dm
new file mode 100644
index 00000000000..4edab185597
--- /dev/null
+++ b/code/modules/mining/equipment/vent_pointer.dm
@@ -0,0 +1,19 @@
+/obj/item/pinpointer/vent
+ name = "ventpointer"
+ desc = "A handheld tracking device. It will locate and point to nearby vents. A bit unreliable though."
+ icon_state = "pinpointer_vent"
+ minimum_range = 14 //gotta use them eyes
+
+/obj/item/pinpointer/vent/scan_for_target()
+ var/closest_dist = INFINITY
+
+ for(var/obj/structure/ore_vent/vent in SSore_generation.possible_vents)
+ if(vent.discovered || vent.tapped)
+ continue
+ if(vent.z != loc.z)
+ continue
+
+ var/target_dist = get_dist(src, vent)
+ if(target_dist < closest_dist)
+ closest_dist = target_dist
+ target = vent
diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm
index 61318f63b92..2eaa1d95db9 100644
--- a/code/modules/mining/machine_processing.dm
+++ b/code/modules/mining/machine_processing.dm
@@ -152,7 +152,7 @@
materials = AddComponent( \
/datum/component/material_container, \
- SSmaterials.materials_by_category[MAT_CATEGORY_SILO], \
+ DSmaterials.materials_by_category[MAT_CATEGORY_SILO], \
INFINITY, \
MATCONTAINER_EXAMINE, \
allowed_items = accepted_type \
diff --git a/code/modules/mining/machine_silo.dm b/code/modules/mining/machine_silo.dm
index 97c3a90b78e..5096f00a770 100644
--- a/code/modules/mining/machine_silo.dm
+++ b/code/modules/mining/machine_silo.dm
@@ -20,7 +20,7 @@
materials = AddComponent( \
/datum/component/material_container, \
- SSmaterials.materials_by_category[MAT_CATEGORY_SILO], \
+ DSmaterials.materials_by_category[MAT_CATEGORY_SILO], \
INFINITY, \
MATCONTAINER_EXAMINE, \
container_signals = list( \
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index f06c16e11de..1eec176a67d 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -429,10 +429,10 @@
var/obscured = NONE
var/hidden_slots = NONE
- for(var/obj/item/I in get_all_worn_items())
- hidden_slots |= I.flags_inv
+ for(var/obj/item/equipped_item in get_equipped_items())
+ hidden_slots |= equipped_item.flags_inv
if(transparent_protection)
- hidden_slots |= I.transparent_protection
+ hidden_slots |= equipped_item.transparent_protection
if(hidden_slots & HIDENECK)
obscured |= ITEM_SLOT_NECK
@@ -504,12 +504,8 @@
if(!I)
to_chat(src, span_warning("You are not holding anything to equip!"))
return
- if (temporarilyRemoveItemFromInventory(I) && !QDELETED(I))
- if(I.equip_to_best_slot(src))
- return
- if(put_in_active_hand(I))
- return
- I.forceMove(drop_location())
+ if(!QDELETED(I))
+ I.equip_to_best_slot(src)
//used in code for items usable by both carbon and drones, this gives the proper back slot for each mob.(defibrillator, backpack watertank, ...)
/mob/proc/getBackSlot()
diff --git a/code/modules/mob/living/basic/bots/_bots.dm b/code/modules/mob/living/basic/bots/_bots.dm
index ccd4b0d617f..d98369294e0 100644
--- a/code/modules/mob/living/basic/bots/_bots.dm
+++ b/code/modules/mob/living/basic/bots/_bots.dm
@@ -104,7 +104,7 @@ GLOBAL_LIST_INIT(command_strings, list(
AddElement(/datum/element/relay_attackers)
RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(handle_loop_movement))
RegisterSignal(src, COMSIG_ATOM_WAS_ATTACKED, PROC_REF(after_attacked))
- RegisterSignal(src, COMSIG_OBJ_ALLOWED, PROC_REF(attempt_access))
+ RegisterSignal(src, COMSIG_MOB_TRIED_ACCESS, PROC_REF(attempt_access))
ADD_TRAIT(src, TRAIT_NO_GLIDE, INNATE_TRAIT)
GLOB.bots_list += src
@@ -757,7 +757,7 @@ GLOBAL_LIST_INIT(command_strings, list(
/mob/living/basic/bot/proc/attempt_access(mob/bot, obj/door_attempt)
SIGNAL_HANDLER
- return (door_attempt.check_access(access_card) ? COMPONENT_OBJ_ALLOW : COMPONENT_OBJ_DISALLOW)
+ return (door_attempt.check_access(access_card) ? ACCESS_ALLOWED : ACCESS_DISALLOWED)
/mob/living/basic/bot/proc/generate_speak_list()
return null
diff --git a/code/modules/mob/living/basic/bots/bot_ai.dm b/code/modules/mob/living/basic/bots/bot_ai.dm
index 16ca5200308..1c30f83b2e6 100644
--- a/code/modules/mob/living/basic/bots/bot_ai.dm
+++ b/code/modules/mob/living/basic/bots/bot_ai.dm
@@ -91,10 +91,9 @@
behavior_flags = AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
/datum/ai_behavior/manage_unreachable_list/perform(seconds_per_tick, datum/ai_controller/controller, list_key)
- . = ..()
if(!isnull(controller.blackboard[list_key]))
controller.clear_blackboard_key(list_key)
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/manage_unreachable_list/finish_action(datum/ai_controller/controller, succeeded)
. = ..()
@@ -123,7 +122,6 @@
/datum/ai_behavior/find_first_beacon_target
/datum/ai_behavior/find_first_beacon_target/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/closest_distance = INFINITY
var/mob/living/basic/bot/bot_pawn = controller.pawn
var/atom/final_target
@@ -138,19 +136,16 @@
final_target = beacon
if(isnull(final_target))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
controller.set_blackboard_key(BB_BEACON_TARGET, final_target)
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/find_next_beacon_target/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/mob/living/basic/bot/bot_pawn = controller.pawn
var/atom/final_target
var/obj/machinery/navbeacon/prev_beacon = controller.blackboard[BB_PREVIOUS_BEACON_TARGET]
if(QDELETED(prev_beacon))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
for(var/obj/machinery/navbeacon/beacon as anything in GLOB.navbeacons["[bot_pawn.z]"])
if(beacon.location == prev_beacon.codes[NAVBEACON_PATROL_NEXT])
@@ -159,10 +154,10 @@
if(isnull(final_target))
controller.clear_blackboard_key(BB_PREVIOUS_BEACON_TARGET)
- finish_action(controller, FALSE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
controller.set_blackboard_key(BB_BEACON_TARGET, final_target)
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/travel_towards/beacon
@@ -224,14 +219,11 @@
/datum/ai_behavior/salute_authority
/datum/ai_behavior/salute_authority/perform(seconds_per_tick, datum/ai_controller/controller, target_key, salute_keys)
- . = ..()
if(!controller.blackboard_key_exists(target_key))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/list/salute_list = controller.blackboard[salute_keys]
if(!length(salute_list))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/mob/living/basic/bot/bot_pawn = controller.pawn
//special interaction if we are wearing a fedora
var/obj/item/our_hat = (locate(/obj/item/clothing/head) in bot_pawn)
@@ -239,8 +231,7 @@
salute_list += "tips [our_hat] at "
bot_pawn.manual_emote(pick(salute_list) + " [controller.blackboard[target_key]]!")
- finish_action(controller, TRUE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/salute_authority/finish_action(datum/ai_controller/controller, succeeded, target_key)
. = ..()
diff --git a/code/modules/mob/living/basic/bots/cleanbot/cleanbot_ai.dm b/code/modules/mob/living/basic/bots/cleanbot/cleanbot_ai.dm
index 537490c8431..a58a97c7274 100644
--- a/code/modules/mob/living/basic/bots/cleanbot/cleanbot_ai.dm
+++ b/code/modules/mob/living/basic/bots/cleanbot/cleanbot_ai.dm
@@ -122,16 +122,14 @@
set_movement_target(controller, target)
/datum/ai_behavior/execute_clean/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/mob/living/basic/living_pawn = controller.pawn
var/atom/target = controller.blackboard[target_key]
if(QDELETED(target))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
living_pawn.UnarmedAttack(target, proximity_flag = TRUE)
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/execute_clean/finish_action(datum/ai_controller/controller, succeeded, target_key, targeting_strategy_key, hiding_location_key)
. = ..()
diff --git a/code/modules/mob/living/basic/bots/hygienebot/hygienebot_ai.dm b/code/modules/mob/living/basic/bots/hygienebot/hygienebot_ai.dm
index d982869595b..2c614e003c8 100644
--- a/code/modules/mob/living/basic/bots/hygienebot/hygienebot_ai.dm
+++ b/code/modules/mob/living/basic/bots/hygienebot/hygienebot_ai.dm
@@ -80,11 +80,10 @@
break
if(isnull(found_target))
- finish_action(controller, succeeded = FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
controller.set_blackboard_key(target_key, found_target)
- finish_action(controller, succeeded = TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
@@ -112,17 +111,15 @@
var/mob/living/carbon/human/unclean_target = controller.blackboard[target_key]
var/mob/living/basic/living_pawn = controller.pawn
if(QDELETED(unclean_target))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
if(living_pawn.loc == get_turf(unclean_target))
living_pawn.melee_attack(unclean_target)
- finish_action(controller, TRUE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
var/frustration_count = controller.blackboard[BB_WASH_FRUSTRATION]
controller.set_blackboard_key(BB_WASH_FRUSTRATION, frustration_count + 1)
- finish_action(controller, FALSE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
/datum/ai_behavior/wash_target/finish_action(datum/ai_controller/controller, succeeded, target_key)
. = ..()
diff --git a/code/modules/mob/living/basic/bots/medbot/medbot_ai.dm b/code/modules/mob/living/basic/bots/medbot/medbot_ai.dm
index 21f9ab29d1b..0a4520ad17b 100644
--- a/code/modules/mob/living/basic/bots/medbot/medbot_ai.dm
+++ b/code/modules/mob/living/basic/bots/medbot/medbot_ai.dm
@@ -53,7 +53,6 @@
action_cooldown = 2 SECONDS
/datum/ai_behavior/find_suitable_patient/perform(seconds_per_tick, datum/ai_controller/basic_controller/bot/controller, target_key, threshold, heal_type, mode_flags, access_flags)
- . = ..()
search_range = (mode_flags & MEDBOT_STATIONARY_MODE) ? 1 : initial(search_range)
var/list/ignore_keys = controller.blackboard[BB_TEMPORARY_IGNORE_LIST]
for(var/mob/living/carbon/human/treatable_target in oview(search_range, controller.pawn))
@@ -71,7 +70,10 @@
controller.set_if_can_reach(BB_PATIENT_TARGET, treatable_target, distance = BOT_PATIENT_PATH_LIMIT, bypass_add_to_blacklist = (search_range == 1))
break
- finish_action(controller, controller.blackboard_key_exists(BB_PATIENT_TARGET))
+ if(controller.blackboard_key_exists(BB_PATIENT_TARGET))
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
+ else
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
/datum/ai_behavior/find_suitable_patient/finish_action(datum/ai_controller/controller, succeeded, target_key)
. = ..()
@@ -91,21 +93,18 @@
set_movement_target(controller, target)
/datum/ai_behavior/tend_to_patient/perform(seconds_per_tick, datum/ai_controller/basic_controller/bot/controller, target_key, threshold, damage_type_healer, access_flags, is_stationary)
- . = ..()
var/mob/living/carbon/human/patient = controller.blackboard[target_key]
if(QDELETED(patient) || patient.stat == DEAD)
- finish_action(controller, FALSE, target_key, is_stationary)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
if(check_if_healed(patient, threshold, damage_type_healer, access_flags))
- finish_action(controller, TRUE, target_key, is_stationary, healed_target = TRUE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
var/mob/living/basic/bot/bot_pawn = controller.pawn
if(patient.stat >= HARD_CRIT && prob(5))
var/datum/action/cooldown/bot_announcement/announcement = controller.blackboard[BB_ANNOUNCE_ABILITY]
announcement?.announce(pick(controller.blackboard[BB_NEAR_DEATH_SPEECH]))
bot_pawn.melee_attack(patient)
- finish_action(controller, TRUE, target_key, is_stationary)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
// only clear the target if they get healed
/datum/ai_behavior/tend_to_patient/finish_action(datum/ai_controller/controller, succeeded, target_key, is_stationary, healed_target = FALSE)
@@ -171,11 +170,10 @@
speech_to_pick_from += MEDIBOT_VOICED_CHICKEN
if(!length(speech_to_pick_from))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
announcement.announce(pick(speech_to_pick_from))
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_planning_subtree/find_and_hunt_target/patients_in_crit
target_key = BB_PATIENT_IN_CRIT
@@ -202,18 +200,15 @@
behavior_flags = AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
/datum/ai_behavior/announce_patient/perform(seconds_per_tick, datum/ai_controller/basic_controller/bot/controller, target_key)
- . = ..()
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
var/datum/action/cooldown/bot_announcement/announcement = controller.blackboard[BB_ANNOUNCE_ABILITY]
if(QDELETED(announcement))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/text_to_announce = "Medical emergency! [living_target] is in critical condition at [get_area(living_target)]!"
announcement.announce(text_to_announce, controller.blackboard[BB_RADIO_CHANNEL])
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/announce_patient/finish_action(datum/ai_controller/controller, succeeded, target_key)
. = ..()
diff --git a/code/modules/mob/living/basic/drone/drone_tools.dm b/code/modules/mob/living/basic/drone/drone_tools.dm
index 2350ec9cafb..1fa3aa7884b 100644
--- a/code/modules/mob/living/basic/drone/drone_tools.dm
+++ b/code/modules/mob/living/basic/drone/drone_tools.dm
@@ -48,7 +48,7 @@
name = "built-in crowbar"
desc = "A crowbar built into your chassis."
icon = 'icons/obj/items_cyborg.dmi'
- icon_state = "crowbar_cyborg"
+ icon_state = "toolkit_engiborg_crowbar"
inhand_icon_state = "crowbar"
item_flags = NO_MAT_REDEMPTION
@@ -56,7 +56,7 @@
name = "built-in screwdriver"
desc = "A screwdriver built into your chassis."
icon = 'icons/obj/items_cyborg.dmi'
- icon_state = "screwdriver_cyborg"
+ icon_state = "toolkit_engiborg_screwdriver"
inhand_icon_state = "screwdriver"
item_flags = NO_MAT_REDEMPTION
random_color = FALSE
@@ -75,7 +75,7 @@
name = "built-in wrench"
desc = "A wrench built into your chassis."
icon = 'icons/obj/items_cyborg.dmi'
- icon_state = "wrench_cyborg"
+ icon_state = "toolkit_engiborg_wrench"
inhand_icon_state = "wrench"
item_flags = NO_MAT_REDEMPTION
@@ -90,7 +90,7 @@
name = "built-in wirecutters"
desc = "Wirecutters built into your chassis."
icon = 'icons/obj/items_cyborg.dmi'
- icon_state = "wirecutters_cyborg"
+ icon_state = "toolkit_engiborg_cutters"
inhand_icon_state = "cutters"
item_flags = NO_MAT_REDEMPTION
random_color = FALSE
@@ -99,6 +99,6 @@
name = "built-in multitool"
desc = "A multitool built into your chassis."
icon = 'icons/obj/items_cyborg.dmi'
- icon_state = "multitool_cyborg"
+ icon_state = "toolkit_engiborg_multitool"
item_flags = NO_MAT_REDEMPTION
toolspeed = 0.5
diff --git a/code/modules/mob/living/basic/drone/visuals_icons.dm b/code/modules/mob/living/basic/drone/visuals_icons.dm
index ec01d7d2d78..7a2122022f8 100644
--- a/code/modules/mob/living/basic/drone/visuals_icons.dm
+++ b/code/modules/mob/living/basic/drone/visuals_icons.dm
@@ -27,7 +27,7 @@
client.screen += internal_storage
-/mob/living/basic/drone/update_worn_head()
+/mob/living/basic/drone/update_worn_head(update_obscured = TRUE)
remove_overlay(DRONE_HEAD_LAYER)
if(head)
@@ -44,7 +44,7 @@
apply_overlay(DRONE_HEAD_LAYER)
-/mob/living/basic/drone/update_worn_mask()
+/mob/living/basic/drone/update_worn_mask(update_obscured = TRUE)
update_worn_head()
/mob/living/basic/drone/regenerate_icons()
diff --git a/code/modules/mob/living/basic/farm_animals/bee/bee_ai_behavior.dm b/code/modules/mob/living/basic/farm_animals/bee/bee_ai_behavior.dm
index 0c48a945381..b4d73ad5927 100644
--- a/code/modules/mob/living/basic/farm_animals/bee/bee_ai_behavior.dm
+++ b/code/modules/mob/living/basic/farm_animals/bee/bee_ai_behavior.dm
@@ -25,7 +25,6 @@
set_movement_target(controller, target)
/datum/ai_behavior/enter_exit_hive/perform(seconds_per_tick, datum/ai_controller/controller, target_key, attack_key)
- . = ..()
var/obj/structure/beebox/current_home = controller.blackboard[target_key]
var/mob/living/bee_pawn = controller.pawn
var/atom/attack_target = controller.blackboard[attack_key]
@@ -35,7 +34,7 @@
var/datum/callback/callback = CALLBACK(bee_pawn, TYPE_PROC_REF(/mob/living/basic/bee, handle_habitation), current_home)
callback.Invoke()
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/inhabit_hive
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH
@@ -48,17 +47,15 @@
set_movement_target(controller, target)
/datum/ai_behavior/inhabit_hive/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/obj/structure/beebox/potential_home = controller.blackboard[target_key]
var/mob/living/bee_pawn = controller.pawn
if(!potential_home.habitable(bee_pawn)) //the house become full before we get to it
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/datum/callback/callback = CALLBACK(bee_pawn, TYPE_PROC_REF(/mob/living/basic/bee, handle_habitation), potential_home)
callback.Invoke()
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/inhabit_hive/finish_action(datum/ai_controller/controller, succeeded, target_key)
. = ..()
@@ -158,19 +155,18 @@
set_movement_target(controller, target)
/datum/ai_behavior/swirl_around_target/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/atom/target = controller.blackboard[target_key]
var/mob/living/living_pawn = controller.pawn
if(QDELETED(target))
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
if(get_dist(target, living_pawn) > 1)
set_movement_target(controller, target)
- return
+ return AI_BEHAVIOR_DELAY
if(!SPT_PROB(swirl_chance, seconds_per_tick))
- return
+ return AI_BEHAVIOR_DELAY
var/list/possible_turfs = list()
@@ -180,10 +176,11 @@
possible_turfs += possible_turf
if(!length(possible_turfs))
- return
+ return AI_BEHAVIOR_DELAY
if(isnull(controller.movement_target_source) || controller.movement_target_source == type)
set_movement_target(controller, pick(possible_turfs))
+ return AI_BEHAVIOR_DELAY
/datum/pet_command/beehive
diff --git a/code/modules/mob/living/basic/festivus_pole.dm b/code/modules/mob/living/basic/festivus_pole.dm
index 90eca4b272d..838674c0811 100644
--- a/code/modules/mob/living/basic/festivus_pole.dm
+++ b/code/modules/mob/living/basic/festivus_pole.dm
@@ -1,3 +1,6 @@
+///how much charge we give off to cells around us when rubbed
+#define FESTIVUS_RECHARGE_VALUE (0.075 * STANDARD_CELL_CHARGE)
+
/mob/living/basic/festivus
name = "festivus pole"
desc = "Serenity now... SERENITY NOW!"
@@ -37,10 +40,6 @@
ai_controller = /datum/ai_controller/basic_controller/festivus_pole
- ///how much charge we give off to cells around us when rubbed
- var/recharge_value = 75 KILO JOULES
-
-
/mob/living/basic/festivus/Initialize(mapload)
. = ..()
AddComponent(/datum/component/seethrough_mob)
@@ -71,16 +70,16 @@
for(var/atom/affected in range(2, get_turf(src)))
if(istype(affected, /obj/item/stock_parts/cell))
var/obj/item/stock_parts/cell/cell = affected
- cell.give(recharge_value)
+ cell.give(FESTIVUS_RECHARGE_VALUE)
cell.update_appearance()
if(istype(affected, /mob/living/silicon/robot))
var/mob/living/silicon/robot/robot = affected
if(robot.cell)
- robot.cell.give(recharge_value)
+ robot.cell.give(FESTIVUS_RECHARGE_VALUE)
if(istype(affected, /obj/machinery/power/apc))
var/obj/machinery/power/apc/apc_target = affected
if(apc_target.cell)
- apc_target.cell.give(recharge_value)
+ apc_target.cell.give(FESTIVUS_RECHARGE_VALUE)
/datum/ai_planning_subtree/find_and_hunt_target/look_for_apcs
hunting_behavior = /datum/ai_behavior/hunt_target/apcs
@@ -118,3 +117,5 @@
return FALSE
return can_see(source, dinner, radius)
+
+#undef FESTIVUS_RECHARGE_VALUE
diff --git a/code/modules/mob/living/basic/icemoon/ice_demon/ice_demon_ai.dm b/code/modules/mob/living/basic/icemoon/ice_demon/ice_demon_ai.dm
index 20bcd8a69a1..8a900b0308a 100644
--- a/code/modules/mob/living/basic/icemoon/ice_demon/ice_demon_ai.dm
+++ b/code/modules/mob/living/basic/icemoon/ice_demon/ice_demon_ai.dm
@@ -48,13 +48,11 @@
/datum/ai_behavior/find_valid_teleport_location
/datum/ai_behavior/find_valid_teleport_location/perform(seconds_per_tick, datum/ai_controller/controller, hunting_target_key, types_to_hunt, hunt_range)
- . = ..()
var/mob/living/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
var/list/possible_turfs = list()
if(QDELETED(target))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
for(var/turf/open/potential_turf in oview(hunt_range, target)) //we check for turfs around the target
if(potential_turf.is_blocked_turf())
@@ -64,11 +62,10 @@
possible_turfs += potential_turf
if(!length(possible_turfs))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
controller.set_blackboard_key(hunting_target_key, pick(possible_turfs))
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/hunt_target/use_ability_on_target/demon_teleport
hunt_cooldown = 2 SECONDS
diff --git a/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm
index 725dcc09b5e..53d7e7191ef 100644
--- a/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm
+++ b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm
@@ -38,8 +38,7 @@
/datum/ai_behavior/hunt_target/unarmed_attack_target/dragon_cannibalise/perform(seconds_per_tick, datum/ai_controller/controller, target_key, attack_key)
var/mob/living/target = controller.blackboard[target_key]
if(QDELETED(target) || target.stat != DEAD || target.pulledby) //we were too slow
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
return ..()
/datum/ai_behavior/cannibalize/finish_action(datum/ai_controller/controller, succeeded, target_key)
@@ -67,17 +66,14 @@
set_movement_target(controller, target)
/datum/ai_behavior/sculpt_statue/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
-
var/atom/target = controller.blackboard[target_key]
var/mob/living/basic/living_pawn = controller.pawn
if(QDELETED(target))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
living_pawn.melee_attack(target)
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/sculpt_statue/finish_action(datum/ai_controller/controller, succeeded, target_key)
. = ..()
@@ -123,8 +119,6 @@
/datum/ai_behavior/set_target_tree
/datum/ai_behavior/set_target_tree/perform(seconds_per_tick, datum/ai_controller/controller, tree_key)
- . = ..()
-
var/mob/living_pawn = controller.pawn
var/list/possible_trees = list()
@@ -134,11 +128,10 @@
possible_trees += possible_tree
if(!length(possible_trees))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
controller.set_blackboard_key(tree_key, pick(possible_trees))
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/targeted_mob_ability/and_clear_target/burn_trees
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
diff --git a/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_ai.dm b/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_ai.dm
index 0012aff294d..98025373b41 100644
--- a/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_ai.dm
+++ b/code/modules/mob/living/basic/lavaland/brimdemon/brimdemon_ai.dm
@@ -43,6 +43,5 @@
/datum/ai_behavior/targeted_mob_ability/brimbeam/perform(seconds_per_tick, datum/ai_controller/controller, ability_key, target_key)
var/mob/living/target = controller.blackboard[target_key]
if (QDELETED(target) || !(get_dir(controller.pawn, target) in GLOB.cardinals) || get_dist(controller.pawn, target) > max_target_distance)
- finish_action(controller, succeeded = FALSE, ability_key = ability_key, target_key = target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
return ..()
diff --git a/code/modules/mob/living/basic/lavaland/goliath/goliath_ai.dm b/code/modules/mob/living/basic/lavaland/goliath/goliath_ai.dm
index 76c230520df..86ba1e00320 100644
--- a/code/modules/mob/living/basic/lavaland/goliath/goliath_ai.dm
+++ b/code/modules/mob/living/basic/lavaland/goliath/goliath_ai.dm
@@ -36,8 +36,7 @@
if (ismecha(target) || (isliving(target) && !target.has_status_effect(/datum/status_effect/incapacitating/stun/goliath_tentacled)))
var/datum/action/cooldown/using_action = controller.blackboard[BB_GOLIATH_TENTACLES]
if (using_action?.IsAvailable())
- finish_action(controller, succeeded = FALSE)
- return
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
return ..()
/datum/ai_planning_subtree/targeted_mob_ability/goliath_tentacles
@@ -67,20 +66,18 @@
var/scan_range = 3
/datum/ai_behavior/goliath_find_diggable_turf/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
var/turf/target_turf = controller.blackboard[target_key]
if (is_valid_turf(target_turf))
- finish_action(controller, succeeded = FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/mob/living/pawn = controller.pawn
var/list/nearby_turfs = RANGE_TURFS(scan_range, pawn)
var/turf/check_turf = pick(nearby_turfs) // This isn't an efficient search algorithm but we don't need it to be
if (!is_valid_turf(check_turf))
- finish_action(controller, succeeded = FALSE) // Otherwise they won't perform idle wanderin
- return
+ // Otherwise they won't perform idle wanderin
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
controller.set_blackboard_key(target_key, check_turf)
- finish_action(controller, succeeded = TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/// Return true if this is a turf we can dig
/datum/ai_behavior/goliath_find_diggable_turf/proc/is_valid_turf(turf/check_turf)
@@ -112,13 +109,12 @@
set_movement_target(controller, target_turf)
/datum/ai_behavior/goliath_dig/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/turf/target_turf = controller.blackboard[target_key]
var/mob/living/basic/basic_mob = controller.pawn
if(!basic_mob.CanReach(target_turf))
- return
+ return AI_BEHAVIOR_DELAY
basic_mob.melee_attack(target_turf)
- finish_action(controller, succeeded = TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/goliath_dig/finish_action(datum/ai_controller/controller, succeeded, target_key)
. = ..()
diff --git a/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers_ai.dm b/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers_ai.dm
index be45879c64b..352f1b46b17 100644
--- a/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers_ai.dm
+++ b/code/modules/mob/living/basic/lavaland/gutlunchers/gutlunchers_ai.dm
@@ -44,12 +44,9 @@
continue
living_pawn.befriend(potential_friend)
to_chat(potential_friend, span_nicegreen("[living_pawn] looks at you with endearing eyes!"))
- finish_action(controller, TRUE)
- return
-
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
/datum/ai_controller/basic_controller/gutlunch/gutlunch_baby
diff --git a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm
index b80d5d6b9f7..c8e294f3e06 100644
--- a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm
+++ b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm
@@ -47,8 +47,8 @@
if (!is_vulnerable)
controller.set_blackboard_key(BB_BASIC_MOB_STOP_FLEEING, FALSE)
if (!controller.blackboard[BB_BASIC_MOB_STOP_FLEEING])
- finish_action(controller = controller, succeeded = TRUE, target_key = target_key) // We don't want to clear our target
- return
+ // We don't want to clear our target
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
return ..()
/datum/ai_planning_subtree/flee_target/lobster
@@ -72,8 +72,7 @@
if (!HAS_TRAIT(target, trait))
continue
controller.set_blackboard_key(BB_BASIC_MOB_STOP_FLEEING, TRUE)
- finish_action(controller, succeeded = FALSE)
- return
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
var/mob/living/us = controller.pawn
if (us.pulling == target)
@@ -132,14 +131,12 @@
set_movement_target(controller, current_target)
/datum/ai_behavior/grab_fingers/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
-
var/atom/current_target = controller.blackboard[target_key]
if (QDELETED(current_target))
- return
+ return AI_BEHAVIOR_DELAY
var/mob/living/living_pawn = controller.pawn
living_pawn.start_pulling(current_target)
- finish_action(controller, succeeded = TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/// How far we'll try to go before eating an arm
#define FLEE_TO_RANGE 9
@@ -159,14 +156,18 @@
if (QDELETED(current_target))
set_movement_target(controller, get_turf(controller.pawn))
return
- target_step_away(controller, current_target, target_key)
+ var/perform_flags = target_step_away(controller, current_target, target_key)
+ if (perform_flags & AI_BEHAVIOR_SUCCEEDED)
+ finish_action(controller, TRUE, target_key)
+ else if(perform_flags & AI_BEHAVIOR_FAILED)
+ finish_action(controller, FALSE, target_key)
/// Find the next step to take away from the current target
/datum/ai_behavior/hoard_fingers/proc/target_step_away(datum/ai_controller/controller, atom/current_target, target_key)
var/turf/next_step = get_step_away(controller.pawn, current_target)
if (!isnull(next_step) && !next_step.is_blocked_turf(exclude_mobs = TRUE))
set_movement_target(controller, next_step)
- return
+ return NONE
var/list/all_dirs = GLOB.alldirs.Copy()
all_dirs -= get_dir(controller.pawn, next_step)
all_dirs -= get_dir(controller.pawn, current_target)
@@ -175,37 +176,37 @@
next_step = get_step(controller.pawn, dir)
if (!isnull(next_step) && !next_step.is_blocked_turf(exclude_mobs = TRUE))
set_movement_target(controller, next_step)
- return
- finish_action(controller, succeeded = FALSE, target_key = target_key)
- return
+ return NONE
+ return AI_BEHAVIOR_FAILED
/datum/ai_behavior/hoard_fingers/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/current_patience = controller.blackboard[patience_key] + 1
if (current_patience >= MAX_LOBSTROSITY_PATIENCE)
- eat_fingers(controller, target_key)
- return
+ if(eat_fingers(controller, target_key))
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
controller.set_blackboard_key(patience_key, current_patience)
var/mob/living/living_pawn = controller.pawn
if (isnull(living_pawn.pulling))
- finish_action(controller, succeeded = FALSE, target_key = target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/atom/current_target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]
if (QDELETED(current_target) || !can_see(controller.pawn, current_target, FLEE_TO_RANGE))
- eat_fingers(controller, target_key)
- return
- target_step_away(controller, current_target, target_key)
+ if(eat_fingers(controller, target_key))
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
+ if(target_step_away(controller, current_target, target_key))
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
/// Finally consume those delicious digits
/datum/ai_behavior/hoard_fingers/proc/eat_fingers(datum/ai_controller/controller, target_key)
var/mob/living/basic/living_pawn = controller.pawn
var/atom/fingers = controller.blackboard[target_key]
if (QDELETED(fingers) || living_pawn.pulling != fingers)
- finish_action(controller, succeeded = FALSE, target_key = target_key)
- return
+ return AI_BEHAVIOR_FAILED
living_pawn.melee_attack(fingers)
- finish_action(controller, succeeded = TRUE, target_key = target_key)
+ return AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/hoard_fingers/finish_action(datum/ai_controller/controller, succeeded, target_key)
. = ..()
diff --git a/code/modules/mob/living/basic/lavaland/mook/mook_ai.dm b/code/modules/mob/living/basic/lavaland/mook/mook_ai.dm
index 50416693061..eeefc7a8b5c 100644
--- a/code/modules/mob/living/basic/lavaland/mook/mook_ai.dm
+++ b/code/modules/mob/living/basic/lavaland/mook/mook_ai.dm
@@ -117,15 +117,13 @@ GLOBAL_LIST_INIT(mook_commands, list(
/datum/ai_behavior/find_village
/datum/ai_behavior/find_village/perform(seconds_per_tick, datum/ai_controller/controller, village_key)
- . = ..()
var/obj/effect/landmark/home_marker = locate(/obj/effect/landmark/mook_village) in GLOB.landmarks_list
if(isnull(home_marker))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
controller.set_blackboard_key(village_key, home_marker)
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
///explore the lands away from the village to look for ore
/datum/ai_planning_subtree/wander_away_from_village
@@ -190,8 +188,7 @@ GLOBAL_LIST_INIT(mook_commands, list(
return return_turf
/datum/ai_behavior/wander/perform(seconds_per_tick, datum/ai_controller/controller, target_key, hiding_location_key)
- . = ..()
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_planning_subtree/mine_walls/mook
find_wall_behavior = /datum/ai_behavior/find_mineral_wall/mook
@@ -367,23 +364,20 @@ GLOBAL_LIST_INIT(mook_commands, list(
action_cooldown = 5 SECONDS
/datum/ai_behavior/issue_commands/perform(seconds_per_tick, datum/ai_controller/controller, target_key, command_path)
- . = ..()
var/mob/living/basic/living_pawn = controller.pawn
var/atom/target = controller.blackboard[target_key]
if(isnull(target))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/datum/pet_command/to_command = locate(command_path) in GLOB.mook_commands
if(isnull(to_command))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/issue_command = pick(to_command.speech_commands)
living_pawn.say(issue_command, forced = "controller")
living_pawn._pointed(target)
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
///find an ore, only pick it up when a mook brings it close to us
diff --git a/code/modules/mob/living/basic/minebots/minebot_ai.dm b/code/modules/mob/living/basic/minebots/minebot_ai.dm
index 059048f761a..959049f957d 100644
--- a/code/modules/mob/living/basic/minebots/minebot_ai.dm
+++ b/code/modules/mob/living/basic/minebots/minebot_ai.dm
@@ -86,15 +86,13 @@
set_movement_target(controller, target)
/datum/ai_behavior/repair_drone/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
var/mob/living/living_pawn = controller.pawn
living_pawn.say("REPAIRING [target]!")
living_pawn.UnarmedAttack(target)
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/repair_drone/finish_action(datum/ai_controller/controller, success, target_key)
. = ..()
@@ -119,20 +117,17 @@
action_cooldown = 2 MINUTES
/datum/ai_behavior/send_sos_message/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/mob/living/carbon/target = controller.blackboard[target_key]
var/mob/living/living_pawn = controller.pawn
if(QDELETED(target) || is_station_level(target.z))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/turf/target_turf = get_turf(target)
var/obj/item/implant/radio/radio_implant = locate(/obj/item/implant/radio) in living_pawn.contents
if(!radio_implant)
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/message = "ALERT, [target] in need of help at coordinates: [target_turf.x], [target_turf.y], [target_turf.z]!"
radio_implant.radio.talk_into(living_pawn, message, RADIO_CHANNEL_SUPPLY)
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/send_sos_message/finish_action(datum/ai_controller/controller, success, target_key)
. = ..()
@@ -182,11 +177,10 @@
minimum_distance = controller.blackboard[BB_MINIMUM_SHOOTING_DISTANCE] ? controller.blackboard[BB_MINIMUM_SHOOTING_DISTANCE] : initial(minimum_distance)
var/atom/target = controller.blackboard[target_key]
if(QDELETED(target))
- finish_action(controller, target_key, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/mob/living/living_pawn = controller.pawn
if(get_dist(living_pawn, target) <= minimum_distance)
- finish_action(controller, target_key, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
///mine walls if we are on automated mining mode
/datum/ai_planning_subtree/minebot_mining/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
@@ -220,24 +214,20 @@
set_movement_target(controller, target)
/datum/ai_behavior/minebot_mine_turf/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/mob/living/basic/living_pawn = controller.pawn
var/turf/target = controller.blackboard[target_key]
if(QDELETED(target))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
if(check_obstacles_in_path(controller, target))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
if(!living_pawn.combat_mode)
living_pawn.set_combat_mode(TRUE)
living_pawn.RangedAttack(target)
- finish_action(controller, TRUE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/minebot_mine_turf/proc/check_obstacles_in_path(datum/ai_controller/controller, turf/target)
var/mob/living/source = controller.pawn
diff --git a/code/modules/mob/living/basic/pets/cat/cat_ai.dm b/code/modules/mob/living/basic/pets/cat/cat_ai.dm
index 7eff8582355..d6589d29b40 100644
--- a/code/modules/mob/living/basic/pets/cat/cat_ai.dm
+++ b/code/modules/mob/living/basic/pets/cat/cat_ai.dm
@@ -60,15 +60,13 @@
set_movement_target(controller, target)
/datum/ai_behavior/enter_cat_home/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/obj/structure/cat_house/home = controller.blackboard[target_key]
var/mob/living/basic/living_pawn = controller.pawn
if(living_pawn == home.resident_cat || isnull(home.resident_cat))
living_pawn.melee_attack(home)
- finish_action(controller, TRUE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
- finish_action(controller, FALSE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
/datum/ai_behavior/enter_cat_home/finish_action(datum/ai_controller/controller, success, target_key)
. = ..()
@@ -133,8 +131,7 @@
var/mob/living/target = controller.blackboard[target_key]
if(QDELETED(target))
- finish_action(controller, TRUE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
var/mob/living/living_pawn = controller.pawn
var/list/threaten_list = controller.blackboard[cries_key]
@@ -149,7 +146,7 @@
loser_controller.set_blackboard_key(BB_BASIC_MOB_FLEE_TARGET, target)
target.ai_controller.clear_blackboard_key(BB_TRESSPASSER_TARGET)
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/territorial_struggle/finish_action(datum/ai_controller/controller, success, target_key)
. = ..()
@@ -191,19 +188,16 @@
set_movement_target(controller, target)
/datum/ai_behavior/play_with_mouse/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/mob/living/basic/mouse/target = controller.blackboard[target_key]
if(QDELETED(target))
- finish_action(controller, TRUE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
consume_chance = istype(target, /mob/living/basic/mouse/brown/tom) ? 5 : initial(consume_chance)
if(prob(consume_chance))
target.splat()
- finish_action(controller, TRUE, target_key)
- return
- finish_action(controller, FALSE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
/datum/ai_behavior/play_with_mouse/finish_action(datum/ai_controller/controller, success, target_key)
. = ..()
@@ -272,22 +266,19 @@
set_movement_target(controller, target)
/datum/ai_behavior/deliver_food_to_kitten/perform(seconds_per_tick, datum/ai_controller/controller, target_key, food_key)
- . = ..()
var/mob/living/target = controller.blackboard[target_key]
if(QDELETED(target))
- finish_action(controller, FALSE, target_key, food_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/mob/living/living_pawn = controller.pawn
var/atom/movable/food = controller.blackboard[food_key]
if(isnull(food) || !(food in living_pawn))
- finish_action(controller, FALSE, target_key, food_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
food.forceMove(get_turf(living_pawn))
- finish_action(controller, TRUE, target_key, food_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/deliver_food_to_kitten/finish_action(datum/ai_controller/controller, success, target_key, food_key)
. = ..()
diff --git a/code/modules/mob/living/basic/pets/cat/kitten_ai.dm b/code/modules/mob/living/basic/pets/cat/kitten_ai.dm
index 15630c07838..b694235a39e 100644
--- a/code/modules/mob/living/basic/pets/cat/kitten_ai.dm
+++ b/code/modules/mob/living/basic/pets/cat/kitten_ai.dm
@@ -30,16 +30,15 @@
action_cooldown = 5 SECONDS
/datum/ai_behavior/beacon_for_food/perform(seconds_per_tick, datum/ai_controller/controller, target_key, meows_key)
- . = ..()
var/atom/target = controller.blackboard[target_key]
if(QDELETED(target))
- finish_action(controller, FALSE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/mob/living/living_pawn = controller.pawn
var/list/meowing_list = controller.blackboard[meows_key]
if(length(meowing_list))
living_pawn.say(pick(meowing_list), forced = "ai_controller")
living_pawn._pointed(target)
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/beacon_for_food/finish_action(datum/ai_controller/controller, success, target_key)
. = ..()
diff --git a/code/modules/mob/living/basic/pets/orbie/orbie_ai.dm b/code/modules/mob/living/basic/pets/orbie/orbie_ai.dm
index 854a0209464..92f433bd08a 100644
--- a/code/modules/mob/living/basic/pets/orbie/orbie_ai.dm
+++ b/code/modules/mob/living/basic/pets/orbie/orbie_ai.dm
@@ -65,18 +65,16 @@
set_movement_target(controller, target)
/datum/ai_behavior/interact_with_playmate/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/mob/living/basic/living_pawn = controller.pawn
var/atom/target = controller.blackboard[target_key]
if(QDELETED(target))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
living_pawn.manual_emote("plays with [target]!")
living_pawn.spin(spintime = 4, speed = 1)
living_pawn.ClickOn(target)
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/interact_with_playmate/finish_action(datum/ai_controller/controller, success, target_key)
. = ..()
@@ -92,16 +90,14 @@
controller.queue_behavior(/datum/ai_behavior/relay_pda_message, BB_LAST_RECIEVED_MESSAGE)
/datum/ai_behavior/relay_pda_message/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/mob/living/basic/living_pawn = controller.pawn
var/text_to_say = controller.blackboard[target_key]
if(isnull(text_to_say))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
living_pawn.say(text_to_say, forced = "AI controller")
living_pawn.spin(spintime = 4, speed = 1)
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/relay_pda_message/finish_action(datum/ai_controller/controller, success, target_key)
. = ..()
diff --git a/code/modules/mob/living/basic/pets/parrot/parrot_ai/parrot_perching.dm b/code/modules/mob/living/basic/pets/parrot/parrot_ai/parrot_perching.dm
index ccc3ef92f6e..b5b34e30cad 100644
--- a/code/modules/mob/living/basic/pets/parrot/parrot_ai/parrot_perching.dm
+++ b/code/modules/mob/living/basic/pets/parrot/parrot_ai/parrot_perching.dm
@@ -47,25 +47,21 @@
set_movement_target(controller, target)
/datum/ai_behavior/perch_on_target/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
var/mob/living/basic/parrot/living_pawn = controller.pawn
if(!ishuman(target))
living_pawn.start_perching(target)
- finish_action(controller, TRUE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
if(!check_human_conditions(target))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
living_pawn.start_perching(target)
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/perch_on_target/proc/check_human_conditions(mob/living/living_human)
if(living_human.stat == DEAD || LAZYLEN(living_human.buckled_mobs) >= living_human.max_buckled_mobs)
diff --git a/code/modules/mob/living/basic/pets/parrot/parrot_ai/parroting_action.dm b/code/modules/mob/living/basic/pets/parrot/parrot_ai/parroting_action.dm
index d1488a60b3b..493d67cbca8 100644
--- a/code/modules/mob/living/basic/pets/parrot/parrot_ai/parroting_action.dm
+++ b/code/modules/mob/living/basic/pets/parrot/parrot_ai/parroting_action.dm
@@ -45,6 +45,6 @@
speaking_pawn.say(modified_speech, forced = "AI Controller")
if(speech_sound)
playsound(speaking_pawn, speech_sound, 80, vary = TRUE)
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
#undef HAS_CHANNEL_PREFIX
diff --git a/code/modules/mob/living/basic/pets/pet_cult/pet_cult_ai.dm b/code/modules/mob/living/basic/pets/pet_cult/pet_cult_ai.dm
index dc778b5816f..fb106809918 100644
--- a/code/modules/mob/living/basic/pets/pet_cult/pet_cult_ai.dm
+++ b/code/modules/mob/living/basic/pets/pet_cult/pet_cult_ai.dm
@@ -100,25 +100,21 @@
set_movement_target(controller, target)
/datum/ai_behavior/activate_rune/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
var/datum/team/cult/cult_team = controller.blackboard[BB_CULT_TEAM]
var/mob/living/revive_mob = locate(/mob/living) in get_turf(target)
if(isnull(revive_mob) || revive_mob.stat != DEAD || !(revive_mob.mind in cult_team.members))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/mob/living/basic/living_pawn = controller.pawn
living_pawn.melee_attack(target)
- finish_action(controller, TRUE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/activate_rune/finish_action(datum/ai_controller/controller, success, target_key)
. = ..()
@@ -211,12 +207,10 @@
set_movement_target(controller, target)
/datum/ai_behavior/drag_target_to_rune/perform(seconds_per_tick, datum/ai_controller/controller, target_key, cultist_key)
- . = ..()
var/mob/living/our_pawn = controller.pawn
var/atom/cultist_target = controller.blackboard[cultist_key]
if(isnull(cultist_target))
- finish_action(controller, FALSE, target_key, cultist_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/list/possible_dirs = GLOB.alldirs.Copy()
possible_dirs -= get_dir(our_pawn, cultist_target)
for(var/direction in possible_dirs)
@@ -225,7 +219,7 @@
possible_dirs -= direction
step(our_pawn, pick(possible_dirs))
our_pawn.stop_pulling()
- finish_action(controller, TRUE, target_key, cultist_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/drag_target_to_rune/finish_action(datum/ai_controller/controller, success, target_key, cultist_key)
diff --git a/code/modules/mob/living/basic/ruin_defender/flesh.dm b/code/modules/mob/living/basic/ruin_defender/flesh.dm
index a6087f08589..6f46e690700 100644
--- a/code/modules/mob/living/basic/ruin_defender/flesh.dm
+++ b/code/modules/mob/living/basic/ruin_defender/flesh.dm
@@ -178,6 +178,6 @@
/mob/living/basic/living_limb_flesh/proc/wake_up(atom/limb)
visible_message(span_warning("[src] begins flailing around!"))
Shake(6, 6, 0.5 SECONDS)
- ai_controller.set_ai_status(AI_STATUS_IDLE)
+ ai_controller.set_ai_status(AI_STATUS_ON)
forceMove(limb.drop_location())
qdel(limb)
diff --git a/code/modules/mob/living/basic/slime/ai/behaviours.dm b/code/modules/mob/living/basic/slime/ai/behaviours.dm
index 0db592099bb..e573bd57354 100644
--- a/code/modules/mob/living/basic/slime/ai/behaviours.dm
+++ b/code/modules/mob/living/basic/slime/ai/behaviours.dm
@@ -1,10 +1,9 @@
/datum/ai_behavior/perform_change_slime_face
/datum/ai_behavior/perform_change_slime_face/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
var/mob/living/basic/slime/slime_pawn = controller.pawn
if(!istype(slime_pawn))
- return
+ return AI_BEHAVIOR_DELAY
var/current_mood = slime_pawn.current_mood
@@ -23,7 +22,7 @@
slime_pawn.current_mood = new_mood
slime_pawn.regenerate_icons()
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/find_hunt_target/find_slime_food
diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp.dm b/code/modules/mob/living/basic/space_fauna/carp/carp.dm
index cf905de5dbf..ee2073987da 100644
--- a/code/modules/mob/living/basic/space_fauna/carp/carp.dm
+++ b/code/modules/mob/living/basic/space_fauna/carp/carp.dm
@@ -134,6 +134,8 @@
/// Gives the carp a list of weakrefs of destinations to try and travel between when it has nothing better to do
/mob/living/basic/carp/proc/migrate_to(list/datum/weakref/migration_points)
+ ai_controller.can_idle = FALSE
+ ai_controller.set_ai_status(AI_STATUS_ON) // We need htem to actually walk to the station
var/list/actual_points = list()
for(var/datum/weakref/point_ref as anything in migration_points)
var/turf/point_resolved = point_ref.resolve()
diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp_ai_actions.dm b/code/modules/mob/living/basic/space_fauna/carp/carp_ai_actions.dm
index 9e767bab3af..71017bd2207 100644
--- a/code/modules/mob/living/basic/space_fauna/carp/carp_ai_actions.dm
+++ b/code/modules/mob/living/basic/space_fauna/carp/carp_ai_actions.dm
@@ -21,8 +21,7 @@
if (QDELETED(using_action))
return ..()
if (!controller.blackboard[BB_MAGICARP_SPELL_SPECIAL_TARGETING] && using_action.IsAvailable())
- finish_action(controller, succeeded = FALSE)
- return
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
return ..()
/**
diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp_ai_migration.dm b/code/modules/mob/living/basic/space_fauna/carp/carp_ai_migration.dm
index 27fdb25ee22..9458877af7f 100644
--- a/code/modules/mob/living/basic/space_fauna/carp/carp_ai_migration.dm
+++ b/code/modules/mob/living/basic/space_fauna/carp/carp_ai_migration.dm
@@ -47,10 +47,8 @@
blackboard_points -= migration_point
if(get_dist(controller.pawn, migration_point) > CARP_DESTINATION_SEARCH_RANGE)
controller.set_blackboard_key(target_key, migration_point)
- finish_action(controller, succeeded = TRUE)
- return
-
- finish_action(controller, succeeded = FALSE)
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_SUCCEEDED
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
#undef CARP_DESTINATION_SEARCH_RANGE
#undef CARP_PORTAL_SEARCH_RANGE
diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp_ai_rift_actions.dm b/code/modules/mob/living/basic/space_fauna/carp/carp_ai_rift_actions.dm
index fc6997896b0..84b96ae3ce4 100644
--- a/code/modules/mob/living/basic/space_fauna/carp/carp_ai_rift_actions.dm
+++ b/code/modules/mob/living/basic/space_fauna/carp/carp_ai_rift_actions.dm
@@ -52,21 +52,19 @@
return controller.blackboard[ability_key] && controller.blackboard[target_key]
/datum/ai_behavior/make_carp_rift/perform(seconds_per_tick, datum/ai_controller/controller, ability_key, target_key)
- . = ..()
var/datum/action/cooldown/mob_cooldown/lesser_carp_rift/ability = controller.blackboard[ability_key]
var/atom/target = controller.blackboard[target_key]
if (!validate_target(controller, target, ability))
- finish_action(controller, FALSE, ability_key, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/turf/target_destination = find_target_turf(controller, target, ability)
if (!target_destination)
- finish_action(controller, FALSE, ability_key, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
- var/result = ability.InterceptClickOn(controller.pawn, null, target_destination)
- finish_action(controller, result, ability_key, target_key)
+ if(ability.InterceptClickOn(controller.pawn, null, target_destination))
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
/// Return true if your target is valid for the action
/datum/ai_behavior/make_carp_rift/proc/validate_target(datum/ai_controller/controller, atom/target, datum/action/cooldown/mob_cooldown/lesser_carp_rift/ability)
diff --git a/code/modules/mob/living/basic/space_fauna/eyeball/eyeball_ai_behavior.dm b/code/modules/mob/living/basic/space_fauna/eyeball/eyeball_ai_behavior.dm
index 57ea39c94dd..f50fca8c559 100644
--- a/code/modules/mob/living/basic/space_fauna/eyeball/eyeball_ai_behavior.dm
+++ b/code/modules/mob/living/basic/space_fauna/eyeball/eyeball_ai_behavior.dm
@@ -1,14 +1,11 @@
/datum/ai_behavior/find_the_blind
/datum/ai_behavior/find_the_blind/perform(seconds_per_tick, datum/ai_controller/controller, blind_key, threshold_key)
- . = ..()
-
var/mob/living_pawn = controller.pawn
var/list/blind_list = list()
var/eye_damage_threshold = controller.blackboard[threshold_key]
if(!eye_damage_threshold)
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
for(var/mob/living/carbon/blind in oview(9, living_pawn))
var/obj/item/organ/internal/eyes/eyes = blind.get_organ_slot(ORGAN_SLOT_EYES)
if(isnull(eyes))
@@ -18,11 +15,10 @@
blind_list += blind
if(!length(blind_list))
- finish_action(controller, FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
controller.set_blackboard_key(blind_key, pick(blind_list))
- finish_action(controller, TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/heal_eye_damage
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH
@@ -35,19 +31,16 @@
set_movement_target(controller, target)
/datum/ai_behavior/heal_eye_damage/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
-
var/mob/living/carbon/target = controller.blackboard[target_key]
var/mob/living/living_pawn = controller.pawn
if(QDELETED(target))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/obj/item/organ/internal/eyes/eyes = target.get_organ_slot(ORGAN_SLOT_EYES)
var/datum/callback/callback = CALLBACK(living_pawn, TYPE_PROC_REF(/mob/living/basic/eyeball, heal_eye_damage), target, eyes)
callback.Invoke()
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/heal_eye_damage/finish_action(datum/ai_controller/controller, succeeded, target_key)
. = ..()
@@ -77,17 +70,18 @@
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/direction_to_compare = get_dir(target, controller.pawn)
var/target_direction = target.dir
if(direction_to_compare != target_direction)
- finish_action(controller, FALSE, ability_key, target_key)
- return
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
var/result = ability.InterceptClickOn(controller.pawn, null, target)
- finish_action(controller, result, ability_key, target_key)
+ if(result == TRUE)
+ return AI_BEHAVIOR_INSTANT
+ else
+ return AI_BEHAVIOR_INSTANT | AI_BEHAVIOR_FAILED
/datum/ai_behavior/hunt_target/unarmed_attack_target/carrot
hunt_cooldown = 2 SECONDS
diff --git a/code/modules/mob/living/basic/space_fauna/hivebot/hivebot_behavior.dm b/code/modules/mob/living/basic/space_fauna/hivebot/hivebot_behavior.dm
index 28cffa4ed8e..7db7a8913fa 100644
--- a/code/modules/mob/living/basic/space_fauna/hivebot/hivebot_behavior.dm
+++ b/code/modules/mob/living/basic/space_fauna/hivebot/hivebot_behavior.dm
@@ -30,19 +30,16 @@
/datum/ai_behavior/relay_message/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(QDELETED(target))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/message_relayed = ""
for(var/i in 1 to length_of_message)
message_relayed += prob(50) ? "1" : "0"
living_pawn.say(message_relayed, forced = "AI Controller")
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/relay_message/finish_action(datum/ai_controller/controller, succeeded, target_key)
. = ..()
diff --git a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_subtrees.dm b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_subtrees.dm
index 8682c8028e3..20f6ce4baf0 100644
--- a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_subtrees.dm
+++ b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_subtrees.dm
@@ -13,19 +13,17 @@
var/scan_range = 3
/datum/ai_behavior/find_unwebbed_turf/perform(seconds_per_tick, datum/ai_controller/controller)
- . = ..()
var/mob/living/spider = controller.pawn
var/atom/current_target = controller.blackboard[target_key]
if (current_target && !(locate(/obj/structure/spider/stickyweb) in current_target))
- finish_action(controller, succeeded = FALSE) // Already got a target
- return
+ // Already got a target
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
controller.clear_blackboard_key(target_key)
var/turf/our_turf = get_turf(spider)
if (is_valid_web_turf(our_turf, spider))
controller.set_blackboard_key(target_key, our_turf)
- finish_action(controller, succeeded = TRUE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
var/list/turfs_by_range = list()
for (var/i in 1 to scan_range)
@@ -41,11 +39,10 @@
final_turfs = turfs_by_range[turf_list]
break
if (!length(final_turfs))
- finish_action(controller, succeeded = FALSE)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
controller.set_blackboard_key(target_key, pick(final_turfs))
- finish_action(controller, succeeded = TRUE)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/ai_behavior/find_unwebbed_turf/proc/is_valid_web_turf(turf/target_turf, mob/living/spider)
if (locate(/obj/structure/spider/stickyweb) in target_turf)
@@ -82,9 +79,10 @@
return ..()
/datum/ai_behavior/spin_web/perform(seconds_per_tick, datum/ai_controller/controller, action_key, target_key)
- . = ..()
var/datum/action/cooldown/web_action = controller.blackboard[action_key]
- finish_action(controller, succeeded = web_action?.Trigger(), action_key = action_key, target_key = target_key)
+ if(web_action?.Trigger())
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
/datum/ai_behavior/spin_web/finish_action(datum/ai_controller/controller, succeeded, action_key, target_key)
controller.clear_blackboard_key(target_key)
diff --git a/code/modules/mob/living/basic/space_fauna/statue/mannequin.dm b/code/modules/mob/living/basic/space_fauna/statue/mannequin.dm
index 7b6bf6c8399..9710421b408 100644
--- a/code/modules/mob/living/basic/space_fauna/statue/mannequin.dm
+++ b/code/modules/mob/living/basic/space_fauna/statue/mannequin.dm
@@ -57,14 +57,13 @@
return ismovable(target) && isturf(target.loc) && ismob(controller.pawn)
/datum/ai_behavior/face_target_or_face_initial/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
var/atom/movable/target = controller.blackboard[target_key]
var/mob/living/we = controller.pawn
if(isnull(target) || get_dist(we, target) > 8)
we.dir = controller.blackboard[BB_STARTING_DIRECTION]
- finish_action(controller, TRUE)
- else
- we.face_atom(target)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
+ we.face_atom(target)
+ return AI_BEHAVIOR_DELAY
/mob/living/basic/statue/mannequin/suspicious
name = "mannequin?"
diff --git a/code/modules/mob/living/basic/trader/trader_ai.dm b/code/modules/mob/living/basic/trader/trader_ai.dm
index 5f447ab3229..d79a12a2d29 100644
--- a/code/modules/mob/living/basic/trader/trader_ai.dm
+++ b/code/modules/mob/living/basic/trader/trader_ai.dm
@@ -61,19 +61,15 @@
return !QDELETED(target)
/datum/ai_behavior/setup_shop/perform(seconds_per_tick, datum/ai_controller/controller, target_key)
- . = ..()
-
//We lost track of our costumer or our ability, abort
if(!controller.blackboard_key_exists(target_key) || !controller.blackboard_key_exists(BB_SETUP_SHOP))
- finish_action(controller, FALSE, target_key)
- return
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/datum/action/setup_shop/shop = controller.blackboard[BB_SETUP_SHOP]
shop.Trigger()
controller.clear_blackboard_key(BB_FIRST_CUSTOMER)
-
- finish_action(controller, TRUE, target_key)
+ return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
/datum/idle_behavior/idle_random_walk/not_while_on_target/trader
target_key = BB_SHOP_SPOT
diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm
index 94a3d70372b..933e6cb86d6 100644
--- a/code/modules/mob/living/carbon/alien/alien.dm
+++ b/code/modules/mob/living/carbon/alien/alien.dm
@@ -116,18 +116,32 @@ Des: Removes all infected images from the alien.
span_alertalien("[src] begins to twist and contort!"),
span_noticealien("You begin to evolve!"),
)
+
new_xeno.setDir(dir)
- if(numba && unique_name)
- new_xeno.numba = numba
- new_xeno.set_name()
- if(!alien_name_regex.Find(name))
- new_xeno.name = name
- new_xeno.real_name = real_name
+ new_xeno.change_name(name, real_name, numba)
+
if(mind)
mind.name = new_xeno.real_name
mind.transfer_to(new_xeno)
+
qdel(src)
+/// Changes the name of the xeno we are evolving into in order to keep the same numerical identifier the old xeno had.
+/mob/living/carbon/alien/proc/change_name(old_name, old_real_name, old_number)
+ if(!alien_name_regex.Find(old_name)) // check to make sure there's no admins doing funny stuff with naming these aliens
+ name = old_name
+ real_name = old_real_name
+ return
+
+ if(!unique_name)
+ return
+
+ if(old_number != 0)
+ numba = old_number
+ name = initial(name) // prevent chicanery like two different numerical identifiers tied to the same mob
+
+ set_name()
+
/mob/living/carbon/alien/can_hold_items(obj/item/I)
return (I && (I.item_flags & XENOMORPH_HOLDABLE || ISADVANCEDTOOLUSER(src)) && ..())
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 97a222cdd95..aeeb33158f9 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -254,7 +254,7 @@
var/obj/item/restraints/cuffs = src.get_item_by_slot(ITEM_SLOT_HANDCUFFED)
buckle_cd = cuffs.breakouttime
- visible_message(span_warning("[src] attempts to unbuckle [p_them()]self!"),
+ visible_message(span_warning("[src] attempts to unbuckle [p_them()]self!"),
span_notice("You attempt to unbuckle yourself... \
(This will take around [DisplayTimeText(buckle_cd)] and you must stay still.)"))
@@ -262,7 +262,7 @@
if(buckled)
to_chat(src, span_warning("You fail to unbuckle yourself!"))
return
-
+
if(QDELETED(src) || isnull(buckled))
return
@@ -283,8 +283,8 @@
type = 2
if(I)
if(type == 1)
- changeNext_move(CLICK_CD_BREAKOUT)
- last_special = world.time + CLICK_CD_BREAKOUT
+ changeNext_move(I.resist_cooldown)
+ last_special = world.time + I.resist_cooldown
if(type == 2)
changeNext_move(CLICK_CD_RANGE)
last_special = world.time + CLICK_CD_RANGE
@@ -658,12 +658,8 @@
*/
/mob/living/carbon/proc/update_tint()
var/tint = 0
- if(isclothing(head))
- tint += head.tint
- if(isclothing(wear_mask))
- tint += wear_mask.tint
- if(isclothing(glasses))
- tint += glasses.tint
+ for(var/obj/item/clothing/worn_item in get_equipped_items())
+ tint += worn_item.tint
var/obj/item/organ/internal/eyes/eyes = get_organ_slot(ORGAN_SLOT_EYES)
if(eyes)
@@ -1259,35 +1255,35 @@
update_worn_back(0)
. = TRUE
- if(head?.wash(clean_types))
- update_worn_head()
- . = TRUE
-
// Check and wash stuff that can be covered
var/obscured = check_obscured_slots()
+ if(!(obscured & ITEM_SLOT_HEAD) && head?.wash(clean_types))
+ update_worn_head()
+ . = TRUE
+
// If the eyes are covered by anything but glasses, that thing will be covering any potential glasses as well.
- if(glasses && is_eyes_covered(ITEM_SLOT_MASK|ITEM_SLOT_HEAD) && glasses.wash(clean_types))
+ if(is_eyes_covered(ITEM_SLOT_MASK|ITEM_SLOT_HEAD) && glasses?.wash(clean_types))
update_worn_glasses()
. = TRUE
- if(wear_mask && !(obscured & ITEM_SLOT_MASK) && wear_mask.wash(clean_types))
+ if(!(obscured & ITEM_SLOT_MASK) && wear_mask?.wash(clean_types))
update_worn_mask()
. = TRUE
- if(ears && !(obscured & ITEM_SLOT_EARS) && ears.wash(clean_types))
- update_inv_ears()
+ if(!(obscured & ITEM_SLOT_EARS) && ears?.wash(clean_types))
+ update_worn_ears()
. = TRUE
- if(wear_neck && !(obscured & ITEM_SLOT_NECK) && wear_neck.wash(clean_types))
+ if(!(obscured & ITEM_SLOT_NECK) && wear_neck?.wash(clean_types))
update_worn_neck()
. = TRUE
- if(shoes && !(obscured & ITEM_SLOT_FEET) && shoes.wash(clean_types))
+ if(!(obscured & ITEM_SLOT_FEET) && shoes?.wash(clean_types))
update_worn_shoes()
. = TRUE
- if(gloves && !(obscured & ITEM_SLOT_GLOVES) && gloves.wash(clean_types))
+ if(!(obscured & ITEM_SLOT_GLOVES) && gloves?.wash(clean_types))
update_worn_gloves()
. = TRUE
diff --git a/code/modules/mob/living/carbon/carbon_update_icons.dm b/code/modules/mob/living/carbon/carbon_update_icons.dm
index 2a17403a83e..c5862a95e12 100644
--- a/code/modules/mob/living/carbon/carbon_update_icons.dm
+++ b/code/modules/mob/living/carbon/carbon_update_icons.dm
@@ -1,38 +1,7 @@
-/mob/living/carbon/human/update_clothing(slot_flags)
- if(slot_flags & ITEM_SLOT_BACK)
- update_worn_back()
- if(slot_flags & ITEM_SLOT_MASK)
- update_worn_mask()
- if(slot_flags & ITEM_SLOT_NECK)
- update_worn_neck()
- if(slot_flags & ITEM_SLOT_HANDCUFFED)
- update_worn_handcuffs()
- if(slot_flags & ITEM_SLOT_LEGCUFFED)
- update_worn_legcuffs()
- if(slot_flags & ITEM_SLOT_BELT)
- update_worn_belt()
- if(slot_flags & ITEM_SLOT_ID)
- update_worn_id()
- if(slot_flags & ITEM_SLOT_EARS)
- update_inv_ears()
- if(slot_flags & ITEM_SLOT_EYES)
- update_worn_glasses()
- if(slot_flags & ITEM_SLOT_GLOVES)
- update_worn_gloves()
- if(slot_flags & ITEM_SLOT_HEAD)
- update_worn_head()
- if(slot_flags & ITEM_SLOT_FEET)
- update_worn_shoes()
- if(slot_flags & ITEM_SLOT_OCLOTHING)
- update_worn_oversuit()
- if(slot_flags & ITEM_SLOT_ICLOTHING)
- update_worn_undersuit()
- if(slot_flags & ITEM_SLOT_SUITSTORE)
- update_suit_storage()
- if(slot_flags & (ITEM_SLOT_LPOCKET|ITEM_SLOT_RPOCKET))
- update_pockets()
- if(slot_flags & ITEM_SLOT_HANDS)
- update_held_items()
+/mob/living/carbon/update_obscured_slots(obscured_flags)
+ ..()
+ if(obscured_flags & (HIDEEARS|HIDEEYES|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT|HIDEMUTWINGS))
+ update_body()
/// Updates features and clothing attached to a specific limb with limb-specific offsets
/mob/living/carbon/proc/update_features(feature_key)
@@ -46,7 +15,7 @@
if(OFFSET_GLASSES)
update_worn_glasses()
if(OFFSET_EARS)
- update_inv_ears()
+ update_worn_ears()
if(OFFSET_SHOES)
update_worn_shoes()
if(OFFSET_S_STORE)
@@ -357,7 +326,7 @@
//SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION (moved to modular)
/*
-/mob/living/carbon/update_worn_mask()
+/mob/living/carbon/update_worn_mask(update_obscured = TRUE)
remove_overlay(FACEMASK_LAYER)
if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
@@ -368,13 +337,15 @@
inv.update_appearance()
if(wear_mask)
+ if(update_obscured)
+ update_obscured_slots(wear_mask.flags_inv)
if(!(check_obscured_slots() & ITEM_SLOT_MASK))
overlays_standing[FACEMASK_LAYER] = wear_mask.build_worn_icon(default_layer = FACEMASK_LAYER, default_icon_file = 'icons/mob/clothing/mask.dmi')
update_hud_wear_mask(wear_mask)
apply_overlay(FACEMASK_LAYER)
-/mob/living/carbon/update_worn_neck()
+/mob/living/carbon/update_worn_neck(update_obscured = TRUE)
remove_overlay(NECK_LAYER)
if(client && hud_used?.inv_slots[TOBITSHIFT(ITEM_SLOT_NECK) + 1])
@@ -382,6 +353,8 @@
inv.update_appearance()
if(wear_neck)
+ if(update_obscured)
+ update_obscured_slots(wear_neck.flags_inv)
if(!(check_obscured_slots() & ITEM_SLOT_NECK))
overlays_standing[NECK_LAYER] = wear_neck.build_worn_icon(default_layer = NECK_LAYER, default_icon_file = 'icons/mob/clothing/neck.dmi')
update_hud_neck(wear_neck)
@@ -392,7 +365,7 @@
//SKYRAT EDIT REMOVAL BEGIN - TESHARI CLOTHES (moved to modular)
/*
-/mob/living/carbon/update_worn_back()
+/mob/living/carbon/update_worn_back(update_obscured = TRUE)
remove_overlay(BACK_LAYER)
if(client && hud_used?.inv_slots[TOBITSHIFT(ITEM_SLOT_BACK) + 1])
@@ -400,6 +373,8 @@
inv.update_appearance()
if(back)
+ if(update_obscured)
+ update_obscured_slots(back.flags_inv)
overlays_standing[BACK_LAYER] = back.build_worn_icon(default_layer = BACK_LAYER, default_icon_file = 'icons/mob/clothing/back.dmi')
update_hud_back(back)
@@ -407,10 +382,12 @@
*/
//SKYRAT EDIT REMOVAL END
-/mob/living/carbon/update_worn_legcuffs()
+/mob/living/carbon/update_worn_legcuffs(update_obscured = TRUE)
remove_overlay(LEGCUFF_LAYER)
clear_alert("legcuffed")
if(legcuffed)
+ if(update_obscured)
+ update_obscured_slots(legcuffed.flags_inv)
overlays_standing[LEGCUFF_LAYER] = mutable_appearance('icons/mob/simple/mob.dmi', "legcuff1", -LEGCUFF_LAYER)
apply_overlay(LEGCUFF_LAYER)
throw_alert("legcuffed", /atom/movable/screen/alert/restrained/legcuffed, new_master = src.legcuffed)
@@ -418,7 +395,7 @@
//SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION (moved to modular)
/*
-/mob/living/carbon/update_worn_head()
+/mob/living/carbon/update_worn_head(update_obscured = TRUE)
remove_overlay(HEAD_LAYER)
if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
@@ -429,7 +406,10 @@
inv.update_appearance()
if(head)
- overlays_standing[HEAD_LAYER] = head.build_worn_icon(default_layer = HEAD_LAYER, default_icon_file = 'icons/mob/clothing/head/default.dmi')
+ if(update_obscured)
+ update_obscured_slots(head.flags_inv)
+ if(!(check_obscured_slots() & ITEM_SLOT_HEAD))
+ overlays_standing[HEAD_LAYER] = head.build_worn_icon(default_layer = HEAD_LAYER, default_icon_file = 'icons/mob/clothing/head/default.dmi')
update_hud_head(head)
apply_overlay(HEAD_LAYER)
@@ -437,9 +417,11 @@
//SKYRAT EDIT REMOVAL END
-/mob/living/carbon/update_worn_handcuffs()
+/mob/living/carbon/update_worn_handcuffs(update_obscured = TRUE)
remove_overlay(HANDCUFF_LAYER)
if(handcuffed && !(handcuffed.item_flags & ABSTRACT)) //SKYRAT EDIT ADDED !(handcuffed.item_flags & ABSTRACT)
+ if(update_obscured)
+ update_obscured_slots(handcuffed.flags_inv)
var/mutable_appearance/handcuff_overlay = mutable_appearance('icons/mob/simple/mob.dmi', "handcuff1", -HANDCUFF_LAYER)
if(handcuffed.blocks_emissive != EMISSIVE_BLOCK_NONE)
handcuff_overlay.overlays += emissive_blocker(handcuff_overlay.icon, handcuff_overlay.icon_state, src, alpha = handcuff_overlay.alpha)
diff --git a/code/modules/mob/living/carbon/emote.dm b/code/modules/mob/living/carbon/emote.dm
index 8d1599d0e80..55453b8904d 100644
--- a/code/modules/mob/living/carbon/emote.dm
+++ b/code/modules/mob/living/carbon/emote.dm
@@ -164,7 +164,7 @@
key_third_person = "snaps"
message = "snaps their fingers."
message_param = "snaps their fingers at %t."
- emote_type = EMOTE_AUDIBLE
+ emote_type = EMOTE_AUDIBLE | EMOTE_VISIBLE
hands_use_check = TRUE
muzzle_ignore = TRUE
diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm
index 154892d57ea..a6a2fa53505 100644
--- a/code/modules/mob/living/carbon/human/_species.dm
+++ b/code/modules/mob/living/carbon/human/_species.dm
@@ -431,7 +431,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
replacement.Insert(organ_holder, special=TRUE, movement_flags = DELETE_IF_REPLACED)
/datum/species/proc/worn_items_fit_body_check(mob/living/carbon/wearer)
- for(var/obj/item/equipped_item in wearer.get_all_worn_items())
+ for(var/obj/item/equipped_item in wearer.get_equipped_items(include_pockets = TRUE))
var/equipped_item_slot = wearer.get_slot_by_item(equipped_item)
if(!equipped_item.mob_can_equip(wearer, equipped_item_slot, bypass_equip_delay_self = TRUE, ignore_equipped = TRUE))
wearer.dropItemToGround(equipped_item, force = TRUE)
@@ -1152,7 +1152,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
attacking_bodypart = brain.get_attacking_limb(target)
if(!attacking_bodypart)
attacking_bodypart = user.get_active_hand()
- var/atk_verb = attacking_bodypart.unarmed_attack_verb
+ var/atk_verb = pick(attacking_bodypart.unarmed_attack_verbs)
var/atk_effect = attacking_bodypart.unarmed_attack_effect
if(atk_effect == ATTACK_EFFECT_BITE)
@@ -1659,10 +1659,26 @@ GLOBAL_LIST_EMPTY(features_by_species)
/datum/species/proc/prepare_human_for_preview(mob/living/carbon/human/human)
return
-/// Returns the species's scream sound.
+/// Returns the species' scream sound.
/datum/species/proc/get_scream_sound(mob/living/carbon/human/human)
return
+/// Returns the species' cry sound.
+/datum/species/proc/get_cry_sound(mob/living/carbon/human/human)
+ return
+
+/// Returns the species' cough sound.
+/datum/species/proc/get_cough_sound(mob/living/carbon/human/human)
+ return
+
+/// Returns the species' laugh sound
+/datum/species/proc/get_laugh_sound(mob/living/carbon/human/human)
+ return
+
+/// Returns the species' sneeze sound.
+/datum/species/proc/get_sneeze_sound(mob/living/carbon/human/human)
+ return
+
/datum/species/proc/get_types_to_preload()
var/list/to_store = list()
to_store += mutant_organs
diff --git a/code/modules/mob/living/carbon/human/dummy.dm b/code/modules/mob/living/carbon/human/dummy.dm
index 44fe6d1a1c0..193200c1e3a 100644
--- a/code/modules/mob/living/carbon/human/dummy.dm
+++ b/code/modules/mob/living/carbon/human/dummy.dm
@@ -41,7 +41,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
//Instead of just deleting our equipment, we save what we can and reinsert it into SSwardrobe's store
//Hopefully this makes preference reloading not the worst thing ever
/mob/living/carbon/human/dummy/delete_equipment()
- var/list/items_to_check = get_all_worn_items() + held_items
+ var/list/items_to_check = get_equipped_items(include_pockets = TRUE) + held_items
var/list/to_nuke = list() //List of items queued for deletion, can't qdel them before iterating their contents in case they hold something
///Travel to the bottom of the contents chain, expanding it out
for(var/i = 1; i <= length(items_to_check); i++) //Needs to be a c style loop since it can expand
@@ -68,6 +68,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
qdel(delete)
/mob/living/carbon/human/dummy/has_equipped(obj/item/item, slot, initial = FALSE)
+ item.item_flags |= IN_INVENTORY
return item.visual_equipped(src, slot, initial)
/mob/living/carbon/human/dummy/proc/wipe_state()
diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm
index 2f977145be3..d7407c0eb4f 100644
--- a/code/modules/mob/living/carbon/human/emote.dm
+++ b/code/modules/mob/living/carbon/human/emote.dm
@@ -1,12 +1,15 @@
/datum/emote/living/carbon/human
mob_type_allowed_typecache = list(/mob/living/carbon/human)
+
/datum/emote/living/carbon/human/cry
key = "cry"
key_third_person = "cries"
message = "cries."
message_mime = "sobs silently."
+ audio_cooldown = 5 SECONDS
emote_type = EMOTE_AUDIBLE | EMOTE_VISIBLE
+ vary = TRUE
stat_allowed = SOFT_CRIT
/datum/emote/living/carbon/human/cry/run_emote(mob/user, params, type_override, intentional)
@@ -16,6 +19,11 @@
var/mob/living/carbon/human/human_user = user
QDEL_IN(human_user.give_emote_overlay(/datum/bodypart_overlay/simple/emote/cry), 12.8 SECONDS)
+/datum/emote/living/carbon/human/cry/get_sound(mob/living/carbon/human/user)
+ if(!istype(user))
+ return
+ return user.dna.species.get_cry_sound(user)
+
/datum/emote/living/carbon/human/dap
key = "dap"
key_third_person = "daps"
@@ -39,6 +47,36 @@
return ..()
return FALSE
+/datum/emote/living/carbon/human/cough
+ key = "cough"
+ key_third_person = "coughs"
+ message = "coughs!"
+ message_mime = "acts out an exaggerated cough!"
+ vary = TRUE
+ audio_cooldown = 5 SECONDS
+ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE | EMOTE_RUNECHAT
+
+/datum/emote/living/cough/can_run_emote(mob/user, status_check = TRUE , intentional)
+ return !HAS_TRAIT(user, TRAIT_SOOTHED_THROAT) && ..()
+
+/datum/emote/living/carbon/human/cough/get_sound(mob/living/carbon/human/user)
+ if(!istype(user))
+ return
+ return user.dna.species.get_cough_sound(user)
+/datum/emote/living/carbon/human/sneeze
+ key = "sneeze"
+ key_third_person = "sneezes"
+ message = "sneezes."
+ audio_cooldown = 5 SECONDS
+ message_mime = "acts out an exaggerated silent sneeze."
+ vary = TRUE
+ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
+
+/datum/emote/living/carbon/human/sneeze/get_sound(mob/living/carbon/human/user)
+ if(!istype(user))
+ return
+ return user.dna.species.get_sneeze_sound(user)
+
/datum/emote/living/carbon/human/glasses/run_emote(mob/user, params, type_override, intentional)
. = ..()
var/image/emote_animation = image('icons/mob/human/emote_visuals.dmi', user, "glasses")
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 8786167e0dc..55996921f8e 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -362,7 +362,7 @@
if(CONSCIOUS)
if(HAS_TRAIT(src, TRAIT_DUMB))
msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
- if(get_organ_by_type(/obj/item/organ/internal/brain))
+ if(get_organ_by_type(/obj/item/organ/internal/brain) && isnull(ai_controller))
if(!key)
msg += "[span_deadsay("[t_He] [t_is] totally catatonic. The stresses of life in deep-space must have been too much for [t_him]. Any recovery is unlikely.")]\n"
else if(!client)
@@ -404,7 +404,7 @@
if(perpname && (HAS_TRAIT(user, TRAIT_SECURITY_HUD) || HAS_TRAIT(user, TRAIT_MEDICAL_HUD)))
var/datum/record/crew/target_record = find_record(perpname)
if(target_record)
- . += "Rank: [target_record.rank]\n\[Front photo\] \[Side photo\] "
+ . += "Rank: [target_record.rank]\n\[Front photo\] \[Side photo\] "
if(HAS_TRAIT(user, TRAIT_MEDICAL_HUD))
var/cyberimp_detect
for(var/obj/item/organ/internal/cyberimp/cyberimp in organs)
@@ -439,11 +439,11 @@
if(target_record.security_note)
security_note = target_record.security_note
if(ishuman(user))
- . += "Criminal status: \[[wanted_status]\] "
+ . += "Criminal status: \[[wanted_status]\] "
else
- . += "Criminal status: [wanted_status]"
- . += "Important Notes: [security_note]"
- . += "Security record: \[View\] "
+ . += "Criminal status: [wanted_status]"
+ . += "Important Notes: [security_note]"
+ . += "Security record: \[View\] "
if(ishuman(user))
. += jointext(list("\[Add citation\] ",
"\[Add crime\] ",
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 767c09bfa68..4febca81d67 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -88,11 +88,6 @@
/mob/living/carbon/human/Topic(href, href_list)
- if(href_list["item"]) //canUseTopic check for this is handled by mob/Topic()
- var/slot = text2num(href_list["item"])
- if(check_obscured_slots(TRUE) & slot)
- to_chat(usr, span_warning("You can't reach that! Something is covering it."))
- return
///////HUDs///////
if(href_list["hud"])
@@ -620,7 +615,7 @@
// Check and wash stuff that can be covered
var/obscured = check_obscured_slots()
- if(w_uniform && !(obscured & ITEM_SLOT_ICLOTHING) && w_uniform.wash(clean_types))
+ if(!(obscured & ITEM_SLOT_ICLOTHING) && w_uniform?.wash(clean_types))
update_worn_undersuit()
. = TRUE
@@ -959,7 +954,7 @@
var/carrydelay = 5 SECONDS //if you have latex you are faster at grabbing
var/skills_space
- var/fitness_level = mind.get_skill_level(/datum/skill/fitness) - 1
+ var/fitness_level = mind.get_skill_level(/datum/skill/athletics) - 1
if(HAS_TRAIT(src, TRAIT_QUICKER_CARRY))
carrydelay -= 2 SECONDS
else if(HAS_TRAIT(src, TRAIT_QUICK_CARRY))
diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm
index d18c0c800f6..c8912cb72a5 100644
--- a/code/modules/mob/living/carbon/human/human_helpers.dm
+++ b/code/modules/mob/living/carbon/human/human_helpers.dm
@@ -75,15 +75,15 @@
return "Unknown"
//Returns "Unknown" if facially disfigured and real_name if not. Useful for setting name when Fluacided or when updating a human's name variable
-/mob/living/carbon/human/proc/get_face_name(if_no_face="Unknown")
+/mob/living/carbon/human/proc/get_face_name(if_no_face = "Unknown")
if(HAS_TRAIT(src, TRAIT_UNKNOWN))
return if_no_face //We're Unknown, no face information for you
- if( wear_mask && (wear_mask.flags_inv&HIDEFACE) ) //Wearing a mask which hides our face, use id-name if possible
+ for(var/obj/item/worn_item in get_equipped_items())
+ if(!(worn_item.flags_inv & HIDEFACE))
+ continue
return if_no_face
- if( head && (head.flags_inv&HIDEFACE) )
- return if_no_face //Likewise for hats
- var/obj/item/bodypart/O = get_bodypart(BODY_ZONE_HEAD)
- if( !O || (HAS_TRAIT(src, TRAIT_DISFIGURED)) || (O.brutestate+O.burnstate)>2 || !real_name || HAS_TRAIT(src, TRAIT_INVISIBLE_MAN)) //disfigured. use id-name if possible
+ var/obj/item/bodypart/head = get_bodypart(BODY_ZONE_HEAD)
+ if(isnull(head) || (HAS_TRAIT(src, TRAIT_DISFIGURED)) || (head.brutestate + head.burnstate) > 2 || !real_name || HAS_TRAIT(src, TRAIT_INVISIBLE_MAN)) //disfigured. use id-name if possible
return if_no_face
return real_name
diff --git a/code/modules/mob/living/carbon/human/human_update_icons.dm b/code/modules/mob/living/carbon/human/human_update_icons.dm
index bfb22804ddf..6f1c3f02ddf 100644
--- a/code/modules/mob/living/carbon/human/human_update_icons.dm
+++ b/code/modules/mob/living/carbon/human/human_update_icons.dm
@@ -54,7 +54,7 @@ There are several things that need to be remembered:
update_worn_id()
update_worn_glasses()
update_worn_gloves()
- update_inv_ears()
+ update_worn_ears()
update_worn_shoes()
update_suit_storage()
update_worn_mask()
@@ -70,10 +70,19 @@ There are several things that need to be remembered:
//damage overlays
update_damage_overlays()
+/mob/living/carbon/human/update_obscured_slots(obscured_flags)
+ ..()
+ if(obscured_flags & HIDEFACE)
+ sec_hud_set_security_status()
+ // SKYRAT EDIT ADDITION START - ERP Overlays
+ if(obscured_flags & HIDESEXTOY)
+ update_inv_lewd()
+ // SKYRAT EDIT ADDITION END
+
/* --------------------------------------- */
//vvvvvv UPDATE_INV PROCS vvvvvv
-/mob/living/carbon/human/update_worn_undersuit()
+/mob/living/carbon/human/update_worn_undersuit(update_obscured = TRUE)
remove_overlay(UNIFORM_LAYER)
if(client && hud_used)
@@ -84,6 +93,9 @@ There are several things that need to be remembered:
var/obj/item/clothing/under/uniform = w_uniform
update_hud_uniform(uniform)
+ if(update_obscured)
+ update_obscured_slots(uniform.flags_inv)
+
if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_ICLOTHING)
return
@@ -153,7 +165,7 @@ There are several things that need to be remembered:
update_mutant_bodyparts()
-/mob/living/carbon/human/update_worn_id()
+/mob/living/carbon/human/update_worn_id(update_obscured = TRUE)
remove_overlay(ID_LAYER)
if(client && hud_used)
@@ -165,6 +177,10 @@ There are several things that need to be remembered:
if(wear_id)
var/obj/item/worn_item = wear_id
update_hud_id(worn_item)
+
+ if(update_obscured)
+ update_obscured_slots(worn_item.flags_inv)
+
var/icon_file = 'icons/mob/clothing/id.dmi'
id_overlay = wear_id.build_worn_icon(default_layer = ID_LAYER, default_icon_file = icon_file)
@@ -179,7 +195,7 @@ There are several things that need to be remembered:
apply_overlay(ID_LAYER)
-/mob/living/carbon/human/update_worn_gloves()
+/mob/living/carbon/human/update_worn_gloves(update_obscured = TRUE)
remove_overlay(GLOVES_LAYER)
if(client && hud_used && hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_GLOVES) + 1])
@@ -202,6 +218,9 @@ There are several things that need to be remembered:
var/obj/item/worn_item = gloves
update_hud_gloves(worn_item)
+ if(update_obscured)
+ update_obscured_slots(worn_item.flags_inv)
+
if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_GLOVES)
return
@@ -230,7 +249,7 @@ There are several things that need to be remembered:
apply_overlay(GLOVES_LAYER)
-/mob/living/carbon/human/update_worn_glasses()
+/mob/living/carbon/human/update_worn_glasses(update_obscured = TRUE)
remove_overlay(GLASSES_LAYER)
var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD)
@@ -245,6 +264,9 @@ There are several things that need to be remembered:
var/obj/item/worn_item = glasses
update_hud_glasses(worn_item)
+ if(update_obscured)
+ update_obscured_slots(worn_item.flags_inv)
+
if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_EYES)
return
@@ -269,7 +291,7 @@ There are several things that need to be remembered:
apply_overlay(GLASSES_LAYER)
-/mob/living/carbon/human/update_inv_ears()
+/mob/living/carbon/human/update_worn_ears(update_obscured = TRUE)
remove_overlay(EARS_LAYER)
var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD)
@@ -284,6 +306,9 @@ There are several things that need to be remembered:
var/obj/item/worn_item = ears
update_hud_ears(worn_item)
+ if(update_obscured)
+ update_obscured_slots(worn_item.flags_inv)
+
if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_EARS)
return
@@ -307,7 +332,7 @@ There are several things that need to be remembered:
overlays_standing[EARS_LAYER] = ears_overlay
apply_overlay(EARS_LAYER)
-/mob/living/carbon/human/update_worn_neck()
+/mob/living/carbon/human/update_worn_neck(update_obscured = TRUE)
remove_overlay(NECK_LAYER)
if(client && hud_used && hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_NECK) + 1])
@@ -318,6 +343,9 @@ There are several things that need to be remembered:
var/obj/item/worn_item = wear_neck
update_hud_neck(wear_neck)
+ if(update_obscured)
+ update_obscured_slots(worn_item.flags_inv)
+
if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_NECK)
return
@@ -349,7 +377,7 @@ There are several things that need to be remembered:
apply_overlay(NECK_LAYER)
-/mob/living/carbon/human/update_worn_shoes()
+/mob/living/carbon/human/update_worn_shoes(update_obscured = TRUE)
remove_overlay(SHOES_LAYER)
if(num_legs < 2)
@@ -363,6 +391,9 @@ There are several things that need to be remembered:
var/obj/item/worn_item = shoes
update_hud_shoes(worn_item)
+ if(update_obscured)
+ update_obscured_slots(worn_item.flags_inv)
+
if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_FEET)
return
@@ -407,7 +438,7 @@ There are several things that need to be remembered:
update_body_parts()
-/mob/living/carbon/human/update_suit_storage()
+/mob/living/carbon/human/update_suit_storage(update_obscured = TRUE)
remove_overlay(SUIT_STORE_LAYER)
if(client && hud_used)
@@ -418,6 +449,9 @@ There are several things that need to be remembered:
var/obj/item/worn_item = s_store
update_hud_s_store(worn_item)
+ if(update_obscured)
+ update_obscured_slots(worn_item.flags_inv)
+
if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_SUITSTORE)
return
@@ -427,7 +461,7 @@ There are several things that need to be remembered:
overlays_standing[SUIT_STORE_LAYER] = s_store_overlay
apply_overlay(SUIT_STORE_LAYER)
-/mob/living/carbon/human/update_worn_head()
+/mob/living/carbon/human/update_worn_head(update_obscured = TRUE)
remove_overlay(HEAD_LAYER)
if(client && hud_used && hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_BACK) + 1])
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_HEAD) + 1]
@@ -437,6 +471,9 @@ There are several things that need to be remembered:
var/obj/item/worn_item = head
update_hud_head(worn_item)
+ if(update_obscured)
+ update_obscured_slots(worn_item.flags_inv)
+
if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_HEAD)
return
@@ -465,10 +502,9 @@ There are several things that need to be remembered:
// SKYRAT EDIT END
overlays_standing[HEAD_LAYER] = head_overlay
- update_mutant_bodyparts()
apply_overlay(HEAD_LAYER)
-/mob/living/carbon/human/update_worn_belt()
+/mob/living/carbon/human/update_worn_belt(update_obscured = TRUE)
remove_overlay(BELT_LAYER)
if(client && hud_used)
@@ -479,6 +515,9 @@ There are several things that need to be remembered:
var/obj/item/worn_item = belt
update_hud_belt(worn_item)
+ if(update_obscured)
+ update_obscured_slots(worn_item.flags_inv)
+
if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_BELT)
return
@@ -504,7 +543,7 @@ There are several things that need to be remembered:
apply_overlay(BELT_LAYER)
-/mob/living/carbon/human/update_worn_oversuit()
+/mob/living/carbon/human/update_worn_oversuit(update_obscured = TRUE)
remove_overlay(SUIT_LAYER)
if(client && hud_used)
@@ -514,6 +553,10 @@ There are several things that need to be remembered:
if(wear_suit)
var/obj/item/worn_item = wear_suit
update_hud_wear_suit(worn_item)
+
+ if(update_obscured)
+ update_obscured_slots(worn_item.flags_inv)
+
var/icon_file = DEFAULT_SUIT_FILE
// SKYRAT EDIT ADDITION
@@ -573,7 +616,7 @@ There are several things that need to be remembered:
client.screen += r_store
update_observer_view(r_store)
-/mob/living/carbon/human/update_worn_mask()
+/mob/living/carbon/human/update_worn_mask(update_obscured = TRUE)
remove_overlay(FACEMASK_LAYER)
var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD)
@@ -588,6 +631,9 @@ There are several things that need to be remembered:
var/obj/item/worn_item = wear_mask
update_hud_wear_mask(worn_item)
+ if(update_obscured)
+ update_obscured_slots(worn_item.flags_inv)
+
if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_MASK)
return
@@ -618,7 +664,7 @@ There are several things that need to be remembered:
apply_overlay(FACEMASK_LAYER)
update_mutant_bodyparts() //e.g. upgate needed because mask now hides lizard snout
-/mob/living/carbon/human/update_worn_back()
+/mob/living/carbon/human/update_worn_back(update_obscured = TRUE)
remove_overlay(BACK_LAYER)
if(client && hud_used && hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_BACK) + 1])
@@ -629,6 +675,10 @@ There are several things that need to be remembered:
var/obj/item/worn_item = back
var/mutable_appearance/back_overlay
update_hud_back(worn_item)
+
+ if(update_obscured)
+ update_obscured_slots(worn_item.flags_inv)
+
var/icon_file = 'icons/mob/clothing/back.dmi'
// SKYRAT EDIT ADDITION
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index 6cafa38164e..f0dadf5f818 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -69,9 +69,6 @@
return ..()
-/mob/living/carbon/human/get_all_worn_items()
- . = get_head_slots() | get_body_slots()
-
/mob/living/carbon/human/proc/get_body_slots()
return list(
back,
@@ -136,15 +133,13 @@
if(ears)
return
ears = equipping
- update_inv_ears()
+ update_worn_ears()
if(ITEM_SLOT_EYES)
if(glasses)
return
glasses = equipping
if(glasses.glass_colour_type)
update_glasses_color(glasses, 1)
- if(glasses.tint)
- update_tint()
if(glasses.vision_flags || glasses.invis_override || glasses.invis_view || !isnull(glasses.lighting_cutoff))
update_sight()
update_worn_glasses()
@@ -171,8 +166,6 @@
wear_suit = equipping
- if(equipping.flags_inv & HIDEJUMPSUIT)
- update_worn_undersuit()
if(wear_suit.breakouttime) //when equipping a straightjacket
ADD_TRAIT(src, TRAIT_RESTRAINED, SUIT_TRAIT)
stop_pulling() //can't pull if restrained
@@ -216,6 +209,7 @@
. = ..() //See mob.dm for an explanation on this and some rage about people copypasting instead of calling ..() like they should.
if(!. || !I)
return
+ var/not_handled = FALSE //if we actually unequipped an item, this is because we dont want to run this proc twice, once for carbons and once for humans
if(I == wear_suit)
if(s_store && invdrop)
dropItemToGround(s_store, TRUE) //It makes no sense for your suit storage to stay on you if you drop your suit.
@@ -225,14 +219,6 @@
update_mob_action_buttons() //certain action buttons may be usable again.
wear_suit = null
if(!QDELETED(src)) //no need to update we're getting deleted anyway
- if(I.flags_inv & HIDEJUMPSUIT)
- update_worn_undersuit()
-
- // SKYRAT EDIT ADDITION START - ERP Overlays
- if(I.flags_inv & HIDESEXTOY)
- update_inv_lewd()
- // SKYRAT EDIT ADDITION END
-
update_worn_oversuit()
else if(I == w_uniform)
w_uniform = null
@@ -263,8 +249,6 @@
var/obj/item/clothing/glasses/G = I
if(G.glass_colour_type)
update_glasses_color(G, 0)
- if(G.tint)
- update_tint()
if(G.vision_flags || G.invis_override || G.invis_view || !isnull(G.lighting_cutoff))
update_sight()
if(!QDELETED(src))
@@ -272,7 +256,7 @@
else if(I == ears)
ears = null
if(!QDELETED(src))
- update_inv_ears()
+ update_worn_ears()
else if(I == shoes)
shoes = null
if(!QDELETED(src))
@@ -298,13 +282,19 @@
s_store = null
if(!QDELETED(src))
update_suit_storage()
-
- update_equipment_speed_mods()
+ else
+ not_handled = TRUE
// Send a signal for when we unequip an item that used to cover our feet/shoes. Used for bloody feet
if((I.body_parts_covered & FEET) || (I.flags_inv | I.transparent_protection) & HIDESHOES)
SEND_SIGNAL(src, COMSIG_CARBON_UNEQUIP_SHOECOVER, I, force, newloc, no_move, invdrop, silent)
+ if(not_handled)
+ return
+
+ update_equipment_speed_mods()
+ update_obscured_slots(I.flags_inv)
+
/mob/living/carbon/human/toggle_internals(obj/item/tank, is_external = FALSE)
// Just close the tank if it's the one the mob already has open.
var/obj/item/existing_tank = is_external ? external : internal
@@ -316,8 +306,8 @@
// Use mask in absence of tube.
if(isclothing(wear_mask) && ((wear_mask.visor_flags & MASKINTERNALS) || (wear_mask.clothing_flags & MASKINTERNALS)))
// Adjust dishevelled breathing mask back onto face.
- if (wear_mask.mask_adjusted)
- wear_mask.adjustmask(src)
+ if (wear_mask.up)
+ wear_mask.adjust_visor(src)
return toggle_open_internals(tank, is_external)
// Use helmet in absence of tube or valid mask.
if(can_breathe_helmet())
@@ -337,30 +327,6 @@
/mob/living/carbon/human/toggle_externals(obj/item/tank)
return toggle_internals(tank, TRUE)
-/mob/living/carbon/human/wear_mask_update(obj/item/I, toggle_off = 1)
- if((I.flags_inv & (HIDEHAIR|HIDEFACIALHAIR)) || (initial(I.flags_inv) & (HIDEHAIR|HIDEFACIALHAIR)))
- update_body_parts()
- // Close internal air tank if mask was the only breathing apparatus.
- if(invalid_internals())
- cutoff_internals()
- if(I.flags_inv & HIDEEYES)
- update_worn_glasses()
- sec_hud_set_security_status()
- ..()
-
-/mob/living/carbon/human/head_update(obj/item/I, forced)
- if((I.flags_inv & (HIDEHAIR|HIDEFACIALHAIR)) || forced)
- update_body_parts()
- // Close internal air tank if helmet was the only breathing apparatus.
- if (invalid_internals())
- cutoff_internals()
- if(I.flags_inv & HIDEEYES || forced)
- update_worn_glasses()
- if(I.flags_inv & HIDEEARS || forced)
- update_body()
- sec_hud_set_security_status()
- ..()
-
/mob/living/carbon/human/proc/equipOutfit(outfit, visualsOnly = FALSE)
var/datum/outfit/O = null
@@ -394,10 +360,10 @@
//delete all equipment without dropping anything
/mob/living/carbon/human/proc/delete_equipment()
- for(var/slot in get_all_worn_items())//order matters, dependant slots go first
+ for(var/slot in get_equipped_items(include_pockets = TRUE))//order matters, dependant slots go first
qdel(slot)
- for(var/obj/item/I in held_items)
- qdel(I)
+ for(var/obj/item/held_item in held_items)
+ qdel(held_item)
/// take the most recent item out of a slot or place held item in a slot
diff --git a/code/modules/mob/living/carbon/human/species_types/felinid.dm b/code/modules/mob/living/carbon/human/species_types/felinid.dm
index 0b5bc2d5c46..0d1a3afdbd3 100644
--- a/code/modules/mob/living/carbon/human/species_types/felinid.dm
+++ b/code/modules/mob/living/carbon/human/species_types/felinid.dm
@@ -60,6 +60,54 @@
features["ears"] = pick("None", "Cat")
return features
+/datum/species/human/felinid/get_laugh_sound(mob/living/carbon/human/felinid)
+ if(felinid.physique == FEMALE)
+ return 'sound/voice/human/womanlaugh.ogg'
+ return pick(
+ 'sound/voice/human/manlaugh1.ogg',
+ 'sound/voice/human/manlaugh2.ogg',
+ )
+
+
+/datum/species/human/felinid/get_cough_sound(mob/living/carbon/human/felinid)
+ if(felinid.physique == FEMALE)
+ return pick(
+ 'sound/voice/human/female_cough1.ogg',
+ 'sound/voice/human/female_cough2.ogg',
+ 'sound/voice/human/female_cough3.ogg',
+ 'sound/voice/human/female_cough4.ogg',
+ 'sound/voice/human/female_cough5.ogg',
+ 'sound/voice/human/female_cough6.ogg',
+ )
+ return pick(
+ 'sound/voice/human/male_cough1.ogg',
+ 'sound/voice/human/male_cough2.ogg',
+ 'sound/voice/human/male_cough3.ogg',
+ 'sound/voice/human/male_cough4.ogg',
+ 'sound/voice/human/male_cough5.ogg',
+ 'sound/voice/human/male_cough6.ogg',
+ )
+
+
+/datum/species/human/felinid/get_cry_sound(mob/living/carbon/human/felinid)
+ if(felinid.physique == FEMALE)
+ return pick(
+ 'sound/voice/human/female_cry1.ogg',
+ 'sound/voice/human/female_cry2.ogg',
+ )
+ return pick(
+ 'sound/voice/human/male_cry1.ogg',
+ 'sound/voice/human/male_cry2.ogg',
+ 'sound/voice/human/male_cry3.ogg',
+ )
+
+
+/datum/species/human/felinid/get_sneeze_sound(mob/living/carbon/human/felinid)
+ if(felinid.physique == FEMALE)
+ return 'sound/voice/human/female_sneeze1.ogg'
+ return 'sound/voice/human/male_sneeze1.ogg'
+
+
/proc/mass_purrbation()
for(var/mob in GLOB.human_list)
purrbation_apply(mob)
diff --git a/code/modules/mob/living/carbon/human/species_types/humans.dm b/code/modules/mob/living/carbon/human/species_types/humans.dm
index e171b76b86d..ec3b5f54009 100644
--- a/code/modules/mob/living/carbon/human/species_types/humans.dm
+++ b/code/modules/mob/living/carbon/human/species_types/humans.dm
@@ -34,6 +34,53 @@
'sound/voice/human/femalescream_5.ogg',
)
+/datum/species/human/get_cough_sound(mob/living/carbon/human/human)
+ if(human.physique == FEMALE)
+ return pick(
+ 'sound/voice/human/female_cough1.ogg',
+ 'sound/voice/human/female_cough2.ogg',
+ 'sound/voice/human/female_cough3.ogg',
+ 'sound/voice/human/female_cough4.ogg',
+ 'sound/voice/human/female_cough5.ogg',
+ 'sound/voice/human/female_cough6.ogg',
+ )
+ return pick(
+ 'sound/voice/human/male_cough1.ogg',
+ 'sound/voice/human/male_cough2.ogg',
+ 'sound/voice/human/male_cough3.ogg',
+ 'sound/voice/human/male_cough4.ogg',
+ 'sound/voice/human/male_cough5.ogg',
+ 'sound/voice/human/male_cough6.ogg',
+ )
+
+/datum/species/human/get_cry_sound(mob/living/carbon/human/human)
+ if(human.physique == FEMALE)
+ return pick(
+ 'sound/voice/human/female_cry1.ogg',
+ 'sound/voice/human/female_cry2.ogg',
+ )
+ return pick(
+ 'sound/voice/human/male_cry1.ogg',
+ 'sound/voice/human/male_cry2.ogg',
+ 'sound/voice/human/male_cry3.ogg',
+ )
+
+
+/datum/species/human/get_sneeze_sound(mob/living/carbon/human/human)
+ if(human.physique == FEMALE)
+ return 'sound/voice/human/female_sneeze1.ogg'
+ return 'sound/voice/human/male_sneeze1.ogg'
+
+/datum/species/human/get_laugh_sound(mob/living/carbon/human/human)
+ if(!ishuman(human))
+ return
+ if(human.physique == FEMALE)
+ return 'sound/voice/human/womanlaugh.ogg'
+ return pick(
+ 'sound/voice/human/manlaugh1.ogg',
+ 'sound/voice/human/manlaugh2.ogg',
+ )
+
/datum/species/human/get_species_description()
return "Humans are the dominant species in the known galaxy. \
Their kind extend from old Earth to the edges of known space."
diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
index 94dbe677949..439dd8b42e9 100644
--- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
@@ -74,6 +74,49 @@
'sound/voice/lizard/lizard_scream_3.ogg',
)
+/datum/species/lizard/get_cough_sound(mob/living/carbon/human/lizard)
+ if(lizard.gender == FEMALE)
+ return pick(
+ 'sound/voice/human/female_cough1.ogg',
+ 'sound/voice/human/female_cough2.ogg',
+ 'sound/voice/human/female_cough3.ogg',
+ 'sound/voice/human/female_cough4.ogg',
+ 'sound/voice/human/female_cough5.ogg',
+ 'sound/voice/human/female_cough6.ogg',
+ )
+ return pick(
+ 'sound/voice/human/male_cough1.ogg',
+ 'sound/voice/human/male_cough2.ogg',
+ 'sound/voice/human/male_cough3.ogg',
+ 'sound/voice/human/male_cough4.ogg',
+ 'sound/voice/human/male_cough5.ogg',
+ 'sound/voice/human/male_cough6.ogg',
+ )
+
+
+/datum/species/lizard/get_cry_sound(mob/living/carbon/human/lizard)
+ if(lizard.gender == FEMALE)
+ return pick(
+ 'sound/voice/human/female_cry1.ogg',
+ 'sound/voice/human/female_cry2.ogg',
+ )
+ return pick(
+ 'sound/voice/human/male_cry1.ogg',
+ 'sound/voice/human/male_cry2.ogg',
+ 'sound/voice/human/male_cry3.ogg',
+ )
+
+
+/datum/species/lizard/get_sneeze_sound(mob/living/carbon/human/lizard)
+ if(lizard.gender == FEMALE)
+ return 'sound/voice/human/female_sneeze1.ogg'
+ return 'sound/voice/human/male_sneeze1.ogg'
+
+/datum/species/lizard/get_laugh_sound(mob/living/carbon/human)
+ if(!istype(human))
+ return
+ return 'sound/voice/lizard/lizard_laugh1.ogg'
+
/datum/species/lizard/get_physical_attributes()
return "Lizardpeople can withstand slightly higher temperatures than most species, but they are very vulnerable to the cold \
and can't regulate their body-temperature internally, making the vacuum of space extremely deadly to them."
diff --git a/code/modules/mob/living/carbon/human/species_types/mothmen.dm b/code/modules/mob/living/carbon/human/species_types/mothmen.dm
index 8f3cd84e1e5..e8f323e1911 100644
--- a/code/modules/mob/living/carbon/human/species_types/mothmen.dm
+++ b/code/modules/mob/living/carbon/human/species_types/mothmen.dm
@@ -64,9 +64,53 @@
features["moth_markings"] = pick(GLOB.moth_wings_list) // SKYRAT EDIT CHANGE - ORIGINAL: features["moth_markings"] = pick(GLOB.moth_markings_list)
return features
-/datum/species/moth/get_scream_sound(mob/living/carbon/human/human)
+/datum/species/moth/get_scream_sound(mob/living/carbon/human)
return 'sound/voice/moth/scream_moth.ogg'
+/datum/species/moth/get_cough_sound(mob/living/carbon/human/moth)
+ if(moth.gender == FEMALE)
+ return pick(
+ 'sound/voice/human/female_cough1.ogg',
+ 'sound/voice/human/female_cough2.ogg',
+ 'sound/voice/human/female_cough3.ogg',
+ 'sound/voice/human/female_cough4.ogg',
+ 'sound/voice/human/female_cough5.ogg',
+ 'sound/voice/human/female_cough6.ogg',
+ )
+ return pick(
+ 'sound/voice/human/male_cough1.ogg',
+ 'sound/voice/human/male_cough2.ogg',
+ 'sound/voice/human/male_cough3.ogg',
+ 'sound/voice/human/male_cough4.ogg',
+ 'sound/voice/human/male_cough5.ogg',
+ 'sound/voice/human/male_cough6.ogg',
+ )
+
+
+/datum/species/moth/get_cry_sound(mob/living/carbon/human/moth)
+ if(moth.gender == FEMALE)
+ return pick(
+ 'sound/voice/human/female_cry1.ogg',
+ 'sound/voice/human/female_cry2.ogg',
+ )
+ return pick(
+ 'sound/voice/human/male_cry1.ogg',
+ 'sound/voice/human/male_cry2.ogg',
+ 'sound/voice/human/male_cry3.ogg',
+ )
+
+
+/datum/species/moth/get_sneeze_sound(mob/living/carbon/human/moth)
+ if(moth.gender == FEMALE)
+ return 'sound/voice/human/female_sneeze1.ogg'
+ return 'sound/voice/human/male_sneeze1.ogg'
+
+
+/datum/species/moth/get_laugh_sound(mob/living/carbon/human)
+ if(!istype(human))
+ return
+ return 'sound/voice/moth/moth_laugh1.ogg'
+
/datum/species/moth/get_physical_attributes()
return "Moths have large and fluffy wings, which help them navigate the station if gravity is offline by pushing the air around them. \
Due to that, it isn't of much use out in space. Their eyes are very sensitive."
diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm
index e0a24d0ab51..45ca4487184 100644
--- a/code/modules/mob/living/carbon/inventory.dm
+++ b/code/modules/mob/living/carbon/inventory.dm
@@ -39,16 +39,6 @@
return ..()
-/mob/living/carbon/proc/get_all_worn_items()
- return list(
- back,
- wear_mask,
- wear_neck,
- head,
- handcuffed,
- legcuffed,
- )
-
/// Returns items which are currently visible on the mob
/mob/living/carbon/proc/get_visible_items()
var/static/list/visible_slots = list(
@@ -126,13 +116,13 @@
if(wear_mask)
return
wear_mask = equipping
- wear_mask_update(equipping, toggle_off = 0)
+ update_worn_mask()
if(ITEM_SLOT_HEAD)
if(head)
return
head = equipping
SEND_SIGNAL(src, COMSIG_CARBON_EQUIP_HAT, equipping)
- head_update(equipping)
+ update_worn_head()
if(ITEM_SLOT_NECK)
if(wear_neck)
return
@@ -162,7 +152,7 @@
return not_handled
/mob/living/carbon/get_equipped_speed_mod_items()
- return ..() + get_all_worn_items()
+ return ..() + get_equipped_items()
/// This proc is called after an item has been successfully handled and equipped to a slot.
/mob/living/carbon/proc/has_equipped(obj/item/item, slot, initial = FALSE)
@@ -173,11 +163,12 @@
if(!. || !I) //We don't want to set anything to null if the parent returned 0.
return
+ var/not_handled = FALSE //if we actually unequipped an item, this is because we dont want to run this proc twice, once for carbons and once for humans
if(I == head)
head = null
SEND_SIGNAL(src, COMSIG_CARBON_UNEQUIP_HAT, I, force, newloc, no_move, invdrop, silent)
if(!QDELETED(src))
- head_update(I)
+ update_worn_head()
else if(I == back)
back = null
if(!QDELETED(src))
@@ -185,8 +176,8 @@
else if(I == wear_mask)
wear_mask = null
if(!QDELETED(src))
- wear_mask_update(I, toggle_off = 1)
- if(I == wear_neck)
+ update_worn_mask()
+ else if(I == wear_neck)
wear_neck = null
if(!QDELETED(src))
update_worn_neck(I)
@@ -200,6 +191,8 @@
legcuffed = null
if(!QDELETED(src))
update_worn_legcuffs()
+ else
+ not_handled = TRUE
// Not an else-if because we're probably equipped in another slot
if(I == internal && (QDELETED(src) || QDELETED(I) || I.loc != src))
@@ -207,7 +200,11 @@
if(!QDELETED(src))
update_mob_action_buttons(UPDATE_BUTTON_STATUS)
+ if(not_handled)
+ return
+
update_equipment_speed_mods()
+ update_obscured_slots(I.flags_inv)
/// Returns TRUE if an air tank compatible helmet is equipped.
/mob/living/carbon/proc/can_breathe_helmet()
@@ -357,27 +354,6 @@
// Carbons can't open their own externals tanks.
return FALSE
-/// Handle stuff to update when a mob equips/unequips a mask.
-/mob/living/proc/wear_mask_update(obj/item/I, toggle_off = 1)
- update_worn_mask()
-
-/mob/living/carbon/wear_mask_update(obj/item/I, toggle_off = 1)
- var/obj/item/clothing/C = I
- if(istype(C) && (C.tint || initial(C.tint)))
- update_tint()
- update_worn_mask()
-
-/// Handle stuff to update when a mob equips/unequips a headgear.
-/mob/living/carbon/proc/head_update(obj/item/I, forced)
- if(isclothing(I))
- var/obj/item/clothing/C = I
- if(C.tint || initial(C.tint))
- update_tint()
- update_sight()
- if(I.flags_inv & HIDEMASK || forced)
- update_worn_mask()
- update_worn_head()
-
/mob/living/carbon/proc/get_holding_bodypart_of_item(obj/item/I)
var/index = get_held_index_of_item(I)
return index && hand_bodyparts[index]
@@ -475,7 +451,7 @@
SHOULD_NOT_OVERRIDE(TRUE)
var/covered_flags = NONE
- var/list/all_worn_items = get_all_worn_items()
+ var/list/all_worn_items = get_equipped_items()
for(var/obj/item/worn_item in all_worn_items)
covered_flags |= worn_item.body_parts_covered
@@ -486,7 +462,7 @@
SHOULD_NOT_OVERRIDE(TRUE)
var/covered_flags = NONE
- var/list/all_worn_items = get_all_worn_items()
+ var/list/all_worn_items = get_equipped_items()
for(var/obj/item/worn_item in all_worn_items)
covered_flags |= worn_item.body_parts_covered
diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm
index 412a63c00eb..a6f424c369b 100644
--- a/code/modules/mob/living/emote.dm
+++ b/code/modules/mob/living/emote.dm
@@ -67,18 +67,6 @@
var/mob/living/L = user
L.Unconscious(40)
-/datum/emote/living/cough
- key = "cough"
- key_third_person = "coughs"
- message = "coughs!"
- message_mime = "acts out an exaggerated cough!"
- emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
-
-/datum/emote/living/cough/can_run_emote(mob/user, status_check = TRUE , intentional)
- . = ..()
- if(HAS_TRAIT(user, TRAIT_SOOTHED_THROAT))
- return FALSE
-
/datum/emote/living/dance
key = "dance"
key_third_person = "dances"
@@ -291,16 +279,11 @@
/datum/emote/living/laugh/can_run_emote(mob/living/user, status_check = TRUE , intentional)
return ..() && user.can_speak(allow_mimes = TRUE)
-/datum/emote/living/laugh/get_sound(mob/living/user)
- . = ..()
+/datum/emote/living/laugh/get_sound(mob/living/carbon/user)
if(!ishuman(user))
return
var/mob/living/carbon/human/human_user = user
- if((ishumanbasic(human_user) || isfelinid(human_user)) && !HAS_MIND_TRAIT(human_user, TRAIT_MIMING))
- if(human_user.gender == FEMALE)
- return 'sound/voice/human/womanlaugh.ogg'
- else
- return pick('sound/voice/human/manlaugh1.ogg', 'sound/voice/human/manlaugh2.ogg')
+ return human_user.dna.species.get_laugh_sound(user)
*/ //SKYRAT EDIT END
/datum/emote/living/look
@@ -335,6 +318,38 @@
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5)
return ..()
+/datum/emote/living/carbon/cry
+ key = "cry"
+ key_third_person = "cries"
+ message = "cries."
+ emote_type = EMOTE_AUDIBLE | EMOTE_VISIBLE
+ stat_allowed = SOFT_CRIT
+ mob_type_blacklist_typecache = list(/mob/living/carbon/human) //Humans get specialized cry emote with sound and animation.
+
+/datum/emote/living/sneeze
+ key = "sneeze"
+ key_third_person = "sneezes"
+ message = "sneezes."
+ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
+ mob_type_blacklist_typecache = list(/mob/living/carbon/human) //Humans get specialized sneeze emote with sound.
+
+/datum/emote/living/carbon/human/glasses/run_emote(mob/user, params, type_override, intentional)
+ . = ..()
+ var/image/emote_animation = image('icons/mob/human/emote_visuals.dmi', user, "glasses")
+ flick_overlay_global(emote_animation, GLOB.clients, 1.6 SECONDS)
+
+/datum/emote/living/carbon/cough
+ key = "cough"
+ key_third_person = "coughs"
+ message = "coughs!"
+ message_mime = "acts out an exaggerated cough!"
+ emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE | EMOTE_RUNECHAT
+ mob_type_blacklist_typecache = list(/mob/living/carbon/human) //Humans get specialized cough emote with sound.
+
+/datum/emote/living/cough/can_run_emote(mob/user, status_check = TRUE , intentional)
+ return !HAS_TRAIT(user, TRAIT_SOOTHED_THROAT) && ..()
+
+
/datum/emote/living/pout
key = "pout"
key_third_person = "pouts"
@@ -410,13 +425,6 @@
key_third_person = "smiles"
message = "smiles."
-/datum/emote/living/sneeze
- key = "sneeze"
- key_third_person = "sneezes"
- message = "sneezes."
- message_mime = "acts out an exaggerated silent sneeze."
- emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE
-
/datum/emote/living/smug
key = "smug"
key_third_person = "smugs"
@@ -757,3 +765,17 @@
message = "says a swear word!"
message_mime = "makes a rude gesture!"
emote_type = EMOTE_AUDIBLE
+
+/datum/emote/living/carbon/whistle
+ key = "whistle"
+ key_third_person = "whistles"
+ message = "whistles."
+ message_mime = "whistles silently!"
+ audio_cooldown = 5 SECONDS
+ vary = TRUE
+ emote_type = EMOTE_AUDIBLE | EMOTE_VISIBLE
+
+/datum/emote/living/carbon/whistle/get_sound(mob/living/user)
+ if(!istype(user))
+ return
+ return 'sound/voice/human/whistle1.ogg'
diff --git a/code/modules/mob/living/init_signals.dm b/code/modules/mob/living/init_signals.dm
index b8f1e60a612..2c390c540ce 100644
--- a/code/modules/mob/living/init_signals.dm
+++ b/code/modules/mob/living/init_signals.dm
@@ -98,7 +98,7 @@
SIGNAL_HANDLER
mobility_flags &= ~MOBILITY_MOVE
if(living_flags & MOVES_ON_ITS_OWN)
- SSmove_manager.stop_looping(src) //stop mid walk //This is also really dumb
+ DSmove_manager.stop_looping(src) //stop mid walk //This is also really dumb
/// Called when [TRAIT_IMMOBILIZED] is removed from the mob.
/mob/living/proc/on_immobilized_trait_loss(datum/source)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index d6c133ea3a8..05fdbad99e8 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -697,7 +697,9 @@
/mob/living/proc/get_up(instant = FALSE)
set waitfor = FALSE
- var/get_up_speed = GET_UP_FAST //SKYRAT EDIT CHANGE : if(!instant && !do_after(src, 1 SECONDS, src, timed_action_flags = (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM), extra_checks = CALLBACK(src, TYPE_PROC_REF(/mob/living, rest_checks_callback)), interaction_key = DOAFTER_SOURCE_GETTING_UP))
+ // if(!instant && !do_after(src, 1 SECONDS, src, timed_action_flags = (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM), extra_checks = CALLBACK(src, TYPE_PROC_REF(/mob/living, rest_checks_callback)), interaction_key = DOAFTER_SOURCE_GETTING_UP, hidden = TRUE)) // SKYRAT EDIT REMOVAL
+ // SKYRAT EDIT ADDITION START
+ var/get_up_speed = GET_UP_FAST
var/stam = getStaminaLoss()
switch(FLOOR(stam,1))
if(STAMINA_THRESHOLD_MEDIUM_GET_UP to STAMINA_THRESHOLD_SLOW_GET_UP)
@@ -706,20 +708,21 @@
get_up_speed = GET_UP_SLOW
if(!instant)
if(get_up_speed == GET_UP_SLOW) //Slow getups are easily noticable
- visible_message(span_notice("[src] weakily attempts to stand up."), span_notice("You weakily attempt to stand up."))
- if(!do_after(src, get_up_speed SECONDS, src, timed_action_flags = (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM), extra_checks = CALLBACK(src, /mob/living/proc/rest_checks_callback), interaction_key = DOAFTER_SOURCE_GETTING_UP))
+ visible_message(span_notice("[src] weakly attempts to stand up."), span_notice("You weakly attempt to stand up."))
+ if(!do_after(src, 1 SECONDS, src, timed_action_flags = (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM), extra_checks = CALLBACK(src, TYPE_PROC_REF(/mob/living, rest_checks_callback)), interaction_key = DOAFTER_SOURCE_GETTING_UP, hidden = TRUE))
if(!body_position == STANDING_UP)
visible_message(span_warning("[src] fails to stand up."), span_warning("You fail to stand up."))
return
else
- if(!do_after(src, get_up_speed SECONDS, src, timed_action_flags = (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM), extra_checks = CALLBACK(src, /mob/living/proc/rest_checks_callback), interaction_key = DOAFTER_SOURCE_GETTING_UP))
+ if(!do_after(src, 1 SECONDS, src, timed_action_flags = (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM), extra_checks = CALLBACK(src, TYPE_PROC_REF(/mob/living, rest_checks_callback)), interaction_key = DOAFTER_SOURCE_GETTING_UP, hidden = TRUE))
return
if(pulledby && pulledby.grab_state)
- to_chat(src, span_warning("You fail to stand up, you're restrained!")) //SKYRAT EDIT ADDITION END
+ to_chat(src, span_warning("You fail to stand up, you're restrained!"))
+ // NOVA EDIT ADDITION END
return
if(resting || body_position == STANDING_UP || HAS_TRAIT(src, TRAIT_FLOORED))
return
- to_chat(src, span_notice("You stand up.")) //SKYRAT EDIT ADDITION
+ to_chat(src, span_notice("You stand up.")) // SKYRAT EDIT ADDITION
set_body_position(STANDING_UP)
set_lying_angle(0)
@@ -1398,7 +1401,8 @@
if(!Adjacent(target) && (target.loc != src) && !recursive_loc_check(src, target))
if(HAS_SILICON_ACCESS(src) && !ispAI(src))
if(!(action_bitflags & ALLOW_SILICON_REACH)) // silicons can ignore range checks (except pAIs)
- to_chat(src, span_warning("You are too far away!"))
+ if(!(action_bitflags & SILENT_ADJACENCY))
+ to_chat(src, span_warning("You are too far away!"))
return FALSE
else // just a normal carbon mob
if((action_bitflags & FORBID_TELEKINESIS_REACH))
@@ -1852,25 +1856,27 @@ GLOBAL_LIST_EMPTY(fire_appearances)
return
//Check the amount of clients exists on the Z level we're leaving from,
- //this excludes us as we haven't added ourselves to the new z level yet.
+ //this excludes us because at this point we are not registered to any z level.
var/old_level_new_clients = (registered_z ? SSmobs.clients_by_zlevel[registered_z].len : null)
//No one is left after we're gone, shut off inactive ones
if(registered_z && old_level_new_clients == 0)
for(var/datum/ai_controller/controller as anything in SSai_controllers.ai_controllers_by_zlevel[registered_z])
controller.set_ai_status(AI_STATUS_OFF)
- //Check the amount of clients exists on the Z level we're moving towards, excluding ourselves.
- var/new_level_old_clients = SSmobs.clients_by_zlevel[new_z].len
+ if(new_z)
+ //Check the amount of clients exists on the Z level we're moving towards, excluding ourselves.
+ var/new_level_old_clients = SSmobs.clients_by_zlevel[new_z].len
+
+ //We'll add ourselves to the list now so get_expected_ai_status() will know we're on the z level.
+ SSmobs.clients_by_zlevel[new_z] += src
+
+ if(new_level_old_clients == 0) //No one was here before, wake up all the AIs.
+ for (var/datum/ai_controller/controller as anything in SSai_controllers.ai_controllers_by_zlevel[new_z])
+ //We don't set them directly on, for instances like AIs acting while dead and other cases that may exist in the future.
+ //This isn't a problem for AIs with a client since the client will prevent this from being called anyway.
+ controller.set_ai_status(controller.get_expected_ai_status())
registered_z = new_z
- //We'll add ourselves to the list now so get_expected_ai_status() will know we're on the z level.
- SSmobs.clients_by_zlevel[registered_z] += src
-
- if(new_level_old_clients == 0) //No one was here before, wake up all the AIs.
- for (var/datum/ai_controller/controller as anything in SSai_controllers.ai_controllers_by_zlevel[new_z])
- //We don't set them directly on, for instances like AIs acting while dead and other cases that may exist in the future.
- //This isn't a problem for AIs with a client since the client will prevent this from being called anyway.
- controller.set_ai_status(controller.get_expected_ai_status())
/mob/living/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents)
..()
@@ -1890,7 +1896,7 @@ GLOBAL_LIST_EMPTY(fire_appearances)
user.put_in_hands(holder)
/mob/living/proc/set_name()
- if(!numba)
+ if(numba == 0)
numba = rand(1, 1000)
name = "[name] ([numba])"
real_name = name
diff --git a/code/modules/mob/living/living_say.dm b/code/modules/mob/living/living_say.dm
index 16705e90165..b903dedd2c1 100644
--- a/code/modules/mob/living/living_say.dm
+++ b/code/modules/mob/living/living_say.dm
@@ -422,7 +422,7 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list(
var/mob/living/carbon/human/human_speaker = src
if(istype(human_speaker.wear_mask, /obj/item/clothing/mask))
var/obj/item/clothing/mask/worn_mask = human_speaker.wear_mask
- if(!worn_mask.mask_adjusted)
+ if(!worn_mask.up)
if(worn_mask.voice_override)
voice_to_use = worn_mask.voice_override
if(worn_mask.voice_filter)
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 292b0f1d7c1..8e7ff5ff45d 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -41,12 +41,13 @@
var/shunted = FALSE //1 if the AI is currently shunted. Used to differentiate between shunted and ghosted/braindead
var/obj/machinery/ai_voicechanger/ai_voicechanger = null // reference to machine that holds the voicechanger
var/malfhacking = FALSE // More or less a copy of the above var, so that malf AIs can hack and still get new cyborgs -- NeoFite
+ /// List of hacked APCs
+ var/list/hacked_apcs = list()
var/malf_cooldown = 0 //Cooldown var for malf modules, stores a worldtime + cooldown
var/obj/machinery/power/apc/malfhack
var/explosive = FALSE //does the AI explode when it dies?
- var/mob/living/silicon/ai/parent
var/camera_light_on = FALSE
var/list/obj/machinery/camera/lit_cameras = list()
@@ -439,6 +440,10 @@
qdel(src)
return ai_core
+/mob/living/silicon/ai/proc/break_core_link()
+ to_chat(src, span_danger("Your core has been destroyed!"))
+ linked_core = null
+
/mob/living/silicon/ai/proc/make_mmi_drop_and_transfer(obj/item/mmi/the_mmi, the_core)
var/mmi_type
if(posibrain_inside)
@@ -947,6 +952,9 @@
module_picker.ui_interact(owner)
/mob/living/silicon/ai/proc/add_malf_picker()
+ if (malf_picker)
+ stack_trace("Attempted to give malf AI malf picker to \[[src]\], who already has a malf picker.")
+ return
to_chat(src, "In the top left corner of the screen you will find the Malfunction Modules button, where you can purchase various abilities, from upgraded surveillance to station ending doomsday devices.")
to_chat(src, "You are also capable of hacking APCs, which grants you more points to spend on your Malfunction powers. The drawback is that a hacked APC will give you away if spotted by the crew. Hacking an APC takes 60 seconds.")
view_core() //A BYOND bug requires you to be viewing your core before your verbs update
@@ -1024,13 +1032,16 @@
malf_ai_datum.update_static_data_for_all_viewers()
else //combat software AIs use a different UI
malf_picker.update_static_data_for_all_viewers()
-
- apc.malfai = parent || src
+ if(apc.malfai) // another malf hacked this one; counter-hack!
+ to_chat(apc.malfai, span_warning("An adversarial subroutine has counter-hacked [apc]!"))
+ apc.malfai.hacked_apcs -= apc
+ apc.malfai = src
apc.malfhack = TRUE
apc.locked = TRUE
apc.coverlocked = TRUE
apc.flicker_hacked_icon()
apc.set_hacked_hud()
+ hacked_apcs += apc
playsound(get_turf(src), 'sound/machines/ding.ogg', 50, TRUE, ignore_walls = FALSE)
to_chat(src, "Hack complete. [apc] is now under your exclusive control.")
diff --git a/code/modules/mob/living/silicon/ai/ai_defense.dm b/code/modules/mob/living/silicon/ai/ai_defense.dm
index 1148b639d01..a80b84b95aa 100644
--- a/code/modules/mob/living/silicon/ai/ai_defense.dm
+++ b/code/modules/mob/living/silicon/ai/ai_defense.dm
@@ -2,6 +2,7 @@
/mob/living/silicon/ai/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/ai_module))
var/obj/item/ai_module/MOD = W
+ disconnect_shell()
if(!mind) //A player mind is required for law procs to run antag checks.
to_chat(user, span_warning("[src] is entirely unresponsive!"))
return
@@ -137,7 +138,7 @@
return ITEM_INTERACT_SUCCESS
balloon_alert(src, "neural network being disconnected...")
balloon_alert(user, "disconnecting neural network...")
- if(!tool.use_tool(src, user, (stat == DEAD ? 40 SECONDS : 5 SECONDS)))
+ if(!tool.use_tool(src, user, (stat == DEAD ? 5 SECONDS : 40 SECONDS)))
return ITEM_INTERACT_SUCCESS
if(IS_MALF_AI(src))
to_chat(user, span_userdanger("The voltage inside the wires rises dramatically!"))
diff --git a/code/modules/mob/living/silicon/ai/ai_say.dm b/code/modules/mob/living/silicon/ai/ai_say.dm
index 2a8b8e6c4a0..4eb56b42384 100644
--- a/code/modules/mob/living/silicon/ai/ai_say.dm
+++ b/code/modules/mob/living/silicon/ai/ai_say.dm
@@ -1,20 +1,3 @@
-/mob/living/silicon/ai/say(
- message,
- bubble_type,
- list/spans = list(),
- sanitize = TRUE,
- datum/language/language,
- ignore_spam = FALSE,
- forced,
- filterproof = FALSE,
- message_range = 7,
- datum/saymode/saymode,
- list/message_mods = list(),
-)
- if(istype(parent) && parent.stat != DEAD) //If there is a defined "parent" AI, it is actually an AI, and it is alive, anything the AI tries to say is said by the parent instead.
- return parent.say(arglist(args))
- return ..()
-
/mob/living/silicon/ai/compose_track_href(atom/movable/speaker, namepart)
var/mob/M = speaker.GetSource()
if(M)
diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm
index 03824857c4e..79e14d649fc 100644
--- a/code/modules/mob/living/silicon/ai/death.dm
+++ b/code/modules/mob/living/silicon/ai/death.dm
@@ -1,4 +1,4 @@
-/mob/living/silicon/ai/death(gibbed)
+/mob/living/silicon/ai/death(gibbed, drop_mmi = TRUE)
if(stat == DEAD)
return
@@ -33,7 +33,7 @@
ShutOffDoomsdayDevice()
- if(gibbed)
+ if(gibbed && drop_mmi)
make_mmi_drop_and_transfer()
if(explosive)
diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm
index 2a9631339fc..0f1cbfa65a5 100644
--- a/code/modules/mob/living/silicon/robot/life.dm
+++ b/code/modules/mob/living/silicon/robot/life.dm
@@ -18,7 +18,7 @@
/mob/living/silicon/robot/proc/use_energy(seconds_per_tick, times_fired)
if(cell?.charge)
- if(cell.charge <= (10 KILO JOULES))
+ if(cell.charge <= 0.01 * STANDARD_CELL_CHARGE)
drop_all_held_items()
var/energy_consumption = max(lamp_power_consumption * lamp_enabled * lamp_intensity * seconds_per_tick, BORG_MINIMUM_POWER_CONSUMPTION * seconds_per_tick) //Lamp will use a max of 5 * [BORG_LAMP_POWER_CONSUMPTION], depending on brightness of lamp. If lamp is off, borg systems consume [BORG_MINIMUM_POWER_CONSUMPTION], or the rest of the cell if it's lower than that.
cell.use(energy_consumption, force = TRUE)
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 9272e63e7ff..799d603996d 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -234,7 +234,7 @@
if(!ionpulse_on)
return
- if(!cell.use(10 KILO JOULES))
+ if(!cell.use(0.01 * STANDARD_CELL_CHARGE))
toggle_ionpulse()
return
return TRUE
diff --git a/code/modules/mob/living/silicon/robot/robot_model.dm b/code/modules/mob/living/silicon/robot/robot_model.dm
index 44207ee8948..4cefbb87d9a 100644
--- a/code/modules/mob/living/silicon/robot/robot_model.dm
+++ b/code/modules/mob/living/silicon/robot/robot_model.dm
@@ -386,9 +386,11 @@
/obj/item/pipe_dispenser,
/obj/item/extinguisher,
/obj/item/weldingtool/largetank/cyborg,
- /obj/item/screwdriver/cyborg/power, // Skyrat Removal/Edit - Combines Screwdriver and Wrench into one
- /obj/item/crowbar/cyborg/power, // Skyrat Removal/Edit - Combines Crowbar and Wirecutters into one
- /obj/item/multitool/cyborg,
+ /obj/item/screwdriver/cyborg/power, // Skyrat ADDITION - Combines Screwdriver and Wrench into one
+ /obj/item/crowbar/cyborg/power, // Skyrat ADDITION - Combines Crowbar and Wirecutters into one
+ /obj/item/multitool/cyborg, //Skyrat ADDITION - Adds multitool for easier access
+ /obj/item/borg/cyborg_omnitool/engineering,
+ ///obj/item/borg/cyborg_omnitool/engineering, //Skyrat REMOVAL
/obj/item/t_scanner,
/obj/item/analyzer,
/obj/item/holosign_creator/atmos, // Skyrat Edit - Adds Holofans to engineering borgos
@@ -681,14 +683,8 @@
/obj/item/borg/apparatus/beaker,
/obj/item/reagent_containers/dropper,
/obj/item/reagent_containers/syringe,
- /obj/item/surgical_drapes,
- /obj/item/retractor,
- /obj/item/hemostat,
- /obj/item/cautery,
- /obj/item/surgicaldrill,
- /obj/item/scalpel,
- /obj/item/circular_saw,
- /obj/item/bonesetter,
+ /obj/item/borg/cyborg_omnitool/medical,
+ /obj/item/borg/cyborg_omnitool/medical,
/obj/item/blood_filter,
/obj/item/extinguisher/mini,
/obj/item/emergency_bed/silicon,
@@ -818,20 +814,29 @@
/obj/item/rsf,
/obj/item/storage/bag/tray,
/obj/item/storage/bag/tray, // SKYRAT EDIT: Moves the second tray up to be near the default one
- /obj/item/cooking/cyborg/power, // SKYRAT EDIT
+ // SKYRAT EDIT START - COMMENTS OUT STUFF, MOVING IT TO SPECIALIZED MODULES
+ /*
+ // Moved to artistic module
/obj/item/pen,
/obj/item/toy/crayon/spraycan/borg,
+ */
/obj/item/extinguisher/mini,
/obj/item/hand_labeler/borg,
/obj/item/razor,
- /obj/item/instrument/guitar,
- /obj/item/instrument/piano_synth,
+ /*
+ // Moved to artistic module
+ //obj/item/instrument/guitar,
+ //obj/item/instrument/piano_synth,
+ */
/obj/item/lighter,
- /obj/item/borg/lollipop,
- /obj/item/stack/pipe_cleaner_coil/cyborg,
- /obj/item/chisel,
+ //obj/item/borg/lollipop, // Moved to snack module
+ /* Moved to artistic module
+ //obj/item/stack/pipe_cleaner_coil/cyborg,
+ //obj/item/chisel,
+ */
/obj/item/reagent_containers/cup/rag,
- /obj/item/storage/bag/money,
+ //obj/item/storage/bag/money, //This is never used and there's already too much bloat
+ // SKYRAT EDIT END
)
radio_channels = list(RADIO_CHANNEL_SERVICE)
emag_modules = list(
@@ -889,15 +894,10 @@
/obj/item/reagent_containers/borghypo/syndicate,
/obj/item/shockpaddles/syndicate/cyborg,
/obj/item/healthanalyzer,
- /obj/item/surgical_drapes,
- /obj/item/retractor,
- /obj/item/hemostat,
- /obj/item/cautery,
- /obj/item/surgicaldrill,
- /obj/item/scalpel,
- /obj/item/melee/energy/sword/cyborg/saw,
- /obj/item/bonesetter,
+ /obj/item/borg/cyborg_omnitool/medical,
+ /obj/item/borg/cyborg_omnitool/medical,
/obj/item/blood_filter,
+ /obj/item/melee/energy/sword/cyborg/saw,
/obj/item/emergency_bed/silicon,
/obj/item/crowbar/cyborg,
/obj/item/extinguisher/mini,
@@ -922,12 +922,9 @@
/obj/item/restraints/handcuffs/cable/zipties,
/obj/item/extinguisher,
/obj/item/weldingtool/largetank/cyborg,
- /obj/item/screwdriver/nuke,
- /obj/item/wrench/cyborg,
- /obj/item/crowbar/cyborg,
- /obj/item/wirecutters/cyborg,
/obj/item/analyzer,
- /obj/item/multitool/cyborg,
+ /obj/item/borg/cyborg_omnitool/engineering,
+ /obj/item/borg/cyborg_omnitool/engineering,
/obj/item/stack/sheet/iron,
/obj/item/stack/sheet/glass,
/obj/item/borg/apparatus/sheet_manipulator,
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index fb201faeeee..4fbd1b55234 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -306,7 +306,7 @@
///Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew.
/mob/living/silicon/proc/checklaws()
laws_sanity_check()
- var/list = "Which laws do you want to include when stating them for the crew? "
+ var/list = "Which laws do you want to include when stating them for the crew? "
var/law_display = "Yes"
if (laws.zeroth)
diff --git a/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm b/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm
index a0c9a964fb3..6d85b9c1867 100644
--- a/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm
+++ b/code/modules/mob/living/simple_animal/bot/SuperBeepsky.dm
@@ -71,7 +71,7 @@
switch(mode)
if(BOT_IDLE) // idle
update_appearance()
- SSmove_manager.stop_looping(src)
+ DSmove_manager.stop_looping(src)
look_for_perp() // see if any criminals are in range
if(!mode && bot_mode_flags & BOT_MODE_AUTOPATROL) // still idle, and set to patrol
mode = BOT_START_PATROL // switch to patrol mode
@@ -80,7 +80,7 @@
playsound(src,'sound/effects/beepskyspinsabre.ogg',100,TRUE,-1)
// general beepsky doesn't give up so easily, jedi scum
if(frustration >= 20)
- SSmove_manager.stop_looping(src)
+ DSmove_manager.stop_looping(src)
back_to_idle()
return
if(target) // make sure target exists
@@ -91,7 +91,7 @@
return
else // not next to perp
var/turf/olddist = get_dist(src, target)
- SSmove_manager.move_to(src, target, 1, 4)
+ DSmove_manager.move_to(src, target, 1, 4)
if((get_dist(src, target)) >= (olddist))
frustration++
else
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index ec204dbc82b..944a00af9b6 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -204,6 +204,7 @@
pa_system = new(src, automated_announcements = automated_announcements)
pa_system.Grant(src)
+ RegisterSignal(src, COMSIG_MOB_TRIED_ACCESS, PROC_REF(attempt_access))
/mob/living/simple_animal/bot/Destroy()
GLOB.bots_list -= src
@@ -951,13 +952,13 @@ Pass a positive integer as an argument to override a bot's default speed.
calc_summon_path()
tries = 0
-/mob/living/simple_animal/bot/Bump(atom/A) //Leave no door unopened!
- . = ..()
- if((istype(A, /obj/machinery/door/airlock) || istype(A, /obj/machinery/door/window)) && (!isnull(access_card)))
- var/obj/machinery/door/D = A
- if(D.check_access(access_card))
- D.open()
- frustration = 0
+/mob/living/simple_animal/bot/proc/attempt_access(mob/bot, obj/door_attempt)
+ SIGNAL_HANDLER
+
+ if(door_attempt.check_access(access_card))
+ frustration = 0
+ return ACCESS_ALLOWED
+ return ACCESS_DISALLOWED
/mob/living/simple_animal/bot/ui_data(mob/user)
var/list/data = list()
diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm
index 45c9802a8f3..8c933e8f83a 100644
--- a/code/modules/mob/living/simple_animal/bot/secbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/secbot.dm
@@ -164,7 +164,7 @@
target = null
oldtarget_name = null
set_anchored(FALSE)
- SSmove_manager.stop_looping(src)
+ DSmove_manager.stop_looping(src)
last_found = world.time
/mob/living/simple_animal/bot/secbot/proc/on_saboteur(datum/source, disrupt_duration)
@@ -389,7 +389,7 @@
switch(mode)
if(BOT_IDLE) // idle
- SSmove_manager.stop_looping(src)
+ DSmove_manager.stop_looping(src)
look_for_perp() // see if any criminals are in range
if((mode == BOT_IDLE) && bot_mode_flags & BOT_MODE_AUTOPATROL) // didn't start hunting during look_for_perp, and set to patrol
mode = BOT_START_PATROL // switch to patrol mode
@@ -397,7 +397,7 @@
if(BOT_HUNT) // hunting for perp
// if can't reach perp for long enough, go idle
if(frustration >= 8)
- SSmove_manager.stop_looping(src)
+ DSmove_manager.stop_looping(src)
back_to_idle()
return
@@ -415,7 +415,7 @@
// not next to perp
var/turf/olddist = get_dist(src, target)
- SSmove_manager.move_to(src, target, 1, 4)
+ DSmove_manager.move_to(src, target, 1, 4)
if((get_dist(src, target)) >= (olddist))
frustration++
else
diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm
index 3ff8f04fb92..86fc82d77e0 100644
--- a/code/modules/mob/living/simple_animal/hostile/hostile.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm
@@ -104,7 +104,7 @@
/mob/living/simple_animal/hostile/Life(seconds_per_tick = SSMOBS_DT, times_fired)
. = ..()
if(!.) //dead
- SSmove_manager.stop_looping(src)
+ DSmove_manager.stop_looping(src)
/mob/living/simple_animal/hostile/handle_automated_action()
if(AIStatus == AI_OFF || QDELETED(src))
@@ -339,11 +339,11 @@
if(!target.Adjacent(target_from) && ranged_cooldown <= world.time) //But make sure they're not in range for a melee attack and our range attack is off cooldown
OpenFire(target)
if(!Process_Spacemove(0)) //Drifting
- SSmove_manager.stop_looping(src)
+ DSmove_manager.stop_looping(src)
return 1
if(retreat_distance != null) //If we have a retreat distance, check if we need to run from our target
if(target_distance <= retreat_distance) //If target's closer than our retreat distance, run
- SSmove_manager.move_away(src, target, retreat_distance, move_to_delay, flags = MOVEMENT_LOOP_IGNORE_GLIDE)
+ DSmove_manager.move_away(src, target, retreat_distance, move_to_delay, flags = MOVEMENT_LOOP_IGNORE_GLIDE)
else
Goto(target,move_to_delay,minimum_distance) //Otherwise, get to our minimum distance so we chase them
else
@@ -378,7 +378,7 @@
approaching_target = TRUE
else
approaching_target = FALSE
- SSmove_manager.move_to(src, target, minimum_distance, delay, flags = MOVEMENT_LOOP_IGNORE_GLIDE)
+ DSmove_manager.move_to(src, target, minimum_distance, delay, flags = MOVEMENT_LOOP_IGNORE_GLIDE)
return TRUE
/mob/living/simple_animal/hostile/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
@@ -418,7 +418,7 @@
GiveTarget(null)
approaching_target = FALSE
in_melee = FALSE
- SSmove_manager.stop_looping(src)
+ DSmove_manager.stop_looping(src)
LoseAggro()
SEND_SIGNAL(src, COMSIG_HOSTILE_MOB_LOST_TARGET) // SKYRAT EDIT ADDITION
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
index d0a5a4df954..81bc6c166d2 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
@@ -341,7 +341,7 @@
. = ..()
if(!.)
return FALSE
-
+
for(var/atom/thing as anything in range(1, src))
if(isturf(thing))
new /obj/effect/decal/cleanable/confetti(thing)
@@ -351,7 +351,7 @@
continue
var/mob/living/carbon/human/new_clown = thing
-
+
if(new_clown.stat != DEAD)
continue
@@ -360,12 +360,12 @@
var/clown_ref = REF(new_clown)
if(clown_ref in clowned_mob_refs) //one clowning per person
continue
-
+
for(var/obj/item/to_strip in new_clown.get_equipped_items())
new_clown.dropItemToGround(to_strip)
new_clown.dress_up_as_job(SSjob.GetJobType(/datum/job/clown))
clowned_mob_refs += clown_ref
-
+
return TRUE
/// Transforms the area to look like a new one
@@ -381,7 +381,7 @@
/obj/machinery/anomalous_crystal/theme_warp/Initialize(mapload)
. = ..()
- terrain_theme = SSmaterials.dimensional_themes[pick(subtypesof(/datum/dimension_theme))]
+ terrain_theme = DSmaterials.dimensional_themes[pick(subtypesof(/datum/dimension_theme))]
observer_desc = "This crystal changes the area around it to match the theme of \"[terrain_theme.name]\"."
/obj/machinery/anomalous_crystal/theme_warp/ActivationReaction(mob/user, method)
@@ -434,18 +434,18 @@
if(!ishuman(thing))
continue
-
+
var/mob/living/carbon/human/to_revive = thing
-
+
if(to_revive.stat != DEAD)
continue
-
+
to_revive.set_species(/datum/species/shadow, TRUE)
to_revive.revive(ADMIN_HEAL_ALL, force_grab_ghost = TRUE)
//Free revives, but significantly limits your options for reviving except via the crystal
//except JK who cares about BADDNA anymore. this even heals suicides.
ADD_TRAIT(to_revive, TRAIT_BADDNA, MAGIC_TRAIT)
-
+
return TRUE
/obj/machinery/anomalous_crystal/helpers //Lets ghost spawn as helpful creatures that can only heal people slightly. Incredibly fragile and they can't converse with humans
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm
index 3a838ac58cd..b2555309f8a 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/curse_blob.dm
@@ -45,7 +45,7 @@
/mob/living/simple_animal/hostile/asteroid/curseblob/proc/move_loop(move_target, delay)
if(our_loop)
return
- our_loop = SSmove_manager.force_move(src, move_target, delay, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
+ our_loop = DSmove_manager.force_move(src, move_target, delay, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
if(!our_loop)
return
RegisterSignal(move_target, COMSIG_MOB_STATCHANGE, PROC_REF(stat_change))
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 23e27ca7707..cda62ce836f 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -539,7 +539,7 @@
/mob/living/simple_animal/proc/Goto(target, delay, minimum_distance)
if(prevent_goto_movement)
return FALSE
- SSmove_manager.move_to(src, target, minimum_distance, delay)
+ DSmove_manager.move_to(src, target, minimum_distance, delay)
return TRUE
//Makes this mob hunt the prey, be it living or an object. Will kill living creatures, and delete objects.
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 1142fff130b..d71db303fb7 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -261,10 +261,12 @@
* message is output to anyone who can see, e.g. `"The [src] does something!"`
*
* Vars:
+ * * message is the message output to anyone who can see.
* * self_message (optional) is what the src mob sees e.g. "You do something!"
* * blind_message (optional) is what blind people will hear e.g. "You hear something!"
* * vision_distance (optional) define how many tiles away the message can be seen.
- * * ignored_mob (optional) doesn't show any message to a given mob if TRUE.
+ * * ignored_mobs (optional) doesn't show any message to any mob in this list.
+ * * visible_message_flags (optional) is the type of message being sent.
*/
/atom/proc/visible_message(message, self_message, blind_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs, visible_message_flags = NONE, separation = " ", pref_to_check) // SKYRAT EDIT ADDITION - separation, pref checks
var/turf/T = get_turf(src)
@@ -328,8 +330,22 @@
///Adds the functionality to self_message.
/mob/visible_message(message, self_message, blind_message, vision_distance = DEFAULT_MESSAGE_RANGE, list/ignored_mobs, visible_message_flags = NONE, separation = " ", pref_to_check) // SKYRAT EDIT ADDITION - Better emotes, pref checks
. = ..()
- if(self_message)
- show_message(self_message, MSG_VISUAL, blind_message, MSG_AUDIBLE)
+ if(!self_message)
+ return
+ var/raw_self_message = self_message
+ var/self_runechat = FALSE
+ if(visible_message_flags & EMOTE_MESSAGE)
+ self_message = "[src] [self_message] " // May make more sense as "You do x"
+
+ if(visible_message_flags & ALWAYS_SHOW_SELF_MESSAGE)
+ to_chat(src, self_message)
+ self_runechat = TRUE
+
+ else
+ self_runechat = show_message(self_message, MSG_VISUAL, blind_message, MSG_AUDIBLE)
+
+ if(self_runechat && (visible_message_flags & EMOTE_MESSAGE) && runechat_prefs_check(src, visible_message_flags))
+ create_chat_message(src, raw_message = raw_self_message, runechat_flags = visible_message_flags)
/**
* Show a message to all mobs in earshot of this atom
@@ -340,6 +356,8 @@
* * message is the message output to anyone who can hear.
* * deaf_message (optional) is what deaf people will see.
* * hearing_distance (optional) is the range, how many tiles away the message can be heard.
+ * * self_message (optional) is what the src mob hears.
+ * * audible_message_flags (optional) is the type of message being sent.
*/
/atom/proc/audible_message(message, deaf_message, hearing_distance = DEFAULT_MESSAGE_RANGE, self_message, audible_message_flags = NONE, separation = " ", pref_to_check) // SKYRAT EDIT ADDITION - Better emotes, pref checks
var/list/hearers = get_hearers_in_view(hearing_distance, src)
@@ -382,9 +400,20 @@
*/
/mob/audible_message(message, deaf_message, hearing_distance = DEFAULT_MESSAGE_RANGE, self_message, audible_message_flags = NONE, separation = " ", pref_to_check) // SKYRAT EDIT ADDITION - Better emotes, pref checks
. = ..()
- if(self_message)
- show_message(self_message, MSG_AUDIBLE, deaf_message, MSG_VISUAL)
+ if(!self_message)
+ return
+ var/raw_self_message = self_message
+ var/self_runechat = FALSE
+ if(audible_message_flags & EMOTE_MESSAGE)
+ self_message = "[src] [self_message] "
+ if(audible_message_flags & ALWAYS_SHOW_SELF_MESSAGE)
+ to_chat(src, self_message)
+ self_runechat = TRUE
+ else
+ self_runechat = show_message(self_message, MSG_AUDIBLE, deaf_message, MSG_VISUAL)
+ if(self_runechat && (audible_message_flags & EMOTE_MESSAGE) && runechat_prefs_check(src, audible_message_flags))
+ create_chat_message(src, raw_message = raw_self_message, runechat_flags = audible_message_flags)
///Returns the client runechat visible messages preference according to the message type.
/atom/proc/runechat_prefs_check(mob/target, visible_message_flags = NONE)
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index ceff6e95658..35ef05ec40f 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -315,7 +315,7 @@
if(rebound.last_pushoff == world.time)
continue
if(continuous_move && !pass_allowed)
- var/datum/move_loop/move/rebound_engine = SSmove_manager.processing_on(rebound, SSspacedrift)
+ var/datum/move_loop/move/rebound_engine = DSmove_manager.processing_on(rebound, SSspacedrift)
// If you're moving toward it and you're both going the same direction, stop
if(moving_direction == get_dir(src, pushover) && rebound_engine && moving_direction == rebound_engine.direction)
continue
@@ -545,7 +545,7 @@
to_chat(src, span_warning("You are not Superman."))
return
balloon_alert(src, "moving up...")
- if(!do_after(src, 1 SECONDS))
+ if(!do_after(src, 1 SECONDS, hidden = TRUE))
return
if(zMove(UP, z_move_flags = ZMOVE_FLIGHT_FLAGS|ZMOVE_FEEDBACK|ventcrawling_flag))
to_chat(src, span_notice("You move upwards."))
@@ -571,7 +571,7 @@
var/ventcrawling_flag = HAS_TRAIT(src, TRAIT_MOVE_VENTCRAWLING) ? ZMOVE_VENTCRAWLING : 0
balloon_alert(src, "moving down...")
- if(!do_after(src, 1 SECONDS))
+ if(!do_after(src, 1 SECONDS, hidden = TRUE))
return
if(zMove(DOWN, z_move_flags = ZMOVE_FLIGHT_FLAGS|ZMOVE_FEEDBACK|ventcrawling_flag))
to_chat(src, span_notice("You move down."))
diff --git a/code/modules/mob/mob_update_icons.dm b/code/modules/mob/mob_update_icons.dm
index b8b84f8782a..a355a385d9f 100644
--- a/code/modules/mob/mob_update_icons.dm
+++ b/code/modules/mob/mob_update_icons.dm
@@ -7,21 +7,75 @@
///Updates every item slot passed into it.
/mob/proc/update_clothing(slot_flags)
- return
+ if(slot_flags & ITEM_SLOT_BACK)
+ update_worn_back()
+ if(slot_flags & ITEM_SLOT_MASK)
+ update_worn_mask()
+ if(slot_flags & ITEM_SLOT_NECK)
+ update_worn_neck()
+ if(slot_flags & ITEM_SLOT_HANDCUFFED)
+ update_worn_handcuffs()
+ if(slot_flags & ITEM_SLOT_LEGCUFFED)
+ update_worn_legcuffs()
+ if(slot_flags & ITEM_SLOT_BELT)
+ update_worn_belt()
+ if(slot_flags & ITEM_SLOT_ID)
+ update_worn_id()
+ if(slot_flags & ITEM_SLOT_EARS)
+ update_worn_ears()
+ if(slot_flags & ITEM_SLOT_EYES)
+ update_worn_glasses()
+ if(slot_flags & ITEM_SLOT_GLOVES)
+ update_worn_gloves()
+ if(slot_flags & ITEM_SLOT_HEAD)
+ update_worn_head()
+ if(slot_flags & ITEM_SLOT_FEET)
+ update_worn_shoes()
+ if(slot_flags & ITEM_SLOT_OCLOTHING)
+ update_worn_oversuit()
+ if(slot_flags & ITEM_SLOT_ICLOTHING)
+ update_worn_undersuit()
+ if(slot_flags & ITEM_SLOT_SUITSTORE)
+ update_suit_storage()
+ if(slot_flags & (ITEM_SLOT_LPOCKET|ITEM_SLOT_RPOCKET))
+ update_pockets()
+ if(slot_flags & ITEM_SLOT_HANDS)
+ update_held_items()
+
+///Updates item slots obscured by this item (or using an override of flags to check)
+/mob/proc/update_obscured_slots(obscured_flags)
+ if(obscured_flags & HIDEGLOVES)
+ update_worn_gloves(update_obscured = FALSE)
+ if(obscured_flags & HIDESUITSTORAGE)
+ update_suit_storage(update_obscured = FALSE)
+ if(obscured_flags & HIDEJUMPSUIT)
+ update_worn_undersuit(update_obscured = FALSE)
+ if(obscured_flags & HIDESHOES)
+ update_worn_shoes(update_obscured = FALSE)
+ if(obscured_flags & HIDEMASK)
+ update_worn_mask(update_obscured = FALSE)
+ if(obscured_flags & HIDEEARS)
+ update_worn_ears(update_obscured = FALSE)
+ if(obscured_flags & HIDEEYES)
+ update_worn_glasses(update_obscured = FALSE)
+ if(obscured_flags & HIDENECK)
+ update_worn_neck(update_obscured = FALSE)
+ if(obscured_flags & HIDEHEADGEAR)
+ update_worn_head(update_obscured = FALSE)
/mob/proc/update_icons()
return
///Updates the handcuff overlay & HUD element.
-/mob/proc/update_worn_handcuffs()
+/mob/proc/update_worn_handcuffs(update_obscured = FALSE)
return
///Updates the legcuff overlay & HUD element.
-/mob/proc/update_worn_legcuffs()
+/mob/proc/update_worn_legcuffs(update_obscured = FALSE)
return
///Updates the back overlay & HUD element.
-/mob/proc/update_worn_back()
+/mob/proc/update_worn_back(update_obscured = FALSE)
return
///Updates the held items overlay(s) & HUD element.
@@ -30,27 +84,27 @@
SEND_SIGNAL(src, COMSIG_MOB_UPDATE_HELD_ITEMS)
///Updates the mask overlay & HUD element.
-/mob/proc/update_worn_mask()
+/mob/proc/update_worn_mask(update_obscured = FALSE)
return
///Updates the neck overlay & HUD element.
-/mob/proc/update_worn_neck()
+/mob/proc/update_worn_neck(update_obscured = FALSE)
return
///Updates the oversuit overlay & HUD element.
-/mob/proc/update_worn_oversuit()
+/mob/proc/update_worn_oversuit(update_obscured = FALSE)
return
///Updates the undersuit/uniform overlay & HUD element.
-/mob/proc/update_worn_undersuit()
+/mob/proc/update_worn_undersuit(update_obscured = FALSE)
return
///Updates the belt overlay & HUD element.
-/mob/proc/update_worn_belt()
+/mob/proc/update_worn_belt(update_obscured = FALSE)
return
///Updates the on-head overlay & HUD element.
-/mob/proc/update_worn_head()
+/mob/proc/update_worn_head(update_obscured = FALSE)
return
///Updates every part of a carbon's body. Including parts, mutant parts, lips, underwear, and socks.
@@ -61,29 +115,29 @@
return
///Updates the glasses overlay & HUD element.
-/mob/proc/update_worn_glasses()
+/mob/proc/update_worn_glasses(update_obscured = FALSE)
return
///Updates the id overlay & HUD element.
-/mob/proc/update_worn_id()
+/mob/proc/update_worn_id(update_obscured = FALSE)
return
///Updates the shoes overlay & HUD element.
-/mob/proc/update_worn_shoes()
+/mob/proc/update_worn_shoes(update_obscured = FALSE)
return
///Updates the glasses overlay & HUD element.
-/mob/proc/update_worn_gloves()
+/mob/proc/update_worn_gloves(update_obscured = FALSE)
return
-///Updates the handcuff overlay & HUD element.
-/mob/proc/update_suit_storage()
+///Updates the suit storage overlay & HUD element.
+/mob/proc/update_suit_storage(update_obscured = FALSE)
return
-///Updates the handcuff overlay & HUD element.
+///Updates the pocket overlay & HUD element.
/mob/proc/update_pockets()
return
-///Updates the handcuff overlay & HUD element.
-/mob/proc/update_inv_ears()
+///Updates the headset overlay & HUD element.
+/mob/proc/update_worn_ears(update_obscured = FALSE)
return
diff --git a/code/modules/mod/mod_activation.dm b/code/modules/mod/mod_activation.dm
index 7d698aa5a75..303d556843e 100644
--- a/code/modules/mod/mod_activation.dm
+++ b/code/modules/mod/mod_activation.dm
@@ -169,23 +169,23 @@
if (ai_assistant)
to_chat(ai_assistant, span_notice("MODsuit [active ? "shutting down" : "starting up"]."))
- if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer))))
+ if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer)), hidden = TRUE))
to_chat(wearer, span_notice("[boots] [active ? "relax their grip on your legs" : "seal around your feet"]."))
playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
seal_part(boots, seal = !active)
- if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer))))
+ if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer)), hidden = TRUE))
to_chat(wearer, span_notice("[gauntlets] [active ? "become loose around your fingers" : "tighten around your fingers and wrists"]."))
playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
seal_part(gauntlets, seal = !active)
- if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer))))
+ if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer)), hidden = TRUE))
to_chat(wearer, span_notice("[chestplate] [active ? "releases your chest" : "cinches tightly against your chest"]."))
playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
seal_part(chestplate, seal = !active)
- if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer))))
+ if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer)), hidden = TRUE))
to_chat(wearer, span_notice("[helmet] hisses [active ? "open" : "closed"]."))
playsound(src, 'sound/mecha/mechmove03.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
seal_part(helmet, seal = !active)
- if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer))))
+ if(do_after(wearer, activation_step_time, wearer, MOD_ACTIVATION_STEP_FLAGS, extra_checks = CALLBACK(src, PROC_REF(has_wearer)), hidden = TRUE))
to_chat(wearer, span_notice("Systems [active ? "shut down. Parts unsealed. Goodbye" : "started up. Parts sealed. Welcome"], [wearer]."))
if(ai_assistant)
to_chat(ai_assistant, span_notice("SYSTEMS [active ? "DEACTIVATED. GOODBYE" : "ACTIVATED. WELCOME"]: \"[ai_assistant]\" "))
@@ -218,21 +218,10 @@
part.heat_protection = NONE
part.cold_protection = NONE
part.alternate_worn_layer = mod_parts[part]
- if(part == boots)
- wearer.update_worn_shoes()
- if(part == gauntlets)
- wearer.update_worn_gloves()
- if(part == chestplate)
- wearer.update_worn_oversuit()
- wearer.update_worn_undersuit()
- if(part == helmet)
- wearer.update_worn_head()
- wearer.update_worn_mask()
- wearer.update_worn_glasses()
- wearer.update_body_parts()
- // Close internal air tank if MOD helmet is unsealed and was the only breathing apparatus.
- if (!seal && wearer?.invalid_internals())
- wearer.cutoff_internals()
+ wearer.update_clothing(part.slot_flags)
+ wearer.update_obscured_slots(part.visor_flags_inv)
+ if((part.clothing_flags & (MASKINTERNALS|HEADINTERNALS)) && wearer.invalid_internals())
+ wearer.cutoff_internals()
/// Finishes the suit's activation
/obj/item/mod/control/proc/finish_activation(on)
diff --git a/code/modules/mod/mod_link.dm b/code/modules/mod/mod_link.dm
index c3d5040c815..eab60af15df 100644
--- a/code/modules/mod/mod_link.dm
+++ b/code/modules/mod/mod_link.dm
@@ -203,7 +203,7 @@
/obj/item/clothing/neck/link_scryer/process(seconds_per_tick)
if(!mod_link.link_call)
return
- cell.use(20 KILO WATTS * seconds_per_tick, force = TRUE)
+ cell.use(0.02 * STANDARD_CELL_RATE * seconds_per_tick, force = TRUE)
/obj/item/clothing/neck/link_scryer/attackby(obj/item/attacked_by, mob/user, params)
. = ..()
diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm
index 2aec3e361c4..adbcc2064f8 100644
--- a/code/modules/mod/modules/modules_general.dm
+++ b/code/modules/mod/modules/modules_general.dm
@@ -834,7 +834,7 @@
. = ..()
if(!length(accepted_mats))
- accepted_mats = SSmaterials.materials_by_category[MAT_CATEGORY_SILO]
+ accepted_mats = DSmaterials.materials_by_category[MAT_CATEGORY_SILO]
container = AddComponent( \
/datum/component/material_container, \
diff --git a/code/modules/mod/modules/modules_medical.dm b/code/modules/mod/modules/modules_medical.dm
index 6068b18fe10..0e04de51c86 100644
--- a/code/modules/mod/modules/modules_medical.dm
+++ b/code/modules/mod/modules/modules_medical.dm
@@ -328,7 +328,7 @@
balloon_alert(mod.wearer, "interrupted!")
return
var/target_zones = body_zone2cover_flags(mod.wearer.zone_selected)
- for(var/obj/item/clothing as anything in carbon_target.get_all_worn_items())
+ for(var/obj/item/clothing as anything in carbon_target.get_equipped_items())
if(!clothing)
continue
var/shared_flags = target_zones & clothing.body_parts_covered
diff --git a/code/modules/mod/modules/modules_ninja.dm b/code/modules/mod/modules/modules_ninja.dm
index 868b4a79500..d52a5e1fb4c 100644
--- a/code/modules/mod/modules/modules_ninja.dm
+++ b/code/modules/mod/modules/modules_ninja.dm
@@ -133,10 +133,6 @@
icon_state = "hacker"
removable = FALSE
incompatible_modules = list(/obj/item/mod/module/hacker)
- /// Minimum amount of energy we can drain in a single drain action
- var/mindrain = 200 KILO JOULES
- /// Maximum amount of energy we can drain in a single drain action
- var/maxdrain = 400 KILO JOULES
/// Whether or not the communication console hack was used to summon another antagonist.
var/communication_console_hack_success = FALSE
/// How many times the module has been used to force open doors.
diff --git a/code/modules/modular_computers/file_system/programs/techweb.dm b/code/modules/modular_computers/file_system/programs/techweb.dm
index a72eef1bc9a..2103e0d4a22 100644
--- a/code/modules/modular_computers/file_system/programs/techweb.dm
+++ b/code/modules/modular_computers/file_system/programs/techweb.dm
@@ -218,7 +218,7 @@
logname = "[id_card_of_human_user.registered_name]"
stored_research.research_logs += list(list(
"node_name" = tech_node.display_name,
- "node_cost" = price["General Research"],
+ "node_cost" = price[TECHWEB_POINT_TYPE_GENERIC],
"node_researcher" = logname,
"node_research_location" = "[get_area(computer)] ([user.x],[user.y],[user.z])",
))
diff --git a/code/modules/pai/card.dm b/code/modules/pai/card.dm
index 77ca42aeebc..ccf0bae5f04 100644
--- a/code/modules/pai/card.dm
+++ b/code/modules/pai/card.dm
@@ -248,7 +248,7 @@
ignore_key = POLL_IGNORE_PAI,
)
- addtimer(VARSET_CALLBACK(src, request_spam, FALSE), PAI_SPAM_TIME, TIMER_UNIQUE | TIMER_STOPPABLE | TIMER_CLIENT_TIME | TIMER_DELETE_ME)
+ addtimer(VARSET_CALLBACK(src, request_spam, FALSE), PAI_SPAM_TIME, TIMER_UNIQUE|TIMER_DELETE_ME)
return TRUE
/**
diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm
index e1bddd6feff..605e88f1e48 100644
--- a/code/modules/paperwork/paper.dm
+++ b/code/modules/paperwork/paper.dm
@@ -30,7 +30,7 @@
grind_results = list(/datum/reagent/cellulose = 3)
color = COLOR_WHITE
item_flags = SKIP_FANTASY_ON_SPAWN
- interaction_flags_click = NEED_DEXTERITY|NEED_HANDS
+ interaction_flags_click = NEED_DEXTERITY|NEED_HANDS|ALLOW_RESTING
/// Lazylist of raw, unsanitised, unparsed text inputs that have been made to the paper.
var/list/datum/paper_input/raw_text_inputs
diff --git a/code/modules/plumbing/plumbers/_plumb_machinery.dm b/code/modules/plumbing/plumbers/_plumb_machinery.dm
index 8baf59508b8..e3f9486bee9 100644
--- a/code/modules/plumbing/plumbers/_plumb_machinery.dm
+++ b/code/modules/plumbing/plumbers/_plumb_machinery.dm
@@ -8,7 +8,8 @@
icon = 'icons/obj/pipes_n_cables/hydrochem/plumbers.dmi'
icon_state = "pump"
density = TRUE
- idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 7.5
+ processing_flags = START_PROCESSING_MANUALLY
+ active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2.75
resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF
///Plumbing machinery is always gonna need reagents, so we might aswell put it here
var/buffer = 50
@@ -26,11 +27,17 @@
. = ..()
. += span_notice("The maximum volume display reads: [reagents.maximum_volume] units .")
-
/obj/machinery/plumbing/wrench_act(mob/living/user, obj/item/tool)
- . = ..()
- default_unfasten_wrench(user, tool)
- return ITEM_INTERACT_SUCCESS
+ if(user.combat_mode)
+ return NONE
+
+ . = ITEM_INTERACT_BLOCKING
+ if(default_unfasten_wrench(user, tool) == SUCCESSFUL_UNFASTEN)
+ if(anchored)
+ begin_processing()
+ else
+ end_processing()
+ return ITEM_INTERACT_SUCCESS
/obj/machinery/plumbing/plunger_act(obj/item/plunger/P, mob/living/user, reinforced)
user.balloon_alert_to_viewers("furiously plunging...")
diff --git a/code/modules/plumbing/plumbers/acclimator.dm b/code/modules/plumbing/plumbers/acclimator.dm
index 79b525d3504..014ff849901 100644
--- a/code/modules/plumbing/plumbers/acclimator.dm
+++ b/code/modules/plumbing/plumbers/acclimator.dm
@@ -14,7 +14,6 @@
icon_state = "acclimator"
base_icon_state = "acclimator"
buffer = 200
- active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2
///towards wich temperature do we build?
var/target_temperature = 300
@@ -32,7 +31,7 @@
AddComponent(/datum/component/plumbing/acclimator, bolt, layer)
/obj/machinery/plumbing/acclimator/process(seconds_per_tick)
- if(machine_stat & NOPOWER || !enabled || !reagents.total_volume || reagents.chem_temp == target_temperature)
+ if(!is_operational || !enabled || !reagents.total_volume || reagents.chem_temp == target_temperature)
if(acclimate_state != NEUTRAL)
acclimate_state = NEUTRAL
update_appearance()
diff --git a/code/modules/plumbing/plumbers/bottler.dm b/code/modules/plumbing/plumbers/bottler.dm
index 1acbed37a74..5f63a3070bd 100644
--- a/code/modules/plumbing/plumbers/bottler.dm
+++ b/code/modules/plumbing/plumbers/bottler.dm
@@ -4,10 +4,8 @@
icon_state = "bottler"
layer = ABOVE_ALL_MOB_LAYER
plane = ABOVE_GAME_PLANE
-
reagent_flags = TRANSPARENT | DRAINABLE
buffer = 100
- active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2
///how much do we fill
var/wanted_amount = 10
@@ -71,7 +69,7 @@
to_chat(user, span_notice(" The [src] will now fill for [wanted_amount]u."))
/obj/machinery/plumbing/bottler/process(seconds_per_tick)
- if(machine_stat & NOPOWER)
+ if(!is_operational)
return
// Sanity check the result locations and stop processing if they don't exist
if(goodspot == null || badspot == null || inputspot == null)
diff --git a/code/modules/plumbing/plumbers/destroyer.dm b/code/modules/plumbing/plumbers/destroyer.dm
index 5f81e24eaf2..503b3e76223 100644
--- a/code/modules/plumbing/plumbers/destroyer.dm
+++ b/code/modules/plumbing/plumbers/destroyer.dm
@@ -3,7 +3,6 @@
desc = "Breaks down chemicals and annihilates them."
icon_state = "disposal"
pass_flags_self = PASSMACHINE | LETPASSTHROW // Small
- active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2
///we remove 5 reagents per second
var/disposal_rate = 5
@@ -13,7 +12,7 @@
AddComponent(/datum/component/plumbing/simple_demand, bolt, layer)
/obj/machinery/plumbing/disposer/process(seconds_per_tick)
- if(machine_stat & NOPOWER)
+ if(!is_operational)
return
if(reagents.total_volume)
if(icon_state != initial(icon_state) + "_working") //threw it here instead of update icon since it only has two states
diff --git a/code/modules/plumbing/plumbers/fermenter.dm b/code/modules/plumbing/plumbers/fermenter.dm
index 8800029779d..ac421bce740 100644
--- a/code/modules/plumbing/plumbers/fermenter.dm
+++ b/code/modules/plumbing/plumbers/fermenter.dm
@@ -6,7 +6,6 @@
plane = ABOVE_GAME_PLANE
reagent_flags = TRANSPARENT | DRAINABLE
buffer = 400
- active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2
///input dir
var/eat_dir = SOUTH
@@ -36,7 +35,7 @@
/// uses fermentation proc similar to fermentation barrels
/obj/machinery/plumbing/fermenter/proc/ferment(atom/AM)
- if(machine_stat & NOPOWER)
+ if(!is_operational)
return
if(reagents.holder_full())
return
diff --git a/code/modules/plumbing/plumbers/grinder_chemical.dm b/code/modules/plumbing/plumbers/grinder_chemical.dm
index ae356fef089..f75ec94f21c 100644
--- a/code/modules/plumbing/plumbers/grinder_chemical.dm
+++ b/code/modules/plumbing/plumbers/grinder_chemical.dm
@@ -4,10 +4,8 @@
icon_state = "grinder_chemical"
layer = ABOVE_ALL_MOB_LAYER
plane = ABOVE_GAME_PLANE
-
reagent_flags = TRANSPARENT | DRAINABLE
buffer = 400
- active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2
/obj/machinery/plumbing/grinder_chemical/Initialize(mapload, bolt, layer)
. = ..()
@@ -47,7 +45,7 @@
* * [AM][atom] - the atom to grind or juice
*/
/obj/machinery/plumbing/grinder_chemical/proc/grind(atom/AM)
- if(machine_stat & NOPOWER)
+ if(!is_operational)
return
if(reagents.holder_full())
return
@@ -56,11 +54,10 @@
var/obj/item/I = AM
var/result
- if(I.grind_results || I.juice_typepath)
+ if(I.grind_results)
+ result = I.grind(reagents, usr)
+ else
+ result = I.juice(reagents, usr)
+ if(result)
use_energy(active_power_usage)
- if(I.grind_results)
- result = I.grind(reagents, usr)
- else if (I.juice_typepath)
- result = I.juice(reagents, usr)
- if(result)
- qdel(I)
+ qdel(I)
diff --git a/code/modules/plumbing/plumbers/iv_drip.dm b/code/modules/plumbing/plumbers/iv_drip.dm
index f9a5ae47598..6e258555384 100644
--- a/code/modules/plumbing/plumbers/iv_drip.dm
+++ b/code/modules/plumbing/plumbers/iv_drip.dm
@@ -6,6 +6,7 @@
base_icon_state = "plumb"
density = TRUE
use_internal_storage = TRUE
+ processing_flags = START_PROCESSING_MANUALLY
/obj/machinery/iv_drip/plumbing/Initialize(mapload, bolt, layer)
. = ..()
@@ -29,10 +30,14 @@
reagents.expose(get_turf(src), TOUCH) //splash on the floor
reagents.clear_reagents()
-
/obj/machinery/iv_drip/plumbing/wrench_act(mob/living/user, obj/item/tool)
- if(default_unfasten_wrench(user, tool) == SUCCESSFUL_UNFASTEN)
- return ITEM_INTERACT_SUCCESS
+ if(user.combat_mode)
+ return NONE
-/obj/machinery/iv_drip/plumbing/on_deconstruction(disassembled)
- qdel(src)
+ . = ITEM_INTERACT_BLOCKING
+ if(default_unfasten_wrench(user, tool) == SUCCESSFUL_UNFASTEN)
+ if(anchored)
+ begin_processing()
+ else
+ end_processing()
+ return ITEM_INTERACT_SUCCESS
diff --git a/code/modules/plumbing/plumbers/pill_press.dm b/code/modules/plumbing/plumbers/pill_press.dm
index 5761474a959..dad5ad943b1 100644
--- a/code/modules/plumbing/plumbers/pill_press.dm
+++ b/code/modules/plumbing/plumbers/pill_press.dm
@@ -10,7 +10,6 @@
name = "chemical press"
desc = "A press that makes pills, patches and bottles."
icon_state = "pill_press"
- active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2
/// current operating product (pills or patches)
var/product = "pill"
@@ -80,7 +79,7 @@
return container
/obj/machinery/plumbing/pill_press/process(seconds_per_tick)
- if(machine_stat & NOPOWER)
+ if(!is_operational)
return
//shift & check to account for floating point inaccuracies
diff --git a/code/modules/plumbing/plumbers/reaction_chamber.dm b/code/modules/plumbing/plumbers/reaction_chamber.dm
index 9bdac2f98b2..59fcfaf7caf 100644
--- a/code/modules/plumbing/plumbers/reaction_chamber.dm
+++ b/code/modules/plumbing/plumbers/reaction_chamber.dm
@@ -9,7 +9,6 @@
icon_state = "reaction_chamber"
buffer = 200
reagent_flags = TRANSPARENT | NO_REACT
- active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2
/**
* list of set reagents that the reaction_chamber allows in, and must all be present before mixing is enabled.
@@ -49,23 +48,18 @@
return NONE
/obj/machinery/plumbing/reaction_chamber/process(seconds_per_tick)
- //half the power for getting reagents in
- var/power_usage = active_power_usage * 0.5
+ if(!is_operational || !reagents.total_volume)
+ return
if(!emptying || reagents.is_reacting)
//adjust temperature of final solution
- var/temp_diff = target_temperature - reagents.chem_temp
- if(abs(temp_diff) > 0.01) //if we are not close enough keep going
- reagents.adjust_thermal_energy(temp_diff * HEATER_COEFFICIENT * seconds_per_tick * SPECIFIC_HEAT_DEFAULT * reagents.total_volume) //keep constant with chem heater
+ var/energy = (target_temperature - reagents.chem_temp) * HEATER_COEFFICIENT * seconds_per_tick * reagents.heat_capacity()
+ reagents.adjust_thermal_energy(energy)
+ use_energy(active_power_usage + abs(ROUND_UP(energy) / 120))
//do other stuff with final solution
handle_reagents(seconds_per_tick)
- //full power for doing reactions
- power_usage *= 2
-
- use_energy(power_usage * seconds_per_tick)
-
///For subtypes that want to do additional reagent handling
/obj/machinery/plumbing/reaction_chamber/proc/handle_reagents(seconds_per_tick)
return
diff --git a/code/modules/plumbing/plumbers/splitters.dm b/code/modules/plumbing/plumbers/splitters.dm
index de279227009..b87a07d694c 100644
--- a/code/modules/plumbing/plumbers/splitters.dm
+++ b/code/modules/plumbing/plumbers/splitters.dm
@@ -3,7 +3,6 @@
name = "chemical splitter"
desc = "A chemical splitter for smart chemical factorization. Waits till a set of conditions is met and then stops all input and splits the buffer evenly or other in two ducts."
icon_state = "splitter"
- active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2
buffer = 100
density = FALSE
diff --git a/code/modules/plumbing/plumbers/synthesizer.dm b/code/modules/plumbing/plumbers/synthesizer.dm
index d7a5d83a251..0399ad85f3c 100644
--- a/code/modules/plumbing/plumbers/synthesizer.dm
+++ b/code/modules/plumbing/plumbers/synthesizer.dm
@@ -4,7 +4,6 @@
desc = "Produces a single chemical at a given volume. Must be plumbed. Most effective when working in unison with other chemical synthesizers, heaters and filters."
icon_state = "synthesizer"
icon = 'icons/obj/pipes_n_cables/hydrochem/plumbers.dmi'
- active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2
///Amount we produce for every process. Ideally keep under 5 since thats currently the standard duct capacity
var/amount = 1
@@ -49,7 +48,7 @@
dispensable_reagents = default_reagents
/obj/machinery/plumbing/synthesizer/process(seconds_per_tick)
- if(machine_stat & NOPOWER || !reagent_id || !amount)
+ if(!is_operational || !reagent_id || !amount)
return
//otherwise we get leftovers, and we need this to be precise
@@ -57,7 +56,7 @@
return
reagents.add_reagent(reagent_id, amount)
- use_energy(active_power_usage)
+ use_energy(active_power_usage * seconds_per_tick)
/obj/machinery/plumbing/synthesizer/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
diff --git a/code/modules/plumbing/plumbers/teleporter.dm b/code/modules/plumbing/plumbers/teleporter.dm
index e1aa26532dc..df79220d15a 100644
--- a/code/modules/plumbing/plumbers/teleporter.dm
+++ b/code/modules/plumbing/plumbers/teleporter.dm
@@ -77,7 +77,7 @@
return TRUE
/obj/machinery/plumbing/receiver/process(seconds_per_tick)
- if(machine_stat & NOPOWER || panel_open)
+ if(!is_operational || panel_open)
return
if(senders.len)
diff --git a/code/modules/plumbing/plumbers/vatgrower.dm b/code/modules/plumbing/plumbers/vatgrower.dm
index ab2a732c9c5..7327a648dad 100644
--- a/code/modules/plumbing/plumbers/vatgrower.dm
+++ b/code/modules/plumbing/plumbers/vatgrower.dm
@@ -27,7 +27,7 @@
return NONE
///When we process, we make use of our reagents to try and feed the samples we have.
-/obj/machinery/plumbing/growing_vat/process()
+/obj/machinery/plumbing/growing_vat/process(seconds_per_tick)
if(!is_operational)
return
if(!biological_sample)
@@ -37,6 +37,7 @@
return
playsound(loc, 'sound/effects/slosh.ogg', 25, TRUE)
audible_message(pick(list(span_notice("[src] grumbles!"), span_notice("[src] makes a splashing noise!"), span_notice("[src] sloshes!"))))
+ use_energy(active_power_usage * seconds_per_tick)
///Handles the petri dish depositing into the vat.
/obj/machinery/plumbing/growing_vat/attacked_by(obj/item/I, mob/living/user)
diff --git a/code/modules/power/apc/apc_attack.dm b/code/modules/power/apc/apc_attack.dm
index b57f3465f0d..acaaac1bd3e 100644
--- a/code/modules/power/apc/apc_attack.dm
+++ b/code/modules/power/apc/apc_attack.dm
@@ -110,13 +110,17 @@
return TRUE
if(!HAS_SILICON_ACCESS(user))
return TRUE
+ . = TRUE
var/mob/living/silicon/ai/AI = user
var/mob/living/silicon/robot/robot = user
- if(aidisabled || malfhack && istype(malfai) && ((istype(AI) && (malfai != AI && malfai != AI.parent)) || (istype(robot) && (robot in malfai.connected_robots))))
- if(!loud)
- balloon_alert(user, "it's disabled!")
- return FALSE
- return TRUE
+ if(istype(AI) || istype(robot))
+ if(aidisabled)
+ . = FALSE
+ else if(istype(malfai) && (malfai != AI || !(robot in malfai.connected_robots)))
+ . = FALSE
+ if (!. && !loud)
+ balloon_alert(user, "it's disabled!")
+ return .
/obj/machinery/power/apc/proc/set_broken()
if(machine_stat & BROKEN)
diff --git a/code/modules/power/apc/apc_main.dm b/code/modules/power/apc/apc_main.dm
index 3dd2df590e1..ae30a350496 100644
--- a/code/modules/power/apc/apc_main.dm
+++ b/code/modules/power/apc/apc_main.dm
@@ -17,6 +17,7 @@
damage_deflection = 10
resistance_flags = FIRE_PROOF
interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON
+ interaction_flags_click = ALLOW_SILICON_REACH
processing_flags = START_PROCESSING_MANUALLY
///Range of the light emitted when on
@@ -227,8 +228,11 @@
find_and_hang_on_wall()
/obj/machinery/power/apc/Destroy()
- if(malfai && operating)
- malfai.malf_picker.processing_time = clamp(malfai.malf_picker.processing_time - 10, 0, 1000)
+ if(malfai)
+ if(operating)
+ malfai.malf_picker.processing_time = clamp(malfai.malf_picker.processing_time - 10, 0, 1000)
+ malfai.hacked_apcs -= src
+ malfai = null
disconnect_from_area()
QDEL_NULL(alarm_manager)
if(occupier)
@@ -636,7 +640,7 @@
/obj/machinery/power/apc/proc/overload_lighting()
if(!operating || shorted)
return
- if(cell && cell.use(20 KILO JOULES))
+ if(cell && cell.use(0.02 * STANDARD_CELL_CHARGE))
INVOKE_ASYNC(src, PROC_REF(break_lights))
/obj/machinery/power/apc/proc/break_lights()
diff --git a/code/modules/power/apc/apc_malf.dm b/code/modules/power/apc/apc_malf.dm
index dee0d95de4d..f4c27e15a40 100644
--- a/code/modules/power/apc/apc_malf.dm
+++ b/code/modules/power/apc/apc_malf.dm
@@ -1,7 +1,7 @@
/obj/machinery/power/apc/proc/get_malf_status(mob/living/silicon/ai/malf)
if(!istype(malf) || !malf.malf_picker)
return APC_AI_NO_MALF
- if(malfai != (malf.parent || malf))
+ if(malfai != malf)
return APC_AI_NO_HACK
if(occupier == malf)
return APC_AI_HACK_SHUNT_HERE
@@ -12,7 +12,7 @@
/obj/machinery/power/apc/proc/malfhack(mob/living/silicon/ai/malf)
if(!istype(malf))
return
- if(get_malf_status(malf) != 1)
+ if(get_malf_status(malf) != APC_AI_NO_HACK)
return
if(malf.malfhacking)
to_chat(malf, span_warning("You are already hacking an APC!"))
@@ -37,18 +37,16 @@
if(!is_station_level(z))
return
malf.ShutOffDoomsdayDevice()
- occupier = new /mob/living/silicon/ai(src, malf.laws.copy_lawset(), malf) //DEAR GOD WHY? //IKR????
- occupier.adjustOxyLoss(malf.getOxyLoss())
+ occupier = malf
+ if (isturf(malf.loc)) // create a deactivated AI core if the AI isn't coming from an emergency mech shunt
+ malf.linked_core = new /obj/structure/ai_core/deactivated
+ malf.linked_core.remote_ai = malf // note that we do not set the deactivated core's core_mmi.brainmob
+ malf.forceMove(src) // move INTO the APC, not to its tile
if(!findtext(occupier.name, "APC Copy"))
occupier.name = "[malf.name] APC Copy"
- if(malf.parent)
- occupier.parent = malf.parent
- else
- occupier.parent = malf
malf.shunted = TRUE
occupier.eyeobj.name = "[occupier.name] (AI Eye)"
- if(malf.parent)
- qdel(malf)
+ occupier.eyeobj.forceMove(src.loc)
for(var/obj/item/pinpointer/nuke/disk_pinpointers in GLOB.pinpointer_list)
disk_pinpointers.switch_mode_to(TRACK_MALF_AI) //Pinpointer will track the shunted AI
var/datum/action/innate/core_return/return_action = new
@@ -58,12 +56,11 @@
/obj/machinery/power/apc/proc/malfvacate(forced)
if(!occupier)
return
- if(occupier.parent && occupier.parent.stat != DEAD)
- occupier.mind.transfer_to(occupier.parent)
- occupier.parent.shunted = FALSE
- occupier.parent.setOxyLoss(occupier.getOxyLoss())
- occupier.parent.cancel_camera()
- qdel(occupier)
+ if(occupier.linked_core)
+ occupier.shunted = FALSE
+ occupier.forceMove(occupier.linked_core.loc)
+ qdel(occupier.linked_core)
+ occupier.cancel_camera()
return
to_chat(occupier, span_danger("Primary core damaged, unable to return core processes."))
if(forced)
@@ -89,7 +86,7 @@
if(!occupier.mind || !occupier.client)
to_chat(user, span_warning("[occupier] is either inactive or destroyed!"))
return FALSE
- if(!occupier.parent.stat)
+ if(occupier.linked_core) //if they have an active linked_core, they can't be transferred from an APC
to_chat(user, span_warning("[occupier] is refusing all attempts at transfer!") )
return FALSE
if(transfer_in_progress)
@@ -127,7 +124,7 @@
to_chat(occupier, span_notice("Transfer complete! You've been stored in [user]'s [card.name]."))
occupier.forceMove(card)
card.AI = occupier
- occupier.parent.shunted = FALSE
+ occupier.shunted = FALSE
occupier.cancel_camera()
occupier = null
transfer_in_progress = FALSE
diff --git a/code/modules/power/apc/apc_tool_act.dm b/code/modules/power/apc/apc_tool_act.dm
index 6a8835cd5b7..0116205fdd4 100644
--- a/code/modules/power/apc/apc_tool_act.dm
+++ b/code/modules/power/apc/apc_tool_act.dm
@@ -168,7 +168,7 @@
if(machine_stat & BROKEN)
balloon_alert(user, "frame is too damaged!")
return ITEM_INTERACT_BLOCKING
- if(!pseudocircuit.adapt_circuit(user, circuit_cost = 50 KILO JOULES))
+ if(!pseudocircuit.adapt_circuit(user, circuit_cost = 0.05 * STANDARD_CELL_CHARGE))
return ITEM_INTERACT_BLOCKING
user.visible_message(
span_notice("[user] fabricates a circuit and places it into [src]."),
@@ -182,7 +182,7 @@
if(machine_stat & MAINT)
balloon_alert(user, "no board for a cell!")
return ITEM_INTERACT_BLOCKING
- if(!pseudocircuit.adapt_circuit(user, circuit_cost = 500 KILO JOULES))
+ if(!pseudocircuit.adapt_circuit(user, circuit_cost = 0.5 * STANDARD_CELL_CHARGE))
return ITEM_INTERACT_BLOCKING
var/obj/item/stock_parts/cell/crap/empty/bad_cell = new(src)
bad_cell.forceMove(src)
diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm
index 00b332e6608..59f1775f4e3 100644
--- a/code/modules/power/cell.dm
+++ b/code/modules/power/cell.dm
@@ -31,7 +31,7 @@
///If the power cell was damaged by an explosion, chance for it to become corrupted and function the same as rigged.
var/corrupted = FALSE
///How much power is given per second in a recharger.
- var/chargerate = STANDARD_CELL_CHARGE * 0.05
+ var/chargerate = STANDARD_CELL_RATE * 0.05
///If true, the cell will state it's maximum charge in it's description
var/ratingdesc = TRUE
///If it's a grown that acts as a battery, add a wire overlay to it.
@@ -334,7 +334,7 @@
desc = "A power cell with a slightly higher capacity than normal!"
maxcharge = STANDARD_CELL_CHARGE * 2.5
custom_materials = list(/datum/material/glass=SMALL_MATERIAL_AMOUNT*0.5)
- chargerate = STANDARD_CELL_CHARGE * 0.5
+ chargerate = STANDARD_CELL_RATE * 0.5
/obj/item/stock_parts/cell/upgraded/plus
name = "upgraded power cell+"
@@ -360,7 +360,7 @@
/obj/item/stock_parts/cell/pulse //200 pulse shots
name = "pulse rifle power cell"
maxcharge = STANDARD_CELL_CHARGE * 40
- chargerate = STANDARD_CELL_CHARGE * 0.75
+ chargerate = STANDARD_CELL_RATE * 0.75
/obj/item/stock_parts/cell/pulse/carbine //25 pulse shots
name = "pulse carbine power cell"
@@ -375,14 +375,14 @@
icon_state = "bscell"
maxcharge = STANDARD_CELL_CHARGE * 10
custom_materials = list(/datum/material/glass=SMALL_MATERIAL_AMOUNT*0.6)
- chargerate = STANDARD_CELL_CHARGE
+ chargerate = STANDARD_CELL_RATE
/obj/item/stock_parts/cell/high
name = "high-capacity power cell"
icon_state = "hcell"
maxcharge = STANDARD_CELL_CHARGE * 10
custom_materials = list(/datum/material/glass=SMALL_MATERIAL_AMOUNT*0.6)
- chargerate = STANDARD_CELL_CHARGE * 0.75
+ chargerate = STANDARD_CELL_RATE * 0.75
/obj/item/stock_parts/cell/high/empty
empty = TRUE
@@ -392,7 +392,7 @@
icon_state = "scell"
maxcharge = STANDARD_CELL_CHARGE * 20
custom_materials = list(/datum/material/glass=SMALL_MATERIAL_AMOUNT * 3)
- chargerate = STANDARD_CELL_CHARGE
+ chargerate = STANDARD_CELL_RATE
/obj/item/stock_parts/cell/super/empty
empty = TRUE
@@ -402,7 +402,7 @@
icon_state = "hpcell"
maxcharge = STANDARD_CELL_CHARGE * 30
custom_materials = list(/datum/material/glass=SMALL_MATERIAL_AMOUNT * 4)
- chargerate = STANDARD_CELL_CHARGE * 1.5
+ chargerate = STANDARD_CELL_RATE * 1.5
/obj/item/stock_parts/cell/hyper/empty
empty = TRUE
@@ -413,7 +413,7 @@
icon_state = "bscell"
maxcharge = STANDARD_CELL_CHARGE * 40
custom_materials = list(/datum/material/glass=SMALL_MATERIAL_AMOUNT*6)
- chargerate = STANDARD_CELL_CHARGE * 2
+ chargerate = STANDARD_CELL_RATE * 2
/obj/item/stock_parts/cell/bluespace/empty
empty = TRUE
@@ -486,7 +486,7 @@
name = "beam rifle capacitor"
desc = "A high powered capacitor that can provide huge amounts of energy in an instant."
maxcharge = STANDARD_CELL_CHARGE * 50
- chargerate = STANDARD_CELL_CHARGE * 2.5 //Extremely energy intensive
+ chargerate = STANDARD_CELL_RATE * 2.5 //Extremely energy intensive
/obj/item/stock_parts/cell/beam_rifle/corrupt()
return
diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm
index 2aa5247451d..bf866f234e3 100644
--- a/code/modules/power/smes.dm
+++ b/code/modules/power/smes.dm
@@ -438,6 +438,16 @@
update_appearance()
log_smes()
+// Variant of SMES that starts with super power cells for higher longevity
+/obj/machinery/power/smes/super
+ name = "super capacity power storage unit"
+ desc = "A super-capacity superconducting magnetic energy storage (SMES) unit. Relatively rare, and typically installed in long-range outposts where minimal maintenance is expected."
+ circuit = /obj/item/circuitboard/machine/smes/super
+ capacity = 100 * STANDARD_CELL_CHARGE
+
+/obj/machinery/power/smes/super/full
+ charge = 100 * STANDARD_CELL_CHARGE
+
/obj/machinery/power/smes/full
charge = 50 * STANDARD_CELL_CHARGE
diff --git a/code/modules/projectiles/boxes_magazines/_box_magazine.dm b/code/modules/projectiles/boxes_magazines/_box_magazine.dm
index 15135bee1a5..ec2139ad5d0 100644
--- a/code/modules/projectiles/boxes_magazines/_box_magazine.dm
+++ b/code/modules/projectiles/boxes_magazines/_box_magazine.dm
@@ -43,7 +43,7 @@
/obj/item/ammo_box/Initialize(mapload)
. = ..()
- custom_materials = SSmaterials.FindOrCreateMaterialCombo(custom_materials, 0.1)
+ custom_materials = DSmaterials.FindOrCreateMaterialCombo(custom_materials, 0.1)
if(!start_empty)
top_off(starting=TRUE)
update_icon_state()
diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm
index c584359b8ce..7481443bade 100644
--- a/code/modules/projectiles/guns/ballistic/shotgun.dm
+++ b/code/modules/projectiles/guns/ballistic/shotgun.dm
@@ -85,7 +85,7 @@
w_class = WEIGHT_CLASS_HUGE
semi_auto = TRUE
accepted_magazine_type = /obj/item/ammo_box/magazine/internal/shot/tube
- interaction_flags_click = NEED_DEXTERITY|NEED_HANDS
+ interaction_flags_click = NEED_DEXTERITY|NEED_HANDS|ALLOW_RESTING
/// If defined, the secondary tube is this type, if you want different shell loads
var/alt_mag_type
/// If TRUE, we're drawing from the alternate_magazine
diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm
index 523f41af752..b9c8b7de41f 100644
--- a/code/modules/projectiles/guns/energy/special.dm
+++ b/code/modules/projectiles/guns/energy/special.dm
@@ -78,6 +78,9 @@
ammo_type = list(/obj/item/ammo_casing/energy/mindflayer)
ammo_x_offset = 2
+/// amount of charge used up to start action (multiplied by amount) and per progress_flash_divisor ticks of welding
+#define PLASMA_CUTTER_CHARGE_WELD (0.025 * STANDARD_CELL_CHARGE)
+
/obj/item/gun/energy/plasmacutter
name = "plasma cutter"
desc = "A mining tool capable of expelling concentrated plasma bursts. You could use it to cut limbs off xenos! Or, you know, mine stuff."
@@ -91,13 +94,10 @@
sharpness = SHARP_EDGED
can_charge = FALSE
gun_flags = NOT_A_REAL_GUN
-
heat = 3800
usesound = list('sound/items/welder.ogg', 'sound/items/welder2.ogg')
tool_behaviour = TOOL_WELDER
toolspeed = 0.7 //plasmacutters can be used as welders, and are faster than standard welders
- /// amount of charge used up to start action (multiplied by amount) and per progress_flash_divisor ticks of welding
- var/charge_weld = 25 KILO JOULES
/obj/item/gun/energy/plasmacutter/Initialize(mapload)
AddElement(/datum/element/update_icon_blocker)
@@ -126,7 +126,7 @@
balloon_alert(user, "already fully charged!")
return
I.use(1)
- cell.give(500 KILO JOULES * charge_multiplier)
+ cell.give(0.5 * STANDARD_CELL_CHARGE * charge_multiplier)
balloon_alert(user, "cell recharged")
else
..()
@@ -148,14 +148,14 @@
// Amount cannot be used if drain is made continuous, e.g. amount = 5, charge_weld = 25
// Then it'll drain 125 at first and 25 periodically, but fail if charge dips below 125 even though it still can finish action
// Alternately it'll need to drain amount*charge_weld every period, which is either obscene or makes it free for other uses
- if(amount ? cell.charge < charge_weld * amount : cell.charge < charge_weld)
+ if(amount ? cell.charge < PLASMA_CUTTER_CHARGE_WELD * amount : cell.charge < PLASMA_CUTTER_CHARGE_WELD)
balloon_alert(user, "not enough charge!")
return FALSE
return TRUE
/obj/item/gun/energy/plasmacutter/use(used)
- return (!QDELETED(cell) && cell.use(used ? used * charge_weld : charge_weld))
+ return (!QDELETED(cell) && cell.use(used ? used * PLASMA_CUTTER_CHARGE_WELD : PLASMA_CUTTER_CHARGE_WELD))
/obj/item/gun/energy/plasmacutter/use_tool(atom/target, mob/living/user, delay, amount=1, volume=0, datum/callback/extra_checks)
@@ -169,6 +169,8 @@
else
. = ..(amount=1)
+#undef PLASMA_CUTTER_CHARGE_WELD
+
/obj/item/gun/energy/plasmacutter/adv
name = "advanced plasma cutter"
icon_state = "adv_plasmacutter"
@@ -407,7 +409,7 @@
COOLDOWN_START(src, coin_regen_cd, coin_regen_rate)
/obj/item/gun/energy/marksman_revolver/afterattack_secondary(atom/target, mob/living/user, params)
- if(!can_see(user, get_turf(target), length = 9))
+ if(!CAN_THEY_SEE(target, user))
return ..()
if(max_coins && coin_count <= 0)
diff --git a/code/modules/reagents/chemistry/machinery/chem_heater.dm b/code/modules/reagents/chemistry/machinery/chem_heater.dm
index 76b2dbf7f96..3cf5b752400 100644
--- a/code/modules/reagents/chemistry/machinery/chem_heater.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_heater.dm
@@ -31,8 +31,12 @@
QDEL_NULL(beaker)
return ..()
-/obj/machinery/chem_heater/on_deconstruction(disassembled)
- beaker?.forceMove(drop_location())
+/obj/machinery/chem_heater/Exited(atom/movable/gone, direction)
+ . = ..()
+ if(gone == beaker)
+ UnregisterSignal(beaker.reagents, COMSIG_REAGENTS_REACTION_STEP)
+ beaker = null
+ update_appearance()
/obj/machinery/chem_heater/add_context(atom/source, list/context, obj/item/held_item, mob/user)
if(isnull(held_item) || (held_item.item_flags & ABSTRACT) || (held_item.flags_1 & HOLOGRAM_1))
@@ -58,7 +62,6 @@
return NONE
-
/obj/machinery/chem_heater/examine(mob/user)
. = ..()
if(in_range(user, src) || isobserver(user))
@@ -80,25 +83,17 @@
icon_state = "[base_icon_state][beaker ? 1 : 0]b"
return ..()
-/obj/machinery/chem_heater/Exited(atom/movable/gone, direction)
- . = ..()
- if(gone == beaker)
- UnregisterSignal(beaker.reagents, COMSIG_REAGENTS_REACTION_STEP)
- beaker = null
- update_appearance()
-
/obj/machinery/chem_heater/RefreshParts()
. = ..()
heater_coefficient = 0.1
for(var/datum/stock_part/micro_laser/micro_laser in component_parts)
heater_coefficient *= micro_laser.tier
-
/obj/machinery/chem_heater/item_interaction(mob/living/user, obj/item/held_item, list/modifiers)
- if((held_item.item_flags & ABSTRACT) || (held_item.flags_1 & HOLOGRAM_1))
+ if(user.combat_mode || (held_item.item_flags & ABSTRACT) || (held_item.flags_1 & HOLOGRAM_1) || !user.can_perform_action(src, ALLOW_SILICON_REACH | FORBID_TELEKINESIS_REACH))
return NONE
- if(QDELETED(beaker))
+ if(!QDELETED(beaker))
if(istype(held_item, /obj/item/reagent_containers/dropper) || istype(held_item, /obj/item/reagent_containers/syringe))
var/obj/item/reagent_containers/injector = held_item
injector.afterattack(beaker, user, proximity_flag = TRUE)
@@ -113,16 +108,25 @@
return NONE
/obj/machinery/chem_heater/wrench_act(mob/living/user, obj/item/tool)
+ if(user.combat_mode)
+ return NONE
+
. = ITEM_INTERACT_BLOCKING
if(default_unfasten_wrench(user, tool) == SUCCESSFUL_UNFASTEN)
return ITEM_INTERACT_SUCCESS
/obj/machinery/chem_heater/screwdriver_act(mob/living/user, obj/item/tool)
+ if(user.combat_mode)
+ return NONE
+
. = ITEM_INTERACT_BLOCKING
if(default_deconstruction_screwdriver(user, "mixer0b", "[base_icon_state][beaker ? 1 : 0]b", tool))
return ITEM_INTERACT_SUCCESS
/obj/machinery/chem_heater/crowbar_act(mob/living/user, obj/item/tool)
+ if(user.combat_mode)
+ return NONE
+
. = ITEM_INTERACT_BLOCKING
if(default_deconstruction_crowbar(tool))
return ITEM_INTERACT_SUCCESS
@@ -174,12 +178,13 @@
PRIVATE_PROC(TRUE)
//must be on and beaker must have something inside to heat
- if(!on || (machine_stat & NOPOWER) || QDELETED(beaker) || !beaker.reagents.total_volume)
+ if(!on || !is_operational || QDELETED(beaker) || !beaker.reagents.total_volume)
return FALSE
//heat the beaker and use some power. we want to use only a small amount of power since this proc gets called frequently
- beaker.reagents.adjust_thermal_energy((target_temperature - beaker.reagents.chem_temp) * heater_coefficient * seconds_per_tick * SPECIFIC_HEAT_DEFAULT * beaker.reagents.total_volume)
- use_energy(active_power_usage * seconds_per_tick * 0.3)
+ var/energy = (target_temperature - beaker.reagents.chem_temp) * heater_coefficient * seconds_per_tick * beaker.reagents.heat_capacity()
+ beaker.reagents.adjust_thermal_energy(energy)
+ use_energy(active_power_usage + abs(ROUND_UP(energy) / 120))
return TRUE
/obj/machinery/chem_heater/proc/on_reaction_step(datum/reagents/holder, num_reactions, seconds_per_tick)
diff --git a/code/modules/reagents/chemistry/machinery/chem_mass_spec.dm b/code/modules/reagents/chemistry/machinery/chem_mass_spec.dm
index ca75736db03..e11910a13af 100644
--- a/code/modules/reagents/chemistry/machinery/chem_mass_spec.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_mass_spec.dm
@@ -241,11 +241,11 @@
lower_mass_range = calculate_mass(smallest = TRUE)
upper_mass_range = calculate_mass(smallest = FALSE)
estimate_time()
-
else //replace output beaker
if(!QDELETED(beaker2))
try_put_in_hand(beaker2, user)
beaker2 = new_beaker
+ log.Cut()
update_appearance()
@@ -258,8 +258,8 @@
return
for(var/datum/reagent/reagent as anything in beaker1.reagents.reagent_list)
- //we don't bother about impure chems
- if(istype(reagent, /datum/reagent/inverse) || (reagent.inverse_chem_val > reagent.purity && reagent.inverse_chem))
+ //we don't deal chems that are so impure that they are about to become inverted
+ if(reagent.inverse_chem_val > reagent.purity && reagent.inverse_chem)
continue
//out of our selected range
if(reagent.mass < lower_mass_range || reagent.mass > upper_mass_range)
@@ -300,10 +300,7 @@
var/purity = target.purity
var/is_inverse = FALSE
- if(istype(reagent, /datum/reagent/inverse))
- log = "Too impure to use" //we don't bother about impure chems
- is_inverse = TRUE
- else if(reagent.inverse_chem_val > reagent.purity && reagent.inverse_chem)
+ if(reagent.inverse_chem_val > reagent.purity && reagent.inverse_chem)
purity = target.get_inverse_purity()
target = GLOB.chemical_reagents_list[reagent.inverse_chem]
log = "Too impure to use" //we don't bother about impure chems
@@ -352,13 +349,9 @@
/obj/machinery/chem_mass_spec/ui_act(action, params, datum/tgui/ui, datum/ui_state/state)
. = ..()
- if(.)
+ if(. || processing_reagents)
return
- if(processing_reagents)
- balloon_alert(ui.user, "still processing")
- return ..()
-
switch(action)
if("activate")
if(QDELETED(beaker1))
@@ -454,10 +447,7 @@
if(!processing_reagents)
return PROCESS_KILL
- if(!is_operational || panel_open || !anchored || (machine_stat & (BROKEN | NOPOWER)))
- return
-
- if(!use_energy(active_power_usage * seconds_per_tick))
+ if(!is_operational || panel_open || !anchored)
return
progress_time += seconds_per_tick
@@ -467,8 +457,8 @@
log.Cut()
for(var/datum/reagent/reagent as anything in beaker1.reagents.reagent_list)
- //we don't bother about impure chems
- if(istype(reagent, /datum/reagent/inverse) || (reagent.inverse_chem_val > reagent.purity && reagent.inverse_chem))
+ //we don't deal chems that are so impure that they are about to become inverted
+ if(reagent.inverse_chem_val > reagent.purity && reagent.inverse_chem)
continue
//out of our selected range
if(reagent.mass < lower_mass_range || reagent.mass > upper_mass_range)
@@ -489,3 +479,5 @@
estimate_time()
update_appearance()
return PROCESS_KILL
+
+ use_energy(active_power_usage * seconds_per_tick)
diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm
index 9f210e12ee4..e7bb73d29f2 100644
--- a/code/modules/reagents/chemistry/machinery/chem_master.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_master.dm
@@ -1,3 +1,5 @@
+#define MAX_CONTAINER_PRINT_AMOUNT 50
+
/obj/machinery/chem_master
name = "ChemMaster 3000"
desc = "Used to separate chemicals and distribute them in a variety of forms."
@@ -26,8 +28,8 @@
var/printing_progress
/// Number of containers to be printed
var/printing_total
- /// The amount of containers that can be printed in 1 cycle
- var/printing_amount = 1
+ /// The time it takes to print a container
+ var/printing_speed = 0.75 SECONDS
/obj/machinery/chem_master/Initialize(mapload)
create_reagents(100)
@@ -76,7 +78,7 @@
/obj/machinery/chem_master/examine(mob/user)
. = ..()
if(in_range(user, src) || isobserver(user))
- . += span_notice("The status display reads: Reagent buffer capacity: [reagents.maximum_volume] units. Number of containers printed per cycle [printing_amount] .")
+ . += span_notice("The status display reads: Reagent buffer capacity: [reagents.maximum_volume] units. Printing speed: [0.75 SECONDS / printing_speed * 100]% .")
if(!QDELETED(beaker))
. += span_notice("[beaker] of [beaker.reagents.maximum_volume]u capacity inserted")
. += span_notice("Right click with empty hand to remove beaker")
@@ -155,10 +157,11 @@
for(var/obj/item/reagent_containers/cup/beaker/beaker in component_parts)
reagents.maximum_volume += beaker.reagents.maximum_volume
- printing_amount = 0
+ //Servo tier determines printing speed
+ printing_speed = 1 SECONDS
for(var/datum/stock_part/servo/servo in component_parts)
- printing_amount += servo.tier * 12.5
- printing_amount = min(50, ROUND_UP(printing_amount))
+ printing_speed -= servo.tier * 0.25 SECONDS
+ printing_speed = max(printing_speed, 0.25 SECONDS)
///Return a map of category->list of containers this machine can print
/obj/machinery/chem_master/proc/load_printable_containers()
@@ -270,6 +273,7 @@
/obj/machinery/chem_master/ui_static_data(mob/user)
var/list/data = list()
+ data["maxPrintable"] = MAX_CONTAINER_PRINT_AMOUNT
data["categories"] = list()
for(var/category in printable_containers)
//make the category
@@ -299,7 +303,6 @@
.["isPrinting"] = is_printing
.["printingProgress"] = printing_progress
.["printingTotal"] = printing_total
- .["maxPrintable"] = printing_amount
//contents of source beaker
var/list/beaker_data = null
@@ -475,7 +478,7 @@
item_count = text2num(item_count)
if(isnull(item_count) || item_count <= 0)
return FALSE
- item_count = min(item_count, printing_amount)
+ item_count = min(item_count, MAX_CONTAINER_PRINT_AMOUNT)
var/volume_in_each = round(reagents.total_volume / item_count, CHEMICAL_VOLUME_ROUNDING)
// Generate item name
@@ -535,7 +538,7 @@
//print more items
item_count --
if(item_count > 0)
- addtimer(CALLBACK(src, PROC_REF(create_containers), user, item_count, item_name, volume_in_each), 0.75 SECONDS)
+ addtimer(CALLBACK(src, PROC_REF(create_containers), user, item_count, item_name, volume_in_each), printing_speed)
else
is_printing = FALSE
update_appearance(UPDATE_OVERLAYS)
@@ -550,3 +553,5 @@
if(!length(containers))
containers = list(CAT_CONDIMENTS = GLOB.reagent_containers[CAT_CONDIMENTS])
return containers
+
+#undef MAX_CONTAINER_PRINT_AMOUNT
diff --git a/code/modules/reagents/chemistry/reagents/unique/eigenstasium.dm b/code/modules/reagents/chemistry/reagents/unique/eigenstasium.dm
index 7c18c7e2014..8c093888028 100644
--- a/code/modules/reagents/chemistry/reagents/unique/eigenstasium.dm
+++ b/code/modules/reagents/chemistry/reagents/unique/eigenstasium.dm
@@ -116,6 +116,6 @@
var/list/lockers = list()
for(var/obj/structure/closet/closet in exposed_turf.contents)
lockers += closet
- if(!length(lockers))
+ if(!lockers.len)
return
- GLOB.eigenstate_manager.create_new_link(lockers)
+ GLOB.eigenstate_manager.create_new_link(lockers, subtle = FALSE)
diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm
index c87a6196835..9bb645254e8 100644
--- a/code/modules/reagents/chemistry/recipes/others.dm
+++ b/code/modules/reagents/chemistry/recipes/others.dm
@@ -945,7 +945,7 @@
optimal_ph_min = 3
optimal_ph_max = 12
required_temp = 50
- reaction_flags = NONE //SKYRAT CHANGE, REACTION_INSTANT TO NONE
+ reaction_flags = REAGENT_SPLITRETAINVOL //SKYRAT EDIT CHANGE - ORIGINAL: reaction_flags = REACTION_INSTANT | REAGENT_SPLITRETAINVOL
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_UNIQUE
/datum/chemical_reaction/ant_slurry // We're basically gluing ants together with synthflesh & maint sludge to make a bigger ant.
diff --git a/code/modules/reagents/reagent_containers/misc.dm b/code/modules/reagents/reagent_containers/misc.dm
index fa8d8cd3628..f631e8e28a0 100644
--- a/code/modules/reagents/reagent_containers/misc.dm
+++ b/code/modules/reagents/reagent_containers/misc.dm
@@ -32,7 +32,7 @@
if(on && (!cell || cell.charge <= 0)) //Check if we ran out of power
change_power_status(FALSE)
return FALSE
- cell.use(5 KILO WATTS * seconds_per_tick) //Basic cell goes for like 200 seconds, bluespace for 8000
+ cell.use(0.005 * STANDARD_CELL_RATE * seconds_per_tick) //Basic cell goes for like 200 seconds, bluespace for 8000
if(!reagents.total_volume)
return FALSE
var/max_temp = min(500 + (500 * (0.2 * cell.rating)), 1000) // 373 to 1000
diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm
index 350f51492cf..e35a71e5d9b 100644
--- a/code/modules/reagents/reagent_containers/spray.dm
+++ b/code/modules/reagents/reagent_containers/spray.dm
@@ -100,7 +100,7 @@
reagent_puff.end_life()
return
- var/datum/move_loop/our_loop = SSmove_manager.move_towards_legacy(reagent_puff, target, wait_step, timeout = range * wait_step, flags = MOVEMENT_LOOP_START_FAST, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
+ var/datum/move_loop/our_loop = DSmove_manager.move_towards_legacy(reagent_puff, target, wait_step, timeout = range * wait_step, flags = MOVEMENT_LOOP_START_FAST, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
reagent_puff.RegisterSignal(our_loop, COMSIG_QDELETING, TYPE_PROC_REF(/obj/effect/decal/chempuff, loop_ended))
reagent_puff.RegisterSignal(our_loop, COMSIG_MOVELOOP_POSTPROCESS, TYPE_PROC_REF(/obj/effect/decal/chempuff, check_move))
diff --git a/code/modules/recycling/conveyor.dm b/code/modules/recycling/conveyor.dm
index 3c04bd924ec..6d5b270cd71 100644
--- a/code/modules/recycling/conveyor.dm
+++ b/code/modules/recycling/conveyor.dm
@@ -241,7 +241,7 @@ GLOBAL_LIST_EMPTY(conveyors_by_id)
/obj/machinery/conveyor/proc/conveyable_enter(datum/source, atom/convayable)
SIGNAL_HANDLER
if(operating == CONVEYOR_OFF)
- SSmove_manager.stop_looping(convayable, SSconveyors)
+ DSmove_manager.stop_looping(convayable, SSconveyors)
return
start_conveying(convayable)
@@ -249,12 +249,12 @@ GLOBAL_LIST_EMPTY(conveyors_by_id)
SIGNAL_HANDLER
var/has_conveyor = neighbors["[direction]"]
if(convayable.z != z || !has_conveyor || !isturf(convayable.loc)) //If you've entered something on us, stop moving
- SSmove_manager.stop_looping(convayable, SSconveyors)
+ DSmove_manager.stop_looping(convayable, SSconveyors)
/obj/machinery/conveyor/proc/start_conveying(atom/movable/moving)
if(QDELETED(moving))
return
- var/datum/move_loop/move/moving_loop = SSmove_manager.processing_on(moving, SSconveyors)
+ var/datum/move_loop/move/moving_loop = DSmove_manager.processing_on(moving, SSconveyors)
if(moving_loop)
moving_loop.direction = movedir
moving_loop.delay = speed * 1 SECONDS
@@ -268,7 +268,7 @@ GLOBAL_LIST_EMPTY(conveyors_by_id)
/obj/machinery/conveyor/proc/stop_conveying(atom/movable/thing)
if(!ismovable(thing))
return
- SSmove_manager.stop_looping(thing, SSconveyors)
+ DSmove_manager.stop_looping(thing, SSconveyors)
// attack with item, place item on conveyor
/obj/machinery/conveyor/attackby(obj/item/attacking_item, mob/living/user, params)
diff --git a/code/modules/recycling/disposal/holder.dm b/code/modules/recycling/disposal/holder.dm
index fff78f74bef..ecc33c240bf 100644
--- a/code/modules/recycling/disposal/holder.dm
+++ b/code/modules/recycling/disposal/holder.dm
@@ -78,7 +78,7 @@
/// Starts the movement process, persists while the holder is moving through pipes
/obj/structure/disposalholder/proc/start_moving()
var/delay = world.tick_lag
- var/datum/move_loop/our_loop = SSmove_manager.move_disposals(src, delay = delay, timeout = delay * count)
+ var/datum/move_loop/our_loop = DSmove_manager.move_disposals(src, delay = delay, timeout = delay * count)
if(our_loop)
RegisterSignal(our_loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(pre_move))
RegisterSignal(our_loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(try_expel))
diff --git a/code/modules/religion/religion_sects.dm b/code/modules/religion/religion_sects.dm
index 16cd82c5650..5d5d3909ec7 100644
--- a/code/modules/religion/religion_sects.dm
+++ b/code/modules/religion/religion_sects.dm
@@ -200,11 +200,11 @@
if(!istype(power_cell))
return
- if(power_cell.charge < 0.3 * STANDARD_CELL_CHARGE)
+ if(power_cell.charge() < 0.3 * STANDARD_CELL_CHARGE)
to_chat(chap, span_notice("[GLOB.deity] does not accept pity amounts of power."))
return
- adjust_favor(round(power_cell.charge/300), chap)
+ adjust_favor(round(power_cell.charge() / (0.3 * STANDARD_CELL_CHARGE)), chap)
to_chat(chap, span_notice("You offer [power_cell]'s power to [GLOB.deity], pleasing them."))
qdel(power_cell)
return TRUE
diff --git a/code/modules/religion/rites.dm b/code/modules/religion/rites.dm
index d907191c33d..af02fa72117 100644
--- a/code/modules/religion/rites.dm
+++ b/code/modules/religion/rites.dm
@@ -391,7 +391,7 @@
/datum/religion_rites/ceremonial_weapon/perform_rite(mob/living/user, atom/religious_tool)
for(var/obj/item/stack/sheet/could_blade in get_turf(religious_tool))
- if(!(GET_MATERIAL_REF(could_blade.material_type) in SSmaterials.materials_by_category[MAT_CATEGORY_ITEM_MATERIAL]))
+ if(!(GET_MATERIAL_REF(could_blade.material_type) in DSmaterials.materials_by_category[MAT_CATEGORY_ITEM_MATERIAL]))
continue
if(could_blade.amount < 5)
continue
diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm
index 75b9add5b80..8d5f561e83b 100644
--- a/code/modules/research/designs/mechfabricator_designs.dm
+++ b/code/modules/research/designs/mechfabricator_designs.dm
@@ -1411,6 +1411,36 @@
RND_CATEGORY_MECHFAB_CYBORG_MODULES + RND_SUBCATEGORY_MECHFAB_CYBORG_MODULES_MEDICAL
)
+/datum/design/borg_upgrade_surgicalomnitool
+ name = "Advanced Surgical Omnitool Upgrade"
+ id = "borg_upgrade_surgicalomnitool"
+ build_type = MECHFAB
+ build_path = /obj/item/borg/upgrade/surgery_omnitool
+ materials = list(
+ /datum/material/iron=SHEET_MATERIAL_AMOUNT*5,
+ /datum/material/titanium=SHEET_MATERIAL_AMOUNT*3,
+ /datum/material/silver=SHEET_MATERIAL_AMOUNT*2,
+ )
+ construction_time = 4 SECONDS
+ category = list(
+ RND_CATEGORY_MECHFAB_CYBORG_MODULES + RND_SUBCATEGORY_MECHFAB_CYBORG_MODULES_MEDICAL
+ )
+
+/datum/design/borg_upgrade_engineeringomnitool
+ name = "Advanced Engineering Omnitool Upgrade"
+ id = "borg_upgrade_engineeringomnitool"
+ build_type = MECHFAB
+ build_path = /obj/item/borg/upgrade/engineering_omnitool
+ materials = list(
+ /datum/material/iron=SHEET_MATERIAL_AMOUNT*5,
+ /datum/material/titanium=SHEET_MATERIAL_AMOUNT*3,
+ /datum/material/gold=SHEET_MATERIAL_AMOUNT*2,
+ )
+ construction_time = 4 SECONDS
+ category = list(
+ RND_CATEGORY_MECHFAB_CYBORG_MODULES + RND_SUBCATEGORY_MECHFAB_CYBORG_MODULES_ENGINEERING,
+ )
+
/datum/design/borg_upgrade_trashofholding
name = "Trash Bag of Holding"
id = "borg_upgrade_trashofholding"
diff --git a/code/modules/research/machinery/_production.dm b/code/modules/research/machinery/_production.dm
index c7a7b320345..48afd76f624 100644
--- a/code/modules/research/machinery/_production.dm
+++ b/code/modules/research/machinery/_production.dm
@@ -1,8 +1,8 @@
/obj/machinery/rnd/production
name = "technology fabricator"
desc = "Makes researched and prototype items with materials and energy."
- // Energy cost per full stack of materials spent. Material insertion is 40% of this.
- active_power_usage = 50 * BASE_MACHINE_ACTIVE_CONSUMPTION
+ /// Energy cost per full stack of materials spent. Material insertion is 40% of this.
+ active_power_usage = 0.05 * STANDARD_CELL_RATE
/// The efficiency coefficient. Material costs and print times are multiplied by this number;
var/efficiency_coeff = 1
@@ -22,10 +22,6 @@
var/drop_direction = 0
/obj/machinery/rnd/production/Initialize(mapload)
- . = ..()
-
- cached_designs = list()
-
materials = AddComponent(
/datum/component/remote_materials, \
mapload, \
@@ -34,6 +30,10 @@
) \
)
+ . = ..()
+
+ cached_designs = list()
+
RegisterSignal(src, COMSIG_SILO_ITEM_CONSUMED, TYPE_PROC_REF(/obj/machinery/rnd/production, silo_material_insert))
AddComponent(
@@ -182,11 +182,10 @@
/obj/machinery/rnd/production/RefreshParts()
. = ..()
- if(materials)
- var/total_storage = 0
- for(var/datum/stock_part/matter_bin/bin in component_parts)
- total_storage += bin.tier * 37.5 * SHEET_MATERIAL_AMOUNT
- materials.set_local_size(total_storage)
+ var/total_storage = 0
+ for(var/datum/stock_part/matter_bin/bin in component_parts)
+ total_storage += bin.tier * 37.5 * SHEET_MATERIAL_AMOUNT
+ materials.set_local_size(total_storage)
efficiency_coeff = compute_efficiency()
diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm
index 04d0c30d9e0..8e13c63f792 100644
--- a/code/modules/research/rdconsole.dm
+++ b/code/modules/research/rdconsole.dm
@@ -129,7 +129,7 @@ Nothing else in the console has ID requirements.
logname = "[ID.registered_name]"
stored_research.research_logs += list(list(
"node_name" = TN.display_name,
- "node_cost" = price["General Research"],
+ "node_cost" = price[TECHWEB_POINT_TYPE_GENERIC],
"node_researcher" = logname,
"node_research_location" = "[get_area(src)] ([src.x],[src.y],[src.z])",
))
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index 7d64e1878b8..8cadca9e134 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -1022,6 +1022,7 @@
"borg_upgrade_rped",
"borg_upgrade_hypermod",
"borg_upgrade_inducer",
+ "borg_upgrade_engineeringomnitool",
)
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2000)
@@ -1037,6 +1038,7 @@
"borg_upgrade_piercinghypospray",
"borg_upgrade_pinpointer",
"borg_upgrade_surgicalprocessor",
+ "borg_upgrade_surgicalomnitool",
)
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2000)
diff --git a/code/modules/shuttle/assault_pod.dm b/code/modules/shuttle/assault_pod.dm
index b628d7c5d84..d9a21cf5e23 100644
--- a/code/modules/shuttle/assault_pod.dm
+++ b/code/modules/shuttle/assault_pod.dm
@@ -28,6 +28,7 @@
var/width = 7
var/height = 7
var/lz_dir = 1
+ var/lzname = "assault_pod"
/obj/item/assault_pod/attack_self(mob/living/user)
@@ -45,8 +46,8 @@
return
var/turf/T = pick(turfs)
var/obj/docking_port/stationary/landing_zone = new /obj/docking_port/stationary(T)
- landing_zone.shuttle_id = "assault_pod([REF(src)])"
- landing_zone.port_destinations = "assault_pod([REF(src)])"
+ landing_zone.shuttle_id = "[lzname]([REF(src)])"
+ landing_zone.port_destinations = "[lzname]([REF(src)])"
landing_zone.name = "Landing Zone"
landing_zone.dwidth = dwidth
landing_zone.dheight = dheight
@@ -61,3 +62,23 @@
to_chat(user, span_notice("Landing zone set."))
qdel(src)
+
+/obj/item/assault_pod/medieval //for the medieval pirates
+ name = "Shuttle placement designator"
+ icon = 'icons/obj/scrolls.dmi'
+ icon_state = "blueprints"
+ inhand_icon_state = null
+ desc = "A map of the station used to select where you want to land your shuttle."
+ shuttle_id = "pirate"
+ dwidth = 1
+ dheight = 1
+ width = 15
+ height = 9
+ lzname = "pirate"
+
+/obj/item/assault_pod/medieval/Initialize(mapload)
+ . = ..()
+ var/counter = length(SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/computer/shuttle/pirate))
+ if(counter != 1)
+ shuttle_id = "[shuttle_id]_[counter]"
+ lzname = "[lzname] [counter]"
diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm
index a55bee71eb3..67f7a1b3588 100644
--- a/code/modules/shuttle/shuttle.dm
+++ b/code/modules/shuttle/shuttle.dm
@@ -6,8 +6,8 @@
//NORTH default dir
/obj/docking_port
invisibility = INVISIBILITY_ABSTRACT
- icon = 'icons/obj/devices/tracker.dmi'
- icon_state = "pinonfar"
+ icon = 'icons/effects/docking_ports.dmi'
+ icon_state = "static"
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
anchored = TRUE
@@ -436,7 +436,7 @@
/obj/docking_port/mobile
name = "shuttle"
- icon_state = "pinonclose"
+ icon_state = "mobile"
area_type = SHUTTLE_DEFAULT_SHUTTLE_AREA_TYPE
diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm
index abf3575f39e..83d3d08d0ba 100644
--- a/code/modules/surgery/bodyparts/_bodyparts.dm
+++ b/code/modules/surgery/bodyparts/_bodyparts.dm
@@ -165,8 +165,8 @@
/// Type of an attack from this limb does. Arms will do punches, Legs for kicks, and head for bites. (TO ADD: tactical chestbumps)
var/attack_type = BRUTE
- /// the verb used for an unarmed attack when using this limb, such as arm.unarmed_attack_verb = punch
- var/unarmed_attack_verb = "bump"
+ /// the verbs used for an unarmed attack when using this limb, such as arm.unarmed_attack_verbs = list("punch")
+ var/list/unarmed_attack_verbs = list("bump")
/// if we have a special attack verb for hitting someone who is grappled by us, it goes here.
var/grappled_attack_verb
/// what visual effect is used when this limb is used to strike someone.
diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm
index 711e21288dc..e2752827f65 100644
--- a/code/modules/surgery/bodyparts/head.dm
+++ b/code/modules/surgery/bodyparts/head.dm
@@ -17,7 +17,7 @@
scars_covered_by_clothes = FALSE
grind_results = null
is_dimorphic = TRUE
- unarmed_attack_verb = "bite"
+ unarmed_attack_verbs = list("bite", "chomp")
unarmed_attack_effect = ATTACK_EFFECT_BITE
unarmed_attack_sound = 'sound/weapons/bite.ogg'
unarmed_miss_sound = 'sound/weapons/bite.ogg'
diff --git a/code/modules/surgery/bodyparts/head_hair_and_lips.dm b/code/modules/surgery/bodyparts/head_hair_and_lips.dm
index fbe219ba01f..bfe70f0f574 100644
--- a/code/modules/surgery/bodyparts/head_hair_and_lips.dm
+++ b/code/modules/surgery/bodyparts/head_hair_and_lips.dm
@@ -9,25 +9,10 @@
hair_hidden = FALSE
facial_hair_hidden = FALSE
if(human_head_owner)
- if(human_head_owner.head)
- var/obj/item/hat = human_head_owner.head
- if(hat.flags_inv & HIDEHAIR)
+ for(var/obj/item/worn_item in human_head_owner.get_equipped_items())
+ if(worn_item.flags_inv & HIDEHAIR)
hair_hidden = TRUE
- if(hat.flags_inv & HIDEFACIALHAIR)
- facial_hair_hidden = TRUE
-
- if(human_head_owner.wear_mask)
- var/obj/item/mask = human_head_owner.wear_mask
- if(mask.flags_inv & HIDEHAIR)
- hair_hidden = TRUE
- if(mask.flags_inv & HIDEFACIALHAIR)
- facial_hair_hidden = TRUE
-
- if(human_head_owner.w_uniform)
- var/obj/item/item_uniform = human_head_owner.w_uniform
- if(item_uniform.flags_inv & HIDEHAIR)
- hair_hidden = TRUE
- if(item_uniform.flags_inv & HIDEFACIALHAIR)
+ if(worn_item.flags_inv & HIDEFACIALHAIR)
facial_hair_hidden = TRUE
//invisibility and husk stuff
if(HAS_TRAIT(human_head_owner, TRAIT_INVISIBLE_MAN) || HAS_TRAIT(human_head_owner, TRAIT_HUSK))
diff --git a/code/modules/surgery/bodyparts/parts.dm b/code/modules/surgery/bodyparts/parts.dm
index 22450ca793d..a5f605ed151 100644
--- a/code/modules/surgery/bodyparts/parts.dm
+++ b/code/modules/surgery/bodyparts/parts.dm
@@ -130,7 +130,7 @@
aux_layer = BODYPARTS_HIGH_LAYER
body_damage_coeff = LIMB_BODY_DAMAGE_COEFFICIENT_DEFAULT
can_be_disabled = TRUE
- unarmed_attack_verb = "punch" /// The classic punch, wonderfully classic and completely random
+ unarmed_attack_verbs = list("punch") /// The classic punch, wonderfully classic and completely random
grappled_attack_verb = "pummel"
unarmed_damage_low = 5
unarmed_damage_high = 10
@@ -391,7 +391,7 @@
can_be_disabled = TRUE
unarmed_attack_effect = ATTACK_EFFECT_KICK
body_zone = BODY_ZONE_L_LEG
- unarmed_attack_verb = "kick" // The lovely kick, typically only accessable by attacking a grouded foe. 1.5 times better than the punch.
+ unarmed_attack_verbs = list("kick") // The lovely kick, typically only accessable by attacking a grouded foe. 1.5 times better than the punch.
unarmed_damage_low = 7
unarmed_damage_high = 15
unarmed_effectiveness = 15
diff --git a/code/modules/surgery/bodyparts/species_parts/ethereal_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/ethereal_bodyparts.dm
index 3eeafa6f4e1..6607dbc5933 100644
--- a/code/modules/surgery/bodyparts/species_parts/ethereal_bodyparts.dm
+++ b/code/modules/surgery/bodyparts/species_parts/ethereal_bodyparts.dm
@@ -36,7 +36,7 @@
limb_id = SPECIES_ETHEREAL
dmg_overlay_type = null
attack_type = BURN //burn bish
- unarmed_attack_verb = "burn"
+ unarmed_attack_verbs = list("burn", "singe")
grappled_attack_verb = "scorch"
unarmed_attack_sound = 'sound/weapons/etherealhit.ogg'
unarmed_miss_sound = 'sound/weapons/etherealmiss.ogg'
@@ -54,7 +54,7 @@
limb_id = SPECIES_ETHEREAL
dmg_overlay_type = null
attack_type = BURN // bish buzz
- unarmed_attack_verb = "burn"
+ unarmed_attack_verbs = list("burn")
grappled_attack_verb = "scorch"
unarmed_attack_sound = 'sound/weapons/etherealhit.ogg'
unarmed_miss_sound = 'sound/weapons/etherealmiss.ogg'
diff --git a/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm
index f2064c5c26a..06db593bca9 100644
--- a/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm
+++ b/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm
@@ -16,7 +16,7 @@
/obj/item/bodypart/arm/left/lizard
icon_greyscale = 'icons/mob/human/species/lizard/bodyparts.dmi'
limb_id = SPECIES_LIZARD
- unarmed_attack_verb = "slash"
+ unarmed_attack_verbs = list("slash", "scratch", "claw")
grappled_attack_verb = "lacerate"
unarmed_attack_effect = ATTACK_EFFECT_CLAW
unarmed_attack_sound = 'sound/weapons/slash.ogg'
@@ -25,7 +25,7 @@
/obj/item/bodypart/arm/right/lizard
icon_greyscale = 'icons/mob/human/species/lizard/bodyparts.dmi'
limb_id = SPECIES_LIZARD
- unarmed_attack_verb = "slash"
+ unarmed_attack_verbs = list("slash", "scratch", "claw")
grappled_attack_verb = "lacerate"
unarmed_attack_effect = ATTACK_EFFECT_CLAW
unarmed_attack_sound = 'sound/weapons/slash.ogg'
diff --git a/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm
index 9cbb786d7e6..9327f468126 100644
--- a/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm
+++ b/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm
@@ -15,7 +15,7 @@
/obj/item/bodypart/arm/left/snail
limb_id = SPECIES_SNAIL
- unarmed_attack_verb = "slap"
+ unarmed_attack_verbs = list("slap")
unarmed_attack_effect = ATTACK_EFFECT_DISARM
unarmed_damage_low = 1
unarmed_damage_high = 2 //snails are soft and squishy
@@ -24,7 +24,7 @@
/obj/item/bodypart/arm/right/snail
limb_id = SPECIES_SNAIL
- unarmed_attack_verb = "slap"
+ unarmed_attack_verbs = list("slap")
unarmed_attack_effect = ATTACK_EFFECT_DISARM
unarmed_damage_low = 1
unarmed_damage_high = 2 //snails are soft and squishy
@@ -222,7 +222,7 @@
/obj/item/bodypart/arm/left/pod
limb_id = SPECIES_PODPERSON
- unarmed_attack_verb = "slash"
+ unarmed_attack_verbs = list("slash", "lash")
grappled_attack_verb = "lacerate"
unarmed_attack_effect = ATTACK_EFFECT_CLAW
unarmed_attack_sound = 'sound/weapons/slice.ogg'
@@ -231,7 +231,7 @@
/obj/item/bodypart/arm/right/pod
limb_id = SPECIES_PODPERSON
- unarmed_attack_verb = "slash"
+ unarmed_attack_verbs = list("slash", "lash")
grappled_attack_verb = "lacerate"
unarmed_attack_effect = ATTACK_EFFECT_CLAW
unarmed_attack_sound = 'sound/weapons/slice.ogg'
diff --git a/code/modules/surgery/bodyparts/species_parts/moth_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/moth_bodyparts.dm
index 25f9e719fda..b21f74805ae 100644
--- a/code/modules/surgery/bodyparts/species_parts/moth_bodyparts.dm
+++ b/code/modules/surgery/bodyparts/species_parts/moth_bodyparts.dm
@@ -26,7 +26,7 @@
icon_static = 'icons/mob/human/species/moth/bodyparts.dmi'
limb_id = SPECIES_MOTH
should_draw_greyscale = FALSE
- unarmed_attack_verb = "slash"
+ unarmed_attack_verbs = list("slash")
grappled_attack_verb = "lacerate"
unarmed_attack_effect = ATTACK_EFFECT_CLAW
unarmed_attack_sound = 'sound/weapons/slash.ogg'
@@ -38,7 +38,7 @@
icon_static = 'icons/mob/human/species/moth/bodyparts.dmi'
limb_id = SPECIES_MOTH
should_draw_greyscale = FALSE
- unarmed_attack_verb = "slash"
+ unarmed_attack_verbs = list("slash")
grappled_attack_verb = "lacerate"
unarmed_attack_effect = ATTACK_EFFECT_CLAW
unarmed_attack_sound = 'sound/weapons/slash.ogg'
diff --git a/code/modules/surgery/bone_mending.dm b/code/modules/surgery/bone_mending.dm
index 87fc3db0af2..ae4ef6e4330 100644
--- a/code/modules/surgery/bone_mending.dm
+++ b/code/modules/surgery/bone_mending.dm
@@ -48,7 +48,7 @@
/datum/surgery_step/repair_bone_hairline
name = "repair hairline fracture (bonesetter/bone gel/tape)"
implements = list(
- /obj/item/bonesetter = 100,
+ TOOL_BONESET = 100,
/obj/item/stack/medical/bone_gel = 100,
/obj/item/stack/sticky_tape/surgical = 100,
/obj/item/stack/sticky_tape/super = 50,
@@ -98,7 +98,7 @@
/datum/surgery_step/reset_compound_fracture
name = "reset bone (bonesetter)"
implements = list(
- /obj/item/bonesetter = 100,
+ TOOL_BONESET = 100,
/obj/item/stack/sticky_tape/surgical = 60,
/obj/item/stack/sticky_tape/super = 40,
/obj/item/stack/sticky_tape = 20)
diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm
index c2c23e9adad..2199e426440 100644
--- a/code/modules/surgery/surgery_step.dm
+++ b/code/modules/surgery/surgery_step.dm
@@ -114,6 +114,9 @@
fail_prob = min(max(0, modded_time - (time * SURGERY_SLOWDOWN_CAP_MULTIPLIER)),99)//if modded_time > time * modifier, then fail_prob = modded_time - time*modifier. starts at 0, caps at 99
modded_time = min(modded_time, time * SURGERY_SLOWDOWN_CAP_MULTIPLIER)//also if that, then cap modded_time at time*modifier
+ if(iscyborg(user))//any immunities to surgery slowdown should go in this check.
+ modded_time = time * tool.toolspeed
+
var/was_sleeping = (target.stat != DEAD && target.IsSleeping())
// Skyrat Edit Addition - reward for doing surgery on calm patients, and for using surgery rooms(ie. surgerying alone)
@@ -129,10 +132,6 @@
modded_time *= SURGERY_SPEEDUP_AREA
to_chat(user, span_notice("You are able to work faster due to the quiet environment!"))
// Skyrat Edit End
- // Skyrat Edit: Cyborgs are no longer immune to surgery speedups.
- //if(iscyborg(user))//any immunities to surgery slowdown should go in this check.
- //modded_time = time
- // Skyrat Edit End
if(do_after(user, modded_time, target = target, interaction_key = user.has_status_effect(/datum/status_effect/hippocratic_oath) ? target : DOAFTER_SOURCE_SURGERY)) //If we have the hippocratic oath, we can perform one surgery on each target, otherwise we can only do one surgery in total.
diff --git a/code/modules/tgui_input/list.dm b/code/modules/tgui_input/list.dm
index 174f16fc7b5..22c6d48edfc 100644
--- a/code/modules/tgui_input/list.dm
+++ b/code/modules/tgui_input/list.dm
@@ -111,7 +111,7 @@
/datum/tgui_list_input/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
- ui = new(user, src, "ListInputModal")
+ ui = new(user, src, "ListInputWindow")
ui.open()
/datum/tgui_list_input/ui_close(mob/user)
diff --git a/code/modules/unit_tests/lootpanel.dm b/code/modules/unit_tests/lootpanel.dm
index c0bec13288c..1903c22d546 100644
--- a/code/modules/unit_tests/lootpanel.dm
+++ b/code/modules/unit_tests/lootpanel.dm
@@ -21,7 +21,7 @@
TEST_ASSERT_EQUAL(length(panel.contents), 1, "Contents should update on searchobj deleted")
TEST_ASSERT_EQUAL(length(panel.to_image), 1, "to_image should update on searchobj deleted")
- var/obj/item/storage/toolbox/new_box = allocate(/obj/item/storage/toolbox, one_over)
+ allocate(/obj/item/storage/toolbox, one_over)
TEST_ASSERT_EQUAL(length(panel.contents), 1, "Contents shouldn't update, we're dumb")
TEST_ASSERT_EQUAL(length(panel.to_image), 1, "to_image shouldn't update, we're dumb")
@@ -32,3 +32,4 @@
TEST_ASSERT_EQUAL(length(panel.contents), 2, "Panel shouldnt dupe searchables if reopened")
mock_client.mob = null
+
diff --git a/code/modules/unit_tests/organ_set_bonus.dm b/code/modules/unit_tests/organ_set_bonus.dm
index b1a314ccda7..8e2c65270f7 100644
--- a/code/modules/unit_tests/organ_set_bonus.dm
+++ b/code/modules/unit_tests/organ_set_bonus.dm
@@ -22,7 +22,7 @@
/datum/infuser_entry/fly,
))
// Fetch the globally instantiated DNA Infuser entries.
- for(var/datum/infuser_entry/infuser_entry as anything in GLOB.infuser_entries)
+ for(var/datum/infuser_entry/infuser_entry as anything in flatten_list(GLOB.infuser_entries))
var/output_organs = infuser_entry.output_organs
var/mob/living/carbon/human/lab_rat = allocate(/mob/living/carbon/human/consistent)
lab_rat.dna.mutant_bodyparts["moth_antennae"] = list(MUTANT_INDEX_NAME = "Plain", MUTANT_INDEX_COLOR_LIST = list("#FFFFFF"), MUTANT_INDEX_EMISSIVE_LIST = list(FALSE)) // SKYRAT EDIT - Customization
diff --git a/code/modules/unit_tests/screenshots/screenshot_antag_icons_obsessed.png b/code/modules/unit_tests/screenshots/screenshot_antag_icons_obsessed.png
index c8aaa0a7120..2c100632d34 100644
Binary files a/code/modules/unit_tests/screenshots/screenshot_antag_icons_obsessed.png and b/code/modules/unit_tests/screenshots/screenshot_antag_icons_obsessed.png differ
diff --git a/code/modules/vehicles/mecha/_mecha.dm b/code/modules/vehicles/mecha/_mecha.dm
index 995764e0bb7..ca1728f3fc0 100644
--- a/code/modules/vehicles/mecha/_mecha.dm
+++ b/code/modules/vehicles/mecha/_mecha.dm
@@ -36,11 +36,11 @@
hud_possible = list(DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_TRACK_HUD, DIAG_CAMERA_HUD)
mouse_pointer = 'icons/effects/mouse_pointers/mecha_mouse.dmi'
///How much energy the mech will consume each time it moves. this is the current active energy consumed
- var/step_energy_drain = 8 KILO JOULES
+ var/step_energy_drain = 0.008 * STANDARD_CELL_CHARGE
///How much energy we drain each time we mechpunch someone
- var/melee_energy_drain = 15 KILO JOULES
+ var/melee_energy_drain = 0.015 * STANDARD_CELL_CHARGE
///Power we use to have the lights on
- var/light_power_drain = 2 KILO WATTS
+ var/light_power_drain = 0.002 * STANDARD_CELL_RATE
///Modifiers for directional damage reduction
var/list/facing_modifiers = list(MECHA_FRONT_ARMOUR = 0.5, MECHA_SIDE_ARMOUR = 1, MECHA_BACK_ARMOUR = 1.5)
///if we cant use our equipment(such as due to EMP)
@@ -274,7 +274,7 @@
/// and gets deleted with the mech. However, they do remain in .contents
var/list/potential_occupants = contents | occupants
for(var/mob/buggy_ejectee in potential_occupants)
- mob_exit(buggy_ejectee, silent = TRUE)
+ mob_exit(buggy_ejectee, silent = TRUE, forced = TRUE)
if(LAZYLEN(flat_equipment))
for(var/obj/item/mecha_parts/mecha_equipment/equip as anything in flat_equipment)
@@ -328,7 +328,7 @@
for(var/mob/living/occupant as anything in occupants)
if(isAI(occupant))
var/mob/living/silicon/ai/ai = occupant
- if(!ai.linked_core) // we probably shouldnt gib AIs with a core
+ if(!ai.linked_core && !ai.can_shunt) // we probably shouldnt gib AIs with a core or shunting abilities
unlucky_ai = occupant
ai.investigate_log("has been gibbed by having their mech destroyed.", INVESTIGATE_DEATHS)
ai.gib(DROP_ALL_REMAINS) //No wreck, no AI to recover
@@ -707,6 +707,26 @@
target.mech_melee_attack(src, user)
TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MELEE_ATTACK, melee_cooldown)
+
+/// Driver alt clicks anything while in mech
+/obj/vehicle/sealed/mecha/proc/on_click_alt(mob/user, atom/target, params)
+ SIGNAL_HANDLER
+
+ . = COMSIG_MOB_CANCEL_CLICKON // Cancel base_click_alt
+
+ if(target != src)
+ return
+
+ if(!(user in occupants))
+ return
+
+ if(!(user in return_controllers_with_flag(VEHICLE_CONTROL_DRIVE)))
+ to_chat(user, span_warning("You're in the wrong seat to control movement."))
+ return
+
+ toggle_strafe()
+
+
/// middle mouse click signal wrapper for AI users
/obj/vehicle/sealed/mecha/proc/on_middlemouseclick(mob/user, atom/target, params)
SIGNAL_HANDLER
diff --git a/code/modules/vehicles/mecha/equipment/tools/mining_tools.dm b/code/modules/vehicles/mecha/equipment/tools/mining_tools.dm
index 25fd2879a6b..8343dc85a54 100644
--- a/code/modules/vehicles/mecha/equipment/tools/mining_tools.dm
+++ b/code/modules/vehicles/mecha/equipment/tools/mining_tools.dm
@@ -10,7 +10,7 @@
desc = "Equipment for engineering and combat exosuits. This is the drill that'll pierce the heavens!"
icon_state = "mecha_drill"
equip_cooldown = 15
- energy_drain = 10 KILO JOULES
+ energy_drain = 0.01 * STANDARD_CELL_CHARGE
force = 15
harmful = TRUE
range = MECHA_MELEE
diff --git a/code/modules/vehicles/mecha/equipment/tools/other_tools.dm b/code/modules/vehicles/mecha/equipment/tools/other_tools.dm
index 067ad2250f0..61853ef1cdc 100644
--- a/code/modules/vehicles/mecha/equipment/tools/other_tools.dm
+++ b/code/modules/vehicles/mecha/equipment/tools/other_tools.dm
@@ -9,7 +9,7 @@
desc = "An exosuit module that allows exosuits to teleport to any position in view."
icon_state = "mecha_teleport"
equip_cooldown = 150
- energy_drain = 1 MEGA JOULES
+ energy_drain = STANDARD_CELL_CHARGE
range = MECHA_RANGED
var/teleport_range = 7
@@ -129,7 +129,7 @@
/obj/item/mecha_parts/mecha_equipment/gravcatapult/proc/do_scatter(atom/movable/scatter, atom/movable/target)
var/dist = 5 - get_dist(scatter, target)
var/delay = 2
- SSmove_manager.move_away(scatter, target, delay = delay, timeout = delay * dist, flags = MOVEMENT_LOOP_START_FAST, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
+ DSmove_manager.move_away(scatter, target, delay = delay, timeout = delay * dist, flags = MOVEMENT_LOOP_START_FAST, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
/obj/item/mecha_parts/mecha_equipment/gravcatapult/get_snowflake_data()
return list(
@@ -285,7 +285,7 @@
///Maximum fuel capacity of the generator, in units
var/max_fuel = 75 * SHEET_MATERIAL_AMOUNT
///Energy recharged per second
- var/rechargerate = 5 KILO WATTS
+ var/rechargerate = 0.005 * STANDARD_CELL_RATE
/obj/item/mecha_parts/mecha_equipment/generator/Initialize(mapload)
. = ..()
diff --git a/code/modules/vehicles/mecha/equipment/tools/work_tools.dm b/code/modules/vehicles/mecha/equipment/tools/work_tools.dm
index e04a40b05f6..c10df9a139c 100644
--- a/code/modules/vehicles/mecha/equipment/tools/work_tools.dm
+++ b/code/modules/vehicles/mecha/equipment/tools/work_tools.dm
@@ -7,7 +7,7 @@
desc = "Equipment for engineering exosuits. Lifts objects and loads them into cargo."
icon_state = "mecha_clamp"
equip_cooldown = 15
- energy_drain = 10 KILO JOULES
+ energy_drain = 0.01 * STANDARD_CELL_CHARGE
tool_behaviour = TOOL_RETRACTOR
range = MECHA_MELEE
toolspeed = 0.8
diff --git a/code/modules/vehicles/mecha/mech_bay.dm b/code/modules/vehicles/mecha/mech_bay.dm
index 1f468565625..1a6ce31e284 100644
--- a/code/modules/vehicles/mecha/mech_bay.dm
+++ b/code/modules/vehicles/mecha/mech_bay.dm
@@ -12,7 +12,7 @@
///Ref to charge console for seeing charge for this port, cyclical reference
var/obj/machinery/computer/mech_bay_power_console/recharge_console
///Power unit per second to charge by
- var/recharge_power = 25 KILO WATTS
+ var/recharge_power = 0.025 * STANDARD_CELL_RATE
///turf that will be checked when a mech wants to charge. directly one turf in the direction it is facing
var/turf/recharging_turf
@@ -46,7 +46,7 @@
var/total_rating = 0
for(var/datum/stock_part/capacitor/capacitor in component_parts)
total_rating += capacitor.tier
- recharge_power = total_rating * 12.5 KILO WATTS
+ recharge_power = total_rating * 0.0125 * STANDARD_CELL_RATE
/obj/machinery/mech_bay_recharge_port/examine(mob/user)
. = ..()
@@ -65,7 +65,7 @@
if(!recharging_mech?.cell)
return
if(recharging_mech.cell.charge < recharging_mech.cell.maxcharge)
- if(!use_energy(active_power_usage * seconds_per_tick))
+ if(!use_energy(active_power_usage * seconds_per_tick, force = FALSE))
return
charge_cell(recharge_power * seconds_per_tick, recharging_mech.cell, grid_only = TRUE)
else
diff --git a/code/modules/vehicles/mecha/mecha_actions.dm b/code/modules/vehicles/mecha/mecha_actions.dm
index d544c829667..322a1189053 100644
--- a/code/modules/vehicles/mecha/mecha_actions.dm
+++ b/code/modules/vehicles/mecha/mecha_actions.dm
@@ -91,15 +91,6 @@
chassis.toggle_strafe()
-/obj/vehicle/sealed/mecha/click_alt(mob/living/user)
- if(!(user in occupants))
- return CLICK_ACTION_BLOCKING
- if(!(user in return_controllers_with_flag(VEHICLE_CONTROL_DRIVE)))
- to_chat(user, span_warning("You're in the wrong seat to control movement."))
- return CLICK_ACTION_BLOCKING
-
- toggle_strafe()
- return CLICK_ACTION_SUCCESS
/obj/vehicle/sealed/mecha/proc/toggle_strafe()
if(!(mecha_flags & CAN_STRAFE))
@@ -108,7 +99,9 @@
strafe = !strafe
- to_chat(occupants, "strafing mode [strafe?"on":"off"].")
+ for(var/mob/occupant in occupants)
+ balloon_alert(occupant, "strafing [strafe?"on":"off"]")
+ occupant.playsound_local(src, 'sound/machines/terminal_eject.ogg', 50, TRUE)
log_message("Toggled strafing mode [strafe?"on":"off"].", LOG_MECHA)
for(var/occupant in occupants)
diff --git a/code/modules/vehicles/mecha/mecha_ai_interaction.dm b/code/modules/vehicles/mecha/mecha_ai_interaction.dm
index 9ae35d8ff4b..3a681cac97d 100644
--- a/code/modules/vehicles/mecha/mecha_ai_interaction.dm
+++ b/code/modules/vehicles/mecha/mecha_ai_interaction.dm
@@ -67,6 +67,7 @@
if(AI_MECH_HACK) //Called by AIs on the mech
AI.linked_core = new /obj/structure/ai_core/deactivated(AI.loc)
+ AI.linked_core.remote_ai = AI
if(AI.can_dominate_mechs && LAZYLEN(occupants)) //Oh, I am sorry, were you using that?
to_chat(AI, span_warning("Occupants detected! Forced ejection initiated!"))
to_chat(occupants, span_danger("You have been forcibly ejected!"))
@@ -101,6 +102,7 @@
AI.eyeobj?.RegisterSignal(src, COMSIG_MOVABLE_MOVED, TYPE_PROC_REF(/mob/camera/ai_eye, update_visibility))
AI.controlled_equipment = src
AI.remote_control = src
+ AI.ShutOffDoomsdayDevice()
to_chat(AI, AI.can_dominate_mechs ? span_greenannounce("Takeover of [name] complete! You are now loaded onto the onboard computer. Do not attempt to leave the station sector!") :\
span_notice("You have been uploaded to a mech's onboard computer."))
to_chat(AI, "Use Middle-Mouse or the action button in your HUD to toggle equipment safety. Clicks with safety enabled will pass AI commands. ")
diff --git a/code/modules/vehicles/mecha/mecha_mob_interaction.dm b/code/modules/vehicles/mecha/mecha_mob_interaction.dm
index 7accab008f1..e72d5505cb6 100644
--- a/code/modules/vehicles/mecha/mecha_mob_interaction.dm
+++ b/code/modules/vehicles/mecha/mecha_mob_interaction.dm
@@ -119,19 +119,29 @@
//stop listening to this signal, as the static update is now handled by the eyeobj's setLoc
AI.eyeobj?.UnregisterSignal(src, COMSIG_MOVABLE_MOVED)
AI.eyeobj?.forceMove(newloc) //kick the eye out as well
- if(forced)//This should only happen if there are multiple AIs in a round, and at least one is Malf.
+ if(forced)
+ AI.controlled_equipment = null
+ AI.remote_control = null
if(!AI.linked_core) //if the victim AI has no core
- AI.investigate_log("has been gibbed by being forced out of their mech by another AI.", INVESTIGATE_DEATHS)
- AI.gib(DROP_ALL_REMAINS) //If one Malf decides to steal a mech from another AI (even other Malfs!), they are destroyed, as they have nowhere to go when replaced.
- AI = null
- mecha_flags &= ~SILICON_PILOT
- return
+ if (!AI.can_shunt || !length(AI.hacked_apcs))
+ AI.investigate_log("has been gibbed by being forced out of their mech.", INVESTIGATE_DEATHS)
+ /// If an AI with no core (and no shunting abilities) gets forced out of their mech
+ /// (in a way that isn't handled by the normal handling of their mech being destroyed)
+ /// we gib 'em here, too.
+ AI.gib(DROP_ALL_REMAINS)
+ AI = null
+ mecha_flags &= ~SILICON_PILOT
+ return
+ else
+ var/obj/machinery/power/apc/emergency_shunt_apc = pick(AI.hacked_apcs)
+ emergency_shunt_apc.malfoccupy(AI) //get shunted into a random APC (you don't get to choose which)
+ AI = null
+ mecha_flags &= ~SILICON_PILOT
+ return
+ newloc = get_turf(AI.linked_core)
+ qdel(AI.linked_core)
+ AI.forceMove(newloc)
else
- if(!AI.linked_core)
- if(!silent)
- to_chat(AI, span_userdanger("Inactive core destroyed. Unable to return."))
- AI.linked_core = null
- return
if(!silent)
to_chat(AI, span_notice("Returning to core..."))
AI.controlled_equipment = null
@@ -139,6 +149,7 @@
mob_container = AI
newloc = get_turf(AI.linked_core)
qdel(AI.linked_core)
+ AI.forceMove(newloc)
else if(isliving(M))
mob_container = M
else
@@ -159,24 +170,26 @@
setDir(SOUTH)
return ..()
-/obj/vehicle/sealed/mecha/add_occupant(mob/M, control_flags)
- RegisterSignal(M, COMSIG_MOB_CLICKON, PROC_REF(on_mouseclick), TRUE)
- RegisterSignal(M, COMSIG_MOB_SAY, PROC_REF(display_speech_bubble), TRUE)
- RegisterSignal(M, COMSIG_MOVABLE_KEYBIND_FACE_DIR, PROC_REF(on_turn), TRUE)
+/obj/vehicle/sealed/mecha/add_occupant(mob/driver, control_flags)
+ RegisterSignal(driver, COMSIG_MOB_CLICKON, PROC_REF(on_mouseclick), TRUE)
+ RegisterSignal(driver, COMSIG_MOB_SAY, PROC_REF(display_speech_bubble), TRUE)
+ RegisterSignal(driver, COMSIG_MOVABLE_KEYBIND_FACE_DIR, PROC_REF(on_turn), TRUE)
+ RegisterSignal(driver, COMSIG_MOB_ALTCLICKON, PROC_REF(on_click_alt))
. = ..()
update_appearance()
-/obj/vehicle/sealed/mecha/remove_occupant(mob/M)
- UnregisterSignal(M, list(
+/obj/vehicle/sealed/mecha/remove_occupant(mob/driver)
+ UnregisterSignal(driver, list(
COMSIG_MOB_CLICKON,
COMSIG_MOB_SAY,
COMSIG_MOVABLE_KEYBIND_FACE_DIR,
+ COMSIG_MOB_ALTCLICKON,
))
- M.clear_alert(ALERT_CHARGE)
- M.clear_alert(ALERT_MECH_DAMAGE)
- if(M.client)
- M.update_mouse_pointer()
- M.client.view_size.resetToDefault()
+ driver.clear_alert(ALERT_CHARGE)
+ driver.clear_alert(ALERT_MECH_DAMAGE)
+ if(driver.client)
+ driver.update_mouse_pointer()
+ driver.client.view_size.resetToDefault()
zoom_mode = FALSE
. = ..()
update_appearance()
@@ -184,9 +197,20 @@
/obj/vehicle/sealed/mecha/container_resist_act(mob/living/user)
if(isAI(user))
var/mob/living/silicon/ai/AI = user
- if(!AI.can_shunt)
- to_chat(AI, span_notice("You can't leave a mech after dominating it!."))
- return FALSE
+ if(!AI.linked_core)
+ to_chat(AI, span_userdanger("Inactive core destroyed. Unable to return."))
+ if(!AI.can_shunt || !AI.hacked_apcs.len)
+ to_chat(AI, span_warning("[AI.can_shunt ? "No hacked APCs available." : "No shunting capabilities."]"))
+ return
+ var/confirm = tgui_alert(AI, "Shunt to a random APC? You won't have anywhere else to go!", "Confirm Emergency Shunt", list("Yes", "No"))
+ if(confirm == "Yes")
+ /// Mechs with open cockpits can have the pilot shot by projectiles, or EMPs may destroy the AI inside
+ /// Alternatively, destroying the mech will shunt the AI if they can shunt, or a deadeye wizard can hit
+ /// them with a teleportation bolt
+ if (AI.stat == DEAD || AI.loc != src)
+ return
+ mob_exit(AI, forced = TRUE)
+ return
to_chat(user, span_notice("You begin the ejection procedure. Equipment is disabled during this process. Hold still to finish ejecting."))
is_currently_ejecting = TRUE
if(do_after(user, has_gravity() ? exit_delay : 0 , target = src))
diff --git a/code/modules/vehicles/motorized_wheelchair.dm b/code/modules/vehicles/motorized_wheelchair.dm
index 128530968e2..8dbdfd93e8f 100644
--- a/code/modules/vehicles/motorized_wheelchair.dm
+++ b/code/modules/vehicles/motorized_wheelchair.dm
@@ -10,7 +10,7 @@
///Self explanatory, ratio of how much power we use
var/power_efficiency = 1
///How much energy we use
- var/energy_usage = 100 KILO JOULES
+ var/energy_usage = 0.1 * STANDARD_CELL_CHARGE
///whether the panel is open so a user can take out the cell
var/panel_open = FALSE
///Parts used in building the wheelchair
diff --git a/code/modules/wiremod/shell/gun.dm b/code/modules/wiremod/shell/gun.dm
index ff581536713..9f196e6c1fc 100644
--- a/code/modules/wiremod/shell/gun.dm
+++ b/code/modules/wiremod/shell/gun.dm
@@ -82,6 +82,6 @@
if(!parent?.cell)
return
var/obj/item/gun/energy/fired_gun = source
- var/totransfer = min(100 KILO JOULES, parent.cell.charge)
- var/transferred = fired_gun.cell.give(totransfer)
- parent.cell.use(transferred)
+ var/transferred = fired_gun.cell.give(min(0.1 * STANDARD_CELL_CHARGE, parent.cell.charge))
+ if(transferred)
+ parent.cell.use(transferred, force = TRUE)
diff --git a/dependencies.sh b/dependencies.sh
index 300e2826c6f..e10d7ec4b47 100644
--- a/dependencies.sh
+++ b/dependencies.sh
@@ -28,7 +28,7 @@ export AUXLUA_REPO=tgstation/auxlua
export AUXLUA_VERSION=1.4.4
#hypnagogic repo
-export CUTTER_REPO=actioninja/hypnagogic
+export CUTTER_REPO=spacestation13/hypnagogic
#hypnagogic git tag
export CUTTER_VERSION=v3.0.1
diff --git a/html/changelogs/AutoChangeLog-pr-27165.yml b/html/changelogs/AutoChangeLog-pr-27165.yml
new file mode 100644
index 00000000000..6a1262bbb81
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-27165.yml
@@ -0,0 +1,4 @@
+author: "Erol509"
+delete-after: True
+changes:
+ - balance: "Nerfs powerator cash generation"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-27275.yml b/html/changelogs/AutoChangeLog-pr-27275.yml
new file mode 100644
index 00000000000..d6e601d22ec
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-27275.yml
@@ -0,0 +1,7 @@
+author: "Majkl-J"
+delete-after: True
+changes:
+ - qol: "Debloated the service borg module count"
+ - balance: "Moved service borg art and music supplies to the new artistic module"
+ - bugfix: "Fixed the dual cooking tools on service borgs, opting to keep tg ones."
+ - spellcheck: "Fixed lowercase on a few borg module recipes"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-27479.yml b/html/changelogs/AutoChangeLog-pr-27479.yml
new file mode 100644
index 00000000000..8a9a52b615e
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-27479.yml
@@ -0,0 +1,4 @@
+author: "aKromatopzia"
+delete-after: True
+changes:
+ - rscadd: "teshari move speed change applies to raptor cybernetics"
\ No newline at end of file
diff --git a/html/changelogs/AutoChangeLog-pr-27512.yml b/html/changelogs/AutoChangeLog-pr-27512.yml
new file mode 100644
index 00000000000..4fde53b2a2d
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-27512.yml
@@ -0,0 +1,5 @@
+author: "tmyqlfpir"
+delete-after: True
+changes:
+ - bugfix: "Automatically link machines to closest research server for off-station z levels (fixes Tarkon/DS-2 machines linking to wrong R&D server)"
+ - qol: "Wrench down research console on DS-2"
\ No newline at end of file
diff --git a/html/changelogs/archive/2024-04.yml b/html/changelogs/archive/2024-04.yml
index 8848d3ef356..6b3ae925c2a 100644
--- a/html/changelogs/archive/2024-04.yml
+++ b/html/changelogs/archive/2024-04.yml
@@ -518,3 +518,43 @@
- bugfix: Hardlight wheelchair no longer drops metal when deconstructed
VexingRaven:
- bugfix: The debug box no longer spills its contents everywhere
+2024-04-30:
+ LT3:
+ - bugfix: Skyrat specific crew monitors work properly
+ Majkl-J:
+ - code_imp: Further cleared out MCR defines
+ Melbert:
+ - bugfix: Midround malf can roll again
+ - bugfix: You can handcuff people with 2 arms and you can no longer handcuff people
+ with 0 arms
+ Rhials:
+ - bugfix: Overwatch Intelligence Agents no longer get their own uplinks, leading
+ to a self-replicating grey goo scenario.
+ - admin: Lazy loading map templates now gives you the option to not ghost/teleport
+ to the loaded area upon completion.
+ - bugfix: Fake handcuffs/Zipties no longer block clicks for a few seconds after
+ being resisted out of.
+ SkyratBot:
+ - bugfix: minebot shields are now actually orderable
+ - bugfix: vinegar may once again be crafted with wine, water, and sugar
+ - rscadd: Added a short scene when getting an Ordeal of Sisyphus achievement.
+ - bugfix: All alert polls ignore option works
+ - bugfix: Mech domination now properly integrates with shunting.
+ - bugfix: Combat upgraded AIs no longer get two buggy malf ability pickers if they
+ also become malfunctioning
+ - refactor: Refactored most of the functionality around malf AI shunting, mech control
+ - bugfix: The start-of-the-round tips will no longer feature virologists, but will,
+ however, start featuring heretics and coroners.
+ - admin: Possess Object is now back in the right-click context menu.
+ - balance: Netguardian Prime can see in the dark.
+ - image: You can see Netguardian Prime in the dark.
+ - bugfix: fixes mobs getting stuck trying to reach something unreachable
+ - bugfix: Examining someone with Med/Sec HUDs will no longer filter the message
+ under Radio.
+ - bugfix: CentCom dispatched a team of interns to fix the loot panel's loading message.
+ It should now load properly. It did before too, but now the message is fixed.
+ - image: The Infiltrator Suit has received a new model, sleeker than ever!
+ - admin: spy can now be rolebanned
+ - bugfix: pAI requests should no longer randomly permanently break in a round.
+ scabs3:
+ - rscadd: Added new lines and responses to the 'dark and brooding lizard plushie'
diff --git a/icons/effects/docking_ports.dmi b/icons/effects/docking_ports.dmi
new file mode 100644
index 00000000000..96909d7bd0f
Binary files /dev/null and b/icons/effects/docking_ports.dmi differ
diff --git a/icons/effects/vent_overlays.dmi b/icons/effects/vent_overlays.dmi
index 54ac3d7a819..375117f4c79 100644
Binary files a/icons/effects/vent_overlays.dmi and b/icons/effects/vent_overlays.dmi differ
diff --git a/icons/mob/clothing/back.dmi b/icons/mob/clothing/back.dmi
index 1b597f0d33d..30469c85dae 100644
Binary files a/icons/mob/clothing/back.dmi and b/icons/mob/clothing/back.dmi differ
diff --git a/icons/mob/clothing/belt.dmi b/icons/mob/clothing/belt.dmi
index 65ec3828d42..b0e74178ce1 100644
Binary files a/icons/mob/clothing/belt.dmi and b/icons/mob/clothing/belt.dmi differ
diff --git a/icons/mob/clothing/belt_mirror.dmi b/icons/mob/clothing/belt_mirror.dmi
index 4f7f64db8c6..37658b154db 100644
Binary files a/icons/mob/clothing/belt_mirror.dmi and b/icons/mob/clothing/belt_mirror.dmi differ
diff --git a/icons/mob/clothing/hands.dmi b/icons/mob/clothing/hands.dmi
index d0e5093d459..a670c33b7dc 100644
Binary files a/icons/mob/clothing/hands.dmi and b/icons/mob/clothing/hands.dmi differ
diff --git a/icons/mob/clothing/head/helmet.dmi b/icons/mob/clothing/head/helmet.dmi
index 317edb56796..74df620a572 100644
Binary files a/icons/mob/clothing/head/helmet.dmi and b/icons/mob/clothing/head/helmet.dmi differ
diff --git a/icons/mob/clothing/modsuit/mod_clothing.dmi b/icons/mob/clothing/modsuit/mod_clothing.dmi
index 793c14ce115..613559b726a 100644
Binary files a/icons/mob/clothing/modsuit/mod_clothing.dmi and b/icons/mob/clothing/modsuit/mod_clothing.dmi differ
diff --git a/icons/mob/clothing/suits/armor.dmi b/icons/mob/clothing/suits/armor.dmi
index 90be12b694a..3f51d089d9b 100644
Binary files a/icons/mob/clothing/suits/armor.dmi and b/icons/mob/clothing/suits/armor.dmi differ
diff --git a/icons/mob/clothing/under/costume.dmi b/icons/mob/clothing/under/costume.dmi
index a3b6c7e5050..34703c07058 100644
Binary files a/icons/mob/clothing/under/costume.dmi and b/icons/mob/clothing/under/costume.dmi differ
diff --git a/icons/mob/inhands/equipment/shields_lefthand.dmi b/icons/mob/inhands/equipment/shields_lefthand.dmi
index ce99a16d476..1aa27021b9e 100644
Binary files a/icons/mob/inhands/equipment/shields_lefthand.dmi and b/icons/mob/inhands/equipment/shields_lefthand.dmi differ
diff --git a/icons/mob/inhands/equipment/shields_righthand.dmi b/icons/mob/inhands/equipment/shields_righthand.dmi
index 1c9c990b43d..4227ba00792 100644
Binary files a/icons/mob/inhands/equipment/shields_righthand.dmi and b/icons/mob/inhands/equipment/shields_righthand.dmi differ
diff --git a/icons/mob/inhands/weapons/axes_lefthand.dmi b/icons/mob/inhands/weapons/axes_lefthand.dmi
index 7a0f4fdd592..8352626ce27 100644
Binary files a/icons/mob/inhands/weapons/axes_lefthand.dmi and b/icons/mob/inhands/weapons/axes_lefthand.dmi differ
diff --git a/icons/mob/inhands/weapons/axes_righthand.dmi b/icons/mob/inhands/weapons/axes_righthand.dmi
index 42cb6350746..7c026e12b66 100644
Binary files a/icons/mob/inhands/weapons/axes_righthand.dmi and b/icons/mob/inhands/weapons/axes_righthand.dmi differ
diff --git a/icons/mob/inhands/weapons/polearms_lefthand.dmi b/icons/mob/inhands/weapons/polearms_lefthand.dmi
index f9b43790df7..a1355ed9c40 100644
Binary files a/icons/mob/inhands/weapons/polearms_lefthand.dmi and b/icons/mob/inhands/weapons/polearms_lefthand.dmi differ
diff --git a/icons/mob/inhands/weapons/polearms_righthand.dmi b/icons/mob/inhands/weapons/polearms_righthand.dmi
index 9f7e6239895..05665fbaf95 100644
Binary files a/icons/mob/inhands/weapons/polearms_righthand.dmi and b/icons/mob/inhands/weapons/polearms_righthand.dmi differ
diff --git a/icons/mob/inhands/weapons/swords_lefthand.dmi b/icons/mob/inhands/weapons/swords_lefthand.dmi
index e0a33fbcee3..6a0520ac9da 100644
Binary files a/icons/mob/inhands/weapons/swords_lefthand.dmi and b/icons/mob/inhands/weapons/swords_lefthand.dmi differ
diff --git a/icons/mob/inhands/weapons/swords_righthand.dmi b/icons/mob/inhands/weapons/swords_righthand.dmi
index fcdac64bdca..29db3057a2a 100644
Binary files a/icons/mob/inhands/weapons/swords_righthand.dmi and b/icons/mob/inhands/weapons/swords_righthand.dmi differ
diff --git a/icons/mob/nonhuman-player/netguardian.dmi b/icons/mob/nonhuman-player/netguardian.dmi
index 057e7a066c2..c788c76772b 100644
Binary files a/icons/mob/nonhuman-player/netguardian.dmi and b/icons/mob/nonhuman-player/netguardian.dmi differ
diff --git a/icons/mob/silicon/robot_items.dmi b/icons/mob/silicon/robot_items.dmi
index e18a9d08f86..5ad091d6c9f 100644
Binary files a/icons/mob/silicon/robot_items.dmi and b/icons/mob/silicon/robot_items.dmi differ
diff --git a/icons/obj/clothing/gloves.dmi b/icons/obj/clothing/gloves.dmi
index d8a2fc0bd13..d5099c64e7f 100644
Binary files a/icons/obj/clothing/gloves.dmi and b/icons/obj/clothing/gloves.dmi differ
diff --git a/icons/obj/clothing/head/helmet.dmi b/icons/obj/clothing/head/helmet.dmi
index 3bea00dcdc3..02281abe6a3 100644
Binary files a/icons/obj/clothing/head/helmet.dmi and b/icons/obj/clothing/head/helmet.dmi differ
diff --git a/icons/obj/clothing/modsuit/mod_clothing.dmi b/icons/obj/clothing/modsuit/mod_clothing.dmi
index 5070dbb145c..3de713477b6 100644
Binary files a/icons/obj/clothing/modsuit/mod_clothing.dmi and b/icons/obj/clothing/modsuit/mod_clothing.dmi differ
diff --git a/icons/obj/clothing/suits/armor.dmi b/icons/obj/clothing/suits/armor.dmi
index 4fb7248dbd8..480d6d9102c 100644
Binary files a/icons/obj/clothing/suits/armor.dmi and b/icons/obj/clothing/suits/armor.dmi differ
diff --git a/icons/obj/clothing/under/costume.dmi b/icons/obj/clothing/under/costume.dmi
index 90bdc205d52..85a49d1b330 100644
Binary files a/icons/obj/clothing/under/costume.dmi and b/icons/obj/clothing/under/costume.dmi differ
diff --git a/icons/obj/devices/tracker.dmi b/icons/obj/devices/tracker.dmi
index 0508fe816bc..59884c0aff8 100644
Binary files a/icons/obj/devices/tracker.dmi and b/icons/obj/devices/tracker.dmi differ
diff --git a/icons/obj/items_cyborg.dmi b/icons/obj/items_cyborg.dmi
index f43d9615313..39624fce676 100644
Binary files a/icons/obj/items_cyborg.dmi and b/icons/obj/items_cyborg.dmi differ
diff --git a/icons/obj/structures.dmi b/icons/obj/structures.dmi
index 1bb6689becf..cf6cdbdf0d8 100644
Binary files a/icons/obj/structures.dmi and b/icons/obj/structures.dmi differ
diff --git a/icons/obj/weapons/fireaxe.dmi b/icons/obj/weapons/fireaxe.dmi
index c89ea533cbe..a4743f680ad 100644
Binary files a/icons/obj/weapons/fireaxe.dmi and b/icons/obj/weapons/fireaxe.dmi differ
diff --git a/icons/obj/weapons/shields.dmi b/icons/obj/weapons/shields.dmi
index 7c4be107566..99e9b06aa40 100644
Binary files a/icons/obj/weapons/shields.dmi and b/icons/obj/weapons/shields.dmi differ
diff --git a/icons/obj/weapons/spear.dmi b/icons/obj/weapons/spear.dmi
index 7262da01c45..7c044d362a7 100644
Binary files a/icons/obj/weapons/spear.dmi and b/icons/obj/weapons/spear.dmi differ
diff --git a/icons/obj/weapons/sword.dmi b/icons/obj/weapons/sword.dmi
index 255c3b0cffd..5dca921bd5b 100644
Binary files a/icons/obj/weapons/sword.dmi and b/icons/obj/weapons/sword.dmi differ
diff --git a/modular_skyrat/master_files/code/controllers/subsystem/research.dm b/modular_skyrat/master_files/code/controllers/subsystem/research.dm
new file mode 100644
index 00000000000..e091808d826
--- /dev/null
+++ b/modular_skyrat/master_files/code/controllers/subsystem/research.dm
@@ -0,0 +1,20 @@
+/**
+ * Sorts the get_available_servers() returned list by closest server source location
+ * Returns the closest server found as a single entity list.
+ */
+/datum/controller/subsystem/research/get_available_servers(turf/location)
+ var/list/local_servers = ..()
+ if(local_servers && (length(local_servers) > 1) && !is_station_level(location.z)) /// If there was more than 1 valid server located off-station, find closest server
+ var/server_distance_closest = INFINITY
+ var/server_distance_current = INFINITY
+ var/obj/machinery/rnd/server/closest_server = local_servers[1]
+
+ for (var/obj/machinery/rnd/server/individual_server as anything in local_servers)
+ if(location.z != individual_server.z) /// Not on the same z level, skip
+ continue
+ server_distance_current = get_dist(location, get_turf(individual_server))
+ if(server_distance_closest > server_distance_current) /// This is closer than the last server we tested
+ server_distance_closest = server_distance_current
+ closest_server = individual_server
+ return list(closest_server)
+ return local_servers
diff --git a/modular_skyrat/master_files/code/datums/traits/good.dm b/modular_skyrat/master_files/code/datums/traits/good.dm
index 483e19630fd..e75fe5c568d 100644
--- a/modular_skyrat/master_files/code/datums/traits/good.dm
+++ b/modular_skyrat/master_files/code/datums/traits/good.dm
@@ -36,7 +36,7 @@
var/obj/item/bodypart/arm/left/left_arm = human_holder.get_bodypart(BODY_ZONE_L_ARM)
if(left_arm)
- left_arm.unarmed_attack_verb = "slash"
+ left_arm.unarmed_attack_verbs = list("slash")
left_arm.unarmed_attack_effect = ATTACK_EFFECT_CLAW
left_arm.unarmed_attack_sound = 'sound/weapons/slash.ogg'
left_arm.unarmed_miss_sound = 'sound/weapons/slashmiss.ogg'
@@ -44,7 +44,7 @@
var/obj/item/bodypart/arm/right/right_arm = human_holder.get_bodypart(BODY_ZONE_R_ARM)
if(right_arm)
- right_arm.unarmed_attack_verb = "slash"
+ right_arm.unarmed_attack_verbs = list("slash")
right_arm.unarmed_attack_effect = ATTACK_EFFECT_CLAW
right_arm.unarmed_attack_sound = 'sound/weapons/slash.ogg'
right_arm.unarmed_miss_sound = 'sound/weapons/slashmiss.ogg'
@@ -54,7 +54,7 @@
var/mob/living/carbon/human/human_holder = quirk_holder
var/obj/item/bodypart/arm/left/left_arm = human_holder.get_bodypart(BODY_ZONE_L_ARM)
if(left_arm)
- left_arm.unarmed_attack_verb = initial(left_arm.unarmed_attack_verb)
+ left_arm.unarmed_attack_verbs = initial(left_arm.unarmed_attack_verbs)
left_arm.unarmed_attack_effect = initial(left_arm.unarmed_attack_effect)
left_arm.unarmed_attack_sound = initial(left_arm.unarmed_attack_sound)
left_arm.unarmed_miss_sound = initial(left_arm.unarmed_miss_sound)
@@ -62,7 +62,7 @@
var/obj/item/bodypart/arm/right/right_arm = human_holder.get_bodypart(BODY_ZONE_R_ARM)
if(right_arm)
- right_arm.unarmed_attack_verb = initial(right_arm.unarmed_attack_verb)
+ right_arm.unarmed_attack_verbs = initial(right_arm.unarmed_attack_verbs)
right_arm.unarmed_attack_effect = initial(right_arm.unarmed_attack_effect)
right_arm.unarmed_attack_sound = initial(right_arm.unarmed_attack_sound)
right_arm.unarmed_miss_sound = initial(right_arm.unarmed_miss_sound)
diff --git a/modular_skyrat/master_files/code/modules/antagonists/pirate/pirate_outfits.dm b/modular_skyrat/master_files/code/modules/antagonists/pirate/pirate_outfits.dm
index 95d1e38dae6..5899a5948a0 100644
--- a/modular_skyrat/master_files/code/modules/antagonists/pirate/pirate_outfits.dm
+++ b/modular_skyrat/master_files/code/modules/antagonists/pirate/pirate_outfits.dm
@@ -7,3 +7,6 @@
/datum/outfit/pirate/irs
back = /obj/item/storage/backpack/satchel/leather
+
+/datum/outfit/pirate/medieval/warlord
+ backpack_contents = null
diff --git a/modular_skyrat/master_files/code/modules/clothing/head/_head.dm b/modular_skyrat/master_files/code/modules/clothing/head/_head.dm
index 970d1ec8caf..8351337d602 100644
--- a/modular_skyrat/master_files/code/modules/clothing/head/_head.dm
+++ b/modular_skyrat/master_files/code/modules/clothing/head/_head.dm
@@ -8,7 +8,7 @@
return
if(slot & ITEM_SLOT_HEAD)
if(user.ears && (flags_inv & HIDEEARS))
- user.update_inv_ears()
+ user.update_worn_ears()
if(!(user.bodyshape & BODYSHAPE_ALT_FACEWEAR_LAYER))
return
if(!isnull(alternate_worn_layer) && alternate_worn_layer < BODY_FRONT_LAYER) // if the alternate worn layer was already lower than snouts then leave it be
@@ -27,7 +27,7 @@
/obj/item/clothing/head/proc/update_on_removed(mob/living/carbon/user, obj/item/hat)
SIGNAL_HANDLER
if(istype(user) && user.ears)
- user.update_inv_ears()
+ user.update_worn_ears()
UnregisterSignal(user, COMSIG_CARBON_UNEQUIP_HAT)
/obj/item/clothing/head/bio_hood
diff --git a/modular_skyrat/master_files/code/modules/clothing/head/hardhat.dm b/modular_skyrat/master_files/code/modules/clothing/head/hardhat.dm
new file mode 100644
index 00000000000..d43fddb414d
--- /dev/null
+++ b/modular_skyrat/master_files/code/modules/clothing/head/hardhat.dm
@@ -0,0 +1,12 @@
+/obj/item/clothing/head/utility/hardhat/welding
+ /// The path to the visor sprite, used for muzzled visors
+ var/visor_sprite_path
+
+// Lets the visor not smush the snout
+/obj/item/clothing/head/utility/hardhat/welding/adjust_visor(mob/living/user)
+ . = ..()
+ var/mob/living/carbon/carbon_user = user
+ if(carbon_user.dna.species.mutant_bodyparts["snout"])
+ visor_sprite_path = 'modular_skyrat/master_files/icons/mob/clothing/head_muzzled.dmi'
+ else
+ visor_sprite_path = 'icons/mob/clothing/head/utility.dmi'
diff --git a/modular_skyrat/master_files/code/modules/research/techweb/all_nodes.dm b/modular_skyrat/master_files/code/modules/research/techweb/all_nodes.dm
index 395a0263bc3..b94791a89e3 100644
--- a/modular_skyrat/master_files/code/modules/research/techweb/all_nodes.dm
+++ b/modular_skyrat/master_files/code/modules/research/techweb/all_nodes.dm
@@ -252,6 +252,12 @@
)
return ..() */ //BUBBERSTATION REMOVAL
+/datum/techweb_node/cyborg_upg_serv/New()
+ design_ids += list(
+ "borg_upgrade_artistic"
+ )
+ return ..()
+
/datum/techweb_node/basic_mining/New()
design_ids += list(
"borg_upgrade_welding",
diff --git a/modular_skyrat/modules/ammo_workbench/code/ammo_workbench.dm b/modular_skyrat/modules/ammo_workbench/code/ammo_workbench.dm
index 64e199150f2..e7e760a6f27 100644
--- a/modular_skyrat/modules/ammo_workbench/code/ammo_workbench.dm
+++ b/modular_skyrat/modules/ammo_workbench/code/ammo_workbench.dm
@@ -68,7 +68,7 @@
/obj/machinery/ammo_workbench/Initialize(mapload)
AddComponent( \
/datum/component/material_container, \
- SSmaterials.materials_by_category[MAT_CATEGORY_ITEM_MATERIAL], \
+ DSmaterials.materials_by_category[MAT_CATEGORY_ITEM_MATERIAL], \
200000, \
MATCONTAINER_EXAMINE, \
allowed_items = /obj/item/stack, \
diff --git a/modular_skyrat/modules/bodyparts/code/_mutant_bodyparts.dm b/modular_skyrat/modules/bodyparts/code/_mutant_bodyparts.dm
index 02a3248ef37..72af12346a5 100644
--- a/modular_skyrat/modules/bodyparts/code/_mutant_bodyparts.dm
+++ b/modular_skyrat/modules/bodyparts/code/_mutant_bodyparts.dm
@@ -34,7 +34,7 @@
/obj/item/bodypart/arm/left/mutant
icon_greyscale = BODYPART_ICON_MAMMAL
limb_id = SPECIES_MAMMAL
- unarmed_attack_verb = "slash"
+ unarmed_attack_verbs = list("slash")
unarmed_attack_effect = ATTACK_EFFECT_CLAW
unarmed_attack_sound = 'sound/weapons/slash.ogg'
unarmed_miss_sound = 'sound/weapons/slashmiss.ogg'
@@ -43,7 +43,7 @@
/obj/item/bodypart/arm/right/mutant
icon_greyscale = BODYPART_ICON_MAMMAL
limb_id = SPECIES_MAMMAL
- unarmed_attack_verb = "slash"
+ unarmed_attack_verbs = list("slash")
unarmed_attack_effect = ATTACK_EFFECT_CLAW
unarmed_attack_sound = 'sound/weapons/slash.ogg'
unarmed_miss_sound = 'sound/weapons/slashmiss.ogg'
diff --git a/modular_skyrat/modules/bodyparts/code/ghoul_bodyparts.dm b/modular_skyrat/modules/bodyparts/code/ghoul_bodyparts.dm
index d58e6cd0c83..0a9cc29aa76 100644
--- a/modular_skyrat/modules/bodyparts/code/ghoul_bodyparts.dm
+++ b/modular_skyrat/modules/bodyparts/code/ghoul_bodyparts.dm
@@ -59,7 +59,7 @@
limb_id = SPECIES_GHOUL
unarmed_damage_low = 1 //lowest possible punch damage. if this is set to 0, punches will always miss
unarmed_damage_high = 5 //highest possible punch damage
- unarmed_attack_verb = "punch"
+ unarmed_attack_verbs = list("punch")
unarmed_attack_effect = ATTACK_EFFECT_PUNCH
unarmed_attack_sound = 'sound/weapons/punch1.ogg'
unarmed_miss_sound = 'sound/weapons/punchmiss.ogg'
@@ -72,7 +72,7 @@
limb_id = SPECIES_GHOUL
unarmed_damage_low = 1 //lowest possible punch damage. if this is set to 0, punches will always miss
unarmed_damage_high = 5 //highest possible punch damage
- unarmed_attack_verb = "punch"
+ unarmed_attack_verbs = list("punch")
unarmed_attack_effect = ATTACK_EFFECT_PUNCH
unarmed_attack_sound = 'sound/weapons/punch1.ogg'
unarmed_miss_sound = 'sound/weapons/punchmiss.ogg'
diff --git a/modular_skyrat/modules/borg_buffs/code/robot.dm b/modular_skyrat/modules/borg_buffs/code/robot.dm
index e282c64be73..fdffd040e4e 100644
--- a/modular_skyrat/modules/borg_buffs/code/robot.dm
+++ b/modular_skyrat/modules/borg_buffs/code/robot.dm
@@ -113,31 +113,6 @@
icon_state = "misc"
default_reagent_types = BASE_SHAKER_MISC_REAGENTS
-/obj/item/cooking/cyborg/power
- name = "automated cooking tool"
- desc = "A cyborg fitted module resembling the rolling pins and Knifes"
- icon = 'modular_skyrat/modules/borg_buffs/icons/items_cyborg.dmi'
- icon_state = "knife_screw_cyborg"
- hitsound = 'sound/items/drill_hit.ogg'
- usesound = 'sound/items/drill_use.ogg'
- toolspeed = 0.5
- tool_behaviour = TOOL_KNIFE
-
-/obj/item/cooking/cyborg/power/examine()
- . = ..()
- . += " It's fitted with a [tool_behaviour == TOOL_KNIFE ? "knife" : "rolling pin"] head."
-
-/obj/item/cooking/cyborg/power/attack_self(mob/user)
- playsound(get_turf(user), 'sound/items/change_drill.ogg', 50, TRUE)
- if(tool_behaviour != TOOL_ROLLINGPIN)
- tool_behaviour = TOOL_ROLLINGPIN
- to_chat(user, span_notice("You attach the rolling pin bit to [src]."))
- icon_state = "rolling_bolt_cyborg"
- else
- tool_behaviour = TOOL_KNIFE
- to_chat(user, span_notice("You attach the knife bit to [src]."))
- icon_state = "knife_screw_cyborg"
-
// Wirebrush for janiborg
/datum/design/borg_wirebrush
name = "Wire-brush Module"
diff --git a/modular_skyrat/modules/borg_buffs/icons/items_cyborg.dmi b/modular_skyrat/modules/borg_buffs/icons/items_cyborg.dmi
index e4f419fb3f4..5ce92085f00 100644
Binary files a/modular_skyrat/modules/borg_buffs/icons/items_cyborg.dmi and b/modular_skyrat/modules/borg_buffs/icons/items_cyborg.dmi differ
diff --git a/modular_skyrat/modules/borgs/code/mechafabricator_designs.dm b/modular_skyrat/modules/borgs/code/mechafabricator_designs.dm
index eba4f673b78..2d0d752cf11 100644
--- a/modular_skyrat/modules/borgs/code/mechafabricator_designs.dm
+++ b/modular_skyrat/modules/borgs/code/mechafabricator_designs.dm
@@ -83,14 +83,17 @@
build_type = MECHFAB
build_path = /obj/item/borg/upgrade/welder
materials = list(
- /datum/material/iron=SHEET_MATERIAL_AMOUNT * 5,
- /datum/material/plasma=SHEET_MATERIAL_AMOUNT * 1,
+ /datum/material/iron = SHEET_MATERIAL_AMOUNT * 5,
+ /datum/material/plasma = SHEET_MATERIAL_AMOUNT * 1,
)
category = list(
RND_CATEGORY_MECHFAB_CYBORG_MODULES + RND_SUBCATEGORY_MECHFAB_CYBORG_MODULES_MINING,
)
-//Cyborg Skyrat overrides
+/*
+* Cyborg parts Skyrat overrides
+*/
+
/datum/design/borg_suit
name = "Cyborg Endoskeleton"
id = "borg_suit"
diff --git a/modular_skyrat/modules/borgs/code/robot_model.dm b/modular_skyrat/modules/borgs/code/robot_model.dm
index 8c94520ad0d..3f660d87956 100644
--- a/modular_skyrat/modules/borgs/code/robot_model.dm
+++ b/modular_skyrat/modules/borgs/code/robot_model.dm
@@ -383,9 +383,9 @@
/obj/item/borg/sight/thermal,
/obj/item/extinguisher,
/obj/item/weldingtool/electric,
- /obj/item/screwdriver/cyborg/power,
+ /obj/item/borg/cyborg_omnitool/engineering,
/obj/item/crowbar/cyborg/power,
- /obj/item/multitool/cyborg,
+ /obj/item/screwdriver/cyborg/power,
/obj/item/construction/rcd/borg/syndicate,
/obj/item/lightreplacer/cyborg,
/obj/item/stack/sheet/iron,
@@ -528,9 +528,9 @@
/obj/item/restraints/handcuffs/cable/zipties,
/obj/item/extinguisher,
/obj/item/weldingtool/electric,
- /obj/item/screwdriver/cyborg/power,
+ /obj/item/borg/cyborg_omnitool/engineering,
/obj/item/crowbar/cyborg/power,
- /obj/item/multitool/cyborg,
+ /obj/item/screwdriver/cyborg/power,
/obj/item/stack/sheet/iron,
/obj/item/stack/sheet/glass,
/obj/item/borg/apparatus/sheet_manipulator,
diff --git a/modular_skyrat/modules/borgs/code/robot_upgrade.dm b/modular_skyrat/modules/borgs/code/robot_upgrade.dm
index 073c8eeeb43..3002e04f489 100644
--- a/modular_skyrat/modules/borgs/code/robot_upgrade.dm
+++ b/modular_skyrat/modules/borgs/code/robot_upgrade.dm
@@ -179,7 +179,7 @@
* ADVANCED CARGO CYBORG UPGRADES
*/
/datum/design/borg_upgrade_clamp
- name = "improved Integrated Hydraulic Clamp Module"
+ name = "Improved Integrated Hydraulic Clamp Module"
id = "borg_upgrade_clamp"
build_type = MECHFAB
build_path = /obj/item/borg/upgrade/better_clamp
@@ -223,7 +223,7 @@
cyborg.model.remove_module(big_clamp, TRUE)
/datum/design/borg_upgrade_cargo_tele
- name = "cargo teleporter module"
+ name = "Cargo teleporter module"
id = "borg_upgrade_cargo_tele"
build_type = MECHFAB
build_path = /obj/item/borg/upgrade/cargo_tele
@@ -234,7 +234,7 @@
)
/obj/item/borg/upgrade/cargo_tele
- name = "borg cargo teleporter module"
+ name = "cargo teleporter module"
desc = "Allows you to upgrade a cargo cyborg with the cargo teleporter"
icon_state = "cyborg_upgrade3"
require_model = TRUE
@@ -265,7 +265,7 @@
cyborg.model.remove_module(locate_tele, TRUE)
/datum/design/borg_upgrade_forging
- name = "borg forging module"
+ name = "Forging module"
id = "borg_upgrade_forging"
build_type = MECHFAB
build_path = /obj/item/borg/upgrade/forging
@@ -276,7 +276,7 @@
)
/obj/item/borg/upgrade/forging
- name = "borg forging module"
+ name = "cyborg forging module"
desc = "Allows you to upgrade a cargo cyborg with forging gear"
icon_state = "cyborg_upgrade3"
require_model = TRUE
@@ -327,13 +327,67 @@
if(locate_forge)
cyborg.model.remove_module(locate_forge, TRUE)
+/*
+* SERVICE CYBORG UPGRADES
+*/
+
+/datum/design/borg_upgrade_artistic
+ name = "Artistic module"
+ id = "borg_upgrade_artistic"
+ build_type = MECHFAB
+ build_path = /obj/item/borg/upgrade/artistic
+ materials = list(/datum/material/iron = SMALL_MATERIAL_AMOUNT * 2,
+ /datum/material/glass = SMALL_MATERIAL_AMOUNT * 2)
+ construction_time = 10 SECONDS
+ category = list(
+ RND_CATEGORY_MECHFAB_CYBORG_MODULES + RND_SUBCATEGORY_MECHFAB_CYBORG_MODULES_SERVICE
+ )
+
+/obj/item/borg/upgrade/artistic
+ name = "borg artistic module"
+ desc = "Allows you to upgrade a service cyborg with tools for creating art."
+ icon_state = "cyborg_upgrade3"
+ require_model = TRUE
+ model_type = list(/obj/item/robot_model/service)
+ model_flags = BORG_MODEL_SERVICE
+ var/list/items_to_add = list(
+ /obj/item/pen,
+ /obj/item/toy/crayon/spraycan/borg,
+ /obj/item/instrument/guitar,
+ /obj/item/instrument/piano_synth,
+ /obj/item/stack/pipe_cleaner_coil/cyborg,
+ /obj/item/chisel,
+ )
+
+/obj/item/borg/upgrade/artistic/action(mob/living/silicon/robot/install, user = usr)
+ . = ..()
+ if(!.)
+ return FALSE
+ for(var/item_to_add in items_to_add)
+ if(locate(item_to_add) in install.model.modules)
+ install.balloon_alert_to_viewers("already installed!")
+ return FALSE
+ else
+ var/obj/item/module_item = new item_to_add(install.model.modules)
+ install.model.basic_modules += module_item
+ install.model.add_module(module_item, FALSE, TRUE)
+
+/obj/item/borg/upgrade/artistic/deactivate(mob/living/silicon/robot/install, user = usr)
+ . = ..()
+ if (!.)
+ return FALSE
+ for(var/item_to_add in items_to_add)
+ var/obj/item/module_item = locate(item_to_add) in install.model.modules
+ if (module_item)
+ install.model.remove_module(module_item, TRUE)
+
/*
* UNIVERSAL CYBORG UPGRADES
*/
/// ShapeShifter
/obj/item/borg/upgrade/borg_shapeshifter
- name = "Cyborg Shapeshifter Module"
+ name = "cyborg shapeshifter module"
desc = "An experimental device which allows a cyborg to disguise themself into another type of cyborg."
icon_state = "cyborg_upgrade3"
diff --git a/modular_skyrat/modules/clock_cult/code/items/clothing.dm b/modular_skyrat/modules/clock_cult/code/items/clothing.dm
index c2e9fca5478..9580234ea3f 100644
--- a/modular_skyrat/modules/clock_cult/code/items/clothing.dm
+++ b/modular_skyrat/modules/clock_cult/code/items/clothing.dm
@@ -191,7 +191,7 @@
if(iscarbon(user))
var/mob/living/carbon/carbon_user = user
- carbon_user.head_update(src, forced = TRUE)
+ carbon_user.update_worn_head()
/// "enable" the spectacles, flipping them down and applying their effects, calling on_toggle_eyes() if someone is wearing them
@@ -294,7 +294,7 @@
if(iscarbon(user))
var/mob/living/carbon/carbon_user = user
- carbon_user.head_update(src, forced = TRUE)
+ carbon_user.update_worn_head()
/// Turn on the visor, calling apply_to_wearer() and changing the icon state
diff --git a/modular_skyrat/modules/customization/game/objects/items/plushes.dm b/modular_skyrat/modules/customization/game/objects/items/plushes.dm
index 0454aff8a73..80cc6d1ead2 100644
--- a/modular_skyrat/modules/customization/game/objects/items/plushes.dm
+++ b/modular_skyrat/modules/customization/game/objects/items/plushes.dm
@@ -495,6 +495,16 @@
squeak_override = list('modular_skyrat/modules/emotes/sound/emotes/female/female_cough_3.ogg' = 1, 'modular_skyrat/modules/emotes/sound/emotes/female/female_cough_2.ogg' = 1, 'modular_skyrat/modules/emotes/sound/emotes/female/female_cough_1.ogg' = 1)
responses = list("The human body can survive three weeks without skiiiiiiiiiiin.", "The thigh bone is connected to the hip boooooooooone.", "Yeeeessss?", "Helloooooo.", "Don't be such a baby, ribs grow baaaaaaaaaack.",)
+// Donation reward for shyshadow
+/obj/item/toy/plush/skyrat/chunko/plushie_winrow
+ name = "dark and brooding lizard plush"
+ desc = "An almost intimidating black lizard plush, this one's got a little beret to come with it! Best not to separate the two. Its eyes shine with suggestion, no maidens?"
+ icon_state = "plushie_shyshadow"
+ gender = MALE
+ attack_verb_continuous = list("slashes", "bites", "rizzes")
+ attack_verb_simple = list("slash", "bite", "rizz")
+ responses = list("Am I looking in a mirror? Because what I see is beautiful.", "I'm not just a toy. I'm a romantic.", "I'm the diamond, and you're the rough because sooner or later...", "Is that mouth just for talking?", "Come on, don't be so hard on me. I'm so soft!", "Is that a glass of scotch? Because I've been thinking about buttering you up.", "Don't look stare for too long. You might get lost in my eyes.", "Oh wow! Looks like I'm not the only handsome thing around these parts.", "Do NOT the plushie. I am not a voodoo doll.",)
+
// Donation reward for tobjv
/obj/item/toy/plush/skyrat/tesh
name = "Squish-Me-Tesh"
@@ -519,12 +529,6 @@
desc = "A not so small voodoo doll made out of cut and sewn potato bags. It almost looks cute."
icon_state = "plushie_gamerguy"
-// Donation reward for shyshadow
-/obj/item/toy/plush/skyrat/plushie_winrow
- name = "dark and brooding lizard plush"
- desc = "An almost intimidating black lizard plush, this one's got a little beret to come with it! Best not to separate the two. Its eyes shine with suggestion, no maidens?"
- icon_state = "plushie_shyshadow"
-
// Donation reward for Dudewithatude
/obj/item/toy/plush/skyrat/plushie_star
name = "star angel plush"
diff --git a/modular_skyrat/modules/customization/modules/clothing/masks/breath.dm b/modular_skyrat/modules/customization/modules/clothing/masks/breath.dm
index 57365317844..25f8e9237ce 100644
--- a/modular_skyrat/modules/customization/modules/clothing/masks/breath.dm
+++ b/modular_skyrat/modules/customization/modules/clothing/masks/breath.dm
@@ -38,7 +38,7 @@
to_chat(user, "You pull the balaclava up to cover your whole head.")
open = 0
user.update_body_parts()
- user.update_inv_ears()
+ user.update_worn_ears()
user.update_worn_mask() //Updates mob icons
/obj/item/clothing/mask/balaclavaadjust/attack_self(mob/user)
diff --git a/modular_skyrat/modules/customization/modules/clothing/~donator/donator_clothing.dm b/modular_skyrat/modules/customization/modules/clothing/~donator/donator_clothing.dm
index 51c37671727..012a696e886 100644
--- a/modular_skyrat/modules/customization/modules/clothing/~donator/donator_clothing.dm
+++ b/modular_skyrat/modules/customization/modules/clothing/~donator/donator_clothing.dm
@@ -283,10 +283,10 @@
interaction_flags_click = NEED_DEXTERITY
/obj/item/clothing/mask/gas/nightlight/attack_self(mob/user)
- adjustmask(user)
+ adjust_visor(user)
/obj/item/clothing/mask/gas/nightlight/click_alt(mob/user)
- adjustmask(user)
+ adjust_visor(user)
return CLICK_ACTION_SUCCESS
/obj/item/clothing/mask/gas/nightlight/examine(mob/user)
@@ -489,7 +489,7 @@
to_chat(user, span_notice("You focus all your willpower to put the goggles down on your eyes."))
goggles = !goggles
if(user)
- user.head_update(src, forced = 1)
+ user.update_worn_head()
user.update_mob_action_buttons()
/obj/item/clothing/head/avipilot/ui_action_click(mob/living/carbon/user, action)
@@ -923,7 +923,7 @@
slot_flags = up ? ITEM_SLOT_EYES | ITEM_SLOT_HEAD : ITEM_SLOT_EYES
toggle_vision_effects()
-/obj/item/clothing/glasses/welding/steampunk_goggles/weldingvisortoggle(mob/user)
+/obj/item/clothing/glasses/welding/steampunk_goggles/adjust_visor(mob/user)
. = ..()
handle_sight_updating(user)
@@ -950,7 +950,7 @@
playsound(user, shutters_sound, 100, TRUE)
if(iscarbon(user))
var/mob/living/carbon/carbon_user = user
- carbon_user.head_update(src, forced = 1)
+ carbon_user.update_worn_head()
update_item_action_buttons()
return TRUE
@@ -982,7 +982,7 @@
if(iscarbon(user))
var/mob/living/carbon/carbon_user = user
carbon_user.update_tint()
- carbon_user.head_update(src, forced = TRUE)
+ carbon_user.update_worn_head()
/obj/item/clothing/glasses/welding/steampunk_goggles/ui_action_click(mob/user, actiontype, is_welding_toggle = FALSE)
if(!is_welding_toggle)
diff --git a/modular_skyrat/modules/ghostcafe/code/robot_ghostcafe.dm b/modular_skyrat/modules/ghostcafe/code/robot_ghostcafe.dm
index 760ec0fd526..d8f9ca2ce28 100644
--- a/modular_skyrat/modules/ghostcafe/code/robot_ghostcafe.dm
+++ b/modular_skyrat/modules/ghostcafe/code/robot_ghostcafe.dm
@@ -39,8 +39,8 @@
/obj/item/assembly/flash/cyborg,
/obj/item/extinguisher/mini,
/obj/item/weldingtool/largetank/cyborg,
- /obj/item/screwdriver/cyborg/power, // Combines Screwdriver and Wrench into one
- /obj/item/crowbar/cyborg/power, // Combines Crowbar and Wirecutters into one
+ /obj/item/borg/cyborg_omnitool/engineering,
+ /obj/item/borg/cyborg_omnitool/engineering,
/obj/item/multitool/cyborg,
/obj/item/stack/sheet/iron,
/obj/item/stack/sheet/glass,
diff --git a/modular_skyrat/modules/goofsec/code/sec_clothing_overrides.dm b/modular_skyrat/modules/goofsec/code/sec_clothing_overrides.dm
index 70ae903aa63..65ab673953e 100644
--- a/modular_skyrat/modules/goofsec/code/sec_clothing_overrides.dm
+++ b/modular_skyrat/modules/goofsec/code/sec_clothing_overrides.dm
@@ -256,7 +256,7 @@
user.update_worn_head()
if(iscarbon(user))
var/mob/living/carbon/carbon_user = user
- carbon_user.head_update(src, forced = TRUE)
+ carbon_user.update_worn_head()
//Beret replacement
diff --git a/modular_skyrat/modules/implants/code/augments_arms.dm b/modular_skyrat/modules/implants/code/augments_arms.dm
index 4cc168247f4..aefb5c076fd 100644
--- a/modular_skyrat/modules/implants/code/augments_arms.dm
+++ b/modular_skyrat/modules/implants/code/augments_arms.dm
@@ -148,7 +148,7 @@
name = "hacking arm implant"
desc = "An small arm implant containing an advanced screwdriver, wirecutters, and multitool designed for engineers and on-the-field machine modification. Actually legal, despite what the name may make you think."
icon = 'icons/obj/items_cyborg.dmi'
- icon_state = "multitool_cyborg"
+ icon_state = "toolkit_engiborg_multitool"
items_to_create = list(/obj/item/screwdriver/cyborg, /obj/item/wirecutters/cyborg, /obj/item/multitool/abductor/implant)
/obj/item/organ/internal/cyberimp/arm/botany
@@ -188,7 +188,7 @@
name = "multitool"
desc = "An optimized, highly advanced stripped-down multitool able to interface with electronics far better than its standard counterpart."
icon = 'icons/obj/items_cyborg.dmi'
- icon_state = "multitool_cyborg"
+ icon_state = "toolkit_engiborg_multitool"
/obj/item/organ/internal/cyberimp/arm/janitor
name = "janitorial tools implant"
diff --git a/modular_skyrat/modules/loadouts/loadout_items/donator/personal/donator_personal.dm b/modular_skyrat/modules/loadouts/loadout_items/donator/personal/donator_personal.dm
index 76fc9a13b56..b48021e3771 100644
--- a/modular_skyrat/modules/loadouts/loadout_items/donator/personal/donator_personal.dm
+++ b/modular_skyrat/modules/loadouts/loadout_items/donator/personal/donator_personal.dm
@@ -462,7 +462,7 @@
/datum/loadout_item/toys/plushe_winrow
name = "Dark and Brooding Lizard Plushie"
- item_path = /obj/item/toy/plush/skyrat/plushie_winrow
+ item_path = /obj/item/toy/plush/skyrat/chunko/plushie_winrow
/datum/loadout_item/toys/plushie_star
name = "Star Angel Plushie"
diff --git a/modular_skyrat/modules/medical/code/anesthetic_machine.dm b/modular_skyrat/modules/medical/code/anesthetic_machine.dm
index eb42dda946e..e15fcc09062 100644
--- a/modular_skyrat/modules/medical/code/anesthetic_machine.dm
+++ b/modular_skyrat/modules/medical/code/anesthetic_machine.dm
@@ -151,7 +151,7 @@
return PROCESS_KILL
// Attempt to restart airflow if it was temporarily interrupted after mask adjustment.
- if(attached_tank && istype(carbon_target) && !carbon_target.external && !attached_mask.mask_adjusted)
+ if(attached_tank && istype(carbon_target) && !carbon_target.external && !attached_mask.up)
carbon_target.open_internals(attached_tank, is_external = TRUE)
/obj/machinery/anesthetic_machine/Destroy()
@@ -210,12 +210,12 @@
to_chat(user, span_notice("[src] retracts back into the [our_machine]."))
our_machine.retract_mask()
-/obj/item/clothing/mask/breath/anesthetic/adjustmask(mob/living/carbon/user)
+/obj/item/clothing/mask/breath/anesthetic/adjust_visor(mob/living/carbon/user)
. = ..()
// Air only goes through the mask, so temporarily pause airflow if mask is getting adjusted.
// Since the mask is NODROP, the only possible user is the wearer
var/mob/living/carbon/carbon_target = loc
- if(mask_adjusted && carbon_target.external)
+ if(up && carbon_target.external)
carbon_target.close_externals()
/// A boxed version of the Anesthetic Machine. This is what is printed from the medical prolathe.
diff --git a/modular_skyrat/modules/microfusion/code/microfusion_cell.dm b/modular_skyrat/modules/microfusion/code/microfusion_cell.dm
index 515dc89f174..c1b9494762f 100644
--- a/modular_skyrat/modules/microfusion/code/microfusion_cell.dm
+++ b/modular_skyrat/modules/microfusion/code/microfusion_cell.dm
@@ -20,14 +20,7 @@ Essentially, power cells that malfunction if not used in an MCR, and should only
/// The upper most time for a microfusion cell meltdown.
#define MICROFUSION_CELL_FAILURE_UPPER (15 SECONDS)
-/// A charge drain failure.
-#define MICROFUSION_CELL_FAILURE_TYPE_CHARGE_DRAIN 1
-/// A small explosion failure.
-#define MICROFUSION_CELL_FAILURE_TYPE_EXPLOSION 2
-/// EMP failure.
-#define MICROFUSION_CELL_FAILURE_TYPE_EMP 3
-/// Radiation failure.
-#define MICROFUSION_CELL_FAILURE_TYPE_RADIATION 4
+
/obj/item/stock_parts/cell/microfusion //Just a standard cell.
name = "microfusion cell"
@@ -112,18 +105,17 @@ Essentially, power cells that malfunction if not used in an MCR, and should only
addtimer(CALLBACK(src, PROC_REF(process_failure)), seconds_to_explode)
/obj/item/stock_parts/cell/microfusion/proc/process_failure()
- var/fuckup_type = rand(1, 4)
remove_filter("rad_glow")
playsound(src, 'sound/effects/spray.ogg', 70)
- switch(fuckup_type)
- if(MICROFUSION_CELL_FAILURE_TYPE_CHARGE_DRAIN)
+ switch(rand(1, 4))
+ if(1) // Charge drain
charge = clamp(charge - MICROFUSION_CELL_DRAIN_FAILURE, 0, maxcharge)
- if(MICROFUSION_CELL_FAILURE_TYPE_EXPLOSION)
+ if(2) // Explosion
explode()
- if(MICROFUSION_CELL_FAILURE_TYPE_EMP)
- empulse(get_turf(src), MICROFUSION_CELL_EMP_HEAVY_FAILURE, MICROFUSION_CELL_EMP_LIGHT_FAILURE, FALSE)
- if(MICROFUSION_CELL_FAILURE_TYPE_RADIATION)
- radiation_pulse(src, MICROFUSION_CELL_RADIATION_RANGE_FAILURE, RAD_MEDIUM_INSULATION)
+ if(3) // Emp pulse
+ empulse(get_turf(src), 2, 4, FALSE) // 2 Heavy, 4 Light
+ if(4) // Deathly radiation pulse
+ radiation_pulse(src, 2, RAD_MEDIUM_INSULATION, 30)
meltdown = FALSE
/obj/item/stock_parts/cell/microfusion/update_overlays()
@@ -236,14 +228,6 @@ Essentially, power cells that malfunction if not used in an MCR, and should only
#undef MICROFUSION_CELL_DRAIN_FAILURE
-#undef MICROFUSION_CELL_EMP_HEAVY_FAILURE
-#undef MICROFUSION_CELL_EMP_LIGHT_FAILURE
-#undef MICROFUSION_CELL_RADIATION_RANGE_FAILURE
#undef MICROFUSION_CELL_FAILURE_LOWER
#undef MICROFUSION_CELL_FAILURE_UPPER
-
-#undef MICROFUSION_CELL_FAILURE_TYPE_CHARGE_DRAIN
-#undef MICROFUSION_CELL_FAILURE_TYPE_EXPLOSION
-#undef MICROFUSION_CELL_FAILURE_TYPE_EMP
-#undef MICROFUSION_CELL_FAILURE_TYPE_RADIATION
diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_machinery/washing_machine.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_machinery/washing_machine.dm
index 4da5f240d41..176750d8d64 100644
--- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_machinery/washing_machine.dm
+++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_machinery/washing_machine.dm
@@ -20,7 +20,7 @@
continue
var/covered = FALSE
- for (var/obj/item/clothing/iter_clothing in buckled_human.get_all_worn_items())
+ for (var/obj/item/clothing/iter_clothing in buckled_human.get_equipped_items())
if (!(iter_clothing.body_parts_covered & GROIN))
continue
if (iter_clothing.clothing_flags & THICKMATERIAL)
diff --git a/modular_skyrat/modules/power/code/powerator.dm b/modular_skyrat/modules/power/code/powerator.dm
index eaf62c9e674..6182b46b22b 100644
--- a/modular_skyrat/modules/power/code/powerator.dm
+++ b/modular_skyrat/modules/power/code/powerator.dm
@@ -71,10 +71,14 @@
/obj/machinery/powerator/Initialize(mapload)
. = ..()
+ SSpowerator_penality.sum_powerators()
+ SSpowerator_penality.calculate_penality()
START_PROCESSING(SSobj, src)
/obj/machinery/powerator/Destroy()
STOP_PROCESSING(SSobj, src)
+ SSpowerator_penality.remove_deled_powerators(src)
+ SSpowerator_penality.calculate_penality()
attached_cable = null
return ..()
@@ -103,6 +107,8 @@
. += span_notice("Current Power: [display_power(current_power)]/[display_power(max_power)]")
. += span_notice("This machine has made [credits_made] credits from selling power so far.")
+ if(length(SSpowerator_penality.powerator_list) > 1)
+ . += span_notice("Multiple powerators detected, total efficiency reduced by [(SSpowerator_penality.diminishing_gains_multiplier)*100]%")
/obj/machinery/powerator/RefreshParts()
. = ..()
@@ -162,7 +168,7 @@
current_power = attached_cable.newavail()
attached_cable.add_delayedload(current_power)
- var/money_ratio = round(current_power * divide_ratio)
+ var/money_ratio = round(current_power * divide_ratio) * SSpowerator_penality.diminishing_gains_multiplier
//BUBBER EDIT CHANGE BEGIN - Use credits_account variable for our department look up
//var/datum/bank_account/synced_bank_account = SSeconomy.get_dep_account(ACCOUNT_CAR) - BUBBER EDIT - ORIGINAL
var/datum/bank_account/synced_bank_account = SSeconomy.get_dep_account(credits_account == "" ? ACCOUNT_CAR : credits_account)
diff --git a/modular_skyrat/modules/power/code/powerator_subsystem.dm b/modular_skyrat/modules/power/code/powerator_subsystem.dm
new file mode 100644
index 00000000000..c816ffca03c
--- /dev/null
+++ b/modular_skyrat/modules/power/code/powerator_subsystem.dm
@@ -0,0 +1,28 @@
+SUBSYSTEM_DEF(powerator_penality)
+ name = "Powerator Penalities"
+ flags = SS_NO_FIRE
+ init_order = INIT_ORDER_POWERATOR_PENALITY
+
+ /// How many powerators we have build on server
+ var/list/powerator_list = list()
+ /// Current penality for powerator cash gain
+ var/diminishing_gains_multiplier = 1
+
+/datum/controller/subsystem/powerator_penality/Initialize()
+ return SS_INIT_SUCCESS
+
+
+/datum/controller/subsystem/powerator_penality/proc/sum_powerators()
+ for(var/obj/machinery/powerator/poweratorc as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/powerator))
+ powerator_list |= poweratorc
+
+/datum/controller/subsystem/powerator_penality/proc/remove_deled_powerators(src)
+ powerator_list -= src
+ return
+
+/datum/controller/subsystem/powerator_penality/proc/calculate_penality()
+ if(length(powerator_list) > 0)
+ diminishing_gains_multiplier = min(1, 2 ** log(4, length(powerator_list)) / length(powerator_list))
+ return diminishing_gains_multiplier
+ else
+ diminishing_gains_multiplier = initial(diminishing_gains_multiplier)
diff --git a/modular_skyrat/modules/primitive_catgirls/code/clothing.dm b/modular_skyrat/modules/primitive_catgirls/code/clothing.dm
index 9c7a378c3ff..a053558992b 100644
--- a/modular_skyrat/modules/primitive_catgirls/code/clothing.dm
+++ b/modular_skyrat/modules/primitive_catgirls/code/clothing.dm
@@ -125,7 +125,7 @@
actions_types = list(/datum/action/item_action/adjust)
/obj/item/clothing/mask/primitive_catgirl_greyscale_gaiter/attack_self(mob/user)
- adjustmask(user)
+ adjust_visor(user)
// Head
diff --git a/modular_skyrat/modules/tesh_augments/code/robot_bodyparts.dm b/modular_skyrat/modules/tesh_augments/code/robot_bodyparts.dm
index 4a8eaa3f4b9..b1d7430627d 100644
--- a/modular_skyrat/modules/tesh_augments/code/robot_bodyparts.dm
+++ b/modular_skyrat/modules/tesh_augments/code/robot_bodyparts.dm
@@ -9,6 +9,8 @@
/*
The damage modifiers here are modified to stay in line with teshari
Although I'm not sure if it's redundant, better safe than sorry.
+
+ Addendum: the limbs lack "limb_id = SPECIES_TESHARI". if this becomes a problem, just put those in xoxo -aKhro
*/
#define TESHARI_PUNCH_LOW 2
@@ -54,6 +56,7 @@
brute_modifier = 1
burn_modifier = 0.9
+ speed_modifier = -0.1
/obj/item/bodypart/leg/right/robot/teshari
name = "cybernetic right raptoral hindlimb"
@@ -67,6 +70,7 @@
brute_modifier = 1
burn_modifier = 0.9
+ speed_modifier = -0.1
/obj/item/bodypart/chest/robot/teshari
name = "cybernetic raptoral torso"
@@ -146,6 +150,7 @@
brute_modifier = 1.25
burn_modifier = 1.2
+ speed_modifier = -0.1
max_damage = LIMB_MAX_HP_PROSTHESIS
body_damage_coeff = LIMB_BODY_DAMAGE_COEFFICIENT_PROSTHESIS
@@ -164,6 +169,7 @@
brute_modifier = 1.25
burn_modifier = 1.2
+ speed_modifier = -0.1
max_damage = LIMB_MAX_HP_PROSTHESIS
body_damage_coeff = LIMB_BODY_DAMAGE_COEFFICIENT_PROSTHESIS
@@ -220,6 +226,7 @@
brute_modifier = 1.25
burn_modifier = 1.2
+ speed_modifier = -0.1
max_damage = LIMB_MAX_HP_PROSTHESIS
@@ -239,6 +246,7 @@
brute_modifier = 1.25
burn_modifier = 1.2
+ speed_modifier = -0.1
max_damage = LIMB_MAX_HP_PROSTHESIS
body_damage_coeff = LIMB_BODY_DAMAGE_COEFFICIENT_PROSTHESIS
@@ -295,6 +303,7 @@
brute_modifier = 0.8
burn_modifier = 1
+ speed_modifier = -0.1
max_damage = LIMB_MAX_HP_ADVANCED
body_damage_coeff = LIMB_BODY_DAMAGE_COEFFICIENT_ADVANCED
@@ -313,6 +322,7 @@
brute_modifier = 0.8
burn_modifier = 1
+ speed_modifier = -0.1
max_damage = LIMB_MAX_HP_ADVANCED
body_damage_coeff = LIMB_BODY_DAMAGE_COEFFICIENT_ADVANCED
@@ -367,6 +377,7 @@
brute_modifier = 1
burn_modifier = 0.9
+ speed_modifier = -0.1
max_damage = LIMB_MAX_HP_ADVANCED
body_damage_coeff = LIMB_BODY_DAMAGE_COEFFICIENT_ADVANCED
@@ -385,6 +396,7 @@
brute_modifier = 1
burn_modifier = 0.9
+ speed_modifier = -0.1
max_damage = LIMB_MAX_HP_ADVANCED
body_damage_coeff = LIMB_BODY_DAMAGE_COEFFICIENT_ADVANCED
diff --git a/sound/ambience/music/sisyphus/sisyphus.ogg b/sound/ambience/music/sisyphus/sisyphus.ogg
new file mode 100644
index 00000000000..c69d0b608eb
Binary files /dev/null and b/sound/ambience/music/sisyphus/sisyphus.ogg differ
diff --git a/sound/attributions.txt b/sound/attributions.txt
index be8df17c535..053051a89ec 100644
--- a/sound/attributions.txt
+++ b/sound/attributions.txt
@@ -147,3 +147,27 @@ https://freesound.org/people/gynation/sounds/82378/
nightmare_poof.ogg and nightmare_reappear.ogg are comprised of breath_01.wav by Nightflame (CC0) and slide-click.wav by Qat (CC0)
https://freesound.org/people/Qat/sounds/108332/
https://freesound.org/people/Nightflame/sounds/368615/
+
+modified by grungussuss:
+male_sneeze1.ogg: https://freesound.org/people/InspectorJ/sounds/352177/ , license: CC BY 4.0 DEED
+male_cry1.ogg: https://freesound.org/people/jacobmathiassen/sounds/254869/ , license: CC BY 4.0 DEED
+male_cry2.ogg: https://freesound.org/people/scottemoil/sounds/263776/ , license: CC0 1.0 DEED
+male_cry3.ogg: https://freesound.org/people/qubodup/sounds/200428/ , license: CC BY 4.0 DEED
+female_cry1.ogg: https://freesound.org/people/Luzanne0/sounds/445299/ , license: CC BY-NC 3.0 DEED
+female_cry2.ogg: https://freesound.org/people/Idalize/sounds/408211/ , license: CC BY-NC 4.0 DEED
+female_cough1.ogg: https://freesound.org/people/OwlStorm/sounds/151213/ , license: CC0 1.0 DEED
+female_cough2.ogg: https://freesound.org/people/thatkellytrna/sounds/425777/ , license: CC0 1.0 DEED
+female_cough3.ogg: https://freesound.org/people/Luzanne0/sounds/445293/ , license: CC BY-NC 3.0 DEED
+female_cough4.ogg: https://freesound.org/people/Luzanne0/sounds/445293/ , license: CC BY-NC 3.0 DEED
+female_cough5.ogg: https://freesound.org/people/DarkNightPrincess/sounds/625322/ , license: CC0 1.0 DEED
+female_cough6.ogg: https://freesound.org/people/drotzruhn/sounds/405206/ , license: CC BY 4.0 DEED
+male_cough1.ogg: https://freesound.org/people/Harris85/sounds/208761/ , license: CC0 1.0 DEED
+male_cough2.ogg: https://freesound.org/people/midwestdocumentary/sounds/722622/ , license: CC0 1.0 DEED
+male_cough3.ogg: https://freesound.org/people/hadescolossus/sounds/701162/ , license: CC0 1.0 DEED
+male_cough4.ogg: https://freesound.org/people/SoundDesignForYou/sounds/646652/ , license: CC0 1.0 DEED
+male_cough5.ogg: https://freesound.org/people/SoundDesignForYou/sounds/646654/ , license: CC0 1.0 DEED
+male_cough6.ogg: https://freesound.org/people/SoundDesignForYou/sounds/646656/ , license: CC0 1.0 DEED
+lizard_laugh1.ogg: https://youtu.be/I7CX0AS8RNI , License: CC-BY-3.0
+moth_laugh1.ogg: https://github.com/BeeStation/BeeStation-Hornet/blob/11ba3fa04105c93dd96a63ad4afaef4b20c02d0d/sound/emotes/ , license: CC-BY-SA-3.0
+whistle1.ogg: https://freesound.org/people/taure/sounds/411638/ , license: CC0 1.0 DEED
+
diff --git a/sound/voice/human/female_cough1.ogg b/sound/voice/human/female_cough1.ogg
new file mode 100644
index 00000000000..53af74368c3
Binary files /dev/null and b/sound/voice/human/female_cough1.ogg differ
diff --git a/sound/voice/human/female_cough2.ogg b/sound/voice/human/female_cough2.ogg
new file mode 100644
index 00000000000..eb3551a31fe
Binary files /dev/null and b/sound/voice/human/female_cough2.ogg differ
diff --git a/sound/voice/human/female_cough3.ogg b/sound/voice/human/female_cough3.ogg
new file mode 100644
index 00000000000..a075963d3b4
Binary files /dev/null and b/sound/voice/human/female_cough3.ogg differ
diff --git a/sound/voice/human/female_cough4.ogg b/sound/voice/human/female_cough4.ogg
new file mode 100644
index 00000000000..0136ea42ccf
Binary files /dev/null and b/sound/voice/human/female_cough4.ogg differ
diff --git a/sound/voice/human/female_cough5.ogg b/sound/voice/human/female_cough5.ogg
new file mode 100644
index 00000000000..7562661bd48
Binary files /dev/null and b/sound/voice/human/female_cough5.ogg differ
diff --git a/sound/voice/human/female_cough6.ogg b/sound/voice/human/female_cough6.ogg
new file mode 100644
index 00000000000..62938b7b761
Binary files /dev/null and b/sound/voice/human/female_cough6.ogg differ
diff --git a/sound/voice/human/female_cry1.ogg b/sound/voice/human/female_cry1.ogg
new file mode 100644
index 00000000000..f4f73864171
Binary files /dev/null and b/sound/voice/human/female_cry1.ogg differ
diff --git a/sound/voice/human/female_cry2.ogg b/sound/voice/human/female_cry2.ogg
new file mode 100644
index 00000000000..e81e93b5c3f
Binary files /dev/null and b/sound/voice/human/female_cry2.ogg differ
diff --git a/sound/voice/human/female_sneeze1.ogg b/sound/voice/human/female_sneeze1.ogg
new file mode 100644
index 00000000000..8fe020a8c7e
Binary files /dev/null and b/sound/voice/human/female_sneeze1.ogg differ
diff --git a/sound/voice/human/male_cough1.ogg b/sound/voice/human/male_cough1.ogg
new file mode 100644
index 00000000000..f553bd855ae
Binary files /dev/null and b/sound/voice/human/male_cough1.ogg differ
diff --git a/sound/voice/human/male_cough2.ogg b/sound/voice/human/male_cough2.ogg
new file mode 100644
index 00000000000..3dcc880175f
Binary files /dev/null and b/sound/voice/human/male_cough2.ogg differ
diff --git a/sound/voice/human/male_cough3.ogg b/sound/voice/human/male_cough3.ogg
new file mode 100644
index 00000000000..a87ba9cc4c7
Binary files /dev/null and b/sound/voice/human/male_cough3.ogg differ
diff --git a/sound/voice/human/male_cough4.ogg b/sound/voice/human/male_cough4.ogg
new file mode 100644
index 00000000000..38052dc7871
Binary files /dev/null and b/sound/voice/human/male_cough4.ogg differ
diff --git a/sound/voice/human/male_cough5.ogg b/sound/voice/human/male_cough5.ogg
new file mode 100644
index 00000000000..5a1b836775d
Binary files /dev/null and b/sound/voice/human/male_cough5.ogg differ
diff --git a/sound/voice/human/male_cough6.ogg b/sound/voice/human/male_cough6.ogg
new file mode 100644
index 00000000000..cfe4e08655b
Binary files /dev/null and b/sound/voice/human/male_cough6.ogg differ
diff --git a/sound/voice/human/male_cry1.ogg b/sound/voice/human/male_cry1.ogg
new file mode 100644
index 00000000000..50ffd0cf72a
Binary files /dev/null and b/sound/voice/human/male_cry1.ogg differ
diff --git a/sound/voice/human/male_cry2.ogg b/sound/voice/human/male_cry2.ogg
new file mode 100644
index 00000000000..8d35a4d5276
Binary files /dev/null and b/sound/voice/human/male_cry2.ogg differ
diff --git a/sound/voice/human/male_cry3.ogg b/sound/voice/human/male_cry3.ogg
new file mode 100644
index 00000000000..58f39b5fff1
Binary files /dev/null and b/sound/voice/human/male_cry3.ogg differ
diff --git a/sound/voice/human/male_sneeze1.ogg b/sound/voice/human/male_sneeze1.ogg
new file mode 100644
index 00000000000..1c7e8f42534
Binary files /dev/null and b/sound/voice/human/male_sneeze1.ogg differ
diff --git a/sound/voice/human/whistle1.ogg b/sound/voice/human/whistle1.ogg
new file mode 100644
index 00000000000..41092606597
Binary files /dev/null and b/sound/voice/human/whistle1.ogg differ
diff --git a/sound/voice/lizard/lizard_laugh1.ogg b/sound/voice/lizard/lizard_laugh1.ogg
new file mode 100644
index 00000000000..b2c02e6d2fc
Binary files /dev/null and b/sound/voice/lizard/lizard_laugh1.ogg differ
diff --git a/sound/voice/moth/moth_laugh1.ogg b/sound/voice/moth/moth_laugh1.ogg
new file mode 100644
index 00000000000..391d6c5aefe
Binary files /dev/null and b/sound/voice/moth/moth_laugh1.ogg differ
diff --git a/strings/pirates.json b/strings/pirates.json
index 22e0e9861b9..191cc927de7 100644
--- a/strings/pirates.json
+++ b/strings/pirates.json
@@ -270,5 +270,22 @@
"Mass of Fermenting Dregs",
"Bloody Valentine",
"Wild Nothing"
+ ],
+ "medieval_names":[
+ "Head Reaper",
+ "The Lords Judgement",
+ "The Judgement",
+ "Peasant Smiter",
+ "Wicked Ravager",
+ "Sheep Reaver",
+ "Never-ending Crusade",
+ "Locus Invicta",
+ "Memento Morieris",
+ "God Conqueror",
+ "Omnium Contra Omnes",
+ "Aries Duo",
+ "Dark Ages Bringer",
+ "Merciless Barricade",
+ "Murder Mcmurderface"
]
}
diff --git a/strings/tips.txt b/strings/tips.txt
index 1b52ee5e0c1..cd0dbbdf0d0 100644
--- a/strings/tips.txt
+++ b/strings/tips.txt
@@ -44,6 +44,14 @@ As a Geneticist, T goes to A, and G goes to C.
As a Ghost, you can both start and join capture the flag games through the minigames menu, or by clicking on one of the team spawners, which can be found under the "Misc" section of the orbit menu.
As a Ghost, you can double click on just about anything to follow it. Or just warp around!
As a Ghost, you can see the inside of a container on the ground by clicking on it.
+As a Heretic, the Path of Ash focuses on stealth and disorientation, but as you progress, sheds this playstyle in favor of a more aggressive, fiery finale.
+As a Heretic, the Path of Moon will literally drive people around you crazy - perhaps crazy enough to become your allies should you succeed.
+As a Heretic, the Path of Lock is an Assistant's best friend, and can open many pathways. Including ones beyond the veil...
+As a Heretic, the Path of Flesh allows you to raise an army by summoning ghouls and monsters from beyond the veil. Through ascension, you become a one-man army yourself.
+As a Heretic, the Path of Void makes people wish they could scream in the vast emptiness of space or have a chance at escaping from you. In the end, the storm takes all.
+As a Heretic, the Path of Blade rewards your ability to fight, by making you better and better at it. Though ascension, you can become an ultimate dueling juggernaut.
+As a Heretic, the Path of Rust is quite overt, but allows you to shrug of a lot of damage as everything around you slowly decays into nothing but rot and rust.
+As a Heretic, the Path of Cosmos allows you to take rightful ownership of the very space the crew treads on. And if they don't respect your status, calling in a friend from beyond should show them.
As a Janitor Cyborg, you are the bane of all slaughter demons and even Bubblegum himself. Cleaning up blood stains will severely gimp them.
As a Janitor, if someone steals your janicart, you can instead use your space cleaner spray, grenades, water sprayer, exact bloody revenge or order another from Cargo.
As a Janitor, mousetraps can be used to create bombs or booby-trap containers.
@@ -60,6 +68,9 @@ As a Medical Doctor, you can extract implants by holding an empty implant case i
As a Medical Doctor, you can point your penlight at people to create a medical hologram. This lets them know that you're coming to treat them.
As a Medical Doctor, you can surgically implant or extract things from people's chests. This can range from putting in a bomb to pulling out an alien larva.
As a Medical Doctor, you must target the correct limb and not be in combat mode when trying to perform surgery on someone. Right clicking your patient will intentionally fail the surgery step.
+As a Medical Doctor, when messing with viruses, remember that robotic organs can give immunity to disease effects and transmissibility. Make use of the inorganic biology symptom to bypass the protection.
+As a Medical Doctor, while there's an pandemic, you only require small amounts of vaccine to heal a sick patient. Work with the Chemist to distribute your cures more efficiently.
+As a Medical Doctor, try messing with the virology lab sometime! Viruses can range from healing powers so great that you can heal out of critical status, or diseases so dangerous they can kill the entire crew with airborne spontaneous combustion. Experiment!
As a Monkey, you can crawl through air or scrubber vents by alt+left clicking them. You must drop everything you are wearing and holding to do this, however.
As a Monkey, you can still wear a few human items, such as backpacks, gas masks and hats, and still have two free hands.
As a Morph, you can talk while disguised, but your words have a chance of being slurred, giving you away!
@@ -149,6 +160,7 @@ As the AI, you can take pictures with your camera and upload them to newscasters
As the AI, you can use CTRL + 1-9 to set a location hotkey for your camera, allowing you to save the location and jump to it at will. Tilde and zero will return you to the last spot you jumped from, and the numpad numbers act as aliases to the regular number keys.
As the Bartender, the drinks you start with only give you the basics. If you want more advanced mixtures, look into working with chemistry, hydroponics, or even mining for things to grind up and throw in!
As the Bartender, you can use a circular saw on your shotgun to make it easier to store.
+As the Bartender, remember to set up the bar sign by walking up to it and clicking it!
As the Blob, don't neglect the creation of factories. These create spores that carry your reagent and can chase crew members far further than you. Spores can also be rallied to swarm the crew and cause panic, and can even take over corpses to create much more dangerous blob zombies!
As the Blob, keep your core some distance from space, as it is both expensive to expand onto space, easy to be attacked from, and does not count towards your win condition. Emitter platforms built in space are especially dangerous.
As the Blob, removing strong blobs, resource nodes, factories, and nodes will give you 4, 15, 25, and 25 resources back, respectively.
@@ -175,10 +187,13 @@ As the Clown, eating bananas heals you slightly. Honk!
As the Clown, if you lose your banana peel, you can still slip people with your PDA! Honk!
As the Clown, if you're a Traitor and get an emag on sale (or convince another traitor), you can emag your Clown Car to unlock a variety of new functions, including the Siege Mode, which will allow you to launch your passengers, preferably directly into the Supermatter! Or into space.
As the Clown, spice your gimmicks up! Nobody likes a one-trick pony.
+As the Clown, click with one long balloon in hand onto another to create a balloon animal! Each combination of colours has its own unique result.
As the Clown, you can use your stamp on a sheet of cardboard as the first step of making a honkbot. Fun for the whole crew!
As the Clown, your Grail is the mineral bananium, which can be given to the Roboticist to build you a fun and robust mech beloved by everyone.
As the Curator, be sure to keep the shelves stocked and the library clean for crew.
As the Curator, you are not completely defenseless. Your whip easily disarms people, your laser pointer can blind humans and cyborgs, and you can hide items in wirecut books.
+As the Coroner, you are more comfortable working on cadavers. You can perform autopsies or harvest organs from corpses a lot faster than your Medical Doctor counterparts. Work in tandem with them by helping prepare bodies for revival.
+As the Coroner, you can perform autopsies on corpses recovered from strange circumstances with your handheld autopsy scanner to discover how they died. By teaming up with a Detective, you can solve several cases together!
As the Detective, people leave fingerprints everywhere and on everything. With the exception of white latex, gloves will hide them. All is not lost, however, as gloves leave fibers specific to their kind such as black or nitrile, pointing to a general department.
As the Detective, you can use your forensics scanner from a distance. Use this to scan boxes or other storage containers.
As the Detective, your revolver can be loaded with .357 ammunition obtained from a hacked autolathe. Firing it has a decent chance to blow up your revolver.
@@ -198,9 +213,6 @@ As the Quartermaster, be sure to check the manifests on crates you receive to ma
As the Quartermaster, you can construct an express supply console that instantly delivers crates by drop pod. The impact will cause a small explosion as well.
As the Research Director, you can lock down cyborgs instead of blowing them up. Then you can have their laws reset or if that doesn't work, safely dismantled.
As the Research Director, you can take AIs out of their cores by loading them into an intelliCard, which lets you see their laws, even ion/syndicate ones. It can then be placed into an AI system integrity restorer computer to revive and/or repair them.
-As the Virologist, robotic organs can give immunity to disease effects and transmissibility. Make use of the inorganic biology symptom to bypass the protection.
-As the Virologist, you only require small amounts of vaccine to heal a sick patient. Work with the Chemist to distribute your cures more efficiently.
-As the Virologist, your viruses can range from healing powers so great that you can heal out of critical status, or diseases so dangerous they can kill the entire crew with airborne spontaneous combustion. Experiment!
As the Warden, if a prisoner's crimes are heinous enough you can put them in permabrig or the gulag. Make sure to check on them once in a while!
As the Warden, keep a close eye on the armory at all times, as it is a favored strike point of nuclear operatives and cocky traitors.
As the Warden, you can implant criminals you suspect might re-offend with devices that will track their location and allow you to remotely inject them with disabling chemicals.
diff --git a/tgstation.dme b/tgstation.dme
index 7d6b7491348..f656d3930b8 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -181,6 +181,7 @@
#include "code\__DEFINES\procpath.dm"
#include "code\__DEFINES\profile.dm"
#include "code\__DEFINES\projectiles.dm"
+#include "code\__DEFINES\pronouns.dm"
#include "code\__DEFINES\qdel.dm"
#include "code\__DEFINES\quirks.dm"
#include "code\__DEFINES\radiation.dm"
@@ -735,13 +736,11 @@
#include "code\controllers\subsystem\atoms.dm"
#include "code\controllers\subsystem\augury.dm"
#include "code\controllers\subsystem\ban_cache.dm"
-#include "code\controllers\subsystem\battle_royale.dm"
#include "code\controllers\subsystem\bitrunning.dm"
#include "code\controllers\subsystem\blackbox.dm"
#include "code\controllers\subsystem\blackmarket.dm"
#include "code\controllers\subsystem\chat.dm"
#include "code\controllers\subsystem\circuit_component.dm"
-#include "code\controllers\subsystem\communications.dm"
#include "code\controllers\subsystem\dbcore.dm"
#include "code\controllers\subsystem\dcs.dm"
#include "code\controllers\subsystem\discord.dm"
@@ -765,7 +764,6 @@
#include "code\controllers\subsystem\lua.dm"
#include "code\controllers\subsystem\machines.dm"
#include "code\controllers\subsystem\mapping.dm"
-#include "code\controllers\subsystem\materials.dm"
#include "code\controllers\subsystem\minor_mapping.dm"
#include "code\controllers\subsystem\mobs.dm"
#include "code\controllers\subsystem\modular_computers.dm"
@@ -832,7 +830,6 @@
#include "code\controllers\subsystem\movement\ai_movement.dm"
#include "code\controllers\subsystem\movement\cliff_falling.dm"
#include "code\controllers\subsystem\movement\hyperspace_drift.dm"
-#include "code\controllers\subsystem\movement\move_handler.dm"
#include "code\controllers\subsystem\movement\movement.dm"
#include "code\controllers\subsystem\movement\movement_types.dm"
#include "code\controllers\subsystem\movement\spacedrift.dm"
@@ -1883,9 +1880,9 @@
#include "code\datums\shuttles\starfury.dm"
#include "code\datums\shuttles\whiteship.dm"
#include "code\datums\skills\_skill.dm"
+#include "code\datums\skills\athletics.dm"
#include "code\datums\skills\cleaning.dm"
#include "code\datums\skills\fishing.dm"
-#include "code\datums\skills\fitness.dm"
#include "code\datums\skills\gaming.dm"
#include "code\datums\skills\mining.dm"
#include "code\datums\station_traits\_station_trait.dm"
@@ -1961,6 +1958,12 @@
#include "code\datums\storage\subtypes\rped.dm"
#include "code\datums\storage\subtypes\surgery_tray.dm"
#include "code\datums\storage\subtypes\trash.dm"
+#include "code\datums\systems\_system.dm"
+#include "code\datums\systems\manager.dm"
+#include "code\datums\systems\ds\battle_royale.dm"
+#include "code\datums\systems\ds\communications.dm"
+#include "code\datums\systems\ds\materials.dm"
+#include "code\datums\systems\ds\move_handler.dm"
#include "code\datums\votes\_vote_datum.dm"
#include "code\datums\votes\custom_vote.dm"
#include "code\datums\votes\map_vote.dm"
@@ -2194,6 +2197,7 @@
#include "code\game\machinery\computer\records\records.dm"
#include "code\game\machinery\computer\records\security.dm"
#include "code\game\machinery\dna_infuser\dna_infuser.dm"
+#include "code\game\machinery\dna_infuser\dna_infusion.dm"
#include "code\game\machinery\dna_infuser\infuser_book.dm"
#include "code\game\machinery\dna_infuser\infuser_entry.dm"
#include "code\game\machinery\dna_infuser\infuser_entries\infuser_tier_one_entries.dm"
@@ -3020,6 +3024,7 @@
#include "code\modules\admin\verbs\SDQL2\SDQL_2_wrappers.dm"
#include "code\modules\admin\view_variables\admin_delete.dm"
#include "code\modules\admin\view_variables\color_matrix_editor.dm"
+#include "code\modules\admin\view_variables\debug_variable_appearance.dm"
#include "code\modules\admin\view_variables\debug_variables.dm"
#include "code\modules\admin\view_variables\filterrific.dm"
#include "code\modules\admin\view_variables\get_variables.dm"
@@ -4651,6 +4656,7 @@
#include "code\modules\mining\equipment\miningradio.dm"
#include "code\modules\mining\equipment\resonator.dm"
#include "code\modules\mining\equipment\survival_pod.dm"
+#include "code\modules\mining\equipment\vent_pointer.dm"
#include "code\modules\mining\equipment\wormhole_jaunter.dm"
#include "code\modules\mining\equipment\monster_organs\brimdust_sac.dm"
#include "code\modules\mining\equipment\monster_organs\monster_organ.dm"
@@ -6321,6 +6327,7 @@
#include "modular_skyrat\master_files\code\controllers\subsystem\dbcore.dm"
#include "modular_skyrat\master_files\code\controllers\subsystem\events.dm"
#include "modular_skyrat\master_files\code\controllers\subsystem\language.dm"
+#include "modular_skyrat\master_files\code\controllers\subsystem\research.dm"
#include "modular_skyrat\master_files\code\datums\ai_laws.dm"
#include "modular_skyrat\master_files\code\datums\emotes.dm"
#include "modular_skyrat\master_files\code\datums\ert.dm"
@@ -6496,6 +6503,7 @@
#include "modular_skyrat\master_files\code\modules\clothing\head\_head.dm"
#include "modular_skyrat\master_files\code\modules\clothing\head\akula_official.dm"
#include "modular_skyrat\master_files\code\modules\clothing\head\cowboy.dm"
+#include "modular_skyrat\master_files\code\modules\clothing\head\hardhat.dm"
#include "modular_skyrat\master_files\code\modules\clothing\head\monkey_magnification_helmet.dm"
#include "modular_skyrat\master_files\code\modules\clothing\masks\_masks.dm"
#include "modular_skyrat\master_files\code\modules\clothing\outfits\ert.dm"
@@ -8064,6 +8072,7 @@
#include "modular_skyrat\modules\poly_commands\parrot.dm"
#include "modular_skyrat\modules\positronic_alert_console\code\positronic_alert_console.dm"
#include "modular_skyrat\modules\power\code\powerator.dm"
+#include "modular_skyrat\modules\power\code\powerator_subsystem.dm"
#include "modular_skyrat\modules\power\code\teg.dm"
#include "modular_skyrat\modules\primitive_catgirls\code\clothing.dm"
#include "modular_skyrat\modules\primitive_catgirls\code\clothing_vendor.dm"
diff --git a/tgui/packages/common/type-utils.ts b/tgui/packages/common/type-utils.ts
new file mode 100644
index 00000000000..a73c0c1d595
--- /dev/null
+++ b/tgui/packages/common/type-utils.ts
@@ -0,0 +1,41 @@
+/**
+ * Helps visualize highly complex ui data on the fly.
+ * @example
+ * ```tsx
+ * const { data } = useBackend();
+ * logger.log(getShallowTypes(data));
+ * ```
+ */
+export function getShallowTypes(
+ data: Record,
+): Record {
+ const output = {};
+
+ for (const key in data) {
+ if (Array.isArray(data[key])) {
+ const arr: any[] = data[key];
+
+ // Return the first array item if it exists
+ if (data[key].length > 0) {
+ output[key] = arr[0];
+ continue;
+ }
+
+ output[key] = 'emptyarray';
+ } else if (typeof data[key] === 'object' && data[key] !== null) {
+ // Please inspect it further and make a new type for it
+ output[key] = 'object (inspect) || Record';
+ } else if (typeof data[key] === 'number') {
+ const num = Number(data[key]);
+
+ // 0 and 1 could be booleans from byond
+ if (num === 1 || num === 0) {
+ output[key] = `${num}, BooleanLike?`;
+ continue;
+ }
+ output[key] = data[key];
+ }
+ }
+
+ return output;
+}
diff --git a/tgui/packages/tgui/components/Dropdown.tsx b/tgui/packages/tgui/components/Dropdown.tsx
index a103a7466d3..1cf2b53ecfd 100644
--- a/tgui/packages/tgui/components/Dropdown.tsx
+++ b/tgui/packages/tgui/components/Dropdown.tsx
@@ -1,12 +1,12 @@
import { classes } from 'common/react';
-import { ReactNode, useCallback, useEffect, useRef, useState } from 'react';
+import { ReactNode, useEffect, useRef, useState } from 'react';
import { BoxProps, unit } from './Box';
import { Button } from './Button';
import { Icon } from './Icon';
import { Popper } from './Popper';
-type DropdownEntry = {
+export type DropdownEntry = {
displayText: ReactNode;
value: string | number;
};
@@ -19,7 +19,11 @@ type Props = {
options: DropdownOption[];
/** Called when a value is picked from the list, `value` is the value that was picked */
onSelected: (value: any) => void;
+ /** Currently selected entry to display. Can be left stateless to permanently display this value. */
+ selected: DropdownOption | null | undefined;
} & Partial<{
+ /** Whether to scroll automatically on open. Defaults to true */
+ autoScroll: boolean;
/** Whether to display previous / next buttons */
buttons: boolean;
/** Whether to clip the selected text */
@@ -28,7 +32,7 @@ type Props = {
color: string;
/** Disables the dropdown */
disabled: boolean;
- /** Text to always display in place of the selected text */
+ /** Overwrites selection text with this. Good for objects etc. */
displayText: ReactNode;
/** Icon to display in dropdown button */
icon: string;
@@ -44,17 +48,26 @@ type Props = {
onClick: (event) => void;
/** Dropdown renders over instead of below */
over: boolean;
- /** Currently selected entry */
- selected: string | number;
+ /** Text to show when nothing has been selected. */
+ placeholder: string;
}> &
BoxProps;
+enum DIRECTION {
+ Previous = 'previous',
+ Next = 'next',
+ Current = 'current',
+}
+
+const NONE = -1;
+
function getOptionValue(option: DropdownOption) {
return typeof option === 'string' ? option : option.value;
}
export function Dropdown(props: Props) {
const {
+ autoScroll = true,
buttons,
className,
clipSelectedText = true,
@@ -70,46 +83,64 @@ export function Dropdown(props: Props) {
onSelected,
options = [],
over,
+ placeholder = 'Select...',
selected,
- width,
+ width = '15rem',
} = props;
const [open, setOpen] = useState(false);
const adjustedOpen = over ? !open : open;
const innerRef = useRef(null);
+ const selectedIndex =
+ options.findIndex((option) => getOptionValue(option) === selected) || 0;
+
+ function scrollTo(position: number) {
+ let scrollPos = position;
+ if (position < selectedIndex) {
+ scrollPos = position < 2 ? 0 : position - 2;
+ } else {
+ scrollPos =
+ position > options.length - 3 ? options.length - 1 : position - 2;
+ }
+
+ const element = innerRef.current?.children[scrollPos];
+ element?.scrollIntoView({ block: 'nearest' });
+ }
+
/** Update the selected value when clicking the left/right buttons */
- const updateSelected = useCallback(
- (direction: 'previous' | 'next') => {
- if (options.length < 1 || disabled) {
- return;
- }
- const startIndex = 0;
- const endIndex = options.length - 1;
+ function updateSelected(direction: DIRECTION) {
+ if (options.length < 1 || disabled) {
+ return;
+ }
- let selectedIndex = options.findIndex(
- (option) => getOptionValue(option) === selected,
- );
+ const startIndex = 0;
+ const endIndex = options.length - 1;
- if (selectedIndex < 0) {
- selectedIndex = direction === 'next' ? endIndex : startIndex;
- }
+ let newIndex: number;
+ if (selectedIndex < 0) {
+ newIndex = direction === 'next' ? endIndex : startIndex; // No selection yet
+ } else if (direction === 'next') {
+ newIndex = selectedIndex === endIndex ? startIndex : selectedIndex + 1; // Move to next option
+ } else {
+ newIndex = selectedIndex === startIndex ? endIndex : selectedIndex - 1; // Move to previous option
+ }
- let newIndex = selectedIndex;
- if (direction === 'next') {
- newIndex = selectedIndex === endIndex ? startIndex : ++selectedIndex;
- } else {
- newIndex = selectedIndex === startIndex ? endIndex : --selectedIndex;
- }
-
- onSelected?.(getOptionValue(options[newIndex]));
- },
- [disabled, onSelected, options, selected],
- );
+ if (open && autoScroll) {
+ scrollTo(newIndex);
+ }
+ onSelected?.(getOptionValue(options[newIndex]));
+ }
/** Allows the menu to be scrollable on open */
useEffect(() => {
- if (!open) return;
+ if (!open) {
+ return;
+ }
+
+ if (autoScroll && selectedIndex !== NONE) {
+ scrollTo(selectedIndex);
+ }
innerRef.current?.focus();
}, [open]);
@@ -151,69 +182,64 @@ export function Dropdown(props: Props) {
}
>
-
-
-
{
- if (disabled && !open) {
- return;
- }
- setOpen(!open);
- onClick?.(event);
+
+
{
+ if (disabled && !open) {
+ return;
+ }
+ setOpen(!open);
+ onClick?.(event);
+ }}
+ >
+ {icon && (
+
+ )}
+
- {icon && (
-
- )}
-
- {displayText || selected}
+ {displayText ||
+ (selected && getOptionValue(selected)) ||
+ placeholder}
+
+ {!noChevron && (
+
+
- {!noChevron && (
-
-
-
- )}
-
- {buttons && (
- <>
-
{
- updateSelected('previous');
- }}
- />
-
- {
- updateSelected('next');
- }}
- />
- >
)}
+ {buttons && (
+ <>
+
{
+ updateSelected(DIRECTION.Previous);
+ }}
+ />
+
+ {
+ updateSelected(DIRECTION.Next);
+ }}
+ />
+ >
+ )}
);
diff --git a/tgui/packages/tgui/components/Stack.tsx b/tgui/packages/tgui/components/Stack.tsx
index 18ae34c09e8..3f5cf72123c 100644
--- a/tgui/packages/tgui/components/Stack.tsx
+++ b/tgui/packages/tgui/components/Stack.tsx
@@ -17,14 +17,23 @@ import {
} from './Flex';
type Props = Partial<{
- vertical: boolean;
+ /** Fills available space. */
fill: boolean;
+ /** Reverses the stack. */
+ reverse: boolean;
+ /** Flex column */
+ vertical: boolean;
+ /** Adds zebra striping to the stack. */
zebra: boolean;
}> &
FlexProps;
-export const Stack = (props: Props) => {
- const { className, vertical, fill, zebra, ...rest } = props;
+export function Stack(props: Props) {
+ const { className, vertical, fill, reverse, zebra, ...rest } = props;
+
+ const directionPrefix = vertical ? 'column' : 'row';
+ const directionSuffix = reverse ? '-reverse' : '';
+
return (
{
fill && 'Stack--fill',
vertical ? 'Stack--vertical' : 'Stack--horizontal',
zebra && 'Stack--zebra',
+ reverse && `Stack--reverse${vertical ? '--vertical' : ''}`,
className,
computeFlexClassName(props),
])}
{...computeFlexProps({
- direction: vertical ? 'column' : 'row',
+ direction: `${directionPrefix}${directionSuffix}`,
...rest,
})}
/>
);
-};
+}
type StackItemProps = FlexItemProps &
Partial<{
innerRef: RefObject
;
}>;
-const StackItem = (props: StackItemProps) => {
+function StackItem(props: StackItemProps) {
const { className, innerRef, ...rest } = props;
+
return (
{
{...computeFlexItemProps(rest)}
/>
);
-};
+}
Stack.Item = StackItem;
@@ -70,8 +81,9 @@ type StackDividerProps = FlexItemProps &
hidden: boolean;
}>;
-const StackDivider = (props: StackDividerProps) => {
+function StackDivider(props: StackDividerProps) {
const { className, hidden, ...rest } = props;
+
return (
{
{...computeFlexItemProps(rest)}
/>
);
-};
+}
Stack.Divider = StackDivider;
diff --git a/tgui/packages/tgui/interfaces/AdminFax.jsx b/tgui/packages/tgui/interfaces/AdminFax.jsx
index 9aeef3247a3..3e6026d4ce4 100644
--- a/tgui/packages/tgui/interfaces/AdminFax.jsx
+++ b/tgui/packages/tgui/interfaces/AdminFax.jsx
@@ -63,10 +63,9 @@ export const FaxMainPanel = (props) => {
setFax(value)}
/>
diff --git a/tgui/packages/tgui/interfaces/AdminPDA.jsx b/tgui/packages/tgui/interfaces/AdminPDA.jsx
index 09570265a20..fa83f200e52 100644
--- a/tgui/packages/tgui/interfaces/AdminPDA.jsx
+++ b/tgui/packages/tgui/interfaces/AdminPDA.jsx
@@ -33,7 +33,8 @@ const ReceiverChoice = (props) => {
showInvisible || !rcvr.invisible)
.map((rcvr) => ({
diff --git a/tgui/packages/tgui/interfaces/AiVoiceChanger.tsx b/tgui/packages/tgui/interfaces/AiVoiceChanger.tsx
index 9e248a01033..09c1aa04e57 100644
--- a/tgui/packages/tgui/interfaces/AiVoiceChanger.tsx
+++ b/tgui/packages/tgui/interfaces/AiVoiceChanger.tsx
@@ -5,37 +5,40 @@ import { Button, Dropdown, Input, LabeledList, Section } from '../components';
import { Window } from '../layouts';
type Data = {
- on: BooleanLike;
- voices: string[];
- say_verb: string;
loud: BooleanLike;
name: string;
+ on: BooleanLike;
+ say_verb: string;
+ selected: string;
+ voices: string[];
};
-export const AiVoiceChanger = (props) => {
+export function AiVoiceChanger(props) {
const { act, data } = useBackend();
- const { loud, name, on, say_verb, voices } = data;
+ const { loud, name, on, say_verb, voices, selected } = data;
return (
-
);
-};
+}
diff --git a/tgui/packages/tgui/interfaces/AlertModal.tsx b/tgui/packages/tgui/interfaces/AlertModal.tsx
index d5b931dc08c..62b6e8bbbc3 100644
--- a/tgui/packages/tgui/interfaces/AlertModal.tsx
+++ b/tgui/packages/tgui/interfaces/AlertModal.tsx
@@ -1,33 +1,29 @@
-import { useState } from 'react';
+import { KEY } from 'common/keys';
+import { BooleanLike } from 'common/react';
+import { KeyboardEvent, useState } from 'react';
-import {
- KEY_ENTER,
- KEY_ESCAPE,
- KEY_LEFT,
- KEY_RIGHT,
- KEY_SPACE,
- KEY_TAB,
-} from '../../common/keycodes';
import { useBackend } from '../backend';
-import { Autofocus, Box, Button, Flex, Section, Stack } from '../components';
+import { Autofocus, Box, Button, Section, Stack } from '../components';
import { Window } from '../layouts';
import { Loader } from './common/Loader';
-type AlertModalData = {
- autofocus: boolean;
+type Data = {
+ autofocus: BooleanLike;
buttons: string[];
- large_buttons: boolean;
+ large_buttons: BooleanLike;
message: string;
- swapped_buttons: boolean;
+ swapped_buttons: BooleanLike;
timeout: number;
title: string;
};
-const KEY_DECREMENT = -1;
-const KEY_INCREMENT = 1;
+enum DIRECTION {
+ Increment = 1,
+ Decrement = -1,
+}
-export const AlertModal = (props) => {
- const { act, data } = useBackend();
+export function AlertModal(props) {
+ const { act, data } = useBackend();
const {
autofocus,
buttons = [],
@@ -36,128 +32,148 @@ export const AlertModal = (props) => {
timeout,
title,
} = data;
+
const [selected, setSelected] = useState(0);
+
+ // At least one of the buttons has a long text message
+ const isVerbose = buttons.some((button) => button.length > 10);
+ const largeSpacing = isVerbose && large_buttons ? 20 : 15;
+
// Dynamically sets window dimensions
const windowHeight =
- 115 +
+ 120 +
+ (isVerbose ? largeSpacing * buttons.length : 0) +
(message.length > 30 ? Math.ceil(message.length / 4) : 0) +
(message.length && large_buttons ? 5 : 0);
- const windowWidth = 325 + (buttons.length > 2 ? 55 : 0);
- const onKey = (direction: number) => {
- if (selected === 0 && direction === KEY_DECREMENT) {
- setSelected(buttons.length - 1);
- } else if (selected === buttons.length - 1 && direction === KEY_INCREMENT) {
- setSelected(0);
- } else {
- setSelected(selected + direction);
+
+ const windowWidth = 345 + (buttons.length > 2 ? 55 : 0);
+
+ /** Changes button selection, etc */
+ function keyDownHandler(event: KeyboardEvent) {
+ switch (event.key) {
+ case KEY.Space:
+ case KEY.Enter:
+ act('choose', { choice: buttons[selected] });
+ return;
+ case KEY.Escape:
+ act('cancel');
+ return;
+ case KEY.Left:
+ event.preventDefault();
+ onKey(DIRECTION.Decrement);
+ return;
+ case KEY.Tab:
+ case KEY.Right:
+ event.preventDefault();
+ onKey(DIRECTION.Increment);
+ return;
}
- };
+ }
+
+ /** Manages iterating through the buttons */
+ function onKey(direction: DIRECTION) {
+ const newIndex = (selected + direction + buttons.length) % buttons.length;
+ setSelected(newIndex);
+ }
return (
{!!timeout && }
- {
- const keyCode = window.event ? e.which : e.keyCode;
- /**
- * Simulate a click when pressing space or enter,
- * allow keyboard navigation, override tab behavior
- */
- if (keyCode === KEY_SPACE || keyCode === KEY_ENTER) {
- act('choose', { choice: buttons[selected] });
- } else if (keyCode === KEY_ESCAPE) {
- act('cancel');
- } else if (keyCode === KEY_LEFT) {
- e.preventDefault();
- onKey(KEY_DECREMENT);
- } else if (keyCode === KEY_TAB || keyCode === KEY_RIGHT) {
- e.preventDefault();
- onKey(KEY_INCREMENT);
- }
- }}
- >
+
-
+
{message}
-
+
{!!autofocus && }
-
+ {isVerbose ? (
+
+ ) : (
+
+ )}
);
+}
+
+type ButtonDisplayProps = {
+ selected: number;
};
/**
* Displays a list of buttons ordered by user prefs.
- * Technically this handles more than 2 buttons, but you
- * should just be using a list input in that case.
*/
-const ButtonDisplay = (props) => {
- const { data } = useBackend();
+function HorizontalButtons(props: ButtonDisplayProps) {
+ const { act, data } = useBackend();
const { buttons = [], large_buttons, swapped_buttons } = data;
const { selected } = props;
return (
-
- {buttons?.map((button, index) =>
- !!large_buttons && buttons.length < 3 ? (
-
-
-
- ) : (
-
-
-
- ),
- )}
-
+
+ {buttons.map((button, index) => (
+
+ act('choose', { choice: button })}
+ overflowX="hidden"
+ px={2}
+ py={large_buttons ? 0.5 : 0}
+ selected={selected === index}
+ textAlign="center"
+ >
+ {!large_buttons ? button : button.toUpperCase()}
+
+
+ ))}
+
);
-};
+}
/**
- * Displays a button with variable sizing.
+ * Technically the parent handles more than 2 buttons, but you
+ * should just be using a list input in that case.
*/
-const AlertButton = (props) => {
- const { act, data } = useBackend();
- const { large_buttons } = data;
- const { button, selected } = props;
- const buttonWidth = button.length > 7 ? button.length : 7;
+function VerticalButtons(props: ButtonDisplayProps) {
+ const { act, data } = useBackend();
+ const { buttons = [], large_buttons, swapped_buttons } = data;
+ const { selected } = props;
return (
- act('choose', { choice: button })}
- m={0.5}
- pl={2}
- pr={2}
- pt={large_buttons ? 0.33 : 0}
- selected={selected}
- textAlign="center"
- width={!large_buttons && buttonWidth}
+
- {!large_buttons ? button : button.toUpperCase()}
-
+ {buttons.map((button, index) => (
+
+ act('choose', { choice: button })}
+ overflowX="hidden"
+ px={2}
+ py={large_buttons ? 0.5 : 0}
+ selected={selected === index}
+ textAlign="center"
+ >
+ {!large_buttons ? button : button.toUpperCase()}
+
+
+ ))}
+
);
-};
+}
diff --git a/tgui/packages/tgui/interfaces/Cargo.jsx b/tgui/packages/tgui/interfaces/Cargo.jsx
deleted file mode 100644
index cbc0f5b112b..00000000000
--- a/tgui/packages/tgui/interfaces/Cargo.jsx
+++ /dev/null
@@ -1,576 +0,0 @@
-import { filter, sortBy } from 'common/collections';
-
-import { useBackend, useSharedState } from '../backend';
-import {
- AnimatedNumber,
- Box,
- Button,
- Flex,
- Icon,
- Input,
- LabeledList,
- NoticeBox,
- RestrictedInput,
- Section,
- Stack,
- Table,
- Tabs,
-} from '../components';
-import { formatMoney } from '../format';
-import { Window } from '../layouts';
-
-export const Cargo = (props) => {
- return (
-
-
-
-
-
- );
-};
-
-export const CargoContent = (props) => {
- /* SKYRAT EDIT BELOW - ADDS act */
- const { act, data } = useBackend();
- /* SKYRAT EDIT END */
- const [tab, setTab] = useSharedState('tab', 'catalog');
- const { cart = [], requests = [], requestonly } = data;
- const cart_length = cart.reduce((total, entry) => total + entry.amount, 0);
-
- return (
-
-
-
-
- setTab('catalog')}
- >
- Catalog
-
- 0 && 'yellow'}
- selected={tab === 'requests'}
- onClick={() => setTab('requests')}
- >
- Requests ({requests.length})
-
- act('company_import_window')}
- >
- Company Imports
-
- {!requestonly && (
- <>
- 0 && 'yellow'}
- selected={tab === 'cart'}
- onClick={() => setTab('cart')}
- >
- Checkout ({cart_length})
-
- setTab('help')}
- >
- Help
-
- >
- )}
-
-
- {tab === 'catalog' && }
- {tab === 'requests' && }
- {tab === 'cart' && }
- {tab === 'help' && }
- {tab === 'company_import_window' && tab === 'catalog'}
-
- );
-};
-
-const CargoStatus = (props) => {
- const { act, data } = useBackend();
- const {
- department,
- grocery,
- away,
- docked,
- loan,
- loan_dispatched,
- location,
- message,
- points,
- requestonly,
- can_send,
- } = data;
-
- return (
-
- formatMoney(value)}
- />
- {' credits'}
-
- }
- >
-
-
- {(docked && !requestonly && can_send && (
- act('send')}
- />
- )) ||
- location}
-
- {message}
- {!!loan && !requestonly && (
-
- {(!loan_dispatched && (
- act('loan')}
- />
- )) || Loaned to Centcom }
-
- )}
-
-
- );
-};
-
-/**
- * Take entire supplies tree
- * and return a flat supply pack list that matches search,
- * sorted by name and only the first page.
- * @param {any[]} supplies Supplies list.
- * @param {string} search The search term
- * @returns {any[]} The flat list of supply packs.
- */
-const searchForSupplies = (supplies, search) => {
- search = search.toLowerCase();
-
- const queriedSupplies = sortBy(
- filter(
- supplies.flatMap((category) => category.packs),
- (pack) =>
- pack.name?.toLowerCase().includes(search.toLowerCase()) ||
- pack.desc?.toLowerCase().includes(search.toLowerCase()),
- ),
- (pack) => pack.name,
- );
-
- return queriedSupplies.slice(0, 25);
-};
-
-export const CargoCatalog = (props) => {
- const { express } = props;
- const { act, data } = useBackend();
-
- const { self_paid, app_cost } = data;
-
- const supplies = Object.values(data.supplies);
- const { amount_by_name = [], max_order } = data;
-
- const [activeSupplyName, setActiveSupplyName] = useSharedState(
- 'supply',
- supplies[0]?.name,
- );
-
- const [searchText, setSearchText] = useSharedState('search_text', '');
-
- const activeSupply =
- activeSupplyName === 'search_results'
- ? { packs: searchForSupplies(supplies, searchText) }
- : supplies.find((supply) => supply.name === activeSupplyName);
-
- return (
-
- );
-};
-
-const CargoRequests = (props) => {
- const { act, data } = useBackend();
- const { requestonly, can_send, can_approve_requests } = data;
- const requests = data.requests || [];
- // Labeled list reimplementation to squeeze extra columns out of it
- return (
-
act('denyall')}
- />
- )
- }
- >
- {requests.length === 0 && No Requests }
- {requests.length > 0 && (
-
- {requests.map((request) => (
-
-
- #{request.id}
-
- {request.object}
-
- {request.orderer}
-
-
- {request.reason}
-
-
- {formatMoney(request.cost)} cr
-
- {(!requestonly || can_send) && can_approve_requests && (
-
-
- act('approve', {
- id: request.id,
- })
- }
- />
-
- act('deny', {
- id: request.id,
- })
- }
- />
-
- )}
-
- ))}
-
- )}
-
- );
-};
-
-const CargoCartButtons = (props) => {
- const { act, data } = useBackend();
- const { requestonly, can_send, can_approve_requests } = data;
- const cart = data.cart || [];
- const total = cart.reduce((total, entry) => total + entry.cost, 0);
- return (
- <>
-
- {cart.length === 0 && 'Cart is empty'}
- {cart.length === 1 && '1 item'}
- {cart.length >= 2 && cart.length + ' items'}{' '}
- {total > 0 && `(${formatMoney(total)} cr)`}
-
- {!requestonly && !!can_send && !!can_approve_requests && (
-
act('clear')}
- />
- )}
- >
- );
-};
-
-const CartHeader = (props) => {
- const { data } = useBackend();
- return (
-
-
- Current-Cart
-
- Quantity
-
-
-
-
-
-
- );
-};
-
-const CargoCart = (props) => {
- const { act, data } = useBackend();
- const {
- requestonly,
- away,
- docked,
- location,
- can_send,
- amount_by_name,
- max_order,
- } = data;
- const cart = data.cart || [];
- return (
-
-
- {cart.length === 0 && Nothing in cart }
- {cart.length > 0 && (
-
- )}
- {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/CargoCatalog.tsx b/tgui/packages/tgui/interfaces/Cargo/CargoCatalog.tsx
new file mode 100644
index 00000000000..baccf90c4bd
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/Cargo/CargoCatalog.tsx
@@ -0,0 +1,238 @@
+import { sortBy } from 'common/collections';
+import { useMemo } from 'react';
+
+import { useBackend, useSharedState } from '../../backend';
+import {
+ Button,
+ Icon,
+ Input,
+ Section,
+ Stack,
+ Table,
+ Tabs,
+ Tooltip,
+} from '../../components';
+import { formatMoney } from '../../format';
+import { CargoCartButtons } from './CargoButtons';
+import { searchForSupplies } from './helpers';
+import { CargoData, Supply, SupplyCategory } from './types';
+
+type Props = {
+ express?: boolean;
+};
+
+export function CargoCatalog(props: Props) {
+ const { express } = props;
+ const { act, data } = useBackend();
+ const { self_paid } = data;
+
+ const supplies = Object.values(data.supplies);
+
+ const [activeSupplyName, setActiveSupplyName] = useSharedState(
+ 'supply',
+ supplies[0]?.name,
+ );
+
+ const [searchText, setSearchText] = useSharedState('search_text', '');
+
+ const packs = useMemo(() => {
+ let fetched: Supply[] | undefined;
+
+ if (activeSupplyName === 'search_results') {
+ fetched = searchForSupplies(supplies, searchText);
+ } else {
+ fetched = supplies.find(
+ (supply) => supply.name === activeSupplyName,
+ )?.packs;
+ }
+
+ if (!fetched) return [];
+
+ fetched = sortBy(fetched, (pack: Supply) => pack.name);
+
+ return fetched;
+ }, [activeSupplyName, supplies, searchText]);
+
+ return (
+
+
+ act('toggleprivate')}
+ tooltip="Use your own funds to purchase items."
+ >
+ Buy Privately
+
+ >
+ )
+ }
+ >
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+type CatalogTabsProps = {
+ activeSupplyName: string;
+ categories: SupplyCategory[];
+ searchText: string;
+ setActiveSupplyName: (name: string) => void;
+ setSearchText: (text: string) => void;
+};
+
+function CatalogTabs(props: CatalogTabsProps) {
+ const {
+ activeSupplyName,
+ categories,
+ searchText,
+ setActiveSupplyName,
+ setSearchText,
+ } = props;
+
+ const sorted = sortBy(categories, (supply) => supply.name);
+
+ return (
+
+
+
+
+
+
+
+ {
+ if (value === searchText) {
+ return;
+ }
+
+ if (value.length) {
+ // Start showing results
+ setActiveSupplyName('search_results');
+ } else if (activeSupplyName === 'search_results') {
+ // return to normal category
+ setActiveSupplyName(sorted[0]?.name);
+ }
+ setSearchText(value);
+ }}
+ />
+
+
+
+
+ {sorted.map((supply) => (
+ {
+ setActiveSupplyName(supply.name);
+ setSearchText('');
+ }}
+ >
+
+ {supply.name}
+ {supply.packs.length}
+
+
+ ))}
+
+ );
+}
+
+type CatalogListProps = {
+ packs: SupplyCategory['packs'];
+};
+
+function CatalogList(props: CatalogListProps) {
+ const { act, data } = useBackend();
+ const { amount_by_name = {}, max_order, self_paid, app_cost } = data;
+ const { packs = [] } = props;
+
+ return (
+
+
+ {packs.map((pack) => {
+ let color = '';
+ const digits = Math.floor(Math.log10(pack.cost) + 1);
+ if (self_paid) {
+ color = 'caution';
+ } else if (digits >= 5 && digits <= 6) {
+ color = 'yellow';
+ } else if (digits > 6) {
+ color = 'bad';
+ }
+
+ return (
+
+ {pack.name}
+
+ {!!pack.small_item && (
+
+
+
+ )}
+
+
+ {!!pack.access && (
+
+
+
+ )}
+
+
+ = max_order}
+ onClick={() =>
+ act('add', {
+ id: pack.id,
+ })
+ }
+ minWidth={5}
+ mb={0.5}
+ >
+ {formatMoney(
+ (self_paid && !pack.goody) || app_cost
+ ? Math.round(pack.cost * 1.1)
+ : pack.cost,
+ )}{' '}
+ cr
+
+
+
+ );
+ })}
+
+
+ );
+}
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 && (
+
+
+ ID
+ Object
+ Orderer
+ Reason
+ Cost
+ {(!requestonly || !!can_send) && !!can_approve_requests && (
+ Actions
+ )}
+
+
+ {requests.map((request) => (
+
+ #{request.id}
+ {request.object}
+
+ {request.orderer}
+
+
+ {decodeHtmlEntities(request.reason)}
+
+
+ {formatMoney(request.cost)} cr
+
+ {(!requestonly || !!can_send) && !!can_approve_requests && (
+
+
+ act('approve', {
+ id: request.id,
+ })
+ }
+ />
+
+ act('deny', {
+ id: request.id,
+ })
+ }
+ />
+
+ )}
+
+ ))}
+
+ )}
+
+ );
+}
diff --git a/tgui/packages/tgui/interfaces/Cargo/CargoStatus.tsx b/tgui/packages/tgui/interfaces/Cargo/CargoStatus.tsx
new file mode 100644
index 00000000000..b230400e4e3
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/Cargo/CargoStatus.tsx
@@ -0,0 +1,75 @@
+import { useBackend } from '../../backend';
+import {
+ AnimatedNumber,
+ Box,
+ Button,
+ LabeledList,
+ Section,
+} from '../../components';
+import { formatMoney } from '../../format';
+import { CargoData } from './types';
+
+export function CargoStatus(props) {
+ const { act, data } = useBackend
();
+ const {
+ department,
+ grocery,
+ away,
+ docked,
+ loan,
+ loan_dispatched,
+ location,
+ message,
+ points,
+ requestonly,
+ can_send,
+ } = data;
+
+ return (
+
+ formatMoney(value)}
+ />
+ {' credits'}
+
+ }
+ >
+
+
+ {!!docked && !requestonly && !!can_send ? (
+ act('send')}
+ >
+ {location}
+
+ ) : (
+ String(location)
+ )}
+
+ {message}
+ {!!loan && !requestonly && (
+
+ {!loan_dispatched ? (
+ act('loan')}>
+ Loan Shuttle
+
+ ) : (
+ Loaned to Centcom
+ )}
+
+ )}
+
+
+ );
+}
diff --git a/tgui/packages/tgui/interfaces/Cargo/helpers.ts b/tgui/packages/tgui/interfaces/Cargo/helpers.ts
new file mode 100644
index 00000000000..e6b67f8ff6d
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/Cargo/helpers.ts
@@ -0,0 +1,35 @@
+import { filter } from 'common/collections';
+import { flow } from 'common/fp';
+
+import { Supply, SupplyCategory } from './types';
+
+/**
+ * Take entire supplies tree
+ * and return a flat supply pack list that matches search,
+ * sorted by name and only the first page.
+ * @param {Supply[]} supplies Supplies list, aka Object.values(data.supplies)
+ * @param {string} search The search term
+ * @returns {Supply[]} The flat list of supply packs.
+ */
+export function searchForSupplies(
+ supplies: SupplyCategory[],
+ search: string,
+): Supply[] {
+ const lowerSearch = search.toLowerCase();
+
+ return flow([
+ // Flat categories
+ (initialSupplies: SupplyCategory[]) =>
+ initialSupplies.flatMap((category) => category.packs),
+ // Filter by name or desc
+ (flatMapped: Supply[]) =>
+ filter(
+ flatMapped,
+ (pack: Supply) =>
+ pack.name?.toLowerCase().includes(lowerSearch) ||
+ pack.desc?.toLowerCase().includes(lowerSearch),
+ ),
+ // Just the first page
+ (filtered: Supply[]) => filtered.slice(0, 25),
+ ])(supplies);
+}
diff --git a/tgui/packages/tgui/interfaces/Cargo/index.tsx b/tgui/packages/tgui/interfaces/Cargo/index.tsx
new file mode 100644
index 00000000000..d39435f4cd9
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/Cargo/index.tsx
@@ -0,0 +1,91 @@
+import { useBackend, useSharedState } from '../../backend';
+import { Stack, Tabs } from '../../components';
+import { Window } from '../../layouts';
+import { CargoCart } from './CargoCart';
+import { CargoCatalog } from './CargoCatalog';
+import { CargoHelp } from './CargoHelp';
+import { CargoRequests } from './CargoRequests';
+import { CargoStatus } from './CargoStatus';
+import { CargoData } from './types';
+
+enum TAB {
+ Catalog = 'catalog',
+ Requests = 'requests',
+ Cart = 'cart',
+ Help = 'help',
+}
+
+export function Cargo(props) {
+ return (
+
+
+
+
+
+ );
+}
+
+export function CargoContent(props) {
+ const { data } = useBackend();
+
+ const { cart = [], requests = [], requestonly } = data;
+
+ const [tab, setTab] = useSharedState('cargotab', TAB.Catalog);
+
+ let amount = 0;
+ for (let i = 0; i < cart.length; i++) {
+ amount += cart[i].amount;
+ }
+
+ return (
+
+
+
+
+
+
+ setTab(TAB.Catalog)}
+ >
+ Catalog
+
+ 0 && 'yellow'}
+ selected={tab === TAB.Requests}
+ onClick={() => setTab(TAB.Requests)}
+ >
+ Requests ({requests.length})
+
+ {!requestonly && (
+ <>
+ 0 && 'yellow'}
+ selected={tab === TAB.Cart}
+ onClick={() => setTab(TAB.Cart)}
+ >
+ Checkout ({amount})
+
+ setTab(TAB.Help)}
+ >
+ Help
+
+ >
+ )}
+
+
+
+ {tab === TAB.Catalog && }
+ {tab === TAB.Requests && }
+ {tab === TAB.Cart && }
+ {tab === TAB.Help && }
+
+
+ );
+}
diff --git a/tgui/packages/tgui/interfaces/Cargo/types.ts b/tgui/packages/tgui/interfaces/Cargo/types.ts
new file mode 100644
index 00000000000..4d9e2817d61
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/Cargo/types.ts
@@ -0,0 +1,58 @@
+import { BooleanLike } from 'common/react';
+
+export type CargoData = {
+ amount_by_name: Record | undefined;
+ app_cost?: number;
+ away: BooleanLike;
+ can_approve_requests: BooleanLike;
+ can_send: BooleanLike;
+ cart: CartEntry[];
+ department: string;
+ docked: BooleanLike;
+ grocery: number;
+ loan_dispatched: BooleanLike;
+ loan: BooleanLike;
+ location: string;
+ max_order: number;
+ message: string;
+ points: number;
+ requests: Request[];
+ requestonly: BooleanLike;
+ self_paid: BooleanLike;
+ supplies: Record;
+};
+
+export type SupplyCategory = {
+ name: string;
+ packs: Supply[];
+};
+
+export type Supply = {
+ access: BooleanLike;
+ cost: number;
+ desc: string;
+ goody: BooleanLike;
+ id: string;
+ name: string;
+ small_item: BooleanLike;
+};
+
+type CartEntry = {
+ amount: number;
+ can_be_cancelled: BooleanLike;
+ cost_type: string;
+ cost: number;
+ dep_order: BooleanLike;
+ id: string;
+ object: string;
+ orderer: string;
+ paid: BooleanLike;
+};
+
+type Request = {
+ cost: number;
+ id: string;
+ object: string;
+ orderer: string;
+ reason: string;
+};
diff --git a/tgui/packages/tgui/interfaces/CargoExpress.tsx b/tgui/packages/tgui/interfaces/CargoExpress.tsx
index 0983e685f7d..83947b5adc4 100644
--- a/tgui/packages/tgui/interfaces/CargoExpress.tsx
+++ b/tgui/packages/tgui/interfaces/CargoExpress.tsx
@@ -9,7 +9,7 @@ import {
Section,
} from '../components';
import { Window } from '../layouts';
-import { CargoCatalog } from './Cargo';
+import { CargoCatalog } from './Cargo/CargoCatalog';
import { InterfaceLockNoticeBox } from './common/InterfaceLockNoticeBox';
type Data = {
@@ -24,7 +24,7 @@ type Data = {
message: string;
};
-export const CargoExpress = (props) => {
+export function CargoExpress(props) {
const { data } = useBackend();
const { locked } = data;
@@ -36,9 +36,9 @@ export const CargoExpress = (props) => {
);
-};
+}
-const CargoExpressContent = (props) => {
+function CargoExpressContent(props) {
const { act, data } = useBackend();
const {
hasBeacon,
@@ -64,11 +64,9 @@ const CargoExpressContent = (props) => {
>
- act('LZCargo')}
- />
+ act('LZCargo')}>
+ Cargo Bay
+
{
>
{beaconzone} ({beaconName})
- act('printBeacon')}
- />
+ act('printBeacon')}>
+ {printMsg}
+
{message}
@@ -88,4 +84,4 @@ const CargoExpressContent = (props) => {
>
);
-};
+}
diff --git a/tgui/packages/tgui/interfaces/Changelog.jsx b/tgui/packages/tgui/interfaces/Changelog.jsx
index 5ea40eaa7f4..75fbd98ad2d 100644
--- a/tgui/packages/tgui/interfaces/Changelog.jsx
+++ b/tgui/packages/tgui/interfaces/Changelog.jsx
@@ -141,7 +141,7 @@ export class Changelog extends Component {
{
const index = dateChoices.indexOf(value);
@@ -157,7 +157,7 @@ export class Changelog extends Component {
return this.getData(dates[index]);
}}
selected={selectedDate}
- width={'150px'}
+ width="150px"
/>
diff --git a/tgui/packages/tgui/interfaces/CircuitModule.jsx b/tgui/packages/tgui/interfaces/CircuitModule.jsx
index 799fea9d15f..bbb323e5e5a 100644
--- a/tgui/packages/tgui/interfaces/CircuitModule.jsx
+++ b/tgui/packages/tgui/interfaces/CircuitModule.jsx
@@ -130,7 +130,7 @@ const PortEntry = (props) => {
diff --git a/tgui/packages/tgui/interfaces/CircuitSignalHandler.tsx b/tgui/packages/tgui/interfaces/CircuitSignalHandler.tsx
index 1fc1f8397f9..66d04644391 100644
--- a/tgui/packages/tgui/interfaces/CircuitSignalHandler.tsx
+++ b/tgui/packages/tgui/interfaces/CircuitSignalHandler.tsx
@@ -221,7 +221,7 @@ const Entry = (props: EntryProps) => {
{(options.length && (
diff --git a/tgui/packages/tgui/interfaces/CommandReport.tsx b/tgui/packages/tgui/interfaces/CommandReport.tsx
index dfe8cf9ff3d..9185bebb5b4 100644
--- a/tgui/packages/tgui/interfaces/CommandReport.tsx
+++ b/tgui/packages/tgui/interfaces/CommandReport.tsx
@@ -117,7 +117,7 @@ const AnnouncementColor = (props) => {
act('update_announcement_color', {
@@ -138,7 +138,7 @@ const AnnouncementSound = (props) => {
act('set_report_sound', {
diff --git a/tgui/packages/tgui/interfaces/ControllerOverview.tsx b/tgui/packages/tgui/interfaces/ControllerOverview.tsx
deleted file mode 100644
index 5b5c210b7bb..00000000000
--- a/tgui/packages/tgui/interfaces/ControllerOverview.tsx
+++ /dev/null
@@ -1,245 +0,0 @@
-import { BooleanLike } from 'common/react';
-import { createSearch } from 'common/string';
-import { useMemo, useState } from 'react';
-
-import { useBackend } from '../backend';
-import {
- Button,
- Collapsible,
- Dropdown,
- Input,
- LabeledList,
- Section,
- Stack,
-} from '../components';
-import { Window } from '../layouts';
-
-type SubsystemData = {
- name: string;
- ref: string;
- init_order: number;
- last_fire: number;
- next_fire: number;
- can_fire: BooleanLike;
- doesnt_fire: BooleanLike;
- cost_ms: number;
- tick_usage: number;
- tick_overrun: number;
- initialized: BooleanLike;
- initialization_failure_message: string | undefined;
-};
-
-type ControllerData = {
- world_time: number;
- fast_update: BooleanLike;
- map_cpu: number;
- subsystems: SubsystemData[];
-};
-
-const SubsystemView = (props: { data: SubsystemData }) => {
- const { act } = useBackend();
- const { data } = props;
- const {
- name,
- ref,
- init_order,
- last_fire,
- next_fire,
- can_fire,
- doesnt_fire,
- cost_ms,
- tick_usage,
- tick_overrun,
- initialized,
- initialization_failure_message,
- } = data;
-
- let icon = 'play';
- if (!initialized) {
- icon = 'circle-exclamation';
- } else if (doesnt_fire) {
- icon = 'check';
- } else if (!can_fire) {
- icon = 'pause';
- }
-
- return (
- {
- act('view_variables', { ref: ref });
- }}
- />
- }
- >
-
- {init_order}
- {last_fire}
- {next_fire}
- {cost_ms}ms
-
- {(tick_usage * 0.01).toFixed(2)}%
-
-
- {(tick_overrun * 0.01).toFixed(2)}%
-
- {initialization_failure_message ? (
-
- {initialization_failure_message}
-
- ) : undefined}
-
-
- );
-};
-
-enum SubsystemSortBy {
- INIT_ORDER = 'Init Order',
- NAME = 'Name',
- LAST_FIRE = 'Last Fire',
- NEXT_FIRE = 'Next Fire',
- TICK_USAGE = 'Tick Usage',
- TICK_OVERRUN = 'Tick Overrun',
- COST = 'Cost',
-}
-
-const sortSubsystemBy = (
- subsystems: SubsystemData[],
- sortBy: SubsystemSortBy,
- asending: boolean = true,
-) => {
- let sorted = subsystems.sort((left, right) => {
- switch (sortBy) {
- case SubsystemSortBy.INIT_ORDER:
- return left.init_order - right.init_order;
- case SubsystemSortBy.NAME:
- return left.name.localeCompare(right.name);
- case SubsystemSortBy.LAST_FIRE:
- return left.last_fire - right.last_fire;
- case SubsystemSortBy.NEXT_FIRE:
- return left.next_fire - right.next_fire;
- case SubsystemSortBy.TICK_USAGE:
- return left.tick_usage - right.tick_usage;
- case SubsystemSortBy.TICK_OVERRUN:
- return left.tick_overrun - right.tick_overrun;
- case SubsystemSortBy.COST:
- return left.cost_ms - right.cost_ms;
- }
- });
- if (!asending) {
- sorted.reverse();
- }
- return sorted;
-};
-
-export const ControllerOverview = () => {
- const { act, data } = useBackend();
- const { world_time, map_cpu, subsystems, fast_update } = data;
-
- const [filterName, setFilterName] = useState('');
- const [sortBy, setSortBy] = useState(SubsystemSortBy.NAME);
- const [sortAscending, setSortAscending] = useState(true);
-
- let filteredSubsystems = useMemo(() => {
- if (!filterName) {
- return subsystems;
- }
-
- return subsystems.filter(() =>
- createSearch(filterName, (subsystem: SubsystemData) => subsystem.name),
- );
- }, [filterName, subsystems]);
-
- let sortedSubsystems = useMemo(() => {
- return sortSubsystemBy(filteredSubsystems, sortBy, sortAscending);
- }, [sortBy, sortAscending, filteredSubsystems]);
-
- const overallUsage = subsystems.reduce(
- (acc, subsystem) => acc + subsystem.tick_usage,
- 0,
- );
- const overallOverrun = subsystems.reduce(
- (acc, subsystem) => acc + subsystem.tick_overrun,
- 0,
- );
-
- return (
-
-
-
-
- World Time: {world_time}
- Map CPU: {map_cpu.toFixed(2)}%
-
- Overall Usage: {(overallUsage * 0.01).toFixed(2)}%
-
-
- Overall Overrun: {(overallOverrun * 0.01).toFixed(2)}%
-
-
-
-
-
-
- {sortedSubsystems.map((subsystem) => (
-
- ))}
-
-
-
-
- );
-};
diff --git a/tgui/packages/tgui/interfaces/ControllerOverview/OverviewSection.tsx b/tgui/packages/tgui/interfaces/ControllerOverview/OverviewSection.tsx
new file mode 100644
index 00000000000..919c19631f6
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/ControllerOverview/OverviewSection.tsx
@@ -0,0 +1,57 @@
+import { useBackend } from '../../backend';
+import { Button, LabeledList, Section, Stack } from '../../components';
+import { ControllerData } from './types';
+
+export function OverviewSection(props) {
+ const { act, data } = useBackend();
+ const { fast_update, map_cpu, subsystems = [], world_time } = data;
+
+ let overallUsage = 0;
+ let overallOverrun = 0;
+ for (let i = 0; i < subsystems.length; i++) {
+ overallUsage += subsystems[i].tick_usage;
+ overallOverrun += subsystems[i].tick_overrun;
+ }
+
+ return (
+ {
+ act('toggle_fast_update');
+ }}
+ >
+ Fast
+
+ }
+ >
+
+
+
+
+ {world_time.toFixed(1)}
+
+
+ {map_cpu.toFixed(2)}%
+
+
+
+
+
+
+ {(overallUsage * 0.01).toFixed(2)}%
+
+
+ {(overallOverrun * 0.01).toFixed(2)}%
+
+
+
+
+
+ );
+}
diff --git a/tgui/packages/tgui/interfaces/ControllerOverview/SubsystemDialog.tsx b/tgui/packages/tgui/interfaces/ControllerOverview/SubsystemDialog.tsx
new file mode 100644
index 00000000000..21acd2dca1d
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/ControllerOverview/SubsystemDialog.tsx
@@ -0,0 +1,69 @@
+import {
+ Box,
+ Button,
+ Divider,
+ LabeledList,
+ Modal,
+ Stack,
+} from '../../components';
+import { SubsystemData } from './types';
+
+type Props = {
+ subsystem: SubsystemData;
+ onClose: () => void;
+};
+
+export function SubsystemDialog(props: Props) {
+ const { subsystem, onClose } = props;
+ const {
+ cost_ms,
+ init_order,
+ initialization_failure_message,
+ last_fire,
+ name,
+ next_fire,
+ tick_overrun,
+ tick_usage,
+ } = subsystem;
+
+ return (
+
+
+
+ {name}
+
+
+
+
+
+
+
+
+ {init_order}
+ {last_fire}
+ {next_fire}
+ {cost_ms}ms
+
+ {(tick_usage * 0.01).toFixed(2)}%
+
+
+ {(tick_overrun * 0.01).toFixed(2)}%
+
+ {initialization_failure_message && (
+
+ {initialization_failure_message}
+
+ )}
+
+
+
+
+
+
+ Close
+
+
+
+
+ );
+}
diff --git a/tgui/packages/tgui/interfaces/ControllerOverview/SubsystemRow.tsx b/tgui/packages/tgui/interfaces/ControllerOverview/SubsystemRow.tsx
new file mode 100644
index 00000000000..0a0bef6a9e6
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/ControllerOverview/SubsystemRow.tsx
@@ -0,0 +1,107 @@
+import { Dispatch } from 'react';
+
+import { useBackend } from '../../backend';
+import {
+ Button,
+ Icon,
+ ProgressBar,
+ Stack,
+ Table,
+ Tooltip,
+} from '../../components';
+import { SORTING_TYPES } from './contants';
+import { SortType, SubsystemData } from './types';
+
+type Props = {
+ max: number;
+ setSelected: Dispatch;
+ showBars: boolean;
+ sortType: SortType;
+ subsystem: SubsystemData;
+};
+
+export function SubsystemRow(props: Props) {
+ const { act } = useBackend();
+ const { max, setSelected, showBars, sortType, subsystem } = props;
+ const { can_fire, doesnt_fire, initialized, name, ref } = subsystem;
+
+ const { propName } = SORTING_TYPES[sortType];
+ const value = subsystem[propName];
+
+ let icon = 'play';
+ let color = 'good';
+ let tooltip = 'Operational';
+ if (!initialized) {
+ icon = 'circle-exclamation';
+ color = 'darkgreen';
+ tooltip = 'Not initialized';
+ } else if (doesnt_fire) {
+ icon = 'check';
+ color = 'grey';
+ tooltip = 'Does not fire';
+ } else if (!can_fire) {
+ icon = 'pause';
+ color = 'grey';
+ tooltip = 'Paused';
+ }
+
+ let valueDisplay = '';
+ let rangeDisplay = {};
+ if (showBars) {
+ if (sortType === SortType.Cost) {
+ valueDisplay = value.toFixed(0) + 'ms';
+ rangeDisplay = {
+ average: [75, 124.99],
+ bad: [125, Infinity],
+ };
+ } else {
+ valueDisplay = (value * 0.01).toFixed(2) + '%';
+ rangeDisplay = {
+ average: [10, 24.99],
+ bad: [25, Infinity],
+ };
+ }
+ } else {
+ valueDisplay = value;
+ }
+
+ return (
+
+
+
+
+
+
+ setSelected(subsystem)}>
+ {showBars ? (
+
+ {name} {valueDisplay}
+
+ ) : (
+
+
+ {name}
+
+ {sortType !== SortType.Name && valueDisplay}
+
+
+
+ )}
+
+
+ {
+ act('view_variables', { ref: ref });
+ }}
+ />
+
+
+ );
+}
diff --git a/tgui/packages/tgui/interfaces/ControllerOverview/SubsystemViews.tsx b/tgui/packages/tgui/interfaces/ControllerOverview/SubsystemViews.tsx
new file mode 100644
index 00000000000..13ea5f3a160
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/ControllerOverview/SubsystemViews.tsx
@@ -0,0 +1,114 @@
+import { Dispatch, useEffect, useState } from 'react';
+
+import { useBackend } from '../../backend';
+import { Button, Section, Stack, Table } from '../../components';
+import { SORTING_TYPES } from './contants';
+import { FilterState } from './filters';
+import { SubsystemRow } from './SubsystemRow';
+import { ControllerData, SubsystemData } from './types';
+
+type Props = {
+ filterOpts: FilterState;
+ setSelected: Dispatch;
+};
+
+export function SubsystemViews(props: Props) {
+ const { data } = useBackend();
+ const { subsystems } = data;
+
+ const { filterOpts, setSelected } = props;
+ const { ascending, inactive, query, smallValues, sortType } = filterOpts;
+ const { propName, inDeciseconds } = SORTING_TYPES[sortType];
+
+ const [bars, setBars] = useState(inDeciseconds);
+
+ const sorted = subsystems
+ .filter((subsystem) => {
+ // Matches search
+ const nameMatchesQuery = subsystem.name
+ .toLowerCase()
+ .includes(query?.toLowerCase());
+
+ // Filters out based on inactive
+ if (inactive && (!!subsystem.doesnt_fire || !subsystem.can_fire)) {
+ return false;
+ }
+
+ // Filters out based on small values
+ if (smallValues && subsystem[propName] < 1) {
+ return false;
+ }
+
+ return nameMatchesQuery;
+ })
+ .sort((a, b) => {
+ if (ascending) {
+ return a[propName] > b[propName] ? 1 : -1;
+ } else {
+ return b[propName] > a[propName] ? 1 : -1;
+ }
+ });
+
+ // Gets our totals for bar display
+ const totals: number[] = [];
+ let currentMax = 0;
+ if (inDeciseconds) {
+ for (let i = 0; i < sorted.length; i++) {
+ let value = sorted[i][propName];
+ if (typeof value !== 'number') {
+ continue;
+ }
+
+ totals.push(value);
+ }
+
+ currentMax = Math.max(...totals);
+ }
+
+ // Toggles default bar view for valid cases
+ useEffect(() => {
+ if (inDeciseconds && !bars) {
+ setBars(true);
+ } else if (!inDeciseconds && bars) {
+ setBars(false);
+ }
+ }, [inDeciseconds]);
+
+ return (
+
+
+ ({sorted.length} / {subsystems.length})
+
+
+ setBars(!bars)}
+ selected={bars}
+ >
+ Bars
+
+
+
+ }
+ >
+
+ {sorted.map((subsystem) => (
+
+ ))}
+
+
+ );
+}
diff --git a/tgui/packages/tgui/interfaces/ControllerOverview/contants.ts b/tgui/packages/tgui/interfaces/ControllerOverview/contants.ts
new file mode 100644
index 00000000000..fdd28bfd36b
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/ControllerOverview/contants.ts
@@ -0,0 +1,43 @@
+type SortType = {
+ label: string;
+ propName: string;
+ inDeciseconds: boolean;
+};
+
+export const SORTING_TYPES: readonly SortType[] = [
+ {
+ label: 'Alphabetical',
+ propName: 'name',
+ inDeciseconds: false,
+ },
+ {
+ label: 'Cost',
+ propName: 'cost_ms',
+ inDeciseconds: true,
+ },
+ {
+ label: 'Init Order',
+ propName: 'init_order',
+ inDeciseconds: false,
+ },
+ {
+ label: 'Last Fire',
+ propName: 'last_fire',
+ inDeciseconds: false,
+ },
+ {
+ label: 'Next Fire',
+ propName: 'next_fire',
+ inDeciseconds: false,
+ },
+ {
+ label: 'Tick Usage',
+ propName: 'tick_usage',
+ inDeciseconds: true,
+ },
+ {
+ label: 'Tick Overrun',
+ propName: 'tick_overrun',
+ inDeciseconds: true,
+ },
+];
diff --git a/tgui/packages/tgui/interfaces/ControllerOverview/filters.ts b/tgui/packages/tgui/interfaces/ControllerOverview/filters.ts
new file mode 100644
index 00000000000..8d975ac9a71
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/ControllerOverview/filters.ts
@@ -0,0 +1,45 @@
+import { SortType } from './types';
+
+export type FilterState = {
+ ascending: boolean;
+ inactive: boolean;
+ query: string;
+ smallValues: boolean;
+ sortType: SortType;
+};
+
+export enum FilterAction {
+ Ascending = 'SET_SORT_ASCENDING',
+ Inactive = 'SET_FILTER_INACTIVE',
+ SmallValues = 'SET_FILTER_SMALL_VALUES',
+ SortType = 'SET_SORT_TYPE',
+ Query = 'SET_FILTER_QUERY',
+ Update = 'UPDATE_FILTER',
+}
+
+type Action =
+ | { type: FilterAction.Ascending; payload: boolean }
+ | { type: FilterAction.Inactive; payload: boolean }
+ | { type: FilterAction.SmallValues; payload: boolean }
+ | { type: FilterAction.SortType; payload: SortType }
+ | { type: FilterAction.Query; payload: string }
+ | { type: FilterAction.Update; payload: Partial };
+
+export function filterReducer(state: FilterState, action: Action): FilterState {
+ switch (action.type) {
+ case FilterAction.Inactive:
+ return { ...state, inactive: action.payload };
+ case FilterAction.SmallValues:
+ return { ...state, smallValues: action.payload };
+ case FilterAction.Ascending:
+ return { ...state, ascending: action.payload };
+ case FilterAction.SortType:
+ return { ...state, sortType: action.payload };
+ case FilterAction.Query:
+ return { ...state, query: action.payload };
+ case FilterAction.Update:
+ return { ...state, ...action.payload };
+ default:
+ return state;
+ }
+}
diff --git a/tgui/packages/tgui/interfaces/ControllerOverview/index.tsx b/tgui/packages/tgui/interfaces/ControllerOverview/index.tsx
new file mode 100644
index 00000000000..388d3d43678
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/ControllerOverview/index.tsx
@@ -0,0 +1,152 @@
+import { useReducer, useState } from 'react';
+
+import { Button, Dropdown, Input, Section, Stack } from '../../components';
+import { Window } from '../../layouts';
+import { SORTING_TYPES } from './contants';
+import { FilterAction, filterReducer, FilterState } from './filters';
+import { OverviewSection } from './OverviewSection';
+import { SubsystemDialog } from './SubsystemDialog';
+import { SubsystemViews } from './SubsystemViews';
+import { SortType, SubsystemData } from './types';
+
+export function ControllerOverview(props) {
+ return (
+
+
+
+
+
+ );
+}
+
+export function ControllerContent(props) {
+ const [state, dispatch] = useReducer(filterReducer, {
+ ascending: true,
+ inactive: true,
+ query: '',
+ smallValues: false,
+ sortType: SortType.Name,
+ });
+
+ const [selected, setSelected] = useState();
+
+ const { label, inDeciseconds } =
+ SORTING_TYPES?.[state.sortType] || SORTING_TYPES[0];
+
+ function onSelectionHandler(value: string) {
+ const updates: Partial = {
+ sortType: SORTING_TYPES.findIndex((type) => type.label === value),
+ };
+
+ if (updates.sortType === undefined) return;
+
+ const { inDeciseconds } = SORTING_TYPES[updates.sortType];
+
+ updates.ascending = !inDeciseconds;
+ updates.smallValues = inDeciseconds;
+
+ dispatch({ type: FilterAction.Update, payload: updates });
+ }
+
+ return (
+
+ {selected && (
+ setSelected(undefined)}
+ subsystem={selected}
+ />
+ )}
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/tgui/packages/tgui/interfaces/ControllerOverview/types.ts b/tgui/packages/tgui/interfaces/ControllerOverview/types.ts
new file mode 100644
index 00000000000..604989b1f75
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/ControllerOverview/types.ts
@@ -0,0 +1,33 @@
+import { BooleanLike } from 'common/react';
+
+export type SubsystemData = {
+ can_fire: BooleanLike;
+ cost_ms: number;
+ doesnt_fire: BooleanLike;
+ init_order: number;
+ initialization_failure_message: string | undefined;
+ initialized: BooleanLike;
+ last_fire: number;
+ name: string;
+ next_fire: number;
+ ref: string;
+ tick_overrun: number;
+ tick_usage: number;
+};
+
+export type ControllerData = {
+ world_time: number;
+ fast_update: BooleanLike;
+ map_cpu: number;
+ subsystems: SubsystemData[];
+};
+
+export enum SortType {
+ Name,
+ Cost,
+ InitOrder,
+ LastFire,
+ NextFire,
+ TickUsage,
+ TickOverrun,
+}
diff --git a/tgui/packages/tgui/interfaces/CrewConsole.jsx b/tgui/packages/tgui/interfaces/CrewConsole.jsx
deleted file mode 100644
index ef3f8c31a38..00000000000
--- a/tgui/packages/tgui/interfaces/CrewConsole.jsx
+++ /dev/null
@@ -1,195 +0,0 @@
-import { sortBy } from 'common/collections';
-
-import { useBackend } from '../backend';
-import { Box, Button, Icon, Section, Table } from '../components';
-import { COLORS } from '../constants';
-import { Window } from '../layouts';
-
-const HEALTH_COLOR_BY_LEVEL = [
- '#17d568',
- '#c4cf2d',
- '#e67e22',
- '#ed5100',
- '#e74c3c',
- '#801308',
-];
-
-const STAT_LIVING = 0;
-const STAT_DEAD = 4;
-
-const jobIsHead = (jobId) => jobId % 10 === 0;
-
-const jobToColor = (jobId) => {
- if (jobId === 0) {
- return COLORS.department.captain;
- }
- if (jobId >= 10 && jobId < 20) {
- return COLORS.department.security;
- }
- if (jobId >= 20 && jobId < 30) {
- return COLORS.department.medbay;
- }
- if (jobId >= 30 && jobId < 40) {
- return COLORS.department.science;
- }
- if (jobId >= 40 && jobId < 50) {
- return COLORS.department.engineering;
- }
- if (jobId >= 50 && jobId < 60) {
- return COLORS.department.cargo;
- }
- if (jobId >= 60 && jobId < 200) {
- return COLORS.department.service;
- }
- if (jobId >= 200 && jobId < 230) {
- return COLORS.department.centcom;
- }
- return COLORS.department.other;
-};
-
-const statToIcon = (life_status) => {
- switch (life_status) {
- case STAT_LIVING:
- return 'heart';
- case STAT_DEAD:
- return 'skull';
- }
- return 'heartbeat';
-};
-
-const healthToAttribute = (oxy, tox, burn, brute, attributeList) => {
- const healthSum = oxy + tox + burn + brute;
- const level = Math.min(Math.max(Math.ceil(healthSum / 25), 0), 5);
- return attributeList[level];
-};
-
-const HealthStat = (props) => {
- const { type, value } = props;
- return (
-
- {value}
-
- );
-};
-
-export const CrewConsole = () => {
- return (
-
-
-
-
-
- );
-};
-
-const CrewTable = (props) => {
- const { act, data } = useBackend();
- const sensors = sortBy(data.sensors ?? [], (s) => s.ijob);
- return (
-
-
- Name
-
-
- Vitals
-
-
- Position
-
- {!!data.link_allowed && (
-
- Tracking
-
- )}
-
- {sensors.map((sensor) => (
-
- ))}
-
- );
-};
-
-const CrewTableEntry = (props) => {
- const { act, data } = useBackend();
- const { link_allowed } = data;
- const { sensor_data } = props;
- const {
- name,
- assignment,
- ijob,
- life_status,
- oxydam,
- toxdam,
- burndam,
- brutedam,
- area,
- can_track,
- } = sensor_data;
-
- return (
-
-
- {name}
- {assignment !== undefined ? ` (${assignment})` : ''}
-
-
- {oxydam !== undefined ? (
-
- ) : life_status !== STAT_DEAD ? (
-
- ) : (
-
- )}
-
-
- {oxydam !== undefined ? (
-
-
- {'/'}
-
- {'/'}
-
- {'/'}
-
-
- ) : life_status !== STAT_DEAD ? (
- 'Alive'
- ) : (
- 'Dead'
- )}
-
-
- {area !== undefined ? (
- area
- ) : (
-
- )}
-
- {!!link_allowed && (
-
-
- act('select_person', {
- name: name,
- })
- }
- />
-
- )}
-
- );
-};
diff --git a/tgui/packages/tgui/interfaces/CrewConsole.tsx b/tgui/packages/tgui/interfaces/CrewConsole.tsx
new file mode 100644
index 00000000000..aa4f272f248
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/CrewConsole.tsx
@@ -0,0 +1,307 @@
+import { BooleanLike } from 'common/react';
+import { createSearch } from 'common/string';
+import { useState } from 'react';
+
+import { useBackend } from '../backend';
+import { Box, Button, Icon, Input, Section, Table } from '../components';
+import { COLORS } from '../constants';
+import { Window } from '../layouts';
+
+const HEALTH_COLOR_BY_LEVEL = [
+ '#17d568',
+ '#c4cf2d',
+ '#e67e22',
+ '#ed5100',
+ '#e74c3c',
+ '#801308',
+];
+
+const SORT_NAMES = {
+ ijob: 'Job',
+ name: 'Name',
+ area: 'Position',
+ health: 'Vitals',
+};
+
+const STAT_LIVING = 0;
+const STAT_DEAD = 4;
+
+const SORT_OPTIONS = ['ijob', 'name', 'area', 'health'];
+
+const jobIsHead = (jobId: number) => jobId % 10 === 0;
+
+const jobToColor = (jobId: number) => {
+ if (jobId === 0) {
+ return COLORS.department.captain;
+ }
+ if (jobId >= 10 && jobId < 20) {
+ return COLORS.department.security;
+ }
+ if (jobId >= 20 && jobId < 30) {
+ return COLORS.department.medbay;
+ }
+ if (jobId >= 30 && jobId < 40) {
+ return COLORS.department.science;
+ }
+ if (jobId >= 40 && jobId < 50) {
+ return COLORS.department.engineering;
+ }
+ if (jobId >= 50 && jobId < 60) {
+ return COLORS.department.cargo;
+ }
+ if (jobId >= 60 && jobId < 200) {
+ return COLORS.department.service;
+ }
+ if (jobId >= 200 && jobId < 230) {
+ return COLORS.department.centcom;
+ }
+ return COLORS.department.other;
+};
+
+const statToIcon = (life_status: number) => {
+ switch (life_status) {
+ case STAT_LIVING:
+ return 'heart';
+ case STAT_DEAD:
+ return 'skull';
+ }
+ return 'heartbeat';
+};
+
+const healthSort = (a: CrewSensor, b: CrewSensor) => {
+ if (a.life_status < b.life_status) return -1;
+ if (a.life_status > b.life_status) return 1;
+ if (a.health > b.health) return -1;
+ if (a.health < b.health) return 1;
+ return 0;
+};
+
+const areaSort = (a: CrewSensor, b: CrewSensor) => {
+ a.area ??= '~';
+ b.area ??= '~';
+ if (a.area < b.area) return -1;
+ if (a.area > b.area) return 1;
+ return 0;
+};
+
+const healthToAttribute = (
+ oxy: number,
+ tox: number,
+ burn: number,
+ brute: number,
+ attributeList: string[],
+) => {
+ const healthSum = oxy + tox + burn + brute;
+ const level = Math.min(Math.max(Math.ceil(healthSum / 25), 0), 5);
+ return attributeList[level];
+};
+
+type HealthStatProps = {
+ type: string;
+ value: number;
+};
+
+const HealthStat = (props: HealthStatProps) => {
+ const { type, value } = props;
+ return (
+
+ {value}
+
+ );
+};
+
+export const CrewConsole = () => {
+ return (
+
+
+
+
+
+ );
+};
+
+type CrewSensor = {
+ name: string;
+ assignment: string | undefined;
+ ijob: number;
+ life_status: number;
+ oxydam: number;
+ toxdam: number;
+ burndam: number;
+ brutedam: number;
+ area: string | undefined;
+ health: number;
+ can_track: BooleanLike;
+ ref: string;
+};
+
+type CrewConsoleData = {
+ sensors: CrewSensor[];
+ link_allowed: BooleanLike;
+};
+
+const CrewTable = () => {
+ const { data } = useBackend();
+ const { sensors } = data;
+
+ const [sortAsc, setSortAsc] = useState(true);
+ const [searchQuery, setSearchQuery] = useState('');
+ const [sortBy, setSortBy] = useState(SORT_OPTIONS[0]);
+
+ const cycleSortBy = () => {
+ let idx = SORT_OPTIONS.indexOf(sortBy) + 1;
+ if (idx === SORT_OPTIONS.length) idx = 0;
+ setSortBy(SORT_OPTIONS[idx]);
+ };
+
+ const nameSearch = createSearch(searchQuery, (crew: CrewSensor) => crew.name);
+
+ const sorted = sensors.filter(nameSearch).sort((a, b) => {
+ switch (sortBy) {
+ case 'name':
+ return sortAsc ? +(a.name > b.name) : +(b.name > a.name);
+ case 'ijob':
+ return sortAsc ? a.ijob - b.ijob : b.ijob - a.ijob;
+ case 'health':
+ return sortAsc ? healthSort(a, b) : healthSort(b, a);
+ case 'area':
+ return sortAsc ? areaSort(a, b) : areaSort(b, a);
+ default:
+ return 0;
+ }
+ });
+
+ return (
+
+ );
+};
+
+type CrewTableEntryProps = {
+ sensor_data: CrewSensor;
+};
+
+const CrewTableEntry = (props: CrewTableEntryProps) => {
+ const { act, data } = useBackend();
+ const { link_allowed } = data;
+ const { sensor_data } = props;
+ const {
+ name,
+ assignment,
+ ijob,
+ life_status,
+ oxydam,
+ toxdam,
+ burndam,
+ brutedam,
+ area,
+ can_track,
+ } = sensor_data;
+
+ return (
+
+
+ {name}
+ {assignment !== undefined ? ` (${assignment})` : ''}
+
+
+ {oxydam !== undefined ? (
+
+ ) : life_status !== STAT_DEAD ? (
+
+ ) : (
+
+ )}
+
+
+ {oxydam !== undefined ? (
+
+
+ {'/'}
+
+ {'/'}
+
+ {'/'}
+
+
+ ) : life_status !== STAT_DEAD ? (
+ 'Alive'
+ ) : (
+ 'Dead'
+ )}
+
+
+ {area !== '~' && area !== undefined ? (
+ area
+ ) : (
+
+ )}
+
+ {!!link_allowed && (
+
+
+ act('select_person', {
+ name: name,
+ })
+ }
+ >
+ Track
+
+
+ )}
+
+ );
+};
diff --git a/tgui/packages/tgui/interfaces/CrewConsoleSkyrat.jsx b/tgui/packages/tgui/interfaces/CrewConsoleSkyrat.jsx
index 6768138a5fe..2818836f733 100644
--- a/tgui/packages/tgui/interfaces/CrewConsoleSkyrat.jsx
+++ b/tgui/packages/tgui/interfaces/CrewConsoleSkyrat.jsx
@@ -88,7 +88,7 @@ export const CrewConsoleSkyrat = () => {
const CrewTable = (props) => {
const { act, data } = useBackend();
- const sensors = sortBy((s) => s.ijob)(data.sensors ?? []);
+ const sensors = sortBy(data.sensors ?? [], (s) => s.ijob);
return (
diff --git a/tgui/packages/tgui/interfaces/DeathmatchLobby.tsx b/tgui/packages/tgui/interfaces/DeathmatchLobby.tsx
index 457c909b2ca..12dad26bc71 100644
--- a/tgui/packages/tgui/interfaces/DeathmatchLobby.tsx
+++ b/tgui/packages/tgui/interfaces/DeathmatchLobby.tsx
@@ -6,228 +6,315 @@ import {
Button,
Divider,
Dropdown,
- Flex,
Icon,
+ LabeledList,
Modal,
+ NoticeBox,
Section,
+ Stack,
Table,
+ Tooltip,
} from '../components';
import { ButtonCheckbox } from '../components/Button';
import { Window } from '../layouts';
-type PlayerLike = {
- [key: string]: {
- host: number;
- ready: BooleanLike;
- };
+type Player = Record;
+
+type PlayerInfo = {
+ host: number;
+ ready: BooleanLike;
};
type Modifier = {
- name: string;
desc: string;
modpath: string;
- selected: BooleanLike;
- selectable: BooleanLike;
- player_selected: BooleanLike;
+ name: string;
player_selectable: BooleanLike;
+ player_selected: BooleanLike;
+ selectable: BooleanLike;
+ selected: BooleanLike;
+};
+
+type Map = {
+ desc: string;
+ max_players: number;
+ min_players: number;
+ name: string;
+ time: number;
};
type Data = {
- self: string;
- host: BooleanLike;
+ active_mods: string;
admin: BooleanLike;
- playing: BooleanLike;
+ host: BooleanLike;
+ loadoutdesc: string;
loadouts: string[];
+ map: Map;
maps: string[];
- map: {
- name: string;
- desc: string;
- time: number;
- min_players: number;
- max_players: number;
- };
mod_menu_open: BooleanLike;
modifiers: Modifier[];
- active_mods: string;
- loadoutdesc: string;
- players: PlayerLike[];
- observers: PlayerLike[];
+ observers: Player[];
+ players: Player[];
+ playing: BooleanLike;
+ self: string;
};
-export const DeathmatchLobby = (props) => {
+export function DeathmatchLobby(props) {
const { act, data } = useBackend();
- const { modifiers = [] } = data;
+ const { admin, observers = [], self, players } = data;
+
+ const allReady = Object.keys(players).every(
+ (player) => players[player].ready,
+ );
+
return (
-
-
-
-
-
-
- Name
- Loadout
- Ready
-
- {Object.keys(data.players).map((player) => (
-
-
- {!!data.players[player].host && }
-
-
- {(!(
- (data.host && !data.players[player].host) ||
- data.admin
- ) && {player} ) || (
-
- act('host', {
- id: player,
- func: value,
- })
- }
- />
- )}
-
-
-
- act('change_loadout', {
- player: player,
- loadout: value,
- })
- }
- />
-
-
- act('ready')}
- />
-
-
- ))}
- {Object.keys(data.observers).map((observer) => (
-
-
- {(!!data.observers[observer].host && (
-
- )) || }
-
-
- {(!(
- (data.host && !data.observers[observer].host) ||
- data.admin
- ) && {observer} ) || (
-
- act('host', {
- id: observer,
- func: value,
- })
- }
- />
- )}
-
- Observing
-
- ))}
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
- {(!!data.host && (
-
- act('host', {
- func: 'change_map',
- map: value,
- })
- }
- />
- )) || {data.map.name} }
-
-
- {data.map.desc}
-
-
- Maximum Play Time: {`${data.map.time / 600}min`}
-
- Min players: {data.map.min_players}
-
- Max players: {data.map.max_players}
-
- Current players: {Object.keys(data.players).length}
-
-
- {data.active_mods}
- {(!!data.admin || !!data.host) && (
- <>
-
+
+
+ {!!admin && (
+ act('admin', { func: 'Force start' })}
+ >
+ Force Start
+
+ )}
+
+
+ act('observe')}>
+ {observers[self] ? 'Join' : 'Observe'}
+
+ act('leave_game')}>
+ Leave Game
+
act('open_mod_menu')}
- />
- >
- )}
-
- Loadout Description
-
- {data.loadoutdesc}
- {!!data.playing && (
- <>
-
-
- The game is currently in progress, or loading.
-
- >
- )}
+ color="good"
+ disabled={!allReady}
+ onClick={() => act('start_game')}
+ >
+ Start Game
+
+
+
-
-
- act('start_game')}
- />
- act('leave_game')}
- />
- act('observe')}
- />
- {!!data.admin && (
- act('admin', { func: 'Force start' })}
- />
- )}
+
+
);
-};
+}
+
+function PlayerColumn(props) {
+ const { act, data } = useBackend();
+ const {
+ admin,
+ host,
+ loadouts = [],
+ observers = [],
+ players = [],
+ self,
+ } = data;
+
+ const allReady = Object.keys(players).every(
+ (player) => players[player].ready,
+ );
+
+ return (
+ 30}>
+
+
+
+ Name
+ Loadout
+
+
+
+
+
+
+ {Object.keys(players).map((player) => {
+ const fullAccess = (!!host && !!players[player].host) || !admin;
+
+ return (
+
+
+ {!!players[player].host && }
+
+
+ {!fullAccess ? (
+ {player}
+ ) : (
+
+ act('host', {
+ id: player,
+ func: value,
+ })
+ }
+ />
+ )}
+
+
+
+ act('change_loadout', {
+ player: player,
+ loadout: value,
+ })
+ }
+ />
+
+
+ act('ready')}
+ />
+
+
+ );
+ })}
+ {Object.keys(observers).map((observer) => {
+ const fullAccess = (!!host && !!players[observer].host) || admin;
+
+ return (
+
+
+ {(!!observers[observer].host && ) || (
+
+ )}
+
+
+ {!fullAccess ? (
+ {observer}
+ ) : (
+
+ act('host', {
+ id: observer,
+ func: value,
+ })
+ }
+ />
+ )}
+
+ Observing
+
+ );
+ })}
+
+
+ );
+}
+
+function HostControls(props) {
+ const { act, data } = useBackend();
+ const {
+ active_mods = [],
+ admin,
+ host,
+ loadoutdesc,
+ map,
+ maps = [],
+ players = [],
+ playing,
+ } = data;
+
+ return (
+
+ {!host ? (
+ {map.name}
+ ) : (
+
+ act('host', {
+ func: 'change_map',
+ map: value,
+ })
+ }
+ />
+ )}
+
+ {map.desc}
+
+
+
+ {`${map.time / 600}min`}
+
+
+ {map.min_players}
+
+
+ {map.max_players}
+
+
+ {Object.keys(players).length}
+
+
+
+
+ {active_mods}
+
+ {(!!admin || !!host) && (
+ <>
+
+ act('open_mod_menu')}>
+ Toggle Modifiers
+
+ >
+ )}
+
+
+ Loadout Description
+
+
+ {loadoutdesc}
+ {!!playing && (
+ <>
+
+
+ The game is currently in progress, or loading.
+
+ >
+ )}
+
+ );
+}
const ModSelector = (props) => {
const { act, data } = useBackend();
@@ -235,21 +322,18 @@ const ModSelector = (props) => {
if (!mod_menu_open || !(host || admin)) {
return null;
}
+
return (
- act('exit_mod_menu')}
- />
+ act('exit_mod_menu')}>
+ Go Back
+
{modifiers.map((mod, index) => {
return (
{
modpath: mod.modpath,
})
}
- />
+ >
+ {mod.name}
+
);
})}
diff --git a/tgui/packages/tgui/interfaces/DeathmatchPanel.jsx b/tgui/packages/tgui/interfaces/DeathmatchPanel.jsx
deleted file mode 100644
index 8ac2ff5f76d..00000000000
--- a/tgui/packages/tgui/interfaces/DeathmatchPanel.jsx
+++ /dev/null
@@ -1,95 +0,0 @@
-import { useBackend } from '../backend';
-import {
- Button,
- Dropdown,
- Flex,
- NoticeBox,
- Section,
- Stack,
- Table,
-} from '../components';
-import { Window } from '../layouts';
-
-export const DeathmatchPanel = (props, context) => {
- const { act, data } = useBackend(context);
- const playing = data.playing || '';
- return (
-
-
-
- If you play, you can still possibly be returned to your body (No
- Guarantees)!
-
-
-
-
- Host
- Map
- Players
-
- {data.lobbies.map((lobby) => (
-
-
- {(!data.admin && lobby.name) || (
-
- act('admin', {
- id: lobby.name,
- func: value,
- })
- }
- />
- )}
-
- {lobby.map}
-
- {lobby.players}/{lobby.max_players}
-
-
- {(!lobby.playing && (
- <>
- act('join', { id: lobby.name })}
- />
- act('spectate', { id: lobby.name })}
- />
- >
- )) || (
- act('spectate', { id: lobby.name })}
- />
- )}
-
-
- ))}
-
-
- act('host')}
- />
-
-
- );
-};
diff --git a/tgui/packages/tgui/interfaces/DeathmatchPanel.tsx b/tgui/packages/tgui/interfaces/DeathmatchPanel.tsx
new file mode 100644
index 00000000000..252a6e51231
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/DeathmatchPanel.tsx
@@ -0,0 +1,162 @@
+import { BooleanLike } from 'common/react';
+
+import { useBackend } from '../backend';
+import {
+ Button,
+ Dropdown,
+ Icon,
+ NoticeBox,
+ Section,
+ Stack,
+ Table,
+ Tooltip,
+} from '../components';
+import { Window } from '../layouts';
+
+type Lobby = {
+ name: string;
+ players: number;
+ max_players: number;
+ map: string;
+ playing: BooleanLike;
+};
+
+type Data = {
+ hosting: BooleanLike;
+ admin: BooleanLike;
+ playing: string;
+ lobbies: Lobby[];
+};
+
+export function DeathmatchPanel(props) {
+ const { act, data } = useBackend();
+ const { hosting } = data;
+
+ return (
+
+
+
+
+
+ If you play, you can still possibly be returned to your body (No
+ Guarantees)!
+
+
+
+
+
+
+ act('host')}
+ >
+ Create Lobby
+
+
+
+
+
+ );
+}
+
+function LobbyPane(props) {
+ const { data } = useBackend();
+ const { lobbies = [] } = data;
+
+ return (
+
+
+
+ Host
+ Map
+
+
+
+
+
+
+
+
+
+
+ {lobbies.length === 0 && (
+
+
+
+ No lobbies found. Start one!
+
+
+
+ )}
+
+ {lobbies.map((lobby, index) => (
+
+ ))}
+
+
+ );
+}
+
+function LobbyDisplay(props) {
+ const { act, data } = useBackend();
+ const { admin, playing, hosting } = data;
+ const { lobby } = props;
+
+ const isActive = (!!hosting || !!playing) && playing !== lobby.name;
+
+ return (
+
+
+ {!admin ? (
+ lobby.name
+ ) : (
+
+ act('admin', {
+ id: lobby.name,
+ func: value,
+ })
+ }
+ />
+ )}
+
+ {lobby.map}
+
+ {lobby.players}/{lobby.max_players}
+
+
+ {!lobby.playing ? (
+ <>
+ act('join', { id: lobby.name })}
+ >
+ {playing === lobby.name ? 'View' : 'Join'}
+
+ act('spectate', { id: lobby.name })}
+ />
+ >
+ ) : (
+ act('spectate', { id: lobby.name })}
+ >
+ Spectate
+
+ )}
+
+
+ );
+}
diff --git a/tgui/packages/tgui/interfaces/IntegratedCircuit/ComponentMenu.jsx b/tgui/packages/tgui/interfaces/IntegratedCircuit/ComponentMenu.jsx
index 9b91ef348fa..e243ef365b0 100644
--- a/tgui/packages/tgui/interfaces/IntegratedCircuit/ComponentMenu.jsx
+++ b/tgui/packages/tgui/interfaces/IntegratedCircuit/ComponentMenu.jsx
@@ -120,7 +120,8 @@ export class ComponentMenu extends Component {
currentLimit: DEFAULT_COMPONENT_MENU_LIMIT,
})
}
- displayText={`Category: ${selectedTab}`}
+ selected={selectedTab}
+ placeholder="Category"
color="transparent"
className="IntegratedCircuit__BlueBorder"
/>
diff --git a/tgui/packages/tgui/interfaces/IntegratedCircuit/FundamentalTypes.jsx b/tgui/packages/tgui/interfaces/IntegratedCircuit/FundamentalTypes.jsx
index 2ea8ce922aa..65d0814d8ce 100644
--- a/tgui/packages/tgui/interfaces/IntegratedCircuit/FundamentalTypes.jsx
+++ b/tgui/packages/tgui/interfaces/IntegratedCircuit/FundamentalTypes.jsx
@@ -88,7 +88,7 @@ export const FUNDAMENTAL_DATA_TYPES = {
color={'transparent'}
options={data}
onSelected={setValue}
- displayText={value}
+ selected={value}
menuWidth={large ? '200px' : undefined}
/>
);
diff --git a/tgui/packages/tgui/interfaces/IntegratedCircuit/VariableMenu.jsx b/tgui/packages/tgui/interfaces/IntegratedCircuit/VariableMenu.jsx
index 955e45da41b..45e7e90d737 100644
--- a/tgui/packages/tgui/interfaces/IntegratedCircuit/VariableMenu.jsx
+++ b/tgui/packages/tgui/interfaces/IntegratedCircuit/VariableMenu.jsx
@@ -1,4 +1,5 @@
import { shallowDiffers } from 'common/react';
+import { multiline } from 'common/string';
import { Component } from 'react';
import {
@@ -15,7 +16,6 @@ import {
VARIABLE_LIST,
VARIABLE_NOT_A_LIST,
} from './constants';
-import { multiline } from 'common/string';
export class VariableMenu extends Component {
constructor(props) {
@@ -145,7 +145,7 @@ export class VariableMenu extends Component {
{
over
mb={1.7}
width="100%"
- displayText={bookName}
+ selected={bookName}
options={inventory.map((book) => book.title)}
value={bookName}
onSelected={(e) => setBookName(e)}
diff --git a/tgui/packages/tgui/interfaces/ListInputModal.tsx b/tgui/packages/tgui/interfaces/ListInputWindow/ListInputModal.tsx
similarity index 57%
rename from tgui/packages/tgui/interfaces/ListInputModal.tsx
rename to tgui/packages/tgui/interfaces/ListInputWindow/ListInputModal.tsx
index 8695ac842f7..a56363f2310 100644
--- a/tgui/packages/tgui/interfaces/ListInputModal.tsx
+++ b/tgui/packages/tgui/interfaces/ListInputWindow/ListInputModal.tsx
@@ -7,35 +7,26 @@ import {
KEY_ESCAPE,
KEY_UP,
KEY_Z,
-} from '../../common/keycodes';
-import { useBackend } from '../backend';
-import { Autofocus, Button, Input, Section, Stack } from '../components';
-import { Window } from '../layouts';
-import { InputButtons } from './common/InputButtons';
-import { Loader } from './common/Loader';
+} from '../../../common/keycodes';
+import { useBackend } from '../../backend';
+import { Autofocus, Button, Input, Section, Stack } from '../../components';
+import { InputButtons } from '../common/InputButtons';
-type ListInputData = {
- init_value: string;
+type ListInputModalProps = {
items: string[];
- large_buttons: boolean;
+ default_item: string;
message: string;
- timeout: number;
- title: string;
+ on_selected: (entry: string) => void;
+ on_cancel: () => void;
};
-export const ListInputModal = (props) => {
- const { act, data } = useBackend();
- const {
- items = [],
- message = '',
- init_value,
- large_buttons,
- timeout,
- title,
- } = data;
- const [selected, setSelected] = useState(items.indexOf(init_value));
+export const ListInputModal = (props: ListInputModalProps) => {
+ const { items = [], default_item, message, on_selected, on_cancel } = props;
+
+ const [selected, setSelected] = useState(items.indexOf(default_item));
const [searchBarVisible, setSearchBarVisible] = useState(items.length > 9);
const [searchQuery, setSearchQuery] = useState('');
+
// User presses up or down on keyboard
// Simulates clicking an item
const onArrowKey = (key: number) => {
@@ -99,82 +90,77 @@ export const ListInputModal = (props) => {
const filteredItems = items.filter((item) =>
item?.toLowerCase().includes(searchQuery.toLowerCase()),
);
- // Dynamically changes the window height based on the message.
- const windowHeight =
- 325 + Math.ceil(message.length / 3) + (large_buttons ? 5 : 0);
// Grabs the cursor when no search bar is visible.
if (!searchBarVisible) {
setTimeout(() => document!.getElementById(selected.toString())?.focus(), 1);
}
return (
-
- {timeout && }
- {
- const keyCode = window.event ? event.which : event.keyCode;
- if (keyCode === KEY_DOWN || keyCode === KEY_UP) {
- event.preventDefault();
- onArrowKey(keyCode);
+ {
+ const keyCode = window.event ? event.which : event.keyCode;
+ if (keyCode === KEY_DOWN || keyCode === KEY_UP) {
+ event.preventDefault();
+ onArrowKey(keyCode);
+ }
+ if (keyCode === KEY_ENTER) {
+ event.preventDefault();
+ on_selected(filteredItems[selected]);
+ }
+ if (!searchBarVisible && keyCode >= KEY_A && keyCode <= KEY_Z) {
+ event.preventDefault();
+ onLetterSearch(keyCode);
+ }
+ if (keyCode === KEY_ESCAPE) {
+ event.preventDefault();
+ on_cancel();
+ }
+ }}
+ buttons={
+ = KEY_A && keyCode <= KEY_Z) {
- event.preventDefault();
- onLetterSearch(keyCode);
- }
- if (keyCode === KEY_ESCAPE) {
- event.preventDefault();
- act('cancel');
- }
- }}
- >
- onSearchBarToggle()}
- />
- }
- className="ListInput__Section"
- fill
- title={message}
- >
-
-
-
-
- {searchBarVisible && (
-
- )}
-
-
-
-
-
-
-
+ tooltipPosition="left"
+ onClick={() => onSearchBarToggle()}
+ />
+ }
+ className="ListInput__Section"
+ fill
+ title={message}
+ >
+
+
+
+
+ {searchBarVisible && (
+
+ )}
+
+ on_selected(filteredItems[selected])}
+ on_cancel={on_cancel}
+ />
+
+
+
);
};
@@ -183,7 +169,7 @@ export const ListInputModal = (props) => {
* If a search query is provided, filters the items.
*/
const ListDisplay = (props) => {
- const { act } = useBackend();
+ const { act } = useBackend();
const { filteredItems, onClick, onFocusSearch, searchBarVisible, selected } =
props;
@@ -227,7 +213,7 @@ const ListDisplay = (props) => {
* Closing the bar defaults input to an empty string.
*/
const SearchBar = (props) => {
- const { act } = useBackend();
+ const { act } = useBackend();
const { filteredItems, onSearch, searchQuery, selected } = props;
return (
diff --git a/tgui/packages/tgui/interfaces/ListInputWindow/index.tsx b/tgui/packages/tgui/interfaces/ListInputWindow/index.tsx
new file mode 100644
index 00000000000..29355ff5d21
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/ListInputWindow/index.tsx
@@ -0,0 +1,44 @@
+import { useBackend } from '../../backend';
+import { Window } from '../../layouts';
+import { Loader } from '../common/Loader';
+import { ListInputModal } from './ListInputModal';
+
+type ListInputData = {
+ init_value: string;
+ items: string[];
+ large_buttons: boolean;
+ message: string;
+ timeout: number;
+ title: string;
+};
+
+export const ListInputWindow = () => {
+ const { act, data } = useBackend();
+ const {
+ items = [],
+ message = '',
+ init_value,
+ large_buttons,
+ timeout,
+ title,
+ } = data;
+
+ // Dynamically changes the window height based on the message.
+ const windowHeight =
+ 325 + Math.ceil(message.length / 3) + (large_buttons ? 5 : 0);
+
+ return (
+
+ {timeout && }
+
+ act('submit', { entry })}
+ on_cancel={() => act('cancel')}
+ />
+
+
+ );
+};
diff --git a/tgui/packages/tgui/interfaces/LootPanel/IconDisplay.tsx b/tgui/packages/tgui/interfaces/LootPanel/IconDisplay.tsx
index 889d50de884..11e52b2ac55 100644
--- a/tgui/packages/tgui/interfaces/LootPanel/IconDisplay.tsx
+++ b/tgui/packages/tgui/interfaces/LootPanel/IconDisplay.tsx
@@ -10,15 +10,23 @@ export function IconDisplay(props: Props) {
item: { icon, icon_state },
} = props;
- const fallback = ;
+ const fallback = ;
if (!icon) {
return fallback;
}
if (icon_state) {
- return ;
+ return (
+
+ );
}
- return ;
+ return ;
}
diff --git a/tgui/packages/tgui/interfaces/LootPanel/LootBox.tsx b/tgui/packages/tgui/interfaces/LootPanel/LootBox.tsx
index 22b0c8532dd..613db1ead53 100644
--- a/tgui/packages/tgui/interfaces/LootPanel/LootBox.tsx
+++ b/tgui/packages/tgui/interfaces/LootPanel/LootBox.tsx
@@ -1,4 +1,4 @@
-import { capitalizeAll } from 'common/string';
+import { capitalizeAll, capitalizeFirst } from 'common/string';
import { useBackend } from '../../backend';
import { Tooltip } from '../../components';
@@ -25,28 +25,35 @@ export function LootBox(props: Props) {
item = props.item;
}
+ const name = !item.name
+ ? '???'
+ : capitalizeFirst(item.name.split(' ')[0]).slice(0, 5);
+
return (
-
- act('grab', {
- ctrl: event.ctrlKey,
- ref: item.ref,
- shift: event.shiftKey,
- })
- }
- onContextMenu={(event) => {
- event.preventDefault();
- act('grab', {
- middle: true,
- ref: item.ref,
- shift: true,
- });
- }}
- >
-
- {amount > 1 &&
{amount}
}
+
+
+ act('grab', {
+ ctrl: event.ctrlKey,
+ ref: item.ref,
+ shift: event.shiftKey,
+ })
+ }
+ onContextMenu={(event) => {
+ event.preventDefault();
+ act('grab', {
+ middle: true,
+ ref: item.ref,
+ shift: true,
+ });
+ }}
+ >
+
+ {amount > 1 &&
{amount}
}
+
+
{name}
);
diff --git a/tgui/packages/tgui/interfaces/LootPanel/index.tsx b/tgui/packages/tgui/interfaces/LootPanel/index.tsx
index bd64113f302..bc6330b1806 100644
--- a/tgui/packages/tgui/interfaces/LootPanel/index.tsx
+++ b/tgui/packages/tgui/interfaces/LootPanel/index.tsx
@@ -24,7 +24,7 @@ export function LootPanel(props) {
const total = contents.length ? contents.length - 1 : 0;
return (
-
+
{
if (event.key === KEY.Escape) {
diff --git a/tgui/packages/tgui/interfaces/MODsuit.tsx b/tgui/packages/tgui/interfaces/MODsuit.tsx
index 9d7fab88bd9..f78bd4dd1d8 100644
--- a/tgui/packages/tgui/interfaces/MODsuit.tsx
+++ b/tgui/packages/tgui/interfaces/MODsuit.tsx
@@ -226,7 +226,7 @@ const ConfigureListEntry = (props) => {
const { act } = useBackend();
return (
act('configure', {
diff --git a/tgui/packages/tgui/interfaces/MineBot.tsx b/tgui/packages/tgui/interfaces/MineBot.tsx
index 4a3087cf8d6..9118562cdd0 100644
--- a/tgui/packages/tgui/interfaces/MineBot.tsx
+++ b/tgui/packages/tgui/interfaces/MineBot.tsx
@@ -97,7 +97,7 @@ export const MineBot = (props) => {
{
return possible_color.color_name;
})}
diff --git a/tgui/packages/tgui/interfaces/NavBeacon.tsx b/tgui/packages/tgui/interfaces/NavBeacon.tsx
index 5194fe42c1c..6cc5036c87f 100644
--- a/tgui/packages/tgui/interfaces/NavBeacon.tsx
+++ b/tgui/packages/tgui/interfaces/NavBeacon.tsx
@@ -20,11 +20,11 @@ export type Data = {
};
export type NavBeaconControl = {
- location: String;
+ location: string;
patrol_enabled: BooleanLike;
- patrol_next: String;
+ patrol_next: string;
delivery_enabled: BooleanLike;
- delivery_direction: String;
+ delivery_direction: string;
cover_locked: BooleanLike;
};
@@ -107,7 +107,7 @@ export const NavBeaconControlSection = (props: DisabledProps) => {
act('set_delivery_direction', {
direction: value,
diff --git a/tgui/packages/tgui/interfaces/NtosCard.tsx b/tgui/packages/tgui/interfaces/NtosCard.tsx
index 7c3991a487c..5997aa0e91c 100644
--- a/tgui/packages/tgui/interfaces/NtosCard.tsx
+++ b/tgui/packages/tgui/interfaces/NtosCard.tsx
@@ -240,7 +240,7 @@ const TemplateDropdown = (props) => {
{
return templates[path];
})}
@@ -249,6 +249,7 @@ const TemplateDropdown = (props) => {
name: sel,
})
}
+ selected="None"
/>
diff --git a/tgui/packages/tgui/interfaces/NtosRoboControl.jsx b/tgui/packages/tgui/interfaces/NtosRoboControl.jsx
index 20c70220d36..9b55c90a456 100644
--- a/tgui/packages/tgui/interfaces/NtosRoboControl.jsx
+++ b/tgui/packages/tgui/interfaces/NtosRoboControl.jsx
@@ -2,7 +2,6 @@ import { useBackend, useSharedState } from '../backend';
import {
Box,
Button,
- Dropdown,
LabeledList,
ProgressBar,
Section,
@@ -71,19 +70,22 @@ export const NtosRoboControl = (props) => {
act('changedroneaccess')}
- />
- act('ping_drones', { ping_type: value })}
- />
+ >
+ {droneaccess ? 'Grant Drone Access' : 'Revoke Drone Access'}
+
+ Drone Pings
+ {dronepingtypes.map((ping_type) => (
+ act('ping_drones', { ping_type })}
+ >
+ {ping_type}
+
+ ))}
{drones?.map((drone) => (
diff --git a/tgui/packages/tgui/interfaces/NtosScipaper.jsx b/tgui/packages/tgui/interfaces/NtosScipaper.jsx
index 3866ccab24c..2af2cd12f43 100644
--- a/tgui/packages/tgui/interfaces/NtosScipaper.jsx
+++ b/tgui/packages/tgui/interfaces/NtosScipaper.jsx
@@ -93,7 +93,7 @@ const PaperPublishing = (props) => {
act('select_file', {
selected_uid: fileList[ordfile_name],
@@ -117,7 +117,7 @@ const PaperPublishing = (props) => {
act('select_experiment', {
selected_expath: expList[experiment_name],
@@ -141,7 +141,7 @@ const PaperPublishing = (props) => {
String(number))}
- displayText={tier ? String(tier) : '-'}
+ selected={String(tier)}
onSelected={(new_tier) =>
act('select_tier', {
selected_tier: Number(new_tier),
@@ -165,7 +165,7 @@ const PaperPublishing = (props) => {
act('select_partner', {
selected_partner: allowedPartners[new_partner],
diff --git a/tgui/packages/tgui/interfaces/NtosVirtualPet.tsx b/tgui/packages/tgui/interfaces/NtosVirtualPet.tsx
index 7b61f2b566e..1894aa703d6 100644
--- a/tgui/packages/tgui/interfaces/NtosVirtualPet.tsx
+++ b/tgui/packages/tgui/interfaces/NtosVirtualPet.tsx
@@ -268,7 +268,7 @@ const PetTricks = (props) => {
UpdateSequence(index, selected)}
/>
@@ -354,7 +354,7 @@ const Customization = (props) => {
{
return selected_hat.hat_name;
})}
@@ -369,7 +369,7 @@ const Customization = (props) => {
{
return possible_color.color_name;
})}
diff --git a/tgui/packages/tgui/interfaces/PersonalCrafting.tsx b/tgui/packages/tgui/interfaces/PersonalCrafting.tsx
index 96ec4b818b3..d45890d271a 100644
--- a/tgui/packages/tgui/interfaces/PersonalCrafting.tsx
+++ b/tgui/packages/tgui/interfaces/PersonalCrafting.tsx
@@ -701,13 +701,33 @@ const RecipeContentCompact = ({ item, craftable, busy, mode }) => {
? 'utensils'
: 'hammer'
}
- iconSpin={busy ? 1 : 0}
+ iconSpin={!!busy}
onClick={() =>
act('make', {
recipe: item.ref,
})
}
/>
+ {!!item.mass_craftable && (
+
+ act('make_mass', {
+ recipe: item.ref,
+ })
+ }
+ />
+ )}
) : (
item.steps && (
@@ -748,7 +768,7 @@ const RecipeContent = ({ item, craftable, busy, mode, diet }) => {
-
+
{item.name}
@@ -823,46 +843,77 @@ const RecipeContent = ({ item, craftable, busy, mode, diet }) => {
)}
-
- {!item.non_craftable && (
-
- act('make', {
- recipe: item.ref,
- })
- }
- />
- )}
- {!!item.complexity && (
-
- Complexity: {item.complexity}
-
- )}
- {item.foodtypes?.length > 0 && (
-
-
- {item.foodtypes.map((foodtype) => (
-
- ))}
-
- )}
+
+
+
+ {!item.non_craftable && (
+
+
+
+ act('make', {
+ recipe: item.ref,
+ })
+ }
+ />
+
+
+ {!!item.mass_craftable && (
+
+ act('make_mass', {
+ recipe: item.ref,
+ })
+ }
+ />
+ )}
+
+
+ )}
+
+
+ {!!item.complexity && (
+
+ Complexity: {item.complexity}
+
+ )}
+ {item.foodtypes?.length > 0 && (
+
+
+ {item.foodtypes.map((foodtype) => (
+
+ ))}
+
+ )}
+
+
diff --git a/tgui/packages/tgui/interfaces/PlaneMasterDebug.tsx b/tgui/packages/tgui/interfaces/PlaneMasterDebug.tsx
index 1a623bb2079..c85cdec2d13 100644
--- a/tgui/packages/tgui/interfaces/PlaneMasterDebug.tsx
+++ b/tgui/packages/tgui/interfaces/PlaneMasterDebug.tsx
@@ -885,7 +885,6 @@ const GroupDropdown = (props) => {
act('set_group', {
target_group: value,
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx
index 1e109a56838..a366ee881fd 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx
@@ -43,7 +43,7 @@ const CharacterProfiles = (props: {
({
value: slot,
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/JobsPage.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/JobsPage.tsx
index 10c962a8302..49e9163467b 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/JobsPage.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/JobsPage.tsx
@@ -274,7 +274,7 @@ const JobRow = (props: { className?: string; job: Job; name: string }) => {
act('set_job_title', { job: name, new_title: value })
}
@@ -374,18 +374,17 @@ const JoblessRoleDropdown = (props) => {
},
];
+ const selection = options?.find(
+ (option) => option.value === selected,
+ )!.displayText;
+
return (
- {options.find((option) => option.value === selected)!.displayText}
-
- }
/>
);
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/LimbsPage.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/LimbsPage.tsx
index 78a85ab3449..727294ed49b 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/LimbsPage.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/LimbsPage.tsx
@@ -45,7 +45,7 @@ export const Markings = (props) => {
act('change_marking', {
limb_slot: props.limb.slot,
@@ -141,7 +141,7 @@ export const AugmentationPage = (props) => {
{
// Since the costs are positive,
// it's added and not substracted
@@ -164,7 +164,7 @@ export const AugmentationPage = (props) => {
act('set_limb_aug_style', {
limb_slot: props.limb.slot,
@@ -195,7 +195,7 @@ export const OrganPage = (props) => {
{
// Since the costs are positive, it's added and not substracted
if (balance + props.organ.costs[value] > 0) {
@@ -226,7 +226,8 @@ export const LimbsPage = (props) => {
act('set_preset', { preset: value })}
/>
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/RandomizationButton.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/RandomizationButton.tsx
index 4152e2d77c1..0620f22da3a 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/RandomizationButton.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/RandomizationButton.tsx
@@ -1,6 +1,6 @@
import { exhaustiveCheck } from 'common/exhaustive';
-import { Dropdown, Icon } from '../../components';
+import { Dropdown } from '../../components';
import { RandomSetting } from './data';
const options = [
@@ -48,12 +48,13 @@ export const RandomizationButton = (props: {
color={color}
{...dropdownProps}
clipSelectedText={false}
- displayText={ }
+ icon="dice-d20"
options={options}
noChevron
onSelected={setValue}
menuWidth="120px"
width={1.85}
+ selected="None"
/>
);
};
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx
index 6da6aec820d..26a05dfbad6 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/base.tsx
@@ -1,5 +1,5 @@
-import { sort, sortBy } from 'common/collections';
-import { BooleanLike, classes } from 'common/react';
+import { sortBy } from 'common/collections';
+import { BooleanLike } from 'common/react';
import {
ComponentType,
createElement,
@@ -124,16 +124,15 @@ export const CheckboxInputInverse = (
);
};
-export const createDropdownInput = (
+export function createDropdownInput(
// Map of value to display texts
choices: Record,
dropdownProps?: Record,
-): FeatureValue => {
+): FeatureValue {
return (props: FeatureValueProps) => {
return (
(
/>
);
};
-};
+}
export type FeatureChoicedServerData = {
choices: string[];
@@ -158,136 +157,6 @@ export type FeatureChoicedServerData = {
export type FeatureChoiced = Feature;
-const capitalizeFirstLetter = (text: string) =>
- text.toString().charAt(0).toUpperCase() + text.toString().slice(1);
-
-export const StandardizedDropdown = (props: {
- choices: string[];
- disabled?: boolean;
- displayNames: Record;
- onSetValue: (newValue: string) => void;
- value: string;
- buttons?: boolean;
-}) => {
- const { choices, disabled, buttons, displayNames, onSetValue, value } = props;
-
- return (
- {
- return {
- displayText: displayNames[choice],
- value: choice,
- };
- })}
- />
- );
-};
-
-export const FeatureDropdownInput = (
- props: FeatureValueProps & {
- disabled?: boolean;
- buttons?: boolean;
- },
-) => {
- const serverData = props.serverData;
- if (!serverData) {
- return null;
- }
-
- const displayNames =
- serverData.display_names ||
- Object.fromEntries(
- serverData.choices.map((choice) => [
- choice,
- capitalizeFirstLetter(choice),
- ]),
- );
-
- return (
-
- );
-};
-
-export type FeatureWithIcons = Feature<
- { value: T },
- T,
- FeatureChoicedServerData
->;
-
-export const FeatureIconnedDropdownInput = (
- props: FeatureValueProps<
- {
- value: string;
- },
- string,
- FeatureChoicedServerData
- >,
-) => {
- const serverData = props.serverData;
- if (!serverData) {
- return null;
- }
-
- const icons = serverData.icons;
-
- const textNames =
- serverData.display_names ||
- Object.fromEntries(
- serverData.choices.map((choice) => [
- choice,
- capitalizeFirstLetter(choice),
- ]),
- );
-
- const displayNames = Object.fromEntries(
- Object.entries(textNames).map(([choice, textName]) => {
- let element: ReactNode = textName;
-
- if (icons && icons[choice]) {
- const icon = icons[choice];
- element = (
-
-
-
-
-
- {element}
-
- );
- }
-
- return [choice, element];
- }),
- );
-
- return (
-
- );
-};
-
export type FeatureNumericData = {
minimum: number;
maximum: number;
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_core_display.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_core_display.tsx
index 6b3e10bb10c..0e73c28526a 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_core_display.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_core_display.tsx
@@ -1,4 +1,5 @@
-import { FeatureIconnedDropdownInput, FeatureWithIcons } from '../base';
+import {} from '../base';
+import { FeatureIconnedDropdownInput, FeatureWithIcons } from '../dropdowns';
export const preferred_ai_core_display: FeatureWithIcons = {
name: 'AI core display',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_emote_display.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_emote_display.tsx
index c8a59a5d9a4..3e958297b88 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_emote_display.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_emote_display.tsx
@@ -1,4 +1,4 @@
-import { FeatureIconnedDropdownInput, FeatureWithIcons } from '../base';
+import { FeatureIconnedDropdownInput, FeatureWithIcons } from '../dropdowns';
export const preferred_ai_emote_display: FeatureWithIcons = {
name: 'AI emote display',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_hologram_display.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_hologram_display.tsx
index 423fcea8ed2..46d572fcda6 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_hologram_display.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_hologram_display.tsx
@@ -1,4 +1,4 @@
-import { FeatureIconnedDropdownInput, FeatureWithIcons } from '../base';
+import { FeatureIconnedDropdownInput, FeatureWithIcons } from '../dropdowns';
export const preferred_ai_hologram_display: FeatureWithIcons = {
name: 'AI hologram display',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/body_type.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/body_type.tsx
index de9d6523e2c..3746e62ceee 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/body_type.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/body_type.tsx
@@ -1,4 +1,5 @@
-import { FeatureChoiced, FeatureDropdownInput } from '../base';
+import { FeatureChoiced } from '../base';
+import { FeatureDropdownInput } from '../dropdowns';
export const body_type: FeatureChoiced = {
name: 'Body type',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/food_allergy.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/food_allergy.tsx
index f5b0ea37ca8..bdcd91ac7af 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/food_allergy.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/food_allergy.tsx
@@ -1,4 +1,5 @@
-import { FeatureChoiced, FeatureDropdownInput } from '../base';
+import { FeatureChoiced } from '../base';
+import { FeatureDropdownInput } from '../dropdowns';
export const food_allergy: FeatureChoiced = {
name: 'Food Allergy',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/glasses.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/glasses.tsx
index 60cb3131f1b..df73451c35a 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/glasses.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/glasses.tsx
@@ -1,4 +1,4 @@
-import { FeatureIconnedDropdownInput, FeatureWithIcons } from '../base';
+import { FeatureIconnedDropdownInput, FeatureWithIcons } from '../dropdowns';
export const glasses: FeatureWithIcons = {
name: 'Glasses',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/hemiplegic.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/hemiplegic.tsx
index 0494558ba77..35837c80099 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/hemiplegic.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/hemiplegic.tsx
@@ -1,4 +1,5 @@
-import { FeatureChoiced, FeatureDropdownInput } from '../base';
+import { FeatureChoiced } from '../base';
+import { FeatureDropdownInput } from '../dropdowns';
export const hemiplegic: FeatureChoiced = {
name: 'Hemiplegic',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/junkie.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/junkie.tsx
index 8ac11ed968d..586b69d86c2 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/junkie.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/junkie.tsx
@@ -1,4 +1,5 @@
-import { FeatureChoiced, FeatureDropdownInput } from '../base';
+import { FeatureChoiced } from '../base';
+import { FeatureDropdownInput } from '../dropdowns';
export const junkie: FeatureChoiced = {
name: 'Addiction',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/language.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/language.tsx
index 6b1a1be1220..39c48ae40d6 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/language.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/language.tsx
@@ -1,4 +1,5 @@
-import { FeatureChoiced, FeatureDropdownInput } from '../base';
+import { FeatureChoiced } from '../base';
+import { FeatureDropdownInput } from '../dropdowns';
export const language: FeatureChoiced = {
name: 'Language',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/pda.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/pda.tsx
index fdc9a2be5da..196dea45c5d 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/pda.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/pda.tsx
@@ -1,9 +1,5 @@
-import {
- Feature,
- FeatureChoiced,
- FeatureDropdownInput,
- FeatureShortTextInput,
-} from '../base';
+import { Feature, FeatureChoiced, FeatureShortTextInput } from '../base';
+import { FeatureDropdownInput } from '../dropdowns';
export const pda_theme: FeatureChoiced = {
name: 'PDA Theme',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/phobia.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/phobia.tsx
index dd14349277f..f2f35f65e16 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/phobia.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/phobia.tsx
@@ -1,4 +1,5 @@
-import { FeatureChoiced, FeatureDropdownInput } from '../base';
+import { FeatureChoiced } from '../base';
+import { FeatureDropdownInput } from '../dropdowns';
export const phobia: FeatureChoiced = {
name: 'Phobia',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/pride_pin.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/pride_pin.tsx
index b0fae6092a1..70c6f8a8efe 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/pride_pin.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/pride_pin.tsx
@@ -1,4 +1,5 @@
-import { FeatureChoiced, FeatureDropdownInput } from '../base';
+import { FeatureChoiced } from '../base';
+import { FeatureDropdownInput } from '../dropdowns';
export const pride_pin: FeatureChoiced = {
name: 'Pride Pin',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prisoner_crime.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prisoner_crime.tsx
index 2ca17aa4e36..b551b68ee2e 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prisoner_crime.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prisoner_crime.tsx
@@ -1,4 +1,5 @@
-import { FeatureChoiced, FeatureDropdownInput } from '../base';
+import { FeatureChoiced } from '../base';
+import { FeatureDropdownInput } from '../dropdowns';
export const prisoner_crime: FeatureChoiced = {
name: 'Prisoner crime',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prosthetic_limb.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prosthetic_limb.tsx
index adbaefe90c8..87a8ea23de1 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prosthetic_limb.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prosthetic_limb.tsx
@@ -1,4 +1,5 @@
-import { FeatureChoiced, FeatureDropdownInput } from '../base';
+import { FeatureChoiced } from '../base';
+import { FeatureDropdownInput } from '../dropdowns';
export const prosthetic: FeatureChoiced = {
name: 'Prosthetic',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prosthetic_organ.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prosthetic_organ.tsx
index da0e37a4173..5b484d5960e 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prosthetic_organ.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/prosthetic_organ.tsx
@@ -1,4 +1,5 @@
-import { FeatureChoiced, FeatureDropdownInput } from '../base';
+import { FeatureChoiced } from '../base';
+import { FeatureDropdownInput } from '../dropdowns';
export const prosthetic_organ: FeatureChoiced = {
name: 'Prosthetic Organ',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/security_department.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/security_department.tsx
index e9f380bd675..a1311e347c8 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/security_department.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/security_department.tsx
@@ -1,4 +1,5 @@
-import { FeatureChoiced, FeatureDropdownInput } from '../base';
+import { FeatureChoiced } from '../base';
+import { FeatureDropdownInput } from '../dropdowns';
export const prefered_security_department: FeatureChoiced = {
name: 'Security department',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skin_tone.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skin_tone.tsx
index 2e5c18f2324..95029374bd2 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skin_tone.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skin_tone.tsx
@@ -1,12 +1,8 @@
import { sortBy } from 'common/collections';
+import { useMemo } from 'react';
+import { Box, Dropdown, Stack } from 'tgui/components';
-import { Box, Stack } from '../../../../../components';
-import {
- Feature,
- FeatureChoicedServerData,
- FeatureValueProps,
- StandardizedDropdown,
-} from '../base';
+import { Feature, FeatureChoicedServerData, FeatureValueProps } from '../base';
type HexValue = {
lightness: number;
@@ -24,43 +20,53 @@ const sortHexValues = (array: [string, HexValue][]) =>
export const skin_tone: Feature = {
name: 'Skin tone',
component: (props: FeatureValueProps) => {
- const { handleSetValue, serverData, value } = props;
+ const { handleSetValue, serverData } = props;
if (!serverData) {
return null;
}
+ const value = { value: props.value };
+
+ const displayNames = useMemo(() => {
+ const sorted = sortHexValues(Object.entries(serverData.to_hex));
+
+ return sorted.map(([key, colorInfo]) => {
+ const displayName = serverData.display_names[key];
+
+ return {
+ value: key,
+ displayText: (
+
+
+
+
+
+ {displayName}
+
+ ),
+ };
+ });
+ }, [serverData.display_names]);
+
return (
- key,
- )}
- displayNames={Object.fromEntries(
- Object.entries(serverData.display_names).map(([key, displayName]) => {
- const hexColor = serverData.to_hex[key];
-
- return [
- key,
-
-
-
-
-
- {displayName}
- ,
- ];
- }),
- )}
- onSetValue={handleSetValue}
- value={value}
+ option.value === value.value)
+ ?.displayText
+ }
+ onSelected={(value) => handleSetValue(value)}
+ options={displayNames}
+ selected={value.value}
+ width="100%"
/>
);
},
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/brain_type.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/brain_type.tsx
index da0fd78de3a..5364d6d767d 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/brain_type.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/brain_type.tsx
@@ -1,5 +1,6 @@
// THIS IS A SKYRAT UI FILE
-import { FeatureChoiced, FeatureDropdownInput } from '../../base';
+import { FeatureChoiced } from '../../base';
+import { FeatureDropdownInput } from '../../dropdowns';
export const brain_type: FeatureChoiced = {
name: 'Silicon and Synthetic Brain Type',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/character_laugh.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/character_laugh.tsx
index ae03698b2b3..2c118ac111b 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/character_laugh.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/character_laugh.tsx
@@ -1,5 +1,6 @@
// THIS IS A SKYRAT UI FILE
-import { FeatureChoiced, FeatureDropdownInput } from '../../base';
+import { FeatureChoiced } from '../../base';
+import { FeatureDropdownInput } from '../../dropdowns';
export const character_laugh: FeatureChoiced = {
name: 'Character Laugh',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/character_scream.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/character_scream.tsx
index 9f6405feead..d6ec7c5bcf0 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/character_scream.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/character_scream.tsx
@@ -1,5 +1,6 @@
// THIS IS A SKYRAT UI FILE
-import { FeatureChoiced, FeatureDropdownInput } from '../../base';
+import { FeatureChoiced } from '../../base';
+import { FeatureDropdownInput } from '../../dropdowns';
export const character_scream: FeatureChoiced = {
name: 'Character Scream',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/genitals.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/genitals.tsx
index 9f420b7ebd9..60818536339 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/genitals.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/genitals.tsx
@@ -4,7 +4,6 @@ import {
Feature,
FeatureChoiced,
FeatureChoicedServerData,
- FeatureDropdownInput,
FeatureNumberInput,
FeatureNumeric,
FeatureToggle,
@@ -12,6 +11,7 @@ import {
FeatureTriColorInput,
FeatureValueProps,
} from '../../base';
+import { FeatureDropdownInput } from '../../dropdowns';
export const feature_penis: Feature = {
name: 'Penis Choice',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/loadout_override_preference.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/loadout_override_preference.tsx
index c0e9cda397e..87de99fb615 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/loadout_override_preference.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/loadout_override_preference.tsx
@@ -1,5 +1,6 @@
// THIS IS A SKYRAT UI FILE
-import { Feature, FeatureDropdownInput } from '../../base';
+import { Feature } from '../../base';
+import { FeatureDropdownInput } from '../../dropdowns';
export const loadout_override_preference: Feature = {
name: 'Loadout Item Preference',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/pet_owner.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/pet_owner.tsx
index 45e2c678965..88579aa989f 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/pet_owner.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/pet_owner.tsx
@@ -1,10 +1,6 @@
// THIS IS A SKYRAT UI FILE
-import {
- Feature,
- FeatureChoiced,
- FeatureDropdownInput,
- FeatureShortTextInput,
-} from '../../base';
+import { Feature, FeatureChoiced, FeatureShortTextInput } from '../../base';
+import { FeatureDropdownInput } from '../../dropdowns';
export const pet_owner: FeatureChoiced = {
name: 'Pet Owner',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/species_features.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/species_features.tsx
index c77e86659c2..120e2fdd5c8 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/species_features.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/skyrat/species_features.tsx
@@ -5,7 +5,6 @@ import {
FeatureChoiced,
FeatureChoicedServerData,
FeatureColorInput,
- FeatureDropdownInput,
FeatureNumberInput,
FeatureShortTextInput,
FeatureTextInput,
@@ -14,6 +13,7 @@ import {
FeatureTriColorInput,
FeatureValueProps,
} from '../../base';
+import { FeatureDropdownInput } from '../../dropdowns';
export const feature_leg_type: FeatureChoiced = {
name: 'Leg type',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/trans_prosthetic.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/trans_prosthetic.tsx
index 368a2a16a1b..fc8601e3cc7 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/trans_prosthetic.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/trans_prosthetic.tsx
@@ -1,4 +1,5 @@
-import { FeatureChoiced, FeatureDropdownInput } from '../base';
+import { FeatureChoiced } from '../base';
+import { FeatureDropdownInput } from '../dropdowns';
export const trans_prosthetic: FeatureChoiced = {
name: 'Augment',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/tts_voice.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/tts_voice.tsx
index 94a208158c5..1f588f07f15 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/tts_voice.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/tts_voice.tsx
@@ -2,11 +2,11 @@ import { Button, Stack } from '../../../../../components';
import {
FeatureChoiced,
FeatureChoicedServerData,
- FeatureDropdownInput,
FeatureNumeric,
FeatureSliderInput,
FeatureValueProps,
} from '../base';
+import { FeatureDropdownInput } from '../dropdowns';
const FeatureTTSDropdownInput = (
props: FeatureValueProps,
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/uplink_loc.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/uplink_loc.tsx
index 06c125c33fc..2b1ffe26a32 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/uplink_loc.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/uplink_loc.tsx
@@ -1,4 +1,5 @@
-import { FeatureChoiced, FeatureDropdownInput } from '../base';
+import { FeatureChoiced } from '../base';
+import { FeatureDropdownInput } from '../dropdowns';
export const uplink_loc: FeatureChoiced = {
name: 'Uplink Spawn Location',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dropdowns.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dropdowns.tsx
new file mode 100644
index 00000000000..32e1161e636
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/dropdowns.tsx
@@ -0,0 +1,113 @@
+import { classes } from 'common/react';
+import { capitalizeFirst } from 'common/string';
+import { ReactNode } from 'react';
+
+import { Box, Dropdown, Stack } from '../../../../components';
+import { Feature, FeatureChoicedServerData, FeatureValueProps } from './base';
+
+type DropdownInputProps = FeatureValueProps<
+ string,
+ string,
+ FeatureChoicedServerData
+> &
+ Partial<{
+ disabled: boolean;
+ buttons: boolean;
+ }>;
+
+type IconnedDropdownInputProps = FeatureValueProps<
+ string,
+ string,
+ FeatureChoicedServerData
+>;
+
+export type FeatureWithIcons = Feature;
+
+export function FeatureDropdownInput(props: DropdownInputProps) {
+ const { serverData, disabled, buttons, handleSetValue, value } = props;
+
+ if (!serverData) {
+ return null;
+ }
+
+ const { choices, display_names } = serverData;
+
+ const dropdownOptions = choices.map((choice) => {
+ let displayText: ReactNode = display_names
+ ? display_names[choice]
+ : capitalizeFirst(choice);
+
+ return {
+ displayText,
+ value: choice,
+ };
+ });
+
+ let display_text = value;
+ if (display_names) {
+ display_text = display_names[value];
+ }
+
+ return (
+
+ );
+}
+
+export function FeatureIconnedDropdownInput(props: IconnedDropdownInputProps) {
+ const { serverData, handleSetValue, value } = props;
+
+ if (!serverData) {
+ return null;
+ }
+
+ const { choices, display_names, icons } = serverData;
+
+ const dropdownOptions = choices.map((choice) => {
+ let displayText: ReactNode = display_names
+ ? display_names[choice]
+ : capitalizeFirst(choice);
+
+ if (icons?.[choice]) {
+ displayText = (
+
+
+
+
+ {displayText}
+
+ );
+ }
+
+ return {
+ displayText,
+ value: choice,
+ };
+ });
+
+ let display_text = value;
+ if (display_names) {
+ display_text = display_names[value];
+ }
+
+ return (
+
+ );
+}
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/admin.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/admin.tsx
index 03244e9f6ee..d99cd329f55 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/admin.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/admin.tsx
@@ -4,9 +4,9 @@ import {
CheckboxInput,
Feature,
FeatureColorInput,
- FeatureDropdownInput,
FeatureToggle,
} from '../base';
+import { FeatureDropdownInput } from '../dropdowns';
export const asaycolor: Feature = {
name: 'Admin chat color',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ghost.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ghost.tsx
index ab973e3659e..5ec16867197 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ghost.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ghost.tsx
@@ -10,10 +10,10 @@ import {
CheckboxInput,
FeatureChoiced,
FeatureChoicedServerData,
- FeatureDropdownInput,
FeatureToggle,
FeatureValueProps,
} from '../base';
+import { FeatureDropdownInput } from '../dropdowns';
export const ghost_accs: FeatureChoiced = {
name: 'Ghost accessories',
@@ -81,9 +81,10 @@ const GhostFormInput = (
return (
= {
name: 'MOD active module key',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/parallax.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/parallax.tsx
index a7b143a6d3d..914af27c382 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/parallax.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/parallax.tsx
@@ -1,4 +1,5 @@
-import { Feature, FeatureDropdownInput } from '../base';
+import { Feature } from '../base';
+import { FeatureDropdownInput } from '../dropdowns';
export const parallax: Feature = {
name: 'Parallax (fancy space)',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/preferred_map.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/preferred_map.tsx
index 1a1755ce714..5b0860ef91e 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/preferred_map.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/preferred_map.tsx
@@ -1,6 +1,7 @@
import { multiline } from 'common/string';
-import { Feature, FeatureDropdownInput } from '../base';
+import { Feature } from '../base';
+import { FeatureDropdownInput } from '../dropdowns';
export const preferred_map: Feature = {
name: 'Preferred map',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/screentips.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/screentips.tsx
index 5c65c4f100a..ff2cf95a048 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/screentips.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/screentips.tsx
@@ -5,9 +5,9 @@ import {
Feature,
FeatureChoiced,
FeatureColorInput,
- FeatureDropdownInput,
FeatureToggle,
} from '../base';
+import { FeatureDropdownInput } from '../dropdowns';
export const screentip_color: Feature = {
name: 'Screentips: Screentips color',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/skyrat/erp_preferences.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/skyrat/erp_preferences.tsx
index 5df13462cc7..fefa333fd7b 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/skyrat/erp_preferences.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/skyrat/erp_preferences.tsx
@@ -1,10 +1,6 @@
// THIS IS A SKYRAT UI FILE
-import {
- CheckboxInput,
- FeatureChoiced,
- FeatureDropdownInput,
- FeatureToggle,
-} from '../../base';
+import { CheckboxInput, FeatureChoiced, FeatureToggle } from '../../base';
+import { FeatureDropdownInput } from '../../dropdowns';
export const master_erp_pref: FeatureToggle = {
name: 'Show/Hide Erotic Roleplay Preferences',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sounds.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sounds.tsx
index 0bce5e0982e..34e968f35c4 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sounds.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/sounds.tsx
@@ -4,10 +4,10 @@ import {
CheckboxInput,
Feature,
FeatureChoiced,
- FeatureDropdownInput,
FeatureSliderInput,
FeatureToggle,
} from '../base';
+import { FeatureDropdownInput } from '../dropdowns';
export const sound_ambience: FeatureToggle = {
name: 'Enable ambience',
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ui_style.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ui_style.tsx
index 218b5b3c580..d3fdc0b94de 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ui_style.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/ui_style.tsx
@@ -46,7 +46,6 @@ const UIStyleInput = (
= {
name: 'Eye color',
diff --git a/tgui/packages/tgui/interfaces/ProcCallMenu.tsx b/tgui/packages/tgui/interfaces/ProcCallMenu.tsx
index 716ae19a147..6db723bcfb4 100644
--- a/tgui/packages/tgui/interfaces/ProcCallMenu.tsx
+++ b/tgui/packages/tgui/interfaces/ProcCallMenu.tsx
@@ -45,7 +45,7 @@ export const ProcCallMenu = (props) => {
@@ -139,7 +139,7 @@ const PortEntry = (props) => {
{
width="100%"
options={sorted_assistance}
selected={recipient}
- displayText={recipient || 'Pick a Recipient'}
+ placeholder="Pick a Recipient"
onSelected={(value) => setRecipient(value)}
/>
)}
@@ -94,7 +94,7 @@ export const MessageWriteTab = (props) => {
width="100%"
options={sorted_supply}
selected={recipient}
- displayText={recipient || 'Pick a Recipient'}
+ placeholder="Pick a Recipient"
onSelected={(value) => setRecipient(value)}
/>
)}
@@ -103,7 +103,7 @@ export const MessageWriteTab = (props) => {
width="100%"
options={sorted_information}
selected={recipient}
- displayText={recipient || 'Pick a Recipient'}
+ placeholder="Pick a Recipient"
onSelected={(value) => setRecipient(value)}
/>
)}
diff --git a/tgui/packages/tgui/interfaces/StationTraitsPanel.tsx b/tgui/packages/tgui/interfaces/StationTraitsPanel.tsx
index e6e7b02ce67..8496d62552f 100644
--- a/tgui/packages/tgui/interfaces/StationTraitsPanel.tsx
+++ b/tgui/packages/tgui/interfaces/StationTraitsPanel.tsx
@@ -34,7 +34,7 @@ const FutureStationTraitsPage = (props) => {
const { act, data } = useBackend();
const { future_station_traits } = data;
- const [selectedTrait, setSelectedTrait] = useState();
+ const [selectedTrait, setSelectedTrait] = useState('');
const traitsByName = Object.fromEntries(
data.valid_station_traits.map((trait) => {
@@ -50,9 +50,9 @@ const FutureStationTraitsPage = (props) => {
diff --git a/tgui/packages/tgui/interfaces/TramController.tsx b/tgui/packages/tgui/interfaces/TramController.tsx
index 0fccd23a911..f787c8726b5 100644
--- a/tgui/packages/tgui/interfaces/TramController.tsx
+++ b/tgui/packages/tgui/interfaces/TramController.tsx
@@ -193,7 +193,7 @@ export const TramController = (props) => {
width="98.5%"
options={destinations.map((id) => id.name)}
selected={tripDestination}
- displayText={tripDestination || 'Pick a Destination'}
+ placeholder="Pick a Destination"
onSelected={(value) => setTripDestination(value)}
/>
void;
+ on_cancel?: () => void;
message?: string;
};
export const InputButtons = (props: InputButtonsProps) => {
const { act, data } = useBackend();
const { large_buttons, swapped_buttons } = data;
- const { input, message } = props;
+ const { input, message, on_submit, on_cancel } = props;
+
+ let on_submit_actual = on_submit;
+ if (!on_submit_actual) {
+ on_submit_actual = () => {
+ act('submit', { entry: input });
+ };
+ }
+
+ let on_cancel_actual = on_cancel;
+ if (!on_cancel_actual) {
+ on_cancel_actual = () => {
+ act('cancel');
+ };
+ }
+
const submitButton = (
act('submit', { entry: input })}
+ onClick={on_submit_actual}
m={0.5}
pl={2}
pr={2}
@@ -37,7 +54,7 @@ export const InputButtons = (props: InputButtonsProps) => {
color="bad"
fluid={!!large_buttons}
height={!!large_buttons && 2}
- onClick={() => act('cancel')}
+ onClick={on_cancel_actual}
m={0.5}
pl={2}
pr={2}
diff --git a/tgui/packages/tgui/styles/components/SearchItem.scss b/tgui/packages/tgui/styles/components/SearchItem.scss
index 76946ec9c5a..5dadcdf8d6a 100644
--- a/tgui/packages/tgui/styles/components/SearchItem.scss
+++ b/tgui/packages/tgui/styles/components/SearchItem.scss
@@ -2,21 +2,34 @@
.SearchItem {
align-items: center;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+}
+
+.SearchItem--box {
background: black;
border: thin solid #212121;
display: flex;
- height: 3rem;
+ align-items: center;
justify-content: center;
+ height: 3rem;
position: relative;
width: 3rem;
- margin-bottom: 0;
}
.SearchItem--amount {
- bottom: -1rem;
+ bottom: -4px;
color: colors.$teal;
font-family: 'Roboto', sans-serif;
font-size: 1.5rem;
position: absolute;
- right: -4px;
+ right: -6px;
+}
+
+.SearchItem--text {
+ color: colors.$label;
+ font-family: 'Roboto', sans-serif;
+ font-size: 1rem;
+ z-index: 1;
}
diff --git a/tgui/packages/tgui/styles/components/Stack.scss b/tgui/packages/tgui/styles/components/Stack.scss
index 02d0e8bbe24..3529c700183 100644
--- a/tgui/packages/tgui/styles/components/Stack.scss
+++ b/tgui/packages/tgui/styles/components/Stack.scss
@@ -28,6 +28,24 @@ $zebra-background-color: base.$color-bg-section !default;
}
}
+.Stack--reverse > .Stack__item {
+ margin-left: 0;
+ margin-right: 0.5em;
+
+ &:first-child {
+ margin-right: 0;
+ }
+}
+
+.Stack--reverse--vertical > .Stack__item {
+ margin-top: 0;
+ margin-bottom: 0.5em;
+
+ &:first-child {
+ margin-bottom: 0;
+ }
+}
+
.Stack--zebra > .Stack__item:nth-child(even) {
background-color: $zebra-background-color;
}
diff --git a/tools/build/build.js b/tools/build/build.js
index 5c66cd6feed..4d2cd9b9045 100644
--- a/tools/build/build.js
+++ b/tools/build/build.js
@@ -77,7 +77,7 @@ export const CiParameter = new Juke.Parameter({ type: 'boolean' });
export const ForceRecutParameter = new Juke.Parameter({
type: 'boolean',
- name: "force_recut",
+ name: "force-recut",
});
export const WarningParameter = new Juke.Parameter({
diff --git a/tools/icon_cutter/check.py b/tools/icon_cutter/check.py
index c6c269635ff..568ec272436 100644
--- a/tools/icon_cutter/check.py
+++ b/tools/icon_cutter/check.py
@@ -69,10 +69,16 @@ def hash_file(path):
return (md5.hexdigest(), None, None)
+path_to_us = os.path.realpath(os.path.dirname(__file__))
pass_count = 0
fail_count = 0
output_hash = {}
-for cutter_template in glob.glob("..\\..\\icons\\**\*.toml", recursive = True):
+files = []
+if platform.system() == "Windows":
+ files = glob.glob(f"{path_to_us}\..\\..\\icons\\**\*.toml", recursive = True)
+else:
+ files = glob.glob(f"{path_to_us}/../../icons/**/*.toml", recursive = True)
+for cutter_template in files:
resource_name = re.sub(chop_extension, r"\1", cutter_template, count = 1)
if not os.path.isfile(resource_name):
print(f"::error template={cutter_template} exists but lacks a matching resource file ({resource_name})")
@@ -89,9 +95,9 @@ for cutter_template in glob.glob("..\\..\\icons\\**\*.toml", recursive = True):
# Execute cutter
if platform.system() == "Windows":
- subprocess.run("..\\build\\build.bat --force-recut --ci icon-cutter")
+ subprocess.run(f"{path_to_us}\..\\build\\build.bat --force-recut --ci icon-cutter")
else:
- subprocess.run("../build/build --force-recut --ci icon-cutter", shell = True)
+ subprocess.run(f"{path_to_us}/../build/build --force-recut --ci icon-cutter", shell = True)
for output_name in output_hash:
old_hash, old_metadata, old_icon_hash = output_hash[output_name]
diff --git a/tools/pull_request_hooks/rerunFlakyTests.js b/tools/pull_request_hooks/rerunFlakyTests.js
index 6625d9caa8c..d3085a67260 100644
--- a/tools/pull_request_hooks/rerunFlakyTests.js
+++ b/tools/pull_request_hooks/rerunFlakyTests.js
@@ -8,20 +8,20 @@ const CONSIDERED_JOBS = [
];
async function getFailedJobsForRun(github, context, workflowRunId, runAttempt) {
- const {
- data: { jobs },
- } = await github.rest.actions.listJobsForWorkflowRunAttempt({
- owner: context.repo.owner,
- repo: context.repo.repo,
- run_id: workflowRunId,
- attempt_number: runAttempt,
- });
+ const jobs = await github.paginate(
+ github.rest.actions.listJobsForWorkflowRunAttempt,
+ {
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ run_id: workflowRunId,
+ attempt_number: runAttempt
+ },
+ response => {
+ return response.data;
+ });
return jobs
- .filter((job) => job.conclusion === "failure")
- .filter((job) =>
- CONSIDERED_JOBS.some((title) => job.name.startsWith(title))
- );
+ .filter((job) => job.conclusion === "failure");
}
export async function rerunFlakyTests({ github, context }) {
@@ -32,16 +32,16 @@ export async function rerunFlakyTests({ github, context }) {
context.payload.workflow_run.run_attempt
);
- if (failingJobs.length > 1) {
- console.log("Multiple jobs failing. PROBABLY not flaky, not rerunning.");
+ const filteredFailingJobs = failingJobs.filter((job) => {
+ console.log(`Failing job: ${job.name}`)
+ return CONSIDERED_JOBS.some((title) => job.name.startsWith(title));
+ });
+ if (filteredFailingJobs.length === 0) {
+ console.log("Failing jobs are NOT designated flaky. Not rerunning.");
return;
}
- if (failingJobs.length === 0) {
- throw new Error(
- "rerunFlakyTests should not have run on a run with no failing jobs"
- );
- }
+ console.log(`Rerunning job: ${filteredFailingJobs[0].name}`);
github.rest.actions.reRunWorkflowFailedJobs({
owner: context.repo.owner,
@@ -244,8 +244,13 @@ export async function reportFlakyTests({ github, context }) {
context.payload.workflow_run.run_attempt - 1
);
+ const filteredFailingJobs = failedJobsFromLastRun.filter((job) => {
+ console.log(`Failing job: ${job.name}`)
+ return CONSIDERED_JOBS.some((title) => job.name.startsWith(title));
+ });
+
// This could one day be relaxed if we face serious enough flaky test problems, so we're going to loop anyway
- if (failedJobsFromLastRun.length !== 1) {
+ if (filteredFailingJobs.length !== 1) {
console.log(
"Multiple jobs failing after retry, assuming maintainer rerun."
);
@@ -253,7 +258,7 @@ export async function reportFlakyTests({ github, context }) {
return;
}
- for (const job of failedJobsFromLastRun) {
+ for (const job of filteredFailingJobs) {
const { data: log } =
await github.rest.actions.downloadJobLogsForWorkflowRun({
owner: context.repo.owner,