diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index a4d6c07526..30029c87bb 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -51,7 +51,7 @@ As mentioned before, you are expected to follow these specifications in order to
### Object Oriented Code
As BYOND's Dream Maker (henceforth "DM") is an object-oriented language, code must be object-oriented when possible in order to be more flexible when adding content to it. If you don't know what "object-oriented" means, we highly recommend you do some light research to grasp the basics.
-### All BYOND paths must contain the full path.
+### All BYOND paths must contain the full path
(i.e. absolute pathing)
DM will allow you nest almost any type keyword into a block, such as:
@@ -105,7 +105,7 @@ The previous code made compliant:
code
```
-### No overriding type safety checks.
+### No overriding type safety checks
The use of the : operator to override type safety checks is not allowed. You must cast the variable to the proper type.
### Type paths must begin with a /
@@ -264,6 +264,8 @@ This prevents nesting levels from getting deeper then they need to be.
* If you used regex to replace code during development of your code, post the regex in your PR for the benefit of future developers and downstream users.
+* Changes to the `/config` tree must be made in a way that allows for updating server deployments while preserving previous behaviour. This is due to the fact that the config tree is to be considered owned by the user and not necessarily updated alongside the remainder of the code. The code to preserve previous behaviour may be removed at some point in the future given the OK by maintainers.
+
#### Enforced not enforced
The following coding styles are not only not enforced at all, but are generally frowned upon to change for little to no reason:
diff --git a/README.md b/README.md
index b286239314..aaf2ad2a27 100644
--- a/README.md
+++ b/README.md
@@ -37,7 +37,7 @@ hassle if you want to make any changes at all, so it's not recommended.)
## INSTALLATION
First-time installation should be fairly straightforward. First, you'll need
-BYOND installed. You can get it from http://www.byond.com/. Once you've done
+BYOND installed. You can get it from https://www.byond.com/download. Once you've done
that, extract the game files to wherever you want to keep them. This is a
sourcecode-only release, so the next step is to compile the server files.
Open tgstation.dme by double-clicking it, open the Build menu, and click
diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm
index 335393adac..2f9716406c 100644
--- a/_maps/map_files/BoxStation/BoxStation.dmm
+++ b/_maps/map_files/BoxStation/BoxStation.dmm
@@ -22174,7 +22174,8 @@
req_access_txt = "20"
},
/obj/structure/window/reinforced,
-/obj/item/aiModule/core/full/corp,
+/obj/effect/spawner/lootdrop/aimodule_harmless,
+/obj/effect/spawner/lootdrop/aimodule_neutral,
/obj/structure/window/reinforced{
dir = 1
},
@@ -22235,7 +22236,7 @@
},
/obj/item/aiModule/reset/purge,
/obj/structure/window/reinforced,
-/obj/item/aiModule/core/full/antimov,
+/obj/effect/spawner/lootdrop/aimodule_harmful,
/obj/structure/window/reinforced{
dir = 1
},
diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm
index 2852c76257..fe77452705 100644
--- a/_maps/map_files/Deltastation/DeltaStation2.dmm
+++ b/_maps/map_files/Deltastation/DeltaStation2.dmm
@@ -54219,14 +54219,10 @@
name = "Core Modules";
req_access_txt = "20"
},
-/obj/item/aiModule/core/full/paladin{
- pixel_x = 3;
- pixel_y = 3
- },
-/obj/item/aiModule/core/full/asimov,
-/obj/item/aiModule/core/full/corp{
- pixel_x = -3;
- pixel_y = -3
+/obj/effect/spawner/lootdrop/aimodule_harmless{
+ fan_out_items = 1;
+ lootdoubles = 0;
+ lootcount = 3
},
/obj/structure/sign/nanotrasen{
pixel_x = -32
@@ -54279,12 +54275,12 @@
name = "Core Modules";
req_access_txt = "20"
},
-/obj/item/aiModule/core/full/antimov{
- pixel_x = 3;
- pixel_y = 3
+/obj/effect/spawner/lootdrop/aimodule_harmful{
+ fan_out_items = 1;
+ lootdoubles = 0;
+ lootcount = 2
},
-/obj/item/aiModule/supplied/oxygen,
-/obj/item/aiModule/supplied/protectStation{
+/obj/item/aiModule/supplied/oxygen{
pixel_x = -3;
pixel_y = -3
},
@@ -55144,6 +55140,10 @@
pixel_y = 3
},
/obj/item/aiModule/core/full/custom,
+/obj/item/aiModule/core/full/asimov{
+ pixel_x = -3;
+ pixel_y = -3
+ },
/turf/open/floor/plasteel/vault{
dir = 8
},
@@ -55226,7 +55226,7 @@
req_access_txt = "20"
},
/obj/structure/window/reinforced,
-/obj/item/aiModule/core/full/tyrant{
+/obj/item/aiModule/supplied/protectStation{
pixel_x = 3;
pixel_y = 3
},
@@ -57252,14 +57252,10 @@
/area/ai_monitored/turret_protected/ai_upload)
"clQ" = (
/obj/structure/table/reinforced,
-/obj/item/aiModule/core/full/drone{
- pixel_x = 3;
- pixel_y = 3
- },
-/obj/item/aiModule/core/full/reporter,
-/obj/item/aiModule/core/full/liveandletlive{
- pixel_x = -3;
- pixel_y = -3
+/obj/effect/spawner/lootdrop/aimodule_neutral{
+ fan_out_items = 1;
+ lootdoubles = 0;
+ lootcount = 3
},
/turf/open/floor/plasteel/vault{
dir = 8
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 8ed9acf09f..3480f9d6c4 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -18443,6 +18443,7 @@
"aMG" = (
/obj/structure/table,
/obj/item/aiModule/core/full/asimov,
+/obj/effect/spawner/lootdrop/aimodule_harmless,
/obj/item/aiModule/core/freeformcore,
/obj/machinery/door/window{
base_state = "right";
@@ -18452,7 +18453,7 @@
req_access_txt = "20"
},
/obj/structure/window/reinforced,
-/obj/item/aiModule/core/full/corp,
+/obj/effect/spawner/lootdrop/aimodule_neutral,
/obj/item/aiModule/core/full/custom,
/obj/machinery/flasher{
pixel_y = 24;
@@ -18477,7 +18478,7 @@
pixel_y = 24;
id = "AI"
},
-/obj/item/aiModule/core/full/antimov,
+/obj/effect/spawner/lootdrop/aimodule_harmful,
/obj/item/aiModule/supplied/oxygen,
/obj/item/aiModule/supplied/protectStation,
/obj/item/aiModule/zeroth/oneHuman,
diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm
index ffda1f471d..787c2a72e2 100644
--- a/_maps/map_files/OmegaStation/OmegaStation.dmm
+++ b/_maps/map_files/OmegaStation/OmegaStation.dmm
@@ -2376,14 +2376,10 @@
name = "Core Modules";
req_access_txt = "20"
},
-/obj/item/aiModule/core/full/paladin{
- pixel_x = 3;
- pixel_y = 3
- },
-/obj/item/aiModule/core/full/asimov,
-/obj/item/aiModule/core/full/corp{
- pixel_x = -3;
- pixel_y = -3
+/obj/effect/spawner/lootdrop/aimodule_harmless{
+ fan_out_items = 1;
+ lootdoubles = 0;
+ lootcount = 3
},
/obj/structure/sign/nanotrasen{
pixel_x = -32
@@ -2499,12 +2495,12 @@
name = "Core Modules";
req_access_txt = "20"
},
-/obj/item/aiModule/core/full/antimov{
- pixel_x = 3;
- pixel_y = 3
+/obj/effect/spawner/lootdrop/aimodule_harmful{
+ fan_out_items = 1;
+ lootdoubles = 0;
+ lootcount = 2
},
-/obj/item/aiModule/supplied/oxygen,
-/obj/item/aiModule/supplied/protectStation{
+/obj/item/aiModule/supplied/oxygen{
pixel_x = -3;
pixel_y = -3
},
@@ -2875,6 +2871,10 @@
pixel_y = 3
},
/obj/item/aiModule/core/full/custom,
+/obj/item/aiModule/core/full/asimov{
+ pixel_x = -3;
+ pixel_y = -3
+ },
/obj/machinery/camera{
c_tag = "AI Core - Port";
dir = 4;
@@ -2900,7 +2900,7 @@
req_access_txt = "20"
},
/obj/structure/window/reinforced,
-/obj/item/aiModule/core/full/tyrant{
+/obj/item/aiModule/supplied/protectStation{
pixel_x = 3;
pixel_y = 3
},
@@ -4361,14 +4361,10 @@
/area/ai_monitored/turret_protected/ai)
"ahV" = (
/obj/structure/table/reinforced,
-/obj/item/aiModule/core/full/drone{
- pixel_x = 3;
- pixel_y = 3
- },
-/obj/item/aiModule/core/full/reporter,
-/obj/item/aiModule/core/full/liveandletlive{
- pixel_x = -3;
- pixel_y = -3
+/obj/effect/spawner/lootdrop/aimodule_neutral{
+ fan_out_items = 1;
+ lootdoubles = 0;
+ lootcount = 3
},
/turf/open/floor/plasteel/vault{
dir = 8
@@ -23737,7 +23733,6 @@
/obj/structure/chair/office/light{
dir = 1
},
-/obj/effect/landmark/start/chemist,
/obj/effect/turf_decal/bot,
/turf/open/floor/plasteel,
/area/medical/chemistry)
@@ -24229,7 +24224,6 @@
/obj/structure/chair/office/light{
dir = 4
},
-/obj/effect/landmark/start/chemist,
/obj/effect/turf_decal/stripes/line{
dir = 6
},
@@ -74189,7 +74183,7 @@ aRf
aSk
aTr
aUt
-aVk
+aVl
aWg
aRf
aXr
diff --git a/_maps/map_files/OmegaStation/job_changes.dm b/_maps/map_files/OmegaStation/job_changes.dm
index 7f6c24fe26..bef766da7b 100644
--- a/_maps/map_files/OmegaStation/job_changes.dm
+++ b/_maps/map_files/OmegaStation/job_changes.dm
@@ -164,4 +164,5 @@ MAP_REMOVE_JOB(geneticist)
MAP_REMOVE_JOB(virologist)
MAP_REMOVE_JOB(rd)
MAP_REMOVE_JOB(warden)
-MAP_REMOVE_JOB(lawyer)
\ No newline at end of file
+MAP_REMOVE_JOB(lawyer)
+MAP_REMOVE_JOB(chemist)
diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm
index 7eb9a7ac7a..a504dc4a0b 100644
--- a/_maps/map_files/PubbyStation/PubbyStation.dmm
+++ b/_maps/map_files/PubbyStation/PubbyStation.dmm
@@ -12140,6 +12140,7 @@
"aED" = (
/obj/structure/table,
/obj/item/aiModule/core/full/asimov,
+/obj/effect/spawner/lootdrop/aimodule_harmless,
/obj/item/aiModule/core/freeformcore,
/obj/machinery/door/window{
base_state = "right";
@@ -12148,7 +12149,7 @@
name = "Core Modules";
req_access_txt = "20"
},
-/obj/item/aiModule/core/full/corp,
+/obj/effect/spawner/lootdrop/aimodule_neutral,
/obj/item/aiModule/core/full/custom,
/obj/structure/window/reinforced{
dir = 1;
@@ -12197,7 +12198,7 @@
req_access_txt = "20"
},
/obj/item/aiModule/reset/purge,
-/obj/item/aiModule/core/full/antimov,
+/obj/effect/spawner/lootdrop/aimodule_harmful,
/obj/item/aiModule/supplied/protectStation,
/obj/structure/window/reinforced{
dir = 1;
diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm
index 1024bb1229..430f7f29b3 100644
--- a/code/__DEFINES/atmospherics.dm
+++ b/code/__DEFINES/atmospherics.dm
@@ -129,38 +129,12 @@
#define MAX_OUTPUT_PRESSURE 4500 // (kPa) What pressure pumps and powered equipment max out at.
#define MAX_TRANSFER_RATE 200 // (L/s) Maximum speed powered equipment can work at.
-//used for device_type vars; used by DEVICE_TYPE_LOOP
+//used for device_type vars
#define UNARY 1
#define BINARY 2
#define TRINARY 3
#define QUATERNARY 4
-//TODO: finally remove this bullshit
-//this is the standard for loop used by all sorts of atmos machinery procs
-#define DEVICE_TYPE_LOOP var/I in 1 to device_type
-
-//defines for the various machinery lists
-//NODE_I, AIR_I, PARENT_I are used within DEVICE_TYPE_LOOP
-
-//nodes list - all atmos machinery
-#define NODE1 nodes[1]
-#define NODE2 nodes[2]
-#define NODE3 nodes[3]
-#define NODE4 nodes[4]
-#define NODE_I nodes[I]
-
-//airs list - components only
-#define AIR1 airs[1]
-#define AIR2 airs[2]
-#define AIR3 airs[3]
-#define AIR_I airs[I]
-
-//parents list - components only
-#define PARENT1 parents[1]
-#define PARENT2 parents[2]
-#define PARENT3 parents[3]
-#define PARENT_I parents[I]
-
//TANKS
#define TANK_MELT_TEMPERATURE 1000000 //temperature in kelvins at which a tank will start to melt
#define TANK_LEAK_PRESSURE (30.*ONE_ATMOSPHERE) //Tank starts leaking
diff --git a/code/__DEFINES/cleaning.dm b/code/__DEFINES/cleaning.dm
index 9f32992eb0..eed0ee5f54 100644
--- a/code/__DEFINES/cleaning.dm
+++ b/code/__DEFINES/cleaning.dm
@@ -4,4 +4,9 @@
#define CLEAN_MEDIUM 3 // Acceptable tools
#define CLEAN_STRONG 4 // Industrial strength
#define CLEAN_IMPRESSIVE 5 // Cleaning strong enough your granny would be proud
-#define CLEAN_GOD 6 // Cleans things spotless down to the atomic structure
\ No newline at end of file
+#define CLEAN_GOD 6 // Cleans things spotless down to the atomic structure
+
+//How strong things have to be to wipe forensic evidence...
+#define CLEAN_STRENGTH_FINGERPRINTS CLEAN_IMPRESSIVE
+#define CLEAN_STRENGTH_BLOOD CLEAN_WEAK
+#define CLEAN_STRENGTH_FIBERS CLEAN_IMPRESSIVE
diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm
index 78ade5c650..7eebdff142 100644
--- a/code/__DEFINES/components.dm
+++ b/code/__DEFINES/components.dm
@@ -27,6 +27,13 @@
#define COMPONENT_NO_AFTERATTACK 1 //Return this in response if you don't want afterattack to be called
#define COMSIG_ATOM_HULK_ATTACK "hulk_attack" //from base of atom/attack_hulk(): (/mob/living/carbon/human)
#define COMSIG_PARENT_EXAMINE "atom_examine" //from base of atom/examine(): (/mob)
+#define COMSIG_ATOM_GET_EXAMINE_NAME "atom_examine_name" //from base of atom/get_examine_name(): (/mob, list/overrides)
+ //Positions for overrides list
+ #define EXAMINE_POSITION_ARTICLE 1
+ #define EXAMINE_POSITION_BEFORE 2
+ #define EXAMINE_POSITION_NAME 3
+ //End positions
+ #define COMPONENT_EXNAME_CHANGED 1
#define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (/atom/movable, /atom)
#define COMSIG_ATOM_EX_ACT "atom_ex_act" //from base of atom/ex_act(): (severity, target)
#define COMSIG_ATOM_EMP_ACT "atom_emp_act" //from base of atom/emp_act(): (severity)
diff --git a/code/__DEFINES/forensics.dm b/code/__DEFINES/forensics.dm
new file mode 100644
index 0000000000..bb512edcde
--- /dev/null
+++ b/code/__DEFINES/forensics.dm
@@ -0,0 +1,2 @@
+#define IF_HAS_BLOOD_DNA(__thing) GET_COMPONENT_FROM(__FR##__thing, /datum/component/forensics, __thing); if(__FR##__thing && length(__FR##__thing.blood_DNA))
+#define IF_HAS_BLOOD_DNA_AND(__thing, __conditions...) GET_COMPONENT_FROM(__FR##__thing, /datum/component/forensics, __thing); if(__FR##__thing && length(__FR##__thing.blood_DNA) && (##__conditions))
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index 707ef6a9c1..95a7b3c63d 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -108,6 +108,7 @@
#define AI_ON 1
#define AI_IDLE 2
#define AI_OFF 3
+#define AI_Z_OFF 4
//determines if a mob can smash through it
#define ENVIRONMENT_SMASH_NONE 0
diff --git a/code/__DEFINES/stat.dm b/code/__DEFINES/stat.dm
index 942a82e73f..96dceb6db2 100644
--- a/code/__DEFINES/stat.dm
+++ b/code/__DEFINES/stat.dm
@@ -25,13 +25,17 @@
// common disability sources
#define EYE_DAMAGE "eye_damage"
#define GENETIC_MUTATION "genetic"
-#define STATUE_MUTE "statue"
-#define CHANGELING_DRAIN "drain"
#define OBESITY "obesity"
#define MAGIC_DISABILITY "magic"
#define STASIS_MUTE "stasis"
#define GENETICS_SPELL "genetics_spell"
#define TRAUMA_DISABILITY "trauma"
+#define CHEMICAL_DISABILITY "chemical"
+
+// unique disability sources, still defines
+#define STATUE_MUTE "statue"
+#define CHANGELING_DRAIN "drain"
+#define ABYSSAL_GAZE_BLIND "abyssal_gaze"
// bitflags for machine stat variable
#define BROKEN 1
diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm
index 4f36ddbb1e..2e1524ebac 100644
--- a/code/__DEFINES/status_effects.dm
+++ b/code/__DEFINES/status_effects.dm
@@ -64,6 +64,8 @@
#define STATUS_EFFECT_KINDLE /datum/status_effect/kindle //A knockdown reduced by 1 second for every 3 points of damage the target takes.
+#define STATUS_EFFECT_ICHORIAL_STAIN /datum/status_effect/ichorial_stain //Prevents a servant from being revived by vitality matrices for one minute.
+
/////////////
// NEUTRAL //
/////////////
diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index 5a0dded276..39f9722486 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -70,6 +70,40 @@
#define INIT_ORDER_SQUEAK -40
#define INIT_ORDER_PERSISTENCE -100
+// Subsystem fire priority, from lowest to highest priority
+// If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child)
+
+#define FIRE_PRIORITY_IDLE_NPC 1
+#define FIRE_PRIORITY_SERVER_MAINT 1
+
+#define FIRE_PRIORITY_GARBAGE 4
+#define FIRE_PRIORITY_RESEARCH 4
+#define FIRE_PRIORITY_AIR 5
+#define FIRE_PRIORITY_NPC 5
+#define FIRE_PRIORITY_PROCESS 6
+#define FIRE_PRIORITY_THROWING 6
+#define FIRE_PRIORITY_FLIGHTPACKS 7
+#define FIRE_PRIORITY_SPACEDRIFT 7
+#define FIRE_PRIOTITY_SMOOTHING 8
+#define FIRE_PRIORITY_ORBIT 8
+#define FIRE_PRIORITY_OBJ 9
+#define FIRE_PRIORUTY_FIELDS 9
+#define FIRE_PRIORITY_ACID 9
+#define FIRE_PRIOTITY_BURNING 9
+#define FIRE_PRIORITY_INBOUNDS 9
+
+#define FIRE_PRIORITY_DEFAULT 10
+
+#define FIRE_PRIORITY_PARALLAX 11
+#define FIRE_PRIORITY_NETWORKS 12
+#define FIRE_PRIORITY_MOBS 13
+#define FIRE_PRIORITY_TGUI 14
+
+#define FIRE_PRIORITY_TICKER 19
+#define FIRE_PRIORITY_OVERLAYS 20
+
+#define FIRE_PRIORITY_INPUT 100 // This must always always be the max highest priority. Player input must never be lost.
+
// SS runlevels
#define RUNLEVEL_INIT 0
diff --git a/code/__HELPERS/level_traits.dm b/code/__HELPERS/level_traits.dm
new file mode 100644
index 0000000000..e2a74cf8e0
--- /dev/null
+++ b/code/__HELPERS/level_traits.dm
@@ -0,0 +1,17 @@
+// Helpers for checking whether a z-level conforms to a specific requirement
+
+// Basic levels
+#define is_centcom_level(z) ((z) == ZLEVEL_CENTCOM)
+
+#define is_station_level(z) ((z) in GLOB.station_z_levels)
+
+#define is_mining_level(z) ((z) == ZLEVEL_MINING)
+
+#define is_reebe(z) ((z) == ZLEVEL_CITYOFCOGS)
+
+#define is_transit_level(z) ((z) == ZLEVEL_TRANSIT)
+
+#define is_away_level(z) ((z) > ZLEVEL_SPACEMAX)
+
+// If true, the singularity cannot strip away asteroid turf on this Z
+#define is_planet_level(z) (GLOB.z_is_planet["z"])
diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm
index 52dd7c6358..8ca98ebf37 100644
--- a/code/__HELPERS/roundend.dm
+++ b/code/__HELPERS/roundend.dm
@@ -18,6 +18,9 @@
//Antag information
gather_antag_data()
+ //Nuke disk
+ record_nuke_disk_location()
+
/datum/controller/subsystem/ticker/proc/gather_antag_data()
var/team_gid = 1
var/list/team_ids = list()
@@ -46,11 +49,57 @@
antag_info["objectives"] += list(list("objective_type"=O.type,"text"=O.explanation_text,"result"=result))
SSblackbox.record_feedback("associative", "antagonists", 1, antag_info)
+/datum/controller/subsystem/ticker/proc/record_nuke_disk_location()
+ var/obj/item/disk/nuclear/N = locate() in GLOB.poi_list
+ if(N)
+ var/list/data = list()
+ var/turf/T = get_turf(N)
+ if(T)
+ data["x"] = T.x
+ data["y"] = T.y
+ data["z"] = T.z
+ var/atom/outer = get_atom_on_turf(N,/mob/living)
+ if(outer != N)
+ if(isliving(outer))
+ var/mob/living/L = outer
+ data["holder"] = L.real_name
+ else
+ data["holder"] = outer.name
+
+ SSblackbox.record_feedback("associative", "roundend_nukedisk", 1 , data)
+
+/datum/controller/subsystem/ticker/proc/gather_newscaster()
+ var/json_file = file("[GLOB.log_directory]/newscaster.json")
+ var/list/file_data = list()
+ var/pos = 1
+ for(var/V in GLOB.news_network.network_channels)
+ var/datum/newscaster/feed_channel/channel = V
+ if(!istype(channel))
+ stack_trace("Non-channel in newscaster channel list")
+ continue
+ file_data["[pos]"] = list("channel name" = "[channel.channel_name]", "author" = "[channel.author]", "censored" = channel.censored ? 1 : 0, "author censored" = channel.authorCensor ? 1 : 0, "messages" = list())
+ for(var/M in channel.messages)
+ var/datum/newscaster/feed_message/message = M
+ if(!istype(message))
+ stack_trace("Non-message in newscaster channel messages list")
+ continue
+ var/list/comment_data = list()
+ for(var/C in message.comments)
+ var/datum/newscaster/feed_comment/comment = C
+ if(!istype(comment))
+ stack_trace("Non-message in newscaster message comments list")
+ continue
+ comment_data += list(list("author" = "[comment.author]", "time stamp" = "[comment.time_stamp]", "body" = "[comment.body]"))
+ file_data["[pos]"]["messages"] += list(list("author" = "[message.author]", "time stamp" = "[message.time_stamp]", "censored" = message.bodyCensor ? 1 : 0, "author censored" = message.authorCensor ? 1 : 0, "photo file" = "[message.photo_file]", "photo caption" = "[message.caption]", "body" = "[message.body]", "comments" = comment_data))
+ pos++
+ if(GLOB.news_network.wanted_issue.active)
+ file_data["wanted"] = list("author" = "[GLOB.news_network.wanted_issue.scannedUser]", "criminal" = "[GLOB.news_network.wanted_issue.criminal]", "description" = "[GLOB.news_network.wanted_issue.body]", "photo file" = "[GLOB.news_network.wanted_issue.photo_file]")
+ WRITE_FILE(json_file, json_encode(file_data))
/datum/controller/subsystem/ticker/proc/declare_completion()
set waitfor = FALSE
- to_chat(world, "
The round has ended.")
+ to_chat(world, "
The round has ended.")
if(LAZYLEN(GLOB.round_end_notifiees))
send2irc("Notice", "[GLOB.round_end_notifiees.Join(", ")] the round has ended.")
@@ -78,7 +127,7 @@
send2irc("Server", "Round just ended.")
- if(CONFIG_GET(string/cross_server_address))
+ if(length(CONFIG_GET(keyed_string_list/cross_server)))
send_news_report()
CHECK_TICK
@@ -182,7 +231,7 @@
num_human_escapees++
if(shuttle_areas[get_area(Player)])
num_shuttle_escapees++
-
+
.[POPCOUNT_SURVIVORS] = num_survivors
.[POPCOUNT_ESCAPEES] = num_escapees
.[POPCOUNT_SHUTTLE_ESCAPEES] = num_shuttle_escapees
@@ -194,7 +243,7 @@
var/list/parts = list()
var/station_evacuated = EMERGENCY_ESCAPED_OR_ENDGAMED
var/popcount = count_survivors()
-
+
//Round statistics report
var/datum/station_state/end_state = new /datum/station_state()
end_state.count()
@@ -346,7 +395,7 @@
currrent_category = A.roundend_category
previous_category = A
result += A.roundend_report()
- result += "
"
+ result += "
"
if(all_antagonists.len)
var/datum/antagonist/last = all_antagonists[all_antagonists.len]
@@ -393,7 +442,7 @@
text += " survived"
if(fleecheck)
var/turf/T = get_turf(ply.current)
- if(!T || !(T.z in GLOB.station_z_levels))
+ if(!T || !is_station_level(T.z))
text += " while fleeing the station"
if(ply.current.real_name != ply.name)
text += " as [ply.current.real_name]"
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 1fd60c2bd4..15a3c73880 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1434,11 +1434,6 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
temp = ((temp + (temp>>3))&29127) % 63 //070707
return temp
-//checks if a turf is in the planet z list.
-/proc/turf_z_is_planet(turf/T)
- return GLOB.z_is_planet["[T.z]"]
-
-
//same as do_mob except for movables and it allows both to drift and doesn't draw progressbar
/proc/do_atom(atom/movable/user , atom/movable/target, time = 30, uninterruptible = 0,datum/callback/extra_checks = null)
if(!user || !target)
diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm
index 89e4481284..c2acea2753 100644
--- a/code/_globalvars/lists/mobs.dm
+++ b/code/_globalvars/lists/mobs.dm
@@ -22,7 +22,7 @@ GLOBAL_LIST_EMPTY(carbon_list) //all instances of /mob/living/carbon and subt
GLOBAL_LIST_EMPTY(ai_list)
GLOBAL_LIST_EMPTY(pai_list)
GLOBAL_LIST_EMPTY(available_ai_shells)
-GLOBAL_LIST_INIT(simple_animals, list(list(),list(),list())) // One for each AI_* status define
+GLOBAL_LIST_INIT(simple_animals, list(list(),list(),list(),list())) // One for each AI_* status define
GLOBAL_LIST_EMPTY(spidermobs) //all sentient spider mobs
GLOBAL_LIST_EMPTY(bots_list)
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index ddfbec5935..68428cae90 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -58,9 +58,11 @@
SendSignal(COMSIG_ITEM_ATTACK, M, user)
if(flags_1 & NOBLUDGEON_1)
return
-
- if(user.has_disability(DISABILITY_PACIFISM))
+
+ if(force && user.has_disability(DISABILITY_PACIFISM))
+ to_chat(user, "You don't want to harm other living beings!")
return
+
if(!force)
playsound(loc, 'sound/weapons/tap.ogg', get_clamped_volume(), 1, -1)
else if(hitsound)
diff --git a/code/citadel/cit_reagents.dm b/code/citadel/cit_reagents.dm
index 12604f26f5..79ccfea936 100644
--- a/code/citadel/cit_reagents.dm
+++ b/code/citadel/cit_reagents.dm
@@ -21,7 +21,7 @@
S = new(T)
S.reagents.add_reagent("semen", reac_volume)
if(data["blood_DNA"])
- S.blood_DNA[data["blood_DNA"]] = data["blood_type"]
+ S.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"]))
/obj/effect/decal/cleanable/semen
name = "semen"
@@ -62,17 +62,16 @@
icon = 'code/citadel/icons/effects.dmi'
icon_state = "fem1"
random_icon_states = list("fem1", "fem2", "fem3", "fem4")
- blood_DNA = list()
blood_state = null
bloodiness = null
/obj/effect/decal/cleanable/femcum/New()
..()
dir = pick(1,2,4,8)
+ add_blood_DNA(list("Non-human DNA" = "A+"))
/obj/effect/decal/cleanable/femcum/replace_decal(obj/effect/decal/cleanable/femcum/F)
- if (F.blood_DNA)
- blood_DNA |= F.blood_DNA.Copy()
+ F.add_blood_DNA(return_blood_DNA())
..()
/datum/reagent/consumable/femcum/reaction_turf(turf/T, reac_volume)
@@ -86,7 +85,7 @@
S = new(T)
S.reagents.add_reagent("femcum", reac_volume)
if(data["blood_DNA"])
- S.blood_DNA[data["blood_DNA"]] = data["blood_type"]
+ S.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"]))
//aphrodisiac & anaphrodisiac
diff --git a/code/citadel/custom_loadout/custom_items.dm b/code/citadel/custom_loadout/custom_items.dm
index 7cda1d9e5a..4e8e3b5e49 100644
--- a/code/citadel/custom_loadout/custom_items.dm
+++ b/code/citadel/custom_loadout/custom_items.dm
@@ -10,6 +10,14 @@
w_class = WEIGHT_CLASS_TINY
flags_1 = NOBLUDGEON_1
+/obj/item/soap/cebu //real versions, for admin shenanigans. Adminspawn only
+ desc = "A bright blue bar of soap that smells of wolves"
+ icon = 'icons/obj/custom.dmi'
+ icon_state = "cebu"
+
+/obj/item/soap/cebu/fast //speedyquick cleaning version. Still not as fast as Syndiesoap. Adminspawn only.
+ cleanspeed = 15
+
/*Inferno707*/
diff --git a/code/citadel/dogborgstuff.dm b/code/citadel/dogborgstuff.dm
index 9a6a6581c9..2713b19976 100644
--- a/code/citadel/dogborgstuff.dm
+++ b/code/citadel/dogborgstuff.dm
@@ -259,7 +259,7 @@
to_chat(user,"You clean \the [target.name].")
var/obj/effect/decal/cleanable/C = locate() in target
qdel(C)
- target.clean_blood()
+ SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
else if(ishuman(target))
if(src.emagged)
var/mob/living/silicon/robot.R = user
@@ -292,7 +292,7 @@
to_chat(user, "You clean \the [target.name].")
var/obj/effect/decal/cleanable/C = locate() in target
qdel(C)
- target.clean_blood()
+ SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
return
diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm
index 8d450e3a8e..c3779dc98f 100644
--- a/code/controllers/subsystem.dm
+++ b/code/controllers/subsystem.dm
@@ -4,7 +4,7 @@
name = "fire coderbus" //name of the subsystem
var/init_order = INIT_ORDER_DEFAULT //order of initialization. Higher numbers are initialized first, lower numbers later. Use defines in __DEFINES/subsystems.dm for easy understanding of order.
var/wait = 20 //time to wait (in deciseconds) between each call to fire(). Must be a positive integer.
- var/priority = 50 //When mutiple subsystems need to run in the same tick, higher priority subsystems will run first and be given a higher share of the tick before MC_TICK_CHECK triggers a sleep
+ var/priority = FIRE_PRIORITY_DEFAULT //When mutiple subsystems need to run in the same tick, higher priority subsystems will run first and be given a higher share of the tick before MC_TICK_CHECK triggers a sleep
var/flags = 0 //see MC.dm in __DEFINES Most flags must be set on world start to take full effect. (You can also restart the mc to force them to process again)
diff --git a/code/controllers/subsystem/acid.dm b/code/controllers/subsystem/acid.dm
index a83afb3923..e3c415960b 100644
--- a/code/controllers/subsystem/acid.dm
+++ b/code/controllers/subsystem/acid.dm
@@ -1,6 +1,6 @@
SUBSYSTEM_DEF(acid)
name = "Acid"
- priority = 40
+ priority = FIRE_PRIORITY_ACID
flags = SS_NO_INIT|SS_BACKGROUND
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm
index 59b6fc34ef..1775d470b0 100644
--- a/code/controllers/subsystem/air.dm
+++ b/code/controllers/subsystem/air.dm
@@ -9,7 +9,7 @@
SUBSYSTEM_DEF(air)
name = "Atmospherics"
init_order = INIT_ORDER_AIR
- priority = 20
+ priority = FIRE_PRIORITY_AIR
wait = 5
flags = SS_BACKGROUND
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
diff --git a/code/controllers/subsystem/communications.dm b/code/controllers/subsystem/communications.dm
index e86d32f76b..fcf7dba607 100644
--- a/code/controllers/subsystem/communications.dm
+++ b/code/controllers/subsystem/communications.dm
@@ -30,7 +30,7 @@ SUBSYSTEM_DEF(communications)
/datum/controller/subsystem/communications/proc/send_message(datum/comm_message/sending,print = TRUE,unique = FALSE)
for(var/obj/machinery/computer/communications/C in GLOB.machines)
- if(!(C.stat & (BROKEN|NOPOWER)) && (C.z in GLOB.station_z_levels))
+ if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
if(unique)
C.add_message(sending)
else //We copy the message for each console, answers and deletions won't be shared
diff --git a/code/controllers/subsystem/fire_burning.dm b/code/controllers/subsystem/fire_burning.dm
index 73358000f1..db6dc6513e 100644
--- a/code/controllers/subsystem/fire_burning.dm
+++ b/code/controllers/subsystem/fire_burning.dm
@@ -1,6 +1,6 @@
SUBSYSTEM_DEF(fire_burning)
name = "Fire Burning"
- priority = 40
+ priority = FIRE_PRIOTITY_BURNING
flags = SS_NO_INIT|SS_BACKGROUND
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm
index 6203f1b474..4faf234ffd 100644
--- a/code/controllers/subsystem/garbage.dm
+++ b/code/controllers/subsystem/garbage.dm
@@ -1,6 +1,6 @@
SUBSYSTEM_DEF(garbage)
name = "Garbage"
- priority = 15
+ priority = FIRE_PRIORITY_GARBAGE
wait = 2 SECONDS
flags = SS_POST_FIRE_TIMING|SS_BACKGROUND|SS_NO_INIT
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
diff --git a/code/controllers/subsystem/icon_smooth.dm b/code/controllers/subsystem/icon_smooth.dm
index 84df089973..d0ad2ffbc3 100644
--- a/code/controllers/subsystem/icon_smooth.dm
+++ b/code/controllers/subsystem/icon_smooth.dm
@@ -2,7 +2,7 @@ SUBSYSTEM_DEF(icon_smooth)
name = "Icon Smoothing"
init_order = INIT_ORDER_ICON_SMOOTHING
wait = 1
- priority = 35
+ priority = FIRE_PRIOTITY_SMOOTHING
flags = SS_TICKER
var/list/smooth_queue = list()
diff --git a/code/controllers/subsystem/idlenpcpool.dm b/code/controllers/subsystem/idlenpcpool.dm
index 49846e6c9d..a033512d58 100644
--- a/code/controllers/subsystem/idlenpcpool.dm
+++ b/code/controllers/subsystem/idlenpcpool.dm
@@ -1,15 +1,21 @@
SUBSYSTEM_DEF(idlenpcpool)
name = "Idling NPC Pool"
- flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND
- priority = 10
+ flags = SS_POST_FIRE_TIMING|SS_BACKGROUND
+ priority = FIRE_PRIORITY_IDLE_NPC
wait = 60
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
var/list/currentrun = list()
+ var/static/list/idle_mobs_by_zlevel[][]
/datum/controller/subsystem/idlenpcpool/stat_entry()
var/list/idlelist = GLOB.simple_animals[AI_IDLE]
- ..("IdleNPCS:[idlelist.len]")
+ var/list/zlist = GLOB.simple_animals[AI_Z_OFF]
+ ..("IdleNPCS:[idlelist.len]|Z:[zlist.len]")
+
+/datum/controller/subsystem/idlenpcpool/Initialize(start_timeofday)
+ idle_mobs_by_zlevel = new /list(world.maxz,0)
+ return ..()
/datum/controller/subsystem/idlenpcpool/fire(resumed = FALSE)
@@ -24,6 +30,9 @@ SUBSYSTEM_DEF(idlenpcpool)
while(currentrun.len)
var/mob/living/simple_animal/SA = currentrun[currentrun.len]
--currentrun.len
+ if (!SA)
+ GLOB.simple_animals[AI_IDLE] -= SA
+ continue
if(!SA.ckey)
if(SA.stat != DEAD)
@@ -32,3 +41,4 @@ SUBSYSTEM_DEF(idlenpcpool)
SA.consider_wakeup()
if (MC_TICK_CHECK)
return
+
diff --git a/code/controllers/subsystem/inbounds.dm b/code/controllers/subsystem/inbounds.dm
index 16e0f53028..63063c258f 100644
--- a/code/controllers/subsystem/inbounds.dm
+++ b/code/controllers/subsystem/inbounds.dm
@@ -1,6 +1,6 @@
SUBSYSTEM_DEF(inbounds)
name = "Inbounds"
- priority = 40
+ priority = FIRE_PRIORITY_INBOUNDS
flags = SS_NO_INIT
runlevels = RUNLEVEL_GAME
diff --git a/code/controllers/subsystem/input.dm b/code/controllers/subsystem/input.dm
index 5dbb642f2e..f553d66307 100644
--- a/code/controllers/subsystem/input.dm
+++ b/code/controllers/subsystem/input.dm
@@ -2,7 +2,7 @@ SUBSYSTEM_DEF(input)
name = "Input"
wait = 1 //SS_TICKER means this runs every tick
flags = SS_TICKER | SS_NO_INIT
- priority = 1000
+ priority = FIRE_PRIORITY_INPUT
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
/datum/controller/subsystem/input/fire()
diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm
index 6b394c3a1f..07c08cda55 100644
--- a/code/controllers/subsystem/mapping.dm
+++ b/code/controllers/subsystem/mapping.dm
@@ -146,7 +146,7 @@ GLOBAL_LIST_EMPTY(the_station_areas)
var/list/station_areas_blacklist = typecacheof(list(/area/space, /area/mine, /area/ruin))
for(var/area/A in world)
var/turf/picked = safepick(get_area_turfs(A.type))
- if(picked && (picked.z in GLOB.station_z_levels))
+ if(picked && is_station_level(picked.z))
if(!(A.type in GLOB.the_station_areas) && !is_type_in_typecache(A, station_areas_blacklist))
GLOB.the_station_areas.Add(A.type)
diff --git a/code/controllers/subsystem/minimap.dm b/code/controllers/subsystem/minimap.dm
index 463b82b13e..4bead36bb1 100644
--- a/code/controllers/subsystem/minimap.dm
+++ b/code/controllers/subsystem/minimap.dm
@@ -61,7 +61,7 @@ SUBSYSTEM_DEF(minimap)
for(var/z in z_levels)
send_asset(client, "minimap_[z].png")
-/datum/controller/subsystem/minimap/proc/generate(z = 1, x1 = 1, y1 = 1, x2 = world.maxx, y2 = world.maxy)
+/datum/controller/subsystem/minimap/proc/generate(z, x1 = 1, y1 = 1, x2 = world.maxx, y2 = world.maxy)
// Load the background.
var/icon/minimap = new /icon('icons/minimap.dmi')
// Scale it up to our target size.
diff --git a/code/controllers/subsystem/mobs.dm b/code/controllers/subsystem/mobs.dm
index bcdb1af8ed..14ad19e1ea 100644
--- a/code/controllers/subsystem/mobs.dm
+++ b/code/controllers/subsystem/mobs.dm
@@ -1,6 +1,6 @@
SUBSYSTEM_DEF(mobs)
name = "Mobs"
- priority = 100
+ priority = FIRE_PRIORITY_MOBS
flags = SS_KEEP_TIMING
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
diff --git a/code/controllers/subsystem/npcpool.dm b/code/controllers/subsystem/npcpool.dm
index 6ee4626f25..ca050cb9b2 100644
--- a/code/controllers/subsystem/npcpool.dm
+++ b/code/controllers/subsystem/npcpool.dm
@@ -6,7 +6,7 @@
SUBSYSTEM_DEF(npcpool)
name = "NPC Pool"
flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND
- priority = 20
+ priority = FIRE_PRIORITY_NPC
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
var/list/canBeUsed = list()
diff --git a/code/controllers/subsystem/orbit.dm b/code/controllers/subsystem/orbit.dm
index 6184bb005b..581b7821b2 100644
--- a/code/controllers/subsystem/orbit.dm
+++ b/code/controllers/subsystem/orbit.dm
@@ -1,44 +1,42 @@
-SUBSYSTEM_DEF(orbit)
- name = "Orbits"
- priority = 35
- wait = 2
- flags = SS_NO_INIT|SS_TICKER
-
- var/list/currentrun = list()
- var/list/processing = list()
-
-/datum/controller/subsystem/orbit/stat_entry()
- ..("P:[processing.len]")
-
-
-/datum/controller/subsystem/orbit/fire(resumed = 0)
- if (!resumed)
- src.currentrun = processing.Copy()
-
- //cache for sanic speed (lists are references anyways)
- var/list/currentrun = src.currentrun
-
- while (currentrun.len)
- var/datum/orbit/O = currentrun[currentrun.len]
- currentrun.len--
- if (!O)
- processing -= O
- if (MC_TICK_CHECK)
- return
- continue
- if (!O.orbiter)
- qdel(O)
- if (MC_TICK_CHECK)
- return
- continue
- if (O.lastprocess >= world.time) //we already checked recently
- if (MC_TICK_CHECK)
- return
- continue
- var/targetloc = get_turf(O.orbiting)
- if (targetloc != O.lastloc || O.orbiter.loc != targetloc)
- O.Check(targetloc)
- if (MC_TICK_CHECK)
- return
-
-
+SUBSYSTEM_DEF(orbit)
+ name = "Orbits"
+ priority = FIRE_PRIORITY_ORBIT
+ wait = 2
+ flags = SS_NO_INIT|SS_TICKER
+
+ var/list/currentrun = list()
+ var/list/processing = list()
+
+/datum/controller/subsystem/orbit/stat_entry()
+ ..("P:[processing.len]")
+
+
+/datum/controller/subsystem/orbit/fire(resumed = 0)
+ if (!resumed)
+ src.currentrun = processing.Copy()
+
+ //cache for sanic speed (lists are references anyways)
+ var/list/currentrun = src.currentrun
+
+ while (currentrun.len)
+ var/datum/orbit/O = currentrun[currentrun.len]
+ currentrun.len--
+ if (!O)
+ processing -= O
+ if (MC_TICK_CHECK)
+ return
+ continue
+ if (!O.orbiter)
+ qdel(O)
+ if (MC_TICK_CHECK)
+ return
+ continue
+ if (O.lastprocess >= world.time) //we already checked recently
+ if (MC_TICK_CHECK)
+ return
+ continue
+ var/targetloc = get_turf(O.orbiting)
+ if (targetloc != O.lastloc || O.orbiter.loc != targetloc)
+ O.Check(targetloc)
+ if (MC_TICK_CHECK)
+ return
diff --git a/code/controllers/subsystem/overlays.dm b/code/controllers/subsystem/overlays.dm
index d0b2e8c303..23edb3e487 100644
--- a/code/controllers/subsystem/overlays.dm
+++ b/code/controllers/subsystem/overlays.dm
@@ -2,7 +2,7 @@ SUBSYSTEM_DEF(overlays)
name = "Overlay"
flags = SS_TICKER
wait = 1
- priority = 500
+ priority = FIRE_PRIORITY_OVERLAYS
init_order = INIT_ORDER_OVERLAY
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_SETUP
diff --git a/code/controllers/subsystem/parallax.dm b/code/controllers/subsystem/parallax.dm
index 4fa843906c..f8f2d463ba 100644
--- a/code/controllers/subsystem/parallax.dm
+++ b/code/controllers/subsystem/parallax.dm
@@ -2,7 +2,7 @@ SUBSYSTEM_DEF(parallax)
name = "Parallax"
wait = 2
flags = SS_POST_FIRE_TIMING | SS_BACKGROUND | SS_NO_INIT
- priority = 65
+ priority = FIRE_PRIORITY_PARALLAX
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
var/list/currentrun
diff --git a/code/controllers/subsystem/processing/fields.dm b/code/controllers/subsystem/processing/fields.dm
index 6a878fa142..b6996377b5 100644
--- a/code/controllers/subsystem/processing/fields.dm
+++ b/code/controllers/subsystem/processing/fields.dm
@@ -1,6 +1,6 @@
PROCESSING_SUBSYSTEM_DEF(fields)
name = "Fields"
wait = 2
- priority = 40
+ priority = FIRE_PRIORUTY_FIELDS
flags = SS_KEEP_TIMING | SS_NO_INIT
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
diff --git a/code/controllers/subsystem/processing/flightpacks.dm b/code/controllers/subsystem/processing/flightpacks.dm
index 1d85811878..2981789338 100644
--- a/code/controllers/subsystem/processing/flightpacks.dm
+++ b/code/controllers/subsystem/processing/flightpacks.dm
@@ -1,6 +1,6 @@
PROCESSING_SUBSYSTEM_DEF(flightpacks)
name = "Flightpack Movement"
- priority = 30
+ priority = FIRE_PRIORITY_FLIGHTPACKS
wait = 2
stat_tag = "FM"
flags = SS_NO_INIT|SS_TICKER|SS_KEEP_TIMING
diff --git a/code/controllers/subsystem/processing/networks.dm b/code/controllers/subsystem/processing/networks.dm
index 69c5fe1b2b..a3f01efd0c 100644
--- a/code/controllers/subsystem/processing/networks.dm
+++ b/code/controllers/subsystem/processing/networks.dm
@@ -1,36 +1,36 @@
-PROCESSING_SUBSYSTEM_DEF(networks)
- name = "Networks"
- priority = 80
- wait = 1
- stat_tag = "NET"
- flags = SS_KEEP_TIMING
- init_order = INIT_ORDER_NETWORKS
- var/datum/ntnet/station/station_network
- var/assignment_hardware_id = HID_RESTRICTED_END
- var/list/networks_by_id = list() //id = network
- var/list/interfaces_by_id = list() //hardware id = component interface
-
-/datum/controller/subsystem/processing/networks/Initialize()
- station_network = new
- station_network.register_map_supremecy()
- . = ..()
-
-/datum/controller/subsystem/processing/networks/proc/register_network(datum/ntnet/network)
- if(!networks_by_id[network.network_id])
- networks_by_id[network.network_id] = network
- return TRUE
- return FALSE
-
-/datum/controller/subsystem/processing/networks/proc/unregister_network(datum/ntnet/network)
- networks_by_id -= network.network_id
- return TRUE
-
-/datum/controller/subsystem/processing/networks/proc/register_interface(datum/component/ntnet_interface/D)
- if(!interfaces_by_id[D.hardware_id])
- interfaces_by_id[D.hardware_id] = D
- return TRUE
- return FALSE
-
-/datum/controller/subsystem/processing/networks/proc/unregister_interface(datum/component/ntnet_interface/D)
- interfaces_by_id -= D.hardware_id
- return TRUE
+PROCESSING_SUBSYSTEM_DEF(networks)
+ name = "Networks"
+ priority = FIRE_PRIORITY_NETWORKS
+ wait = 1
+ stat_tag = "NET"
+ flags = SS_KEEP_TIMING
+ init_order = INIT_ORDER_NETWORKS
+ var/datum/ntnet/station/station_network
+ var/assignment_hardware_id = HID_RESTRICTED_END
+ var/list/networks_by_id = list() //id = network
+ var/list/interfaces_by_id = list() //hardware id = component interface
+
+/datum/controller/subsystem/processing/networks/Initialize()
+ station_network = new
+ station_network.register_map_supremecy()
+ . = ..()
+
+/datum/controller/subsystem/processing/networks/proc/register_network(datum/ntnet/network)
+ if(!networks_by_id[network.network_id])
+ networks_by_id[network.network_id] = network
+ return TRUE
+ return FALSE
+
+/datum/controller/subsystem/processing/networks/proc/unregister_network(datum/ntnet/network)
+ networks_by_id -= network.network_id
+ return TRUE
+
+/datum/controller/subsystem/processing/networks/proc/register_interface(datum/component/ntnet_interface/D)
+ if(!interfaces_by_id[D.hardware_id])
+ interfaces_by_id[D.hardware_id] = D
+ return TRUE
+ return FALSE
+
+/datum/controller/subsystem/processing/networks/proc/unregister_interface(datum/component/ntnet_interface/D)
+ interfaces_by_id -= D.hardware_id
+ return TRUE
diff --git a/code/controllers/subsystem/processing/obj.dm b/code/controllers/subsystem/processing/obj.dm
index 29fe277232..68f6f16cea 100644
--- a/code/controllers/subsystem/processing/obj.dm
+++ b/code/controllers/subsystem/processing/obj.dm
@@ -1,6 +1,6 @@
SUBSYSTEM_DEF(obj)
name = "Objects"
- priority = 40
+ priority = FIRE_PRIORITY_OBJ
flags = SS_NO_INIT
var/list/processing = list()
diff --git a/code/controllers/subsystem/processing/processing.dm b/code/controllers/subsystem/processing/processing.dm
index 0586975866..f6d45ebff2 100644
--- a/code/controllers/subsystem/processing/processing.dm
+++ b/code/controllers/subsystem/processing/processing.dm
@@ -2,7 +2,7 @@
SUBSYSTEM_DEF(processing)
name = "Processing"
- priority = 25
+ priority = FIRE_PRIORITY_PROCESS
flags = SS_BACKGROUND|SS_POST_FIRE_TIMING|SS_NO_INIT
wait = 10
diff --git a/code/controllers/subsystem/processing/projectiles.dm b/code/controllers/subsystem/processing/projectiles.dm
index ebf217c79a..cc2399e3df 100644
--- a/code/controllers/subsystem/processing/projectiles.dm
+++ b/code/controllers/subsystem/processing/projectiles.dm
@@ -1,6 +1,5 @@
PROCESSING_SUBSYSTEM_DEF(projectiles)
name = "Projectiles"
- priority = 25
wait = 1
stat_tag = "PP"
flags = SS_NO_INIT|SS_TICKER|SS_KEEP_TIMING
diff --git a/code/controllers/subsystem/radiation.dm b/code/controllers/subsystem/radiation.dm
index 0b69e003fc..a6cd658bf6 100644
--- a/code/controllers/subsystem/radiation.dm
+++ b/code/controllers/subsystem/radiation.dm
@@ -1,7 +1,6 @@
PROCESSING_SUBSYSTEM_DEF(radiation)
name = "Radiation"
flags = SS_NO_INIT | SS_BACKGROUND
- priority = 25
var/list/warned_atoms = list()
diff --git a/code/controllers/subsystem/research.dm b/code/controllers/subsystem/research.dm
index 5faeffde5c..f10ed9125a 100644
--- a/code/controllers/subsystem/research.dm
+++ b/code/controllers/subsystem/research.dm
@@ -2,7 +2,7 @@
SUBSYSTEM_DEF(research)
name = "Research"
flags = SS_KEEP_TIMING
- priority = 15 //My powergame is priority.
+ priority = FIRE_PRIORITY_RESEARCH
wait = 10
init_order = INIT_ORDER_RESEARCH
var/list/invalid_design_ids = list() //associative id = number of times
diff --git a/code/controllers/subsystem/server_maint.dm b/code/controllers/subsystem/server_maint.dm
index cb5a86bd75..dd68443bd7 100644
--- a/code/controllers/subsystem/server_maint.dm
+++ b/code/controllers/subsystem/server_maint.dm
@@ -4,7 +4,7 @@ SUBSYSTEM_DEF(server_maint)
name = "Server Tasks"
wait = 6
flags = SS_POST_FIRE_TIMING
- priority = 10
+ priority = FIRE_PRIORITY_SERVER_MAINT
init_order = INIT_ORDER_SERVER_MAINT
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
var/list/currentrun
diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm
index e385e48a10..65385c031f 100644
--- a/code/controllers/subsystem/shuttle.dm
+++ b/code/controllers/subsystem/shuttle.dm
@@ -325,7 +325,7 @@ SUBSYSTEM_DEF(shuttle)
continue
var/turf/T = get_turf(thing)
- if(T && (T.z in GLOB.station_z_levels))
+ if(T && is_station_level(T.z))
callShuttle = 0
break
diff --git a/code/controllers/subsystem/spacedrift.dm b/code/controllers/subsystem/spacedrift.dm
index 8fe7cbe048..56a6786a20 100644
--- a/code/controllers/subsystem/spacedrift.dm
+++ b/code/controllers/subsystem/spacedrift.dm
@@ -1,6 +1,6 @@
SUBSYSTEM_DEF(spacedrift)
name = "Space Drift"
- priority = 30
+ priority = FIRE_PRIORITY_SPACEDRIFT
wait = 5
flags = SS_NO_INIT|SS_KEEP_TIMING
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
diff --git a/code/controllers/subsystem/tgui.dm b/code/controllers/subsystem/tgui.dm
index a9b307bc0d..e03299f57f 100644
--- a/code/controllers/subsystem/tgui.dm
+++ b/code/controllers/subsystem/tgui.dm
@@ -2,7 +2,7 @@ SUBSYSTEM_DEF(tgui)
name = "tgui"
wait = 9
flags = SS_NO_INIT
- priority = 110
+ priority = FIRE_PRIORITY_TGUI
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
var/list/currentrun = list()
diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm
index ec21f3bab2..a080f1a159 100644
--- a/code/controllers/subsystem/throwing.dm
+++ b/code/controllers/subsystem/throwing.dm
@@ -3,7 +3,7 @@
SUBSYSTEM_DEF(throwing)
name = "Throwing"
- priority = 25
+ priority = FIRE_PRIORITY_THROWING
wait = 1
flags = SS_NO_INIT|SS_KEEP_TIMING|SS_TICKER
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index 0f06caa20d..d14404ed97 100755
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -4,7 +4,7 @@ SUBSYSTEM_DEF(ticker)
name = "Ticker"
init_order = INIT_ORDER_TICKER
- priority = 200
+ priority = FIRE_PRIORITY_TICKER
flags = SS_KEEP_TIMING
runlevels = RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME
diff --git a/code/datums/antagonists/blob.dm b/code/datums/antagonists/blob.dm
new file mode 100644
index 0000000000..5689e6a567
--- /dev/null
+++ b/code/datums/antagonists/blob.dm
@@ -0,0 +1,59 @@
+/datum/antagonist/blob
+ name = "Blob"
+ roundend_category = "blobs"
+ job_rank = ROLE_BLOB
+
+ var/datum/action/innate/blobpop/pop_action
+ var/starting_points_human_blob = 60
+ var/point_rate_human_blob = 2
+
+/datum/antagonist/blob/roundend_report()
+ var/basic_report = ..()
+ //Display max blobpoints for blebs that lost
+ if(isovermind(owner.current)) //embarrasing if not
+ var/mob/camera/blob/overmind = owner.current
+ if(!overmind.victory_in_progress) //if it won this doesn't really matter
+ var/point_report = "
[owner.name] took over [overmind.max_count] tiles at the height of its growth."
+ return basic_report+point_report
+ return basic_report
+
+/datum/antagonist/blob/greet()
+ if(!isovermind(owner.current))
+ to_chat(owner,"You feel bloated.")
+
+/datum/antagonist/blob/on_gain()
+ create_objectives()
+ . = ..()
+
+/datum/antagonist/blob/proc/create_objectives()
+ var/datum/objective/blob_takeover/main = new
+ main.owner = owner
+ objectives += main
+ owner.objectives |= objectives
+
+/datum/antagonist/blob/apply_innate_effects(mob/living/mob_override)
+ if(!isovermind(owner.current))
+ if(!pop_action)
+ pop_action = new
+ pop_action.Grant(owner.current)
+
+/datum/objective/blob_takeover
+ explanation_text = "Reach critical mass!"
+
+//Non-overminds get this on blob antag assignment
+/datum/action/innate/blobpop
+ name = "Pop"
+ desc = "Unleash the blob"
+ icon_icon = 'icons/mob/blob.dmi'
+ button_icon_state = "blob"
+
+/datum/action/innate/blobpop/Activate()
+ var/mob/old_body = owner
+ var/datum/antagonist/blob/blobtag = owner.mind.has_antag_datum(/datum/antagonist/blob)
+ if(!blobtag)
+ Remove()
+ return
+ var/mob/camera/blob/B = new /mob/camera/blob(get_turf(old_body), blobtag.starting_points_human_blob)
+ owner.mind.transfer_to(B)
+ old_body.gib()
+ B.place_blob_core(blobtag.point_rate_human_blob, pop_override = TRUE)
\ No newline at end of file
diff --git a/code/datums/antagonists/cult.dm b/code/datums/antagonists/cult.dm
index 916123ddff..5b80cb68a6 100644
--- a/code/datums/antagonists/cult.dm
+++ b/code/datums/antagonists/cult.dm
@@ -257,7 +257,7 @@
var/sanity = 0
while(summon_spots.len < SUMMON_POSSIBILITIES && sanity < 100)
var/area/summon = pick(GLOB.sortedAreas - summon_spots)
- if(summon && (summon.z in GLOB.station_z_levels) && summon.valid_territory)
+ if(summon && is_station_level(summon.z) && summon.valid_territory)
summon_spots += summon
sanity++
update_explanation_text()
diff --git a/code/datums/antagonists/nukeop.dm b/code/datums/antagonists/nukeop.dm
index 8b7fc7826f..441098aabd 100644
--- a/code/datums/antagonists/nukeop.dm
+++ b/code/datums/antagonists/nukeop.dm
@@ -232,7 +232,7 @@
/datum/team/nuclear/proc/syndies_escaped()
var/obj/docking_port/mobile/S = SSshuttle.getShuttle("syndicate")
- return (S && (S.z == ZLEVEL_CENTCOM || S.z == ZLEVEL_TRANSIT))
+ return S && (is_centcom_level(S.z) || is_transit_level(S.z))
/datum/team/nuclear/proc/get_result()
var/evacuation = SSshuttle.emergency.mode == SHUTTLE_ENDGAME
diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm
index fcd4651459..46ffc25643 100644
--- a/code/datums/components/_component.dm
+++ b/code/datums/components/_component.dm
@@ -205,13 +205,13 @@
new_comp = new nt(arglist(args))
if(!QDELETED(new_comp))
old_comp.InheritComponent(new_comp, TRUE)
- qdel(new_comp)
+ QDEL_NULL(new_comp)
if(COMPONENT_DUPE_HIGHLANDER)
if(!new_comp)
new_comp = new nt(arglist(args))
if(!QDELETED(new_comp))
new_comp.InheritComponent(old_comp, FALSE)
- qdel(old_comp)
+ QDEL_NULL(old_comp)
if(COMPONENT_DUPE_UNIQUE_PASSARGS)
if(!new_comp)
var/list/arguments = args.Copy(2)
diff --git a/code/datums/components/cleaning.dm b/code/datums/components/cleaning.dm
index 5d9d5992e2..cb91d3c513 100644
--- a/code/datums/components/cleaning.dm
+++ b/code/datums/components/cleaning.dm
@@ -13,28 +13,28 @@
if(!isturf(tile))
return
- tile.clean_blood()
+ tile.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
for(var/A in tile)
if(is_cleanable(A))
qdel(A)
else if(istype(A, /obj/item))
- var/obj/item/cleaned_item = A
- cleaned_item.clean_blood()
+ var/obj/item/I = A
+ I.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
else if(ishuman(A))
var/mob/living/carbon/human/cleaned_human = A
if(cleaned_human.lying)
if(cleaned_human.head)
- cleaned_human.head.clean_blood()
+ cleaned_human.head.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
cleaned_human.update_inv_head()
if(cleaned_human.wear_suit)
- cleaned_human.wear_suit.clean_blood()
+ cleaned_human.wear_suit.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
cleaned_human.update_inv_wear_suit()
else if(cleaned_human.w_uniform)
- cleaned_human.w_uniform.clean_blood()
+ cleaned_human.w_uniform.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
cleaned_human.update_inv_w_uniform()
if(cleaned_human.shoes)
- cleaned_human.shoes.clean_blood()
+ cleaned_human.shoes.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
cleaned_human.update_inv_shoes()
- cleaned_human.clean_blood()
+ cleaned_human.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
cleaned_human.wash_cream()
to_chat(cleaned_human, "[AM] cleans your face!")
diff --git a/code/datums/components/decal.dm b/code/datums/components/decal.dm
index a79de32898..53faa27f39 100644
--- a/code/datums/components/decal.dm
+++ b/code/datums/components/decal.dm
@@ -6,19 +6,11 @@
var/mutable_appearance/pic
/datum/component/decal/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_GOD, _color, _layer=TURF_LAYER, _description)
- if(!isatom(parent) || !_icon || !_icon_state)
+ if(!isatom(parent) || !generate_appearance(_icon, _icon_state, _dir, _layer, _color))
. = COMPONENT_INCOMPATIBLE
CRASH("A turf decal was applied incorrectly to [parent.type]: icon:[_icon ? _icon : "none"] icon_state:[_icon_state ? _icon_state : "none"]")
-
- // It has to be made from an image or dir breaks because of a byond bug
- var/temp_image = image(_icon, null, _icon_state, _layer, _dir)
- pic = new(temp_image)
- pic.color = _color
-
- cleanable = _cleanable
description = _description
-
- apply()
+ cleanable = _cleanable
if(_dir) // If no dir is assigned at start then it follows the atom's dir
RegisterSignal(COMSIG_ATOM_DIR_CHANGE, .proc/rotate_react)
@@ -26,6 +18,7 @@
RegisterSignal(COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react)
if(_description)
RegisterSignal(COMSIG_PARENT_EXAMINE, .proc/examine)
+ apply()
/datum/component/decal/Destroy()
remove()
@@ -36,6 +29,15 @@
remove(thing)
apply(thing)
+/datum/component/decal/proc/generate_appearance(_icon, _icon_state, _dir, _layer, _color)
+ if(!_icon || !_icon_state)
+ return FALSE
+ // It has to be made from an image or dir breaks because of a byond bug
+ var/temp_image = image(_icon, null, _icon_state, _layer, _dir)
+ pic = new(temp_image)
+ pic.color = _color
+ return TRUE
+
/datum/component/decal/proc/apply(atom/thing)
var/atom/master = thing || parent
master.add_overlay(pic, TRUE)
diff --git a/code/datums/components/decals/blood.dm b/code/datums/components/decals/blood.dm
new file mode 100644
index 0000000000..f2dc9a48d0
--- /dev/null
+++ b/code/datums/components/decals/blood.dm
@@ -0,0 +1,35 @@
+/datum/component/decal/blood
+ dupe_mode = COMPONENT_DUPE_UNIQUE
+
+/datum/component/decal/blood/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_STRENGTH_BLOOD, _color, _layer=ABOVE_OBJ_LAYER)
+ if(!isitem(parent))
+ . = COMPONENT_INCOMPATIBLE
+ CRASH("Warning: Blood decal attempted to be added to non-item of type [parent.type]")
+ . = ..()
+ RegisterSignal(COMSIG_ATOM_GET_EXAMINE_NAME, .proc/get_examine_name)
+
+/datum/component/decal/blood/generate_appearance(_icon, _icon_state, _dir, _layer, _color)
+ var/obj/item/I = parent
+ if(!_icon)
+ _icon = 'icons/effects/blood.dmi'
+ if(!_icon_state)
+ _icon_state = "itemblood"
+ if(!initial(I.icon) || !initial(I.icon_state))
+ return FALSE
+ var/static/list/blood_splatter_appearances = list()
+ //try to find a pre-processed blood-splatter. otherwise, make a new one
+ var/index = "[REF(initial(I.icon))]-[initial(I.icon_state)]"
+ pic = blood_splatter_appearances[index]
+ if(!pic)
+ var/icon/blood_splatter_icon = icon(initial(I.icon), initial(I.icon_state), , 1) //we only want to apply blood-splatters to the initial icon_state for each object
+ blood_splatter_icon.Blend("#fff", ICON_ADD) //fills the icon_state with white (except where it's transparent)
+ blood_splatter_icon.Blend(icon(_icon, _icon_state), ICON_MULTIPLY) //adds blood and the remaining white areas become transparant
+ pic = mutable_appearance(blood_splatter_icon, initial(I.icon_state), I.layer)
+ blood_splatter_appearances[index] = pic
+ return TRUE
+
+/datum/component/decal/blood/proc/get_examine_name(mob/user, list/override)
+ var/atom/A = parent
+ override[EXAMINE_POSITION_ARTICLE] = A.gender == PLURAL? "some" : "a"
+ override[EXAMINE_POSITION_BEFORE] = " blood-stained "
+ return COMPONENT_EXNAME_CHANGED
diff --git a/code/datums/components/forensics.dm b/code/datums/components/forensics.dm
index 1950b8b664..55633a2087 100644
--- a/code/datums/components/forensics.dm
+++ b/code/datums/components/forensics.dm
@@ -138,7 +138,7 @@
if(laststamppos)
LAZYSET(hiddenprints, M.key, copytext(hiddenprints[M.key], 1, laststamppos))
hiddenprints[M.key] += " Last: [M.real_name]\[[current_time]\][hasgloves]. Ckey: [M.ckey]" //made sure to be existing by if(!LAZYACCESS);else
- parent.fingerprintslast = M.ckey
+ fingerprintslast = M.ckey
return TRUE
/datum/component/forensics/proc/add_blood_DNA(list/dna) //list(dna_enzymes = type)
diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm
index 60f90d61ad..c3970baee0 100644
--- a/code/datums/diseases/advance/advance.dm
+++ b/code/datums/diseases/advance/advance.dm
@@ -408,7 +408,7 @@
AD.Refresh()
for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list))
- if(!(H.z in GLOB.station_z_levels))
+ if(!is_station_level(H.z))
continue
if(!H.HasDisease(D))
H.ForceContractDisease(D)
diff --git a/code/datums/explosion.dm b/code/datums/explosion.dm
index 73b76a9155..85a8e40863 100644
--- a/code/datums/explosion.dm
+++ b/code/datums/explosion.dm
@@ -55,6 +55,8 @@ GLOBAL_LIST_EMPTY(explosions)
var/orig_heavy_range = heavy_impact_range
var/orig_light_range = light_impact_range
+ var/orig_max_distance = max(devastation_range, heavy_impact_range, light_impact_range, flash_range, flame_range)
+
//Zlevel specific bomb cap multiplier
var/cap_multiplier = 1
switch(epicenter.z)
@@ -119,11 +121,13 @@ GLOBAL_LIST_EMPTY(explosions)
// If inside the blast radius + world.view - 2
if(dist <= round(max_range + world.view - 2, 1))
M.playsound_local(epicenter, null, 100, 1, frequency, falloff = 5, S = explosion_sound)
+ shake_camera(M, 25, min(orig_max_distance - dist, 100))
// You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station.
else if(dist <= far_dist)
var/far_volume = CLAMP(far_dist, 30, 50) // Volume is based on explosion size and dist
far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion
M.playsound_local(epicenter, null, far_volume, 1, frequency, falloff = 5, S = far_explosion_sound)
+ shake_camera(M, 10, min(orig_max_distance - dist, 50))
EX_PREPROCESS_CHECK_TICK
//postpone processing for a bit
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 231ce66f28..e4cab0d014 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -545,7 +545,7 @@
if(I == src)
continue
var/mob/M = I.current
- if(M && (M.z in GLOB.station_z_levels) && !M.stat)
+ if(M && is_station_level(M.z) && !M.stat)
last_healthy_headrev = FALSE
break
text += "head | not mindshielded | employee | [last_healthy_headrev ? "LAST " : ""]HEADREV | rev"
diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm
index cc64cc2eb8..22868f855f 100644
--- a/code/datums/status_effects/debuffs.dm
+++ b/code/datums/status_effects/debuffs.dm
@@ -479,3 +479,27 @@
desc = "Blinding light dances in your vision, stunning and silencing you. Any damage taken will shorten the light's effects!"
icon_state = "kindle"
alerttooltipstyle = "clockcult"
+
+
+//Ichorial Stain: Applied to servants revived by a vitality matrix. Prevents them from being revived by one again until the effect fades.
+/datum/status_effect/ichorial_stain
+ id = "ichorial_stain"
+ status_type = STATUS_EFFECT_UNIQUE
+ duration = 600
+ examine_text = "SUBJECTPRONOUN is drenched in thick, blue ichor!"
+ alert_type = /obj/screen/alert/status_effect/ichorial_stain
+
+/datum/status_effect/ichorial_stain/on_apply()
+ owner.visible_message("[owner] gets back up, [owner.p_their()] body dripping blue ichor!", \
+ "Thick blue ichor covers your body; you can't be revived like this again until it dries!")
+ return TRUE
+
+/datum/status_effect/ichorial_stain/on_remove()
+ owner.visible_message("The blue ichor on [owner]'s body dries out!", \
+ "The ichor on your body is dry - you can now be revived by vitality matrices again!")
+
+/obj/screen/alert/status_effect/ichorial_stain
+ name = "Ichorial Stain"
+ desc = "Your body is covered in blue ichor! You can't be revived by vitality matrices."
+ icon_state = "ichorial_stain"
+ alerttooltipstyle = "clockcult"
diff --git a/code/datums/status_effects/status_effect.dm b/code/datums/status_effects/status_effect.dm
index 19bd880a77..e24359d18c 100644
--- a/code/datums/status_effects/status_effect.dm
+++ b/code/datums/status_effects/status_effect.dm
@@ -9,6 +9,7 @@
var/mob/living/owner //The mob affected by the status effect.
var/status_type = STATUS_EFFECT_UNIQUE //How many of the effect can be on one mob, and what happens when you try to add another
var/on_remove_on_mob_delete = FALSE //if we call on_remove() when the mob is deleted
+ var/examine_text //If defined, this text will appear when the mob is examined - to use he, she etc. use "SUBJECTPRONOUN" and replace it in the examines themselves
var/alert_type = /obj/screen/alert/status_effect //the alert thrown by the status effect, contains name and description
var/obj/screen/alert/status_effect/linked_alert = null //the alert itself, if it exists
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index a2564eaea9..f4965fea13 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -76,7 +76,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
if(GLOB.teleportlocs[AR.name])
continue
var/turf/picked = safepick(get_area_turfs(AR.type))
- if (picked && (picked.z in GLOB.station_z_levels))
+ if (picked && is_station_level(picked.z))
GLOB.teleportlocs[AR.name] = AR
sortTim(GLOB.teleportlocs, /proc/cmp_text_dsc)
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 211f9dea59..eb63ca147f 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -5,10 +5,6 @@
var/flags_1 = 0
var/flags_2 = 0
-
- var/list/fingerprints
- var/list/fingerprintshidden
- var/list/blood_DNA
var/container_type = NONE
var/admin_spawned = 0 //was this spawned by an admin? used for stat tracking stuff.
var/datum/reagents/reagents = null
@@ -113,7 +109,7 @@
if(!T)
return FALSE
- if(T.z == ZLEVEL_TRANSIT)
+ if(is_transit_level(T.z))
for(var/A in SSshuttle.mobile)
var/obj/docking_port/mobile/M = A
if(M.launch_status == ENDGAME_TRANSIT)
@@ -122,7 +118,7 @@
if(T in shuttle_area)
return TRUE
- if(T.z != ZLEVEL_CENTCOM)//if not, don't bother
+ if(!is_centcom_level(T.z))//if not, don't bother
return FALSE
//Check for centcom itself
@@ -141,15 +137,15 @@
/atom/proc/onSyndieBase()
var/turf/T = get_turf(src)
if(!T)
- return 0
+ return FALSE
- if(T.z != ZLEVEL_CENTCOM)//if not, don't bother
- return 0
+ if(!is_centcom_level(T.z))//if not, don't bother
+ return FALSE
- if(istype(T.loc, /area/shuttle/syndicate) || istype(T.loc, /area/syndicate_mothership))
- return 1
+ if(istype(T.loc, /area/shuttle/syndicate) || istype(T.loc, /area/syndicate_mothership) || istype(T.loc, /area/shuttle/assault_pod))
+ return TRUE
- return 0
+ return FALSE
/atom/proc/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
SendSignal(COMSIG_ATOM_HULK_ATTACK, user)
@@ -232,21 +228,22 @@
/atom/proc/in_contents_of(container)//can take class or object instance as argument
if(ispath(container))
if(istype(src.loc, container))
- return 1
+ return TRUE
else if(src in container)
- return 1
+ return TRUE
+ return FALSE
+
+/atom/proc/get_examine_name(mob/user)
+ . = "\a [src]"
+ var/list/override = list(gender == PLURAL? "some" : "a" , " ", "[name]")
+ if(SendSignal(COMSIG_ATOM_GET_EXAMINE_NAME, user, override) & COMPONENT_EXNAME_CHANGED)
+ . = override.Join("")
+
+/atom/proc/get_examine_string(mob/user, thats = FALSE)
+ . = "[icon2html(src, user)] [thats? "That's ":""][get_examine_name(user)]"
/atom/proc/examine(mob/user)
- //This reformat names to get a/an properly working on item descriptions when they are bloody
- var/f_name = "\a [src]."
- if(src.blood_DNA && !istype(src, /obj/effect/decal))
- if(gender == PLURAL)
- f_name = "some "
- else
- f_name = "a "
- f_name += "blood-stained [name]!"
-
- to_chat(user, "[icon2html(src, user)] That's [f_name]")
+ to_chat(user, get_examine_string(user, TRUE))
if(desc)
to_chat(user, desc)
@@ -303,11 +300,6 @@
if(AM && isturf(AM.loc))
step(AM, turn(AM.dir, 180))
-GLOBAL_LIST_EMPTY(blood_splatter_icons)
-
-/atom/proc/blood_splatter_index()
- return "[REF(initial(icon))]-[initial(icon_state)]"
-
//returns the mob's dna info as a list, to be inserted in an object's blood_DNA list
/mob/living/proc/get_blood_dna_list()
if(get_blood_id() != "blood")
@@ -332,100 +324,28 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
// Returns 0 if we have that blood already
var/new_blood_dna = L.get_blood_dna_list()
if(!new_blood_dna)
- return 0
- if(!blood_DNA) //if our list of DNA doesn't exist yet, initialise it.
- blood_DNA = list()
- var/old_length = blood_DNA.len
- blood_DNA |= new_blood_dna
- if(blood_DNA.len == old_length)
- return 0
- return 1
-
-//to add blood dna info to the object's blood_DNA list
-/atom/proc/transfer_blood_dna(list/blood_dna)
- if(!blood_DNA)
- blood_DNA = list()
- var/old_length = blood_DNA.len
- blood_DNA |= blood_dna
- if(blood_DNA.len > old_length)
- return 1//some new blood DNA was added
-
+ return FALSE
+ var/old_length = blood_DNA_length()
+ add_blood_DNA(new_blood_dna)
+ if(blood_DNA_length() == old_length)
+ return FALSE
+ return TRUE
//to add blood from a mob onto something, and transfer their dna info
/atom/proc/add_mob_blood(mob/living/M)
var/list/blood_dna = M.get_blood_dna_list()
if(!blood_dna)
- return 0
- return add_blood(blood_dna)
-
-//to add blood onto something, with blood dna info to include.
-/atom/proc/add_blood(list/blood_dna)
- return 0
-
-/obj/add_blood(list/blood_dna)
- return transfer_blood_dna(blood_dna)
-
-/obj/item/add_blood(list/blood_dna)
- var/blood_count = !blood_DNA ? 0 : blood_DNA.len
- if(!..())
- return 0
- if(!blood_count)//apply the blood-splatter overlay if it isn't already in there
- add_blood_overlay()
- return 1 //we applied blood to the item
-
-/obj/item/proc/add_blood_overlay()
- if(initial(icon) && initial(icon_state))
- //try to find a pre-processed blood-splatter. otherwise, make a new one
- var/index = blood_splatter_index()
- var/icon/blood_splatter_icon = GLOB.blood_splatter_icons[index]
- if(!blood_splatter_icon)
- blood_splatter_icon = icon(initial(icon), initial(icon_state), , 1) //we only want to apply blood-splatters to the initial icon_state for each object
- blood_splatter_icon.Blend("#fff", ICON_ADD) //fills the icon_state with white (except where it's transparent)
- blood_splatter_icon.Blend(icon('icons/effects/blood.dmi', "itemblood"), ICON_MULTIPLY) //adds blood and the remaining white areas become transparant
- blood_splatter_icon = fcopy_rsc(blood_splatter_icon)
- GLOB.blood_splatter_icons[index] = blood_splatter_icon
- add_overlay(blood_splatter_icon)
-
-/obj/item/clothing/gloves/add_blood(list/blood_dna)
- . = ..()
- transfer_blood = rand(2, 4)
-
-/turf/add_blood(list/blood_dna, list/datum/disease/diseases)
- var/obj/effect/decal/cleanable/blood/splatter/B = locate() in src
- if(!B)
- B = new /obj/effect/decal/cleanable/blood/splatter(src, diseases)
- B.transfer_blood_dna(blood_dna) //give blood info to the blood decal.
- return 1 //we bloodied the floor
-
-/mob/living/carbon/human/add_blood(list/blood_dna)
- if(wear_suit)
- wear_suit.add_blood(blood_dna)
- update_inv_wear_suit()
- else if(w_uniform)
- w_uniform.add_blood(blood_dna)
- update_inv_w_uniform()
- if(gloves)
- var/obj/item/clothing/gloves/G = gloves
- G.add_blood(blood_dna)
- else
- transfer_blood_dna(blood_dna)
- bloody_hands = rand(2, 4)
- update_inv_gloves() //handles bloody hands overlays and updating
- return 1
-
-/atom/proc/clean_blood()
- if(islist(blood_DNA))
- blood_DNA = null
- return 1
+ return FALSE
+ return add_blood_DNA(blood_dna)
/atom/proc/wash_cream()
- return 1
+ return TRUE
/atom/proc/isinspace()
if(isspaceturf(get_turf(src)))
- return 1
+ return TRUE
else
- return 0
+ return FALSE
/atom/proc/handle_fall()
return
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index ddb768488a..c606cb1d3b 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -144,27 +144,27 @@
/atom/movable/proc/clean_on_move()
var/turf/tile = loc
if(isturf(tile))
- tile.clean_blood()
+ tile.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
for(var/A in tile)
if(is_cleanable(A))
qdel(A)
else if(istype(A, /obj/item))
var/obj/item/cleaned_item = A
- cleaned_item.clean_blood()
+ cleaned_item.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
else if(ishuman(A))
var/mob/living/carbon/human/cleaned_human = A
if(cleaned_human.lying)
if(cleaned_human.head)
- cleaned_human.head.clean_blood()
+ cleaned_human.head.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
cleaned_human.update_inv_head()
if(cleaned_human.wear_suit)
- cleaned_human.wear_suit.clean_blood()
+ cleaned_human.wear_suit.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
cleaned_human.update_inv_wear_suit()
else if(cleaned_human.w_uniform)
- cleaned_human.w_uniform.clean_blood()
+ cleaned_human.w_uniform.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
cleaned_human.update_inv_w_uniform()
if(cleaned_human.shoes)
- cleaned_human.shoes.clean_blood()
+ cleaned_human.shoes.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
cleaned_human.update_inv_shoes()
cleaned_human.clean_blood()
cleaned_human.wash_cream()
@@ -611,8 +611,8 @@
/atom/movable/proc/in_bounds()
. = FALSE
- var/turf/currentturf = get_turf(src)
- if(currentturf && (currentturf.z == ZLEVEL_CENTCOM || (currentturf.z in GLOB.station_z_levels) || currentturf.z == ZLEVEL_TRANSIT))
+ var/turf/T = get_turf(src)
+ if (T && (is_centcom_level(T.z) || is_station_level(T.z) || is_transit_level(T.z)))
. = TRUE
diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm
index d8ba1f5fa1..4315f382f4 100644
--- a/code/game/gamemodes/antag_spawner.dm
+++ b/code/game/gamemodes/antag_spawner.dm
@@ -108,7 +108,7 @@
if(!user.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE))
to_chat(user, "AUTHENTICATION FAILURE. ACCESS DENIED.")
return FALSE
- if(user.z != ZLEVEL_CENTCOM)
+ if(!user.onSyndieBase())
to_chat(user, "[src] is out of range! It can only be used at your base!")
return FALSE
return TRUE
@@ -208,7 +208,7 @@
/obj/item/antag_spawner/slaughter_demon/attack_self(mob/user)
- if(!(user.z in GLOB.station_z_levels))
+ if(!is_station_level(user.z))
to_chat(user, "You should probably wait until you reach the station.")
return
if(used)
diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm
index 878b747ea9..cc96a69f34 100644
--- a/code/game/gamemodes/blob/overmind.dm
+++ b/code/game/gamemodes/blob/overmind.dm
@@ -4,6 +4,7 @@ GLOBAL_LIST_EMPTY(blob_cores)
GLOBAL_LIST_EMPTY(overminds)
GLOBAL_LIST_EMPTY(blob_nodes)
+
/mob/camera/blob
name = "Blob Overmind"
real_name = "Blob Overmind"
@@ -33,10 +34,12 @@ GLOBAL_LIST_EMPTY(blob_nodes)
var/manualplace_min_time = 600 //in deciseconds //a minute, to get bearings
var/autoplace_max_time = 3600 //six minutes, as long as should be needed
var/list/blobs_legit = list()
+ var/max_count = 0 //The biggest it got before death
var/blobwincount = 400
var/victory_in_progress = FALSE
/mob/camera/blob/Initialize(mapload, starting_points = 60)
+ validate_location()
blob_points = starting_points
manualplace_min_time += world.time
autoplace_max_time += world.time
@@ -50,11 +53,18 @@ GLOBAL_LIST_EMPTY(blob_nodes)
color = blob_reagent_datum.complementary_color
if(blob_core)
blob_core.update_icon()
-
SSshuttle.registerHostileEnvironment(src)
-
.= ..()
+/mob/camera/blob/proc/validate_location()
+ var/turf/T = get_turf(src)
+ var/area/A = get_area(T)
+ if(((A && !A.blob_allowed) || !T || !(T.z in GLOB.station_z_levels)) && LAZYLEN(GLOB.blobstart))
+ T = get_turf(pick(GLOB.blobstart))
+ if(!T)
+ CRASH("No blobspawnpoints and blob spawned in nullspace.")
+ forceMove(T)
+
/mob/camera/blob/Life()
if(!blob_core)
if(!placed)
@@ -73,6 +83,9 @@ GLOBAL_LIST_EMPTY(blob_nodes)
max_blob_points = INFINITY
blob_points = INFINITY
addtimer(CALLBACK(src, .proc/victory), 450)
+
+ if(!victory_in_progress && max_count < blobs_legit.len)
+ max_count = blobs_legit.len
..()
@@ -111,6 +124,11 @@ GLOBAL_LIST_EMPTY(blob_nodes)
A.layer = BELOW_MOB_LAYER
A.invisibility = 0
A.blend_mode = 0
+ var/datum/antagonist/blob/B = mind.has_antag_datum(/datum/antagonist/blob)
+ if(B)
+ var/datum/objective/blob_takeover/main_objective = locate() in B.objectives
+ if(main_objective)
+ main_objective.completed = TRUE
to_chat(world, "[real_name] consumed the station in an unstoppable tide!")
SSticker.news_report = BLOB_WIN
SSticker.force_ending = 1
@@ -134,7 +152,6 @@ GLOBAL_LIST_EMPTY(blob_nodes)
/mob/camera/blob/Login()
..()
- sync_mind()
to_chat(src, "You are the overmind!")
blob_help()
update_health_hud()
@@ -224,3 +241,9 @@ GLOBAL_LIST_EMPTY(blob_nodes)
return 0
forceMove(NewLoc)
return 1
+
+/mob/camera/blob/mind_initialize()
+ . = ..()
+ var/datum/antagonist/blob/B = mind.has_antag_datum(/datum/antagonist/blob)
+ if(!B)
+ mind.add_antag_datum(/datum/antagonist/blob)
\ No newline at end of file
diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm
index 2ef047506f..e88cc8fb96 100644
--- a/code/game/gamemodes/blob/powers.dm
+++ b/code/game/gamemodes/blob/powers.dm
@@ -7,22 +7,23 @@
// Power verbs
-/mob/camera/blob/proc/place_blob_core(point_rate, placement_override)
+/mob/camera/blob/proc/place_blob_core(point_rate, placement_override , pop_override = FALSE)
if(placed && placement_override != -1)
return 1
if(!placement_override)
- for(var/mob/living/M in range(7, src))
- if("blob" in M.faction)
- continue
- if(M.client)
- to_chat(src, "There is someone too close to place your blob core!")
- return 0
- for(var/mob/living/M in view(13, src))
- if("blob" in M.faction)
- continue
- if(M.client)
- to_chat(src, "Someone could see your blob core from here!")
- return 0
+ if(!pop_override)
+ for(var/mob/living/M in range(7, src))
+ if("blob" in M.faction)
+ continue
+ if(M.client)
+ to_chat(src, "There is someone too close to place your blob core!")
+ return 0
+ for(var/mob/living/M in view(13, src))
+ if("blob" in M.faction)
+ continue
+ if(M.client)
+ to_chat(src, "Someone could see your blob core from here!")
+ return 0
var/turf/T = get_turf(src)
if(T.density)
to_chat(src, "This spot is too dense to place a blob core on!")
@@ -37,7 +38,7 @@
else if(O.density)
to_chat(src, "This spot is too dense to place a blob core on!")
return 0
- if(world.time <= manualplace_min_time && world.time <= autoplace_max_time)
+ if(!pop_override && world.time <= manualplace_min_time && world.time <= autoplace_max_time)
to_chat(src, "It is too early to place your blob core!")
return 0
else if(placement_override == 1)
diff --git a/code/game/gamemodes/changeling/powers/headcrab.dm b/code/game/gamemodes/changeling/powers/headcrab.dm
index e7f23bc07b..7a219407a4 100644
--- a/code/game/gamemodes/changeling/powers/headcrab.dm
+++ b/code/game/gamemodes/changeling/powers/headcrab.dm
@@ -8,6 +8,8 @@
/obj/effect/proc_holder/changeling/headcrab/sting_action(mob/user)
set waitfor = FALSE
+ if(alert("Are we sure we wish to kill ourself and create a headslug?",,"Yes", "No") == "No")
+ return
var/datum/mind/M = user.mind
var/list/organs = user.getorganszone("head", 1)
@@ -35,4 +37,4 @@
if(crab.origin)
crab.origin.active = 1
crab.origin.transfer_to(crab)
- to_chat(crab, "You burst out of the remains of your former body in a shower of gore!")
\ No newline at end of file
+ to_chat(crab, "You burst out of the remains of your former body in a shower of gore!")
diff --git a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm
index 29655a0ac9..3237cf5d35 100644
--- a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm
+++ b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm
@@ -278,7 +278,7 @@
animate(src, alpha = 255, time = 10, flags = ANIMATION_END_NOW) //we may have a previous animation going. finish it first, then do this one without delay.
sleep(10)
//as long as they're still on the sigil and are either not a servant or they're a servant AND it has remaining vitality
- while(L && (!is_servant_of_ratvar(L) || (is_servant_of_ratvar(L) && (GLOB.ratvar_awakens || GLOB.clockwork_vitality))) && get_turf(L) == get_turf(src))
+ while(L && (!is_servant_of_ratvar(L) || (is_servant_of_ratvar(L) && (GLOB.ratvar_awakens || GLOB.clockwork_vitality))) && get_turf(L) == get_turf(src) && !L.buckled)
sigil_active = TRUE
if(animation_number >= 4)
new /obj/effect/temp_visual/ratvar/sigil/vitality(get_turf(src))
@@ -313,21 +313,28 @@
revival_cost = 0
var/mob/dead/observer/ghost = L.get_ghost(TRUE)
if(GLOB.clockwork_vitality >= revival_cost && (ghost || (L.mind && L.mind.active)))
- if(ghost)
- ghost.reenter_corpse()
- L.revive(1, 1)
- var/obj/effect/temp_visual/ratvar/sigil/vitality/V = new /obj/effect/temp_visual/ratvar/sigil/vitality(get_turf(src))
- animate(V, alpha = 0, transform = matrix()*2, time = 8)
- playsound(L, 'sound/magic/staff_healing.ogg', 50, 1)
- L.visible_message("[L] suddenly gets back up, [L.p_their()] body dripping blue ichor!", "\"[text2ratvar("You will be okay, child.")]\"")
- GLOB.clockwork_vitality -= revival_cost
+ if(L.has_status_effect(STATUS_EFFECT_ICHORIAL_STAIN))
+ visible_message("[src] strains, but nothing happens...")
+ if(L.pulledby)
+ to_chat(L.pulledby, "[L] was already revived recently by a vitality matrix! Wait a bit longer!")
+ break
+ else
+ if(ghost)
+ ghost.reenter_corpse()
+ L.revive(1, 1)
+ var/obj/effect/temp_visual/ratvar/sigil/vitality/V = new /obj/effect/temp_visual/ratvar/sigil/vitality(get_turf(src))
+ animate(V, alpha = 0, transform = matrix()*2, time = 8)
+ playsound(L, 'sound/magic/staff_healing.ogg', 50, 1)
+ to_chat(L, "\"[text2ratvar("You will be okay, child.")]\"")
+ L.apply_status_effect(STATUS_EFFECT_ICHORIAL_STAIN)
+ GLOB.clockwork_vitality -= revival_cost
break
if(!L.client || L.client.is_afk())
set waitfor = FALSE
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [L.name], an inactive clock cultist?", "[name]", null, "Clock Cultist", 50, L)
var/mob/dead/observer/theghost = null
if(candidates.len)
- to_chat(L, "Your physical form has been taken over by another soul due to your inactivity! Ahelp if you wish to regain your form!")
+ to_chat(L, "Your physical form has been taken over by another soul due to your inactivity! Ahelp if you wish to regain your form!")
message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(L)]) to replace an inactive clock cultist.")
L.ghostize(0)
L.key = theghost.key
diff --git a/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm b/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm
index 50076e0919..74493c6cc5 100644
--- a/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm
+++ b/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm
@@ -165,13 +165,13 @@
var/list/teleportnames = list()
for(var/obj/structure/destructible/clockwork/powered/clockwork_obelisk/O in GLOB.all_clockwork_objects)
- if(!O.Adjacent(invoker) && O != src && (O.z <= ZLEVEL_SPACEMAX) && O.anchored) //don't list obelisks that we're next to
+ if(!O.Adjacent(invoker) && O != src && !is_away_level(O.z) && O.anchored) //don't list obelisks that we're next to
var/area/A = get_area(O)
var/locname = initial(A.name)
possible_targets[avoid_assoc_duplicate_keys("[locname] [O.name]", teleportnames)] = O
for(var/mob/living/L in GLOB.alive_mob_list)
- if(!L.stat && is_servant_of_ratvar(L) && !L.Adjacent(invoker) && (L.z <= ZLEVEL_SPACEMAX)) //People right next to the invoker can't be portaled to, for obvious reasons
+ if(!L.stat && is_servant_of_ratvar(L) && !L.Adjacent(invoker) && !is_away_level(L.z)) //People right next to the invoker can't be portaled to, for obvious reasons
possible_targets[avoid_assoc_duplicate_keys("[L.name] ([L.real_name])", teleportnames)] = L
if(!possible_targets.len)
diff --git a/code/game/gamemodes/clock_cult/clock_items/replica_fabricator.dm b/code/game/gamemodes/clock_cult/clock_items/replica_fabricator.dm
index 44fa24c134..bc8a5d47a5 100644
--- a/code/game/gamemodes/clock_cult/clock_items/replica_fabricator.dm
+++ b/code/game/gamemodes/clock_cult/clock_items/replica_fabricator.dm
@@ -94,7 +94,7 @@
fabrication_values["power_cost"] = 0
var/turf/Y = get_turf(user)
- if(!Y || (!(Y.z in GLOB.station_z_levels) && Y.z != ZLEVEL_CENTCOM && Y.z != ZLEVEL_MINING && Y.z != ZLEVEL_LAVALAND))
+ if(!Y || (!is_centcom_level(Y.z) && !is_station_level(Y.z) && !is_mining_level(Y.z)))
fabrication_values["operation_time"] *= 2
if(fabrication_values["power_cost"] > 0)
fabrication_values["power_cost"] *= 2
diff --git a/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm b/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm
index 8416e4651d..20c1d38389 100644
--- a/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm
+++ b/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm
@@ -63,7 +63,7 @@
hierophant_message("The Eminence: \"[message]\"")
/mob/camera/eminence/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
- if(z == ZLEVEL_CITYOFCOGS || is_servant_of_ratvar(speaker) || GLOB.ratvar_approaches || GLOB.ratvar_awakens) //Away from Reebe, the Eminence can't hear anything
+ if(is_reebe(z) || is_servant_of_ratvar(speaker) || GLOB.ratvar_approaches || GLOB.ratvar_awakens) //Away from Reebe, the Eminence can't hear anything
to_chat(src, message)
return
to_chat(src, "[speaker] says something, but you can't understand any of it...")
@@ -233,7 +233,7 @@
button_icon_state = "warp_down"
/datum/action/innate/eminence/station_jump/Activate()
- if(owner.z == ZLEVEL_CITYOFCOGS)
+ if(is_reebe(owner.z))
owner.forceMove(get_turf(pick(GLOB.generic_event_spawns)))
owner.playsound_local(owner, 'sound/magic/magic_missile.ogg', 50, TRUE)
flash_color(owner, flash_color = "#AF0AAF", flash_time = 25)
diff --git a/code/game/gamemodes/clock_cult/clock_scripture.dm b/code/game/gamemodes/clock_cult/clock_scripture.dm
index 94983923f9..046196f03a 100644
--- a/code/game/gamemodes/clock_cult/clock_scripture.dm
+++ b/code/game/gamemodes/clock_cult/clock_scripture.dm
@@ -126,7 +126,7 @@ Applications: 8 servants, 3 caches, and 100 CV
/datum/clockwork_scripture/proc/check_offstation_penalty()
var/turf/T = get_turf(invoker)
- if(!T || (!(T.z in GLOB.station_z_levels) && T.z != ZLEVEL_CENTCOM && T.z != ZLEVEL_MINING && T.z != ZLEVEL_LAVALAND && T.z != ZLEVEL_CITYOFCOGS))
+ if(!T || (!is_centcom_level(T.z) && !is_station_level(T.z) && !is_mining_level(T.z) && !is_reebe(T.z)))
channel_time *= 2
power_cost *= 2
return TRUE
@@ -262,7 +262,7 @@ Applications: 8 servants, 3 caches, and 100 CV
to_chat(invoker, "There are too many constructs of this type ([constructs])! You may only have [round(construct_limit)] at once.")
return
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar
- if(G && !G.active && combat_construct && invoker.z == ZLEVEL_CITYOFCOGS && !confirmed) //Putting marauders on the base during the prep phase is a bad idea mmkay
+ if(G && !G.active && combat_construct && is_reebe(invoker.z) && !confirmed) //Putting marauders on the base during the prep phase is a bad idea mmkay
if(alert(invoker, "This is a combat construct, and you cannot easily get it to the station. Are you sure you want to make one here?", "Construct Alert", "Yes", "Cancel") == "Cancel")
return
if(!is_servant_of_ratvar(invoker) || !invoker.canUseTopic(slab))
diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm
index 8275e4d20e..7e05e6a187 100644
--- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm
+++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm
@@ -209,7 +209,7 @@
quickbind_desc = "Returns you to Reebe."
/datum/clockwork_scripture/abscond/check_special_requirements()
- if(invoker.z == ZLEVEL_CITYOFCOGS)
+ if(is_reebe(invoker.z))
to_chat(invoker, "You're already at Reebe.")
return
return TRUE
diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm
index 09cfeb99d3..c4774fe0ad 100644
--- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm
+++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm
@@ -70,6 +70,12 @@
quickbind = TRUE
quickbind_desc = "Creates a Vitality Matrix, which drains non-Servants on it to heal Servants that cross it."
+/datum/clockwork_scripture/create_object/vitality_matrix/check_special_requirements()
+ if(locate(object_path) in range(1, invoker))
+ to_chat(invoker, "Vitality matrices placed next to each other could interfere and cause a feedback loop! Move away from the other ones!")
+ return FALSE
+ return ..()
+
//Judicial Visor: Creates a judicial visor, which can smite an area.
/datum/clockwork_scripture/create_object/judicial_visor
diff --git a/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/pressure_sensor.dm b/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/pressure_sensor.dm
index f6a7b8e347..fffabe8f5c 100644
--- a/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/pressure_sensor.dm
+++ b/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/pressure_sensor.dm
@@ -3,7 +3,7 @@
name = "pressure sensor"
desc = "A thin plate of brass, barely visible but clearly distinct."
clockwork_desc = "A trigger that will activate when a non-servant runs across it."
- max_integrity = 25
+ max_integrity = 5
icon_state = "pressure_sensor"
alpha = 80
layer = LOW_ITEM_LAYER
diff --git a/code/game/gamemodes/clock_cult/clock_structures/traps/brass_skewer.dm b/code/game/gamemodes/clock_cult/clock_structures/traps/brass_skewer.dm
index d79ca88ecb..c91cf594e8 100644
--- a/code/game/gamemodes/clock_cult/clock_structures/traps/brass_skewer.dm
+++ b/code/game/gamemodes/clock_cult/clock_structures/traps/brass_skewer.dm
@@ -21,9 +21,10 @@
STOP_PROCESSING(SSfastprocess, src)
if(buckled_mobs && buckled_mobs.len)
var/mob/living/L = buckled_mobs[1]
- L.Knockdown(100)
- L.visible_message("[L] is maimed as the skewer shatters while still in their body!")
- L.adjustBruteLoss(15)
+ if(iscarbon(L))
+ L.Knockdown(100)
+ L.visible_message("[L] is maimed as the skewer shatters while still in their body!")
+ L.adjustBruteLoss(15)
unbuckle_mob(L)
return ..()
@@ -48,14 +49,22 @@
/obj/structure/destructible/clockwork/trap/brass_skewer/activate()
if(density)
return
- var/mob/living/carbon/squirrel = locate() in get_turf(src)
+ var/mob/living/squirrel = locate() in get_turf(src)
if(squirrel)
- squirrel.visible_message("A massive brass spike erupts from the ground, impaling [squirrel]!", \
- "A massive brass spike rams through your chest, hoisting you into the air!")
- squirrel.emote("scream")
- playsound(squirrel, 'sound/effects/splat.ogg', 50, TRUE)
- playsound(squirrel, 'sound/misc/desceration-03.ogg', 50, TRUE)
- squirrel.apply_damage(20, BRUTE, "chest")
+ if(iscyborg(squirrel))
+ if(!squirrel.stat)
+ squirrel.visible_message("A massive brass spike erupts from the ground, rending [squirrel]'s chassis but shattering into pieces!", \
+ "A massive brass spike rips through your chassis and bursts into shrapnel in your casing!")
+ squirrel.adjustBruteLoss(50)
+ squirrel.Stun(20)
+ addtimer(CALLBACK(src, .proc/take_damage, max_integrity), 1)
+ else
+ squirrel.visible_message("A massive brass spike erupts from the ground, impaling [squirrel]!", \
+ "A massive brass spike rams through your chest, hoisting you into the air!")
+ squirrel.emote("scream")
+ playsound(squirrel, 'sound/effects/splat.ogg', 50, TRUE)
+ playsound(squirrel, 'sound/misc/desceration-03.ogg', 50, TRUE)
+ squirrel.apply_damage(20, BRUTE, "chest")
mouse_opacity = MOUSE_OPACITY_OPAQUE //So players can interact with the tile it's on to pull them off
buckle_mob(squirrel, TRUE)
else
diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm
index f0934b524f..30e78ff1af 100644
--- a/code/game/gamemodes/cult/ritual.dm
+++ b/code/game/gamemodes/cult/ritual.dm
@@ -203,7 +203,7 @@ This file contains the arcane tome files.
A = get_area(src)
if(!src || QDELETED(src) || !Adjacent(user) || user.incapacitated() || !check_rune_turf(Turf, user))
return
-
+
//AAAAAAAAAAAAAAAH, i'm rewriting enough for now so TODO: remove this shit
if(ispath(rune_to_scribe, /obj/effect/rune/narsie))
if(!summon_objective)
@@ -265,8 +265,7 @@ This file contains the arcane tome files.
if(locate(/obj/effect/rune) in T)
to_chat(user, "There is already a rune here.")
return FALSE
-
- if(!(T.z in GLOB.station_z_levels) && T.z != ZLEVEL_MINING)
+ if(!is_station_level(T.z) && !is_mining_level(T.z))
to_chat(user, "The veil is not weak enough here.")
return FALSE
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index ce769737dc..4feee3f23b 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -268,7 +268,7 @@ structure_check() searches for nearby cultist structures required for the invoca
var/list/teleportnames = list()
for(var/R in GLOB.teleport_runes)
var/obj/effect/rune/teleport/T = R
- if(T != src && (T.z <= ZLEVEL_SPACEMAX))
+ if(T != src && !is_away_level(T.z))
potential_runes[avoid_assoc_duplicate_keys(T.listkey, teleportnames)] = T
if(!potential_runes.len)
@@ -277,8 +277,9 @@ structure_check() searches for nearby cultist structures required for the invoca
fail_invoke()
return
- if(user.z > ZLEVEL_SPACEMAX)
- to_chat(user, "You are not in the right dimension!")
+ var/turf/T = get_turf(src)
+ if(is_away_level(T.z))
+ to_chat(user, "You are not in the right dimension!")
log_game("Teleport rune failed - user in away mission")
fail_invoke()
return
@@ -289,7 +290,6 @@ structure_check() searches for nearby cultist structures required for the invoca
fail_invoke()
return
- var/turf/T = get_turf(src)
var/turf/target = get_turf(actual_selected_rune)
if(is_blocked_turf(target, TRUE))
to_chat(user, "The target rune is blocked. Attempting to teleport to it would be massively unwise.")
@@ -479,7 +479,7 @@ structure_check() searches for nearby cultist structures required for the invoca
/obj/effect/rune/narsie/invoke(var/list/invokers)
if(used)
return
- if(!(z in GLOB.station_z_levels))
+ if(!is_station_level(z))
return
if(locate(/obj/singularity/narsie) in GLOB.poi_list)
@@ -815,8 +815,8 @@ structure_check() searches for nearby cultist structures required for the invoca
fail_invoke()
log_game("Summon Cultist rune failed - target was deconverted")
return
- if(cultist_to_summon.z > ZLEVEL_SPACEMAX)
- to_chat(user, "[cultist_to_summon] is not in our dimension!")
+ if(is_away_level(cultist_to_summon.z))
+ to_chat(user, "[cultist_to_summon] is not in our dimension!")
fail_invoke()
log_game("Summon Cultist rune failed - target in away mission")
return
diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm
index e3792b6be4..855dfa7255 100644
--- a/code/game/gamemodes/cult/talisman.dm
+++ b/code/game/gamemodes/cult/talisman.dm
@@ -65,8 +65,8 @@
log_game("Teleport talisman failed - no other teleport runes")
return ..(user, 0)
- if(user.z > ZLEVEL_SPACEMAX)
- to_chat(user, "You are not in the right dimension!")
+ if(is_away_level(user.z))
+ to_chat(user, "You are not in the right dimension!")
log_game("Teleport talisman failed - user in away mission")
return ..(user, 0)
diff --git a/code/game/gamemodes/devil/true_devil/_true_devil.dm b/code/game/gamemodes/devil/true_devil/_true_devil.dm
index 10f0b3393f..c1197a5742 100644
--- a/code/game/gamemodes/devil/true_devil/_true_devil.dm
+++ b/code/game/gamemodes/devil/true_devil/_true_devil.dm
@@ -67,10 +67,7 @@
//Left hand items
for(var/obj/item/I in held_items)
if(!(I.flags_1 & ABSTRACT_1))
- if(I.blood_DNA)
- msg += "It is holding [icon2html(I, user)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in its [get_held_index_name(get_held_index_of_item(I))]!\n"
- else
- msg += "It is holding [icon2html(I, user)] \a [I] in its [get_held_index_name(get_held_index_of_item(I))].\n"
+ msg += "It is holding [I.get_examine_string(user)] in its [get_held_index_name(get_held_index_of_item(I))].\n"
//Braindead
if(!client && stat != DEAD)
diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm
index 743a4aea3c..6013b48016 100644
--- a/code/game/gamemodes/events.dm
+++ b/code/game/gamemodes/events.dm
@@ -1,7 +1,7 @@
/proc/power_failure()
priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", 'sound/ai/poweroff.ogg')
for(var/obj/machinery/power/smes/S in GLOB.machines)
- if(istype(get_area(S), /area/ai_monitored/turret_protected) || !(S.z in GLOB.station_z_levels))
+ if(istype(get_area(S), /area/ai_monitored/turret_protected) || !is_station_level(S.z))
continue
S.charge = 0
S.output_level = 0
@@ -22,7 +22,7 @@
break
if(A.contents)
for(var/atom/AT in A.contents)
- if(!(AT.z in GLOB.station_z_levels)) //Only check one, it's enough.
+ if(!is_station_level(AT.z)) //Only check one, it's enough.
skip = 1
break
if(skip)
@@ -33,7 +33,7 @@
A.power_change()
for(var/obj/machinery/power/apc/C in GLOB.apcs_list)
- if(C.cell && (C.z in GLOB.station_z_levels))
+ if(C.cell && is_station_level(C.z))
var/area/A = C.area
var/skip = 0
@@ -50,11 +50,11 @@
priority_announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", 'sound/ai/poweron.ogg')
for(var/obj/machinery/power/apc/C in GLOB.machines)
- if(C.cell && (C.z in GLOB.station_z_levels))
+ if(C.cell && is_station_level(C.z))
C.cell.charge = C.cell.maxcharge
C.failure_timer = 0
for(var/obj/machinery/power/smes/S in GLOB.machines)
- if(!(S.z in GLOB.station_z_levels))
+ if(!is_station_level(S.z))
continue
S.charge = S.capacity
S.output_level = S.output_level_max
@@ -72,7 +72,7 @@
priority_announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", 'sound/ai/poweron.ogg')
for(var/obj/machinery/power/smes/S in GLOB.machines)
- if(!(S.z in GLOB.station_z_levels))
+ if(!is_station_level(S.z))
continue
S.charge = S.capacity
S.output_level = S.output_level_max
diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm
index 1c17893a28..a4b9398de4 100644
--- a/code/game/gamemodes/malfunction/Malf_Modules.dm
+++ b/code/game/gamemodes/malfunction/Malf_Modules.dm
@@ -233,7 +233,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
/datum/action/innate/ai/nuke_station/Activate()
var/turf/T = get_turf(owner)
- if(!istype(T) || !(T.z in GLOB.station_z_levels))
+ if(!istype(T) || !is_station_level(T.z))
to_chat(owner, "You cannot activate the doomsday device while off-station!")
return
if(alert(owner, "Send arming signal? (true = arm, false = cancel)", "purge_all_life()", "confirm = TRUE;", "confirm = FALSE;") != "confirm = TRUE;")
@@ -356,7 +356,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
/obj/machinery/doomsday_device/process()
var/turf/T = get_turf(src)
- if(!T || !(T.z in GLOB.station_z_levels))
+ if(!T || !is_station_level(T.z))
minor_announce("DOOMSDAY DEVICE OUT OF STATION RANGE, ABORTING", "ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4", TRUE)
SSshuttle.clearHostileEnvironment(src)
qdel(src)
@@ -378,7 +378,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
for(var/i in GLOB.mob_living_list)
var/mob/living/L = i
var/turf/T = get_turf(L)
- if(!T || !(T.z in GLOB.station_z_levels))
+ if(!T || !is_station_level(T.z))
continue
if(issilicon(L))
continue
@@ -425,7 +425,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
/datum/action/innate/ai/lockdown/Activate()
for(var/obj/machinery/door/D in GLOB.airlocks)
- if(!(D.z in GLOB.station_z_levels))
+ if(!is_station_level(D.z))
continue
INVOKE_ASYNC(D, /obj/machinery/door.proc/hostile_lockdown, owner)
addtimer(CALLBACK(D, /obj/machinery/door.proc/disable_lockdown), 900)
@@ -503,7 +503,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
/datum/action/innate/ai/break_fire_alarms/Activate()
for(var/obj/machinery/firealarm/F in GLOB.machines)
- if(!(F.z in GLOB.station_z_levels))
+ if(!is_station_level(F.z))
continue
F.emagged = TRUE
to_chat(owner, "All thermal sensors on the station have been disabled. Fire alerts will no longer be recognized.")
@@ -530,7 +530,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
/datum/action/innate/ai/break_air_alarms/Activate()
for(var/obj/machinery/airalarm/AA in GLOB.machines)
- if(!(AA.z in GLOB.station_z_levels))
+ if(!is_station_level(AA.z))
continue
AA.emagged = TRUE
to_chat(owner, "All air alarm safeties on the station have been overriden. Air alarms may now use the Flood environmental mode.")
@@ -753,7 +753,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
/datum/action/innate/ai/emergency_lights/Activate()
for(var/obj/machinery/light/L in GLOB.machines)
- if(L.z in GLOB.station_z_levels)
+ if(is_station_level(L.z))
L.no_emergency = TRUE
INVOKE_ASYNC(L, /obj/machinery/light/.proc/update, FALSE)
CHECK_TICK
diff --git a/code/game/gamemodes/miniantags/borer/borer_event.dm b/code/game/gamemodes/miniantags/borer/borer_event.dm
index 567adddf53..e036c2a474 100644
--- a/code/game/gamemodes/miniantags/borer/borer_event.dm
+++ b/code/game/gamemodes/miniantags/borer/borer_event.dm
@@ -27,7 +27,7 @@
if(QDELETED(temp_vent))
continue
if(temp_vent.loc.z == ZLEVEL_STATION_PRIMARY && !temp_vent.welded)
- var/datum/pipeline/temp_vent_parent = temp_vent.PARENT1
+ var/datum/pipeline/temp_vent_parent = temp_vent.parents[1]
if(temp_vent_parent.other_atmosmch.len > 20)
vents += temp_vent
diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
index 3fe32a7f33..956af60580 100644
--- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
+++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm
@@ -454,7 +454,7 @@
if(target == src)
return
- if(!(z in GLOB.station_z_levels) && z != ZLEVEL_LAVALAND)
+ if(!is_station_level(z) && !is_mining_level(z))
to_chat(src, "Our bluespace transceiver cannot locate a viable bluespace link, our teleportation abilities are useless in this area.")
return
diff --git a/code/game/gamemodes/miniantags/monkey/monkey.dm b/code/game/gamemodes/miniantags/monkey/monkey.dm
index 7e6d92d927..71afe1c823 100644
--- a/code/game/gamemodes/miniantags/monkey/monkey.dm
+++ b/code/game/gamemodes/miniantags/monkey/monkey.dm
@@ -67,7 +67,7 @@
var/datum/disease/D = new /datum/disease/transformation/jungle_fever() //ugly but unfortunately needed
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
- if(!(H.z in GLOB.station_z_levels))
+ if(!is_station_level(H.z))
continue
if(H.mind && H.client && H.stat != DEAD)
if(H.HasDisease(D))
diff --git a/code/game/gamemodes/nuclear/nuclear_challenge.dm b/code/game/gamemodes/nuclear/nuclear_challenge.dm
index 58128b89ce..ce750e6a88 100644
--- a/code/game/gamemodes/nuclear/nuclear_challenge.dm
+++ b/code/game/gamemodes/nuclear/nuclear_challenge.dm
@@ -67,7 +67,7 @@
if(GLOB.player_list.len < CHALLENGE_MIN_PLAYERS)
to_chat(user, "The enemy crew is too small to be worth declaring war on.")
return FALSE
- if(user.z != ZLEVEL_CENTCOM)
+ if(!user.onSyndieBase())
to_chat(user, "You have to be at your base to use this.")
return FALSE
if(world.time-SSticker.round_start_time > CHALLENGE_TIME_LIMIT)
diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm
index d6d14a3f84..bf85215f94 100644
--- a/code/game/gamemodes/nuclear/nuclearbomb.dm
+++ b/code/game/gamemodes/nuclear/nuclearbomb.dm
@@ -451,12 +451,12 @@
var/off_station = 0
var/turf/bomb_location = get_turf(src)
var/area/A = get_area(bomb_location)
- if(bomb_location && (bomb_location.z in GLOB.station_z_levels))
+ if(bomb_location && is_station_level(bomb_location.z))
if(istype(A, /area/space))
off_station = NUKE_NEAR_MISS
if((bomb_location.x < (128-NUKERANGE)) || (bomb_location.x > (128+NUKERANGE)) || (bomb_location.y < (128-NUKERANGE)) || (bomb_location.y > (128+NUKERANGE)))
off_station = NUKE_NEAR_MISS
- else if((istype(A, /area/syndicate_mothership) || (istype(A, /area/shuttle/syndicate)) && bomb_location.z == ZLEVEL_CENTCOM))
+ else if(bomb_location.onSyndieBase())
off_station = NUKE_SYNDICATE_BASE
else
off_station = NUKE_MISS_STATION
@@ -556,7 +556,7 @@ This is here to make the tiles around the station mininuke change when it's arme
addtimer(CALLBACK(user, /atom/proc/add_atom_colour, (i % 2)? "#00FF00" : "#FF0000", ADMIN_COLOUR_PRIORITY), i)
addtimer(CALLBACK(src, .proc/manual_suicide, user), 101)
return MANUAL_SUICIDE
-
+
/obj/item/disk/proc/manual_suicide(mob/living/user)
user.remove_atom_colour(ADMIN_COLOUR_PRIORITY)
user.visible_message("[user] was destroyed by the nuclear blast!")
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index 46f96961c9..a505d6248b 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -154,7 +154,7 @@
if(!target || !considered_alive(target) || considered_afk(target))
return TRUE
var/turf/T = get_turf(target.current)
- return T && !(T.z in GLOB.station_z_levels)
+ return T && !is_station_level(T.z)
/datum/objective/mutiny/update_explanation_text()
..()
diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm
index f20e16b36b..71947fc682 100644
--- a/code/game/gamemodes/revolution/revolution.dm
+++ b/code/game/gamemodes/revolution/revolution.dm
@@ -164,7 +164,7 @@
/datum/game_mode/revolution/proc/check_heads_victory()
for(var/datum/mind/rev_mind in revolution.head_revolutionaries())
var/turf/T = get_turf(rev_mind.current)
- if(!considered_afk(rev_mind) && considered_alive(rev_mind) && (T.z in GLOB.station_z_levels))
+ if(!considered_afk(rev_mind) && considered_alive(rev_mind) && is_station_level(T.z))
if(ishuman(rev_mind.current))
return FALSE
return TRUE
diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm
index 21de0fc2f9..6c662fbc18 100644
--- a/code/game/gamemodes/wizard/artefact.dm
+++ b/code/game/gamemodes/wizard/artefact.dm
@@ -213,7 +213,7 @@
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
var/mob/living/carbon/human/target = null
var/list/mob/living/carbon/human/possible = list()
- var/obj/item/linked_item = null
+ var/obj/item/voodoo_link = null
var/cooldown_time = 30 //3s
var/cooldown = 0
max_integrity = 10
@@ -237,10 +237,10 @@
cooldown = world.time +cooldown_time
return
- if(!linked_item)
+ if(!voodoo_link)
if(I.loc == user && istype(I) && I.w_class <= WEIGHT_CLASS_SMALL)
if (user.transferItemToLoc(I,src))
- linked_item = I
+ voodoo_link = I
to_chat(user, "You attach [I] to the doll.")
update_targets()
@@ -255,11 +255,11 @@
return
if(user.zone_selected == "chest")
- if(linked_item)
+ if(voodoo_link)
target = null
- linked_item.forceMove(drop_location())
- to_chat(user, "You remove the [linked_item] from the doll.")
- linked_item = null
+ voodoo_link.forceMove(drop_location())
+ to_chat(user, "You remove the [voodoo_link] from the doll.")
+ voodoo_link = null
update_targets()
return
@@ -291,10 +291,13 @@
/obj/item/voodoo/proc/update_targets()
possible = list()
- if(!linked_item)
+ if(!voodoo_link)
return
+ var/list/prints = voodoo_link.return_fingerprints()
+ if(!length(prints))
+ return FALSE
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
- if(md5(H.dna.uni_identity) in linked_item.fingerprints)
+ if(prints[md5(H.dna.uni_identity)])
possible |= H
/obj/item/voodoo/proc/GiveHint(mob/victim,force=0)
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index 1e0b41bca0..3d3d929c81 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -149,8 +149,6 @@
if(href_list["make"])
- var/turf/T = loc
-
/////////////////
//href protection
being_built = stored_research.isDesignResearchedID(href_list["make"])
@@ -174,34 +172,8 @@
use_power(power)
icon_state = "autolathe"
flick("autolathe_n",src)
- if(is_stack)
- spawn(32*coeff)
- use_power(power)
- var/list/materials_used = list(MAT_METAL=metal_cost*multiplier, MAT_GLASS=glass_cost*multiplier)
- materials.use_amount(materials_used)
-
- var/obj/item/stack/N = new being_built.build_path(T, multiplier)
- N.update_icon()
- N.autolathe_crafted(src)
-
- for(var/obj/item/stack/S in T.contents - N)
- if(istype(S, N.merge_type))
- N.merge(S)
- busy = FALSE
- updateUsrDialog()
-
- else
- spawn(32*coeff*multiplier)
- use_power(power)
- var/list/materials_used = list(MAT_METAL=metal_cost*coeff*multiplier, MAT_GLASS=glass_cost*coeff*multiplier)
- materials.use_amount(materials_used)
- for(var/i=1, i<=multiplier, i++)
- var/obj/item/new_item = new being_built.build_path(T)
- for(var/mat in materials_used)
- new_item.materials[mat] = materials_used[mat] / multiplier
- new_item.autolathe_crafted(src)
- busy = FALSE
- updateUsrDialog()
+ var/time = is_stack ? 32 : 32*coeff*multiplier
+ addtimer(CALLBACK(src, .proc/make_item, power, metal_cost, glass_cost, multiplier, coeff, is_stack), time)
if(href_list["search"])
matching_designs.Cut()
@@ -218,6 +190,30 @@
return
+/obj/machinery/autolathe/proc/make_item(power, metal_cost, glass_cost, multiplier, coeff, is_stack)
+ GET_COMPONENT(materials, /datum/component/material_container)
+ var/atom/A = drop_location()
+ use_power(power)
+ var/list/materials_used = list(MAT_METAL=metal_cost*coeff*multiplier, MAT_GLASS=glass_cost*coeff*multiplier)
+ materials.use_amount(materials_used)
+
+ if(is_stack)
+ var/obj/item/stack/N = new being_built.build_path(A, multiplier)
+ N.update_icon()
+ N.autolathe_crafted(src)
+ for(var/obj/item/stack/S in (A.contents - N))
+ if(istype(S, N.merge_type))
+ N.merge(S)
+ else
+ for(var/i=1, i<=multiplier, i++)
+ var/obj/item/new_item = new being_built.build_path(A)
+ for(var/mat in materials_used)
+ new_item.materials[mat] = materials_used[mat] / multiplier
+ new_item.autolathe_crafted(src)
+
+ busy = FALSE
+ updateDialog()
+
/obj/machinery/autolathe/RefreshParts()
var/T = 0
for(var/obj/item/stock_parts/matter_bin/MB in component_parts)
diff --git a/code/game/machinery/bank_machine.dm b/code/game/machinery/bank_machine.dm
index b8d20b0c59..6be865788b 100644
--- a/code/game/machinery/bank_machine.dm
+++ b/code/game/machinery/bank_machine.dm
@@ -59,7 +59,7 @@
if(..())
return
src.add_fingerprint(usr)
- var/dat = "[world.name] secure vault. Authorized personnel only.
"
+ var/dat = "[station_name()] secure vault. Authorized personnel only.
"
dat += "Current Balance: [SSshuttle.points] credits.
"
if(!siphoning)
dat += "Siphon Credits
"
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index 8a58c7fae5..4742172108 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -53,7 +53,7 @@
LAZYADD(myarea.cameras, src)
proximity_monitor = new(src, 1)
- if(mapload && (z in GLOB.station_z_levels) && prob(3) && !start_active)
+ if(mapload && is_station_level(z) && prob(3) && !start_active)
toggle_cam()
/obj/machinery/camera/Destroy()
diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm
index 7831437dc2..41f093a6d2 100644
--- a/code/game/machinery/computer/buildandrepair.dm
+++ b/code/game/machinery/computer/buildandrepair.dm
@@ -121,7 +121,7 @@
to_chat(user, "You remove the glass panel.")
state = 3
icon_state = "3"
- var/obj/item/stack/sheet/glass/G = new (drop_location(), 2)
+ var/obj/item/stack/sheet/glass/G = new(drop_location(), 2)
G.add_fingerprint(user)
return
if(istype(P, /obj/item/screwdriver))
diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm
index 8bab6a9d9a..73e629e561 100644
--- a/code/game/machinery/computer/camera.dm
+++ b/code/game/machinery/computer/camera.dm
@@ -124,7 +124,7 @@
/obj/machinery/computer/security/proc/get_available_cameras()
var/list/L = list()
for (var/obj/machinery/camera/C in GLOB.cameranet.cameras)
- if((z > ZLEVEL_SPACEMAX || C.z > ZLEVEL_SPACEMAX) && (C.z != z))//if on away mission, can only recieve feed from same z_level cameras
+ if((is_away_level(z) || is_away_level(C.z)) && (C.z != z))//if on away mission, can only recieve feed from same z_level cameras
continue
L.Add(C)
diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm
index e59bb1692e..a8199190fd 100644
--- a/code/game/machinery/computer/camera_advanced.dm
+++ b/code/game/machinery/computer/camera_advanced.dm
@@ -303,7 +303,7 @@
var/mob/camera/aiEye/remote/remote_eye = user.remote_control
var/obj/machinery/computer/camera_advanced/ratvar/R = target
var/turf/T = get_turf(remote_eye)
- if(user.z != ZLEVEL_CITYOFCOGS || !(T.z in GLOB.station_z_levels))
+ if(!is_reebe(user.z) || !is_station_level(T.z))
return
if(isclosedturf(T))
to_chat(user, "You can't teleport into a wall.")
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index 6223011736..e02a5f0e2a 100755
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -9,7 +9,7 @@
var/authenticated = 0
var/auth_id = "Unknown" //Who is currently logged in?
var/list/datum/comm_message/messages = list()
- var/datum/comm_message/currmsg
+ var/datum/comm_message/currmsg
var/datum/comm_message/aicurrmsg
var/state = STATE_DEFAULT
var/aistate = STATE_DEFAULT
@@ -53,7 +53,7 @@
/obj/machinery/computer/communications/Topic(href, href_list)
if(..())
return
- if(!(z in GLOB.station_z_levels) && z != ZLEVEL_CENTCOM) //Can only use on centcom and SS13
+ if(!is_station_level(z) && !is_centcom_level(z)) //Can only use on centcom and SS13
to_chat(usr, "Unable to establish a connection: \black You're too far away from the station!")
return
usr.set_machine(src)
@@ -136,7 +136,9 @@
to_chat(usr, "Arrays recycling. Please stand by.")
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
- var/input = stripped_multiline_input(usr, "Please choose a message to transmit to an allied station. Please be aware that this process is very expensive, and abuse will lead to... termination.", "Send a message to an allied station.", "")
+
+
+ var/input = stripped_multiline_input(usr, "Please choose a message to transmit to allied stations. Please be aware that this process is very expensive, and abuse will lead to... termination.", "Send a message to an allied station.", "")
if(!input || !(usr in view(1,src)))
return
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
@@ -739,4 +741,4 @@
if(content)
content = new_content
if(new_possible_answers)
- possible_answers = new_possible_answers
\ No newline at end of file
+ possible_answers = new_possible_answers
diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm
index 5068955849..525c474bd9 100644
--- a/code/game/machinery/computer/prisoner.dm
+++ b/code/game/machinery/computer/prisoner.dm
@@ -56,7 +56,7 @@
var/loc_display = "Unknown"
var/mob/living/M = T.imp_in
- if((Tr.z in GLOB.station_z_levels) && !isspaceturf(M.loc))
+ if(is_station_level(Tr.z) && !isspaceturf(M.loc))
var/turf/mob_loc = get_turf(M)
loc_display = mob_loc.loc
diff --git a/code/game/machinery/computer/teleporter.dm b/code/game/machinery/computer/teleporter.dm
index 56a583fff6..704576f2c0 100644
--- a/code/game/machinery/computer/teleporter.dm
+++ b/code/game/machinery/computer/teleporter.dm
@@ -204,3 +204,14 @@
if(trg.teleporter_console)
trg.teleporter_console.stat &= ~NOPOWER
trg.teleporter_console.update_icon()
+
+/obj/machinery/computer/teleporter/proc/is_eligible(atom/movable/AM)
+ var/turf/T = get_turf(AM)
+ if(!T)
+ return FALSE
+ if(is_centcom_level(T.z) || is_away_level(T.z))
+ return FALSE
+ var/area/A = get_area(T)
+ if(!A || A.noteleport)
+ return FALSE
+ return TRUE
diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm
index ae4af4072d..5a306cac50 100644
--- a/code/game/machinery/firealarm.dm
+++ b/code/game/machinery/firealarm.dm
@@ -70,7 +70,7 @@
if(stat & NOPOWER)
return
- if(src.z in GLOB.station_z_levels)
+ if(is_station_level(z))
add_overlay("overlay_[GLOB.security_level]")
else
add_overlay("overlay_[SEC_LEVEL_GREEN]")
@@ -124,7 +124,7 @@
var/list/data = list()
data["emagged"] = emagged
- if(src.z in GLOB.station_z_levels)
+ if(is_station_level(z))
data["seclevel"] = get_security_level()
else
data["seclevel"] = "green"
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index ee9b1ff31a..541c931593 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/game/machinery/newscaster.dm
@@ -22,6 +22,7 @@ GLOBAL_LIST_EMPTY(allCasters)
var/creationTime
var/authorCensor
var/bodyCensor
+ var/photo_file
/datum/newscaster/feed_message/proc/returnAuthor(censor)
if(censor == -1)
@@ -97,6 +98,7 @@ GLOBAL_LIST_EMPTY(allCasters)
var/scannedUser
var/isAdminMsg
var/icon/img
+ var/photo_file
/datum/newscaster/feed_network
var/list/datum/newscaster/feed_channel/network_channels = list()
@@ -126,6 +128,7 @@ GLOBAL_LIST_EMPTY(allCasters)
if(photo)
newMsg.img = photo.img
newMsg.caption = photo.scribble
+ newMsg.photo_file = save_photo(photo.img)
for(var/datum/newscaster/feed_channel/FC in network_channels)
if(FC.channel_name == channel_name)
FC.messages += newMsg
@@ -143,6 +146,7 @@ GLOBAL_LIST_EMPTY(allCasters)
wanted_issue.isAdminMsg = adminMsg
if(photo)
wanted_issue.img = photo.img
+ wanted_issue.photo_file = save_photo(photo.img)
if(newMessage)
for(var/obj/machinery/newscaster/N in GLOB.allCasters)
N.newsAlert()
@@ -157,7 +161,12 @@ GLOBAL_LIST_EMPTY(allCasters)
for(var/obj/machinery/newscaster/NEWSCASTER in GLOB.allCasters)
NEWSCASTER.update_icon()
-
+/datum/newscaster/feed_network/proc/save_photo(icon/photo)
+ var/photo_file = copytext(md5("\icon[photo]"), 1, 6)
+ if(!fexists("[GLOB.log_directory]/photos/[photo_file].png"))
+ var/icon/p = icon(photo, frame = 1)
+ fcopy(p, "[GLOB.log_directory]/photos/[photo_file].png")
+ return photo_file
/obj/item/wallframe/newscaster
name = "newscaster frame"
diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm
index a67ce24c9c..f3d3933428 100644
--- a/code/game/machinery/pipe/pipe_dispenser.dm
+++ b/code/game/machinery/pipe/pipe_dispenser.dm
@@ -154,11 +154,8 @@
to_chat(usr, "There's not enough room to build that here!")
qdel(C)
return
-
-
if(href_list["dir"])
C.setDir(text2num(href_list["dir"]))
-
C.add_fingerprint(usr)
C.update_icon()
wait = world.time + 15
diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm
index 83681475fd..bdbee201b8 100644
--- a/code/game/machinery/status_display.dm
+++ b/code/game/machinery/status_display.dm
@@ -107,7 +107,7 @@
var/line1
var/line2
if(SSshuttle.supply.mode == SHUTTLE_IDLE)
- if(SSshuttle.supply.z in GLOB.station_z_levels)
+ if(is_station_level(SSshuttle.supply.z))
line1 = "CARGO"
line2 = "Docked"
else
@@ -140,7 +140,7 @@
var/obj/docking_port/mobile/shuttle = SSshuttle.supply
var/shuttleMsg = null
if (shuttle.mode == SHUTTLE_IDLE)
- if (shuttle.z in GLOB.station_z_levels)
+ if (is_station_level(shuttle.z))
shuttleMsg = "Docked"
else
shuttleMsg = "[shuttle.getModeStr()]: [shuttle.getTimerStr()]"
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index 53c0b746bd..307107d517 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -236,8 +236,7 @@
visible_message("[src]'s door slides open, barraging you with the nauseating smell of charred flesh.")
playsound(src, 'sound/machines/airlockclose.ogg', 25, 1)
for(var/obj/item/I in src) //Scorches away blood and forensic evidence, although the SSU itself is unaffected
- I.clean_blood()
- I.fingerprints = list()
+ I.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRONG)
var/datum/component/radioactive/contamination = I.GetComponent(/datum/component/radioactive)
if(contamination)
qdel(contamination)
diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm
index 868c9ee728..e72964c79d 100644
--- a/code/game/machinery/teleporter.dm
+++ b/code/game/machinery/teleporter.dm
@@ -42,7 +42,7 @@
return power_station
/obj/machinery/teleport/hub/CollidedWith(atom/movable/AM)
- if(z == ZLEVEL_CENTCOM)
+ if(is_centcom_level(z))
to_chat(AM, "You can't use this here.")
return
if(is_ready())
diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm
index f1384c0ea3..b48f14e508 100644
--- a/code/game/machinery/washing_machine.dm
+++ b/code/game/machinery/washing_machine.dm
@@ -12,6 +12,10 @@
var/obj/item/color_source
var/max_wash_capacity = 5
+/obj/machinery/washing_machine/ComponentInitialize()
+ . = ..()
+ AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT), CALLBACK(src, .proc/clean_blood))
+
/obj/machinery/washing_machine/examine(mob/user)
..()
to_chat(user, "Alt-click it to start a wash cycle.")
@@ -36,20 +40,17 @@
busy = TRUE
update_icon()
- sleep(200)
- wash_cycle()
+ addtimer(CALLBACK(src, .proc/wash_cycle), 200)
-/obj/machinery/washing_machine/clean_blood()
- ..()
+/obj/machinery/washing_machine/proc/clean_blood()
if(!busy)
- bloody_mess = 0
+ bloody_mess = FALSE
update_icon()
-
/obj/machinery/washing_machine/proc/wash_cycle()
for(var/X in contents)
var/atom/movable/AM = X
- AM.clean_blood()
+ AM.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
AM.machine_wash(src)
busy = FALSE
diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm
index 385d112542..b82a46b7e0 100644
--- a/code/game/mecha/equipment/tools/other_tools.dm
+++ b/code/game/mecha/equipment/tools/other_tools.dm
@@ -13,7 +13,7 @@
range = RANGED
/obj/item/mecha_parts/mecha_equipment/teleporter/action(atom/target)
- if(!action_checks(target) || src.loc.z == ZLEVEL_CENTCOM)
+ if(!action_checks(target) || is_centcom_level(loc.z))
return
var/turf/T = get_turf(target)
if(T)
@@ -34,7 +34,7 @@
/obj/item/mecha_parts/mecha_equipment/wormhole_generator/action(atom/target)
- if(!action_checks(target) || src.loc.z == ZLEVEL_CENTCOM)
+ if(!action_checks(target) || is_centcom_level(loc.z))
return
var/list/theareas = get_areas_in_range(100, chassis)
if(!theareas.len)
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index f06525863d..d6b70604af 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -79,14 +79,11 @@
add_blood = bloodiness
bloodiness -= add_blood
S.bloody_shoes[blood_state] = min(MAX_SHOE_BLOODINESS,S.bloody_shoes[blood_state]+add_blood)
- if(blood_DNA && blood_DNA.len)
- S.add_blood(blood_DNA)
+ S.add_blood_DNA(return_blood_DNA())
S.blood_state = blood_state
update_icon()
H.update_inv_shoes()
-
-
/obj/effect/decal/cleanable/proc/can_bloodcrawl_in()
if((blood_state != BLOOD_STATE_OIL) && (blood_state != BLOOD_STATE_NOT_BLOODY))
return bloodiness
diff --git a/code/game/objects/effects/decals/cleanable/aliens.dm b/code/game/objects/effects/decals/cleanable/aliens.dm
index 333da7f48a..55d5d32ffc 100644
--- a/code/game/objects/effects/decals/cleanable/aliens.dm
+++ b/code/game/objects/effects/decals/cleanable/aliens.dm
@@ -6,10 +6,13 @@
icon = 'icons/effects/blood.dmi'
icon_state = "xfloor1"
random_icon_states = list("xfloor1", "xfloor2", "xfloor3", "xfloor4", "xfloor5", "xfloor6", "xfloor7")
- blood_DNA = list("UNKNOWN DNA" = "X*")
bloodiness = MAX_SHOE_BLOODINESS
blood_state = BLOOD_STATE_XENO
+/obj/effect/decal/cleanable/xenoblood/Initialize()
+ . = ..()
+ add_blood_DNA(list("UNKNOWN DNA" = "X*"))
+
/obj/effect/decal/cleanable/xenoblood/xsplatter
random_icon_states = list("xgibbl1", "xgibbl2", "xgibbl3", "xgibbl4", "xgibbl5")
@@ -62,4 +65,7 @@
/obj/effect/decal/cleanable/blood/xtracks
icon_state = "xtracks"
random_icon_states = null
- blood_DNA = list("UNKNOWN DNA" = "X*")
+
+/obj/effect/decal/cleanable/blood/xtracks/Initialize()
+ . = ..()
+ add_blood_DNA(list("Unknown DNA" = "X*"))
diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm
index 42aec1582e..fbcf22fb90 100644
--- a/code/game/objects/effects/decals/cleanable/humans.dm
+++ b/code/game/objects/effects/decals/cleanable/humans.dm
@@ -4,13 +4,11 @@
icon = 'icons/effects/blood.dmi'
icon_state = "floor1"
random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7")
- blood_DNA = list()
blood_state = BLOOD_STATE_HUMAN
bloodiness = MAX_SHOE_BLOODINESS
/obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C)
- if (C.blood_DNA)
- blood_DNA |= C.blood_DNA.Copy()
+ add_blood_DNA(C.return_blood_DNA())
..()
/obj/effect/decal/cleanable/blood/old
@@ -21,7 +19,7 @@
/obj/effect/decal/cleanable/blood/old/Initialize(mapload, list/datum/disease/diseases)
. = ..()
icon_state += "-old" //This IS necessary because the parent /blood type uses icon randomization.
- blood_DNA["Non-human DNA"] = "A+"
+ add_blood_DNA(list("Non-human DNA" = "A+"))
/obj/effect/decal/cleanable/blood/splatter
random_icon_states = list("gibbl1", "gibbl2", "gibbl3", "gibbl4", "gibbl5")
@@ -37,11 +35,9 @@
desc = "Your instincts say you shouldn't be following these."
random_icon_states = null
var/list/existing_dirs = list()
- blood_DNA = list()
/obj/effect/decal/cleanable/trail_holder/can_bloodcrawl_in()
- return 1
-
+ return TRUE
/obj/effect/decal/cleanable/blood/gibs
name = "gibs"
@@ -100,8 +96,7 @@
. = ..()
setDir(pick(1,2,4,8))
icon_state += "-old"
- blood_DNA["Non-human DNA"] = "A+"
-
+ add_blood_DNA(list("Non-human DNA" = "A+"))
/obj/effect/decal/cleanable/blood/drip
name = "drips of blood"
@@ -111,9 +106,8 @@
bloodiness = 0
var/drips = 1
-
/obj/effect/decal/cleanable/blood/drip/can_bloodcrawl_in()
- return 1
+ return TRUE
//BLOODY FOOTPRINTS
@@ -151,7 +145,7 @@
if (!(exited_dirs & H.dir))
exited_dirs |= H.dir
update_icon()
-
+
/obj/effect/decal/cleanable/blood/footprints/update_icon()
cut_overlays()
diff --git a/code/game/objects/effects/spawners/gibspawner.dm b/code/game/objects/effects/spawners/gibspawner.dm
index 43f10dc45e..79627a7a80 100644
--- a/code/game/objects/effects/spawners/gibspawner.dm
+++ b/code/game/objects/effects/spawners/gibspawner.dm
@@ -30,9 +30,9 @@
digester.stomach_contents += gib
if(MobDNA)
- gib.blood_DNA[MobDNA.unique_enzymes] = MobDNA.blood_type
+
else if(istype(src, /obj/effect/gibspawner/generic)) // Probably a monkey
- gib.blood_DNA["Non-human DNA"] = "A+"
+ gib.add_blood_DNA(list("Non-human DNA" = "A+"))
var/list/directions = gibdirections[i]
if(isturf(loc))
if(directions.len)
diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm
index 34e6793d5b..a2ff5b0674 100644
--- a/code/game/objects/effects/spawners/lootdrop.dm
+++ b/code/game/objects/effects/spawners/lootdrop.dm
@@ -5,19 +5,29 @@
var/lootcount = 1 //how many items will be spawned
var/lootdoubles = TRUE //if the same item can be spawned twice
var/list/loot //a list of possible items to spawn e.g. list(/obj/item, /obj/structure, /obj/effect)
+ var/fan_out_items = FALSE //Whether the items should be distributed to offsets 0,3,-3,6,-6,9,-9.. This overrides pixel_x/y on the spawner itself
/obj/effect/spawner/lootdrop/Initialize(mapload)
..()
if(loot && loot.len)
var/turf/T = get_turf(src)
- while(lootcount && loot.len)
+ var/loot_spawned = 0
+ while((lootcount-loot_spawned) && loot.len)
var/lootspawn = pickweight(loot)
if(!lootdoubles)
loot.Remove(lootspawn)
if(lootspawn)
- new lootspawn(T)
- lootcount--
+ var/atom/movable/spawned_loot = new lootspawn(T)
+ if (!fan_out_items)
+ if (pixel_x != 0)
+ spawned_loot.pixel_x = pixel_x
+ if (pixel_y != 0)
+ spawned_loot.pixel_y = pixel_y
+ else
+ if (loot_spawned)
+ spawned_loot.pixel_x = spawned_loot.pixel_y = ((!(loot_spawned%2)*loot_spawned/2)*-3)+((loot_spawned%2)*(loot_spawned+1)/2*3)
+ loot_spawned++
return INITIALIZE_HINT_QDEL
/obj/effect/spawner/lootdrop/armory_contraband
diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm
index 4ecba7c982..83d24a26ee 100644
--- a/code/game/objects/effects/spiders.dm
+++ b/code/game/objects/effects/spiders.dm
@@ -133,7 +133,7 @@
else if(entry_vent)
if(get_dist(src, entry_vent) <= 1)
var/list/vents = list()
- var/datum/pipeline/entry_vent_parent = entry_vent.PARENT1
+ var/datum/pipeline/entry_vent_parent = entry_vent.parents[1]
for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in entry_vent_parent.other_atmosmch)
vents.Add(temp_vent)
if(!vents.len)
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index e03d8c1a7e..11edcb11b2 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -553,20 +553,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
if(M.become_blind())
to_chat(M, "You go blind!")
-/obj/item/clean_blood()
- . = ..()
- if(.)
- if(initial(icon) && initial(icon_state))
- var/index = blood_splatter_index()
- var/icon/blood_splatter_icon = GLOB.blood_splatter_icons[index]
- if(blood_splatter_icon)
- cut_overlay(blood_splatter_icon)
-
-/obj/item/clothing/gloves/clean_blood()
- . = ..()
- if(.)
- transfer_blood = 0
-
/obj/item/singularity_pull(S, current_size)
..()
if(current_size >= STAGE_FOUR)
diff --git a/code/game/objects/items/clown_items.dm b/code/game/objects/items/clown_items.dm
index f2a804e9e9..e9ccda03ea 100644
--- a/code/game/objects/items/clown_items.dm
+++ b/code/game/objects/items/clown_items.dm
@@ -86,7 +86,7 @@
var/obj/effect/decal/cleanable/C = locate() in target
qdel(C)
target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
- target.clean_blood()
+ target.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
target.wash_cream()
return
diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm
index 1b9e2c0e14..57c252258d 100644
--- a/code/game/objects/items/devices/PDA/cart.dm
+++ b/code/game/objects/items/devices/PDA/cart.dm
@@ -430,14 +430,14 @@ Code:
switch(SSshuttle.supply.mode)
if(SHUTTLE_CALL)
menu += "Moving to "
- if(!(SSshuttle.supply.z in GLOB.station_z_levels))
+ if(!is_station_level(SSshuttle.supply.z))
menu += "station"
else
menu += "centcom"
menu += " ([SSshuttle.supply.timeLeft(600)] Mins)"
else
menu += "At "
- if(!(SSshuttle.supply.z in GLOB.station_z_levels))
+ if(!is_station_level(SSshuttle.supply.z))
menu += "centcom"
else
menu += "station"
diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm
index 3e9ce8c341..9cd0ca5d29 100644
--- a/code/game/objects/items/devices/radio/intercom.dm
+++ b/code/game/objects/items/devices/radio/intercom.dm
@@ -139,8 +139,8 @@
else
icon_state = initial(icon_state)
-/obj/item/device/radio/intercom/add_blood(list/blood_dna)
- return 0
+/obj/item/device/radio/intercom/add_blood_DNA(list/blood_dna)
+ return FALSE
//Created through the autolathe or through deconstructing intercoms. Can be applied to wall to make a new intercom on it!
/obj/item/wallframe/intercom
diff --git a/code/game/objects/items/flamethrower.dm b/code/game/objects/items/flamethrower.dm
index 3a351a6514..8cc6d6b179 100644
--- a/code/game/objects/items/flamethrower.dm
+++ b/code/game/objects/items/flamethrower.dm
@@ -233,7 +233,7 @@
/obj/item/flamethrower/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
var/obj/item/projectile/P = hitby
if(damage && attack_type == PROJECTILE_ATTACK && P.damage_type != STAMINA && prob(15))
- owner.visible_message("[attack_text] hits the fueltank on [owner]'s [src], rupturing it! What a shot!")
+ owner.visible_message("\The [attack_text] hits the fueltank on [owner]'s [name], rupturing it! What a shot!")
var/target_turf = get_turf(owner)
igniter.ignite_turf(src,target_turf, release_amount = 100)
qdel(ptank)
diff --git a/code/game/objects/items/melee/energy.dm b/code/game/objects/items/melee/energy.dm
index 6eaf3f08bd..146bcbb3c3 100644
--- a/code/game/objects/items/melee/energy.dm
+++ b/code/game/objects/items/melee/energy.dm
@@ -20,8 +20,8 @@
user.visible_message("[user] is [pick("slitting [user.p_their()] stomach open with", "falling on")] [src]! It looks like [user.p_theyre()] trying to commit seppuku!")
return (BRUTELOSS|FIRELOSS)
-/obj/item/melee/transforming/energy/add_blood(list/blood_dna)
- return 0
+/obj/item/melee/transforming/energy/add_blood_DNA(list/blood_dna)
+ return FALSE
/obj/item/melee/transforming/energy/is_sharp()
return active * sharpness
diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm
index 874ffee050..3f1b5cd54e 100644
--- a/code/game/objects/items/melee/misc.dm
+++ b/code/game/objects/items/melee/misc.dm
@@ -285,8 +285,8 @@
shard.Consume()
T.CalculateAdjacentTurfs()
-/obj/item/melee/supermatter_sword/add_blood(list/blood_dna)
- return 0
+/obj/item/melee/supermatter_sword/add_blood_DNA(list/blood_dna)
+ return FALSE
/obj/item/melee/curator_whip
name = "curator's whip"
diff --git a/code/game/objects/items/mop.dm b/code/game/objects/items/mop.dm
index e47cafdea9..45c687a66f 100644
--- a/code/game/objects/items/mop.dm
+++ b/code/game/objects/items/mop.dm
@@ -23,7 +23,6 @@
/obj/item/mop/proc/clean(turf/A)
if(reagents.has_reagent("water", 1) || reagents.has_reagent("holywater", 1) || reagents.has_reagent("vodka", 1) || reagents.has_reagent("cleaner", 1))
- A.clean_blood()
A.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
for(var/obj/effect/O in A)
if(is_cleanable(O))
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index 5e80353db9..0e92d578a1 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -336,10 +336,10 @@
else
. = ..()
-/obj/item/stack/proc/copy_evidences(obj/item/stack/from as obj)
- blood_DNA = from.blood_DNA
- fingerprints = from.fingerprints
- fingerprintshidden = from.fingerprintshidden
+/obj/item/stack/proc/copy_evidences(obj/item/stack/from)
+ add_blood_DNA(from.return_blood_DNA())
+ add_fingerprint_list(from.return_fingerprints())
+ add_hiddenprint_list(from.return_hiddenprints())
fingerprintslast = from.fingerprintslast
//TODO bloody overlay
diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm
index 533858b748..84cd51fe22 100644
--- a/code/game/objects/items/storage/backpack.dm
+++ b/code/game/objects/items/storage/backpack.dm
@@ -72,7 +72,7 @@
/obj/item/storage/backpack/holding/handle_item_insertion(obj/item/W, prevent_warning = 0, mob/living/user)
if((istype(W, /obj/item/storage/backpack/holding) || count_by_type(W.GetAllContents(), /obj/item/storage/backpack/holding)))
var/turf/loccheck = get_turf(src)
- if(loccheck.z == ZLEVEL_CITYOFCOGS)
+ if(is_reebe(loccheck.z))
user.visible_message("An unseen force knocks [user] to the ground!", "\"I think not!\"")
user.Knockdown(60)
return
diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm
index 4c85a3b0e9..c88dc51474 100644
--- a/code/game/objects/items/storage/book.dm
+++ b/code/game/objects/items/storage/book.dm
@@ -212,5 +212,5 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
else
return ..(M,user,heal_mode = FALSE)
-/obj/item/storage/book/bible/syndicate/add_blood(list/blood_dna)
+/obj/item/storage/book/bible/syndicate/add_blood_DNA(list/blood_dna)
return FALSE
diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm
index 93876164b4..7012eee386 100644
--- a/code/game/objects/items/teleportation.dm
+++ b/code/game/objects/items/teleportation.dm
@@ -52,7 +52,7 @@ Frequency:
if (usr.stat || usr.restrained())
return
var/turf/current_location = get_turf(usr)//What turf is the user on?
- if(!current_location || current_location.z == ZLEVEL_CENTCOM)//If turf was not found or they're on CentCom
+ if(!current_location || is_centcom_level(current_location.z))//If turf was not found or they're on CentCom
to_chat(usr, "[src] is malfunctioning.")
return
if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)))
@@ -167,7 +167,7 @@ Frequency:
/obj/item/hand_tele/attack_self(mob/user)
var/turf/current_location = get_turf(user)//What turf is the user on?
var/area/current_area = current_location.loc
- if(!current_location || current_area.noteleport || current_location.z > ZLEVEL_SPACEMAX || !isturf(user.loc))//If turf was not found or they're on z level 2 or >7 which does not currently exist. or if user is not located on a turf
+ if(!current_location || current_area.noteleport || is_away_level(current_location.z) || !isturf(user.loc))//If turf was not found or they're on z level 2 or >7 which does not currently exist. or if user is not located on a turf
to_chat(user, "\The [src] is malfunctioning.")
return
var/list/L = list( )
@@ -205,7 +205,7 @@ Frequency:
return
current_location = get_turf(user) //Recheck.
current_area = current_location.loc
- if(!current_location || current_area.noteleport || current_location.z > ZLEVEL_SPACEMAX || !isturf(user.loc))//If turf was not found or they're on z level 2 or >7 which does not currently exist. or if user is not located on a turf
+ if(!current_location || current_area.noteleport || is_away_level(current_location.z) || !isturf(user.loc))//If turf was not found or they're on z level 2 or >7 which does not currently exist. or if user is not located on a turf
to_chat(user, "\The [src] is malfunctioning.")
return
user.show_message("Locked In.", 2)
diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm
index b7b48ff043..539c3c70a0 100644
--- a/code/game/objects/items/twohanded.dm
+++ b/code/game/objects/items/twohanded.dm
@@ -293,7 +293,7 @@
icon_state = "dualsaber[item_color][wielded]"
else
icon_state = "dualsaber0"
- clean_blood()//blood overlays get weird otherwise, because the sprite changes.
+ SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
/obj/item/twohanded/dualsaber/attack(mob/target, mob/living/carbon/human/user)
if(user.has_dna())
diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm
index 306d3d0b84..b1d1af6342 100644
--- a/code/game/objects/structures/lattice.dm
+++ b/code/game/objects/structures/lattice.dm
@@ -63,7 +63,7 @@
canSmoothWith += /turf/open/indestructible/clock_spawn_room //list overrides are a terrible thing
. = ..()
ratvar_act()
- if(z == ZLEVEL_CITYOFCOGS)
+ if(is_reebe(z))
resistance_flags |= INDESTRUCTIBLE
/obj/structure/lattice/clockwork/ratvar_act()
@@ -120,7 +120,7 @@
if(!mapload)
new /obj/effect/temp_visual/ratvar/floor/catwalk(loc)
new /obj/effect/temp_visual/ratvar/beam/catwalk(loc)
- if(z == ZLEVEL_CITYOFCOGS)
+ if(is_reebe(z))
resistance_flags |= INDESTRUCTIBLE
/obj/structure/lattice/catwalk/clockwork/ratvar_act()
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index 77b992704a..ab0f676007 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -296,8 +296,7 @@
/obj/machinery/shower/proc/wash_obj(obj/O)
- O.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
- . = O.clean_blood()
+ . = O.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
O.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
if(isitem(O))
var/obj/item/I = O
@@ -310,7 +309,6 @@
var/turf/tile = loc
tile.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
tile.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
- tile.clean_blood()
for(var/obj/effect/E in tile)
if(is_cleanable(E))
qdel(E)
@@ -361,7 +359,7 @@
else if(H.w_uniform && wash_obj(H.w_uniform))
H.update_inv_w_uniform()
if(washgloves)
- H.clean_blood()
+ H.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
if(H.shoes && washshoes && wash_obj(H.shoes))
H.update_inv_shoes()
if(H.wear_mask && washmask && wash_obj(H.wear_mask))
@@ -378,9 +376,9 @@
else
if(M.wear_mask && wash_obj(M.wear_mask))
M.update_inv_wear_mask(0)
- M.clean_blood()
+ M.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
else
- L.clean_blood()
+ L.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
/obj/machinery/shower/proc/contamination_cleanse(atom/movable/thing)
var/datum/component/radioactive/healthy_green_glow = thing.GetComponent(/datum/component/radioactive)
@@ -473,8 +471,7 @@
H.regenerate_icons()
user.drowsyness = max(user.drowsyness - rand(2,3), 0) //Washing your face wakes you up if you're falling asleep
else
- user.clean_blood()
-
+ user.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
/obj/structure/sink/attackby(obj/item/O, mob/living/user, params)
if(busy)
@@ -530,7 +527,7 @@
busy = FALSE
return 1
busy = FALSE
- O.clean_blood()
+ O.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
O.acid_level = 0
create_reagents(5)
reagents.add_reagent(dispensedreagent, 5)
diff --git a/code/game/turfs/ChangeTurf.dm b/code/game/turfs/ChangeTurf.dm
index 2f165d9a20..26bbc84078 100644
--- a/code/game/turfs/ChangeTurf.dm
+++ b/code/game/turfs/ChangeTurf.dm
@@ -119,27 +119,53 @@
// Take the input as baseturfs and put it underneath the current baseturfs
// If fake_turf_type is provided and new_baseturfs is not the baseturfs list will be created identical to the turf type's
// If both or just new_baseturfs is provided they will be inserted below the existing baseturfs
-/turf/proc/PlaceOnBottom(turf/fake_turf_type, list/new_baseturfs)
+/turf/proc/PlaceOnBottom(list/new_baseturfs, turf/fake_turf_type)
if(fake_turf_type)
if(!new_baseturfs)
var/list/old_baseturfs = baseturfs.Copy()
assemble_baseturfs(fake_turf_type)
+ if(!length(baseturfs))
+ baseturfs = list(baseturfs)
baseturfs += old_baseturfs
return
else if(!length(new_baseturfs))
new_baseturfs = list(new_baseturfs, fake_turf_type)
else
new_baseturfs += fake_turf_type
+ if(!length(baseturfs))
+ baseturfs = list(baseturfs)
baseturfs.Insert(1, new_baseturfs)
// Make a new turf and put it on top
-/turf/proc/PlaceOnTop(turf/fake_turf_type, list/new_baseturfs)
- var/list/temp_baseturfs = list()
- temp_baseturfs += baseturfs // Doesn't matter if baseturfs is a list or single item, either will get added correctly
- temp_baseturfs += type
- if(new_baseturfs)
- temp_baseturfs += new_baseturfs
- return ChangeTurf(fake_turf_type, temp_baseturfs)
+// The args behave identical to PlaceOnBottom except they go on top
+/turf/proc/PlaceOnTop(list/new_baseturfs, turf/fake_turf_type)
+ var/turf/newT
+ if(fake_turf_type)
+ if(!new_baseturfs) // If no baseturfs list then we want to create one from the turf type
+ var/list/old_baseturfs = baseturfs.Copy()
+ newT = ChangeTurf(fake_turf_type)
+ newT.assemble_baseturfs(initial(fake_turf_type.baseturfs)) // The baseturfs list is created like roundstart
+ if(!length(baseturfs))
+ newT.baseturfs = list(baseturfs)
+ newT.baseturfs.Insert(1, old_baseturfs) // The old baseturfs are put underneath
+ return newT
+ if(!length(baseturfs))
+ baseturfs = list(baseturfs)
+ baseturfs += type
+ baseturfs += new_baseturfs
+ return ChangeTurf(fake_turf_type)
+ if(!length(baseturfs))
+ baseturfs = list(baseturfs)
+ baseturfs += type
+ var/turf/change_type
+ if(length(new_baseturfs))
+ change_type = new_baseturfs[new_baseturfs.len]
+ new_baseturfs.len--
+ if(new_baseturfs.len)
+ baseturfs += new_baseturfs
+ else
+ change_type = new_baseturfs
+ return ChangeTurf(change_type)
// Copy an existing turf and put it on top
/turf/proc/CopyOnTop(turf/copytarget, ignore_bottom=1, depth=INFINITY) // x, 1, 0
diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm
index 653f1946e5..b8d46977be 100644
--- a/code/game/turfs/open.dm
+++ b/code/game/turfs/open.dm
@@ -173,7 +173,7 @@
for(var/mob/living/simple_animal/slime/M in src)
M.apply_water()
- clean_blood()
+ SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
for(var/obj/effect/O in src)
if(is_cleanable(O))
qdel(O)
diff --git a/code/game/turfs/simulated/floor/plating/asteroid.dm b/code/game/turfs/simulated/floor/plating/asteroid.dm
index 2cdac898b7..8ffcab7949 100644
--- a/code/game/turfs/simulated/floor/plating/asteroid.dm
+++ b/code/game/turfs/simulated/floor/plating/asteroid.dm
@@ -59,7 +59,7 @@
/turf/open/floor/plating/asteroid/singularity_act()
- if(turf_z_is_planet(src))
+ if(is_planet_level(z))
return ..()
ScrapeAway()
diff --git a/code/game/turfs/simulated/river.dm b/code/game/turfs/simulated/river.dm
index fe9a5926bb..a5753edcd1 100644
--- a/code/game/turfs/simulated/river.dm
+++ b/code/game/turfs/simulated/river.dm
@@ -4,7 +4,7 @@
#define RANDOM_LOWER_X 50
#define RANDOM_LOWER_Y 50
-/proc/spawn_rivers(target_z = 5, nodes = 4, turf_type = /turf/open/lava/smooth/lava_land_surface, whitelist_area = /area/lavaland/surface/outdoors, min_x = RANDOM_LOWER_X, min_y = RANDOM_LOWER_Y, max_x = RANDOM_UPPER_X, max_y = RANDOM_UPPER_Y)
+/proc/spawn_rivers(target_z = ZLEVEL_LAVALAND, nodes = 4, turf_type = /turf/open/lava/smooth/lava_land_surface, whitelist_area = /area/lavaland/surface/outdoors, min_x = RANDOM_LOWER_X, min_y = RANDOM_LOWER_Y, max_x = RANDOM_UPPER_X, max_y = RANDOM_UPPER_Y)
var/list/river_nodes = list()
var/num_spawned = 0
while(num_spawned < nodes)
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 43651cebef..ba1cb9c524 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -606,7 +606,7 @@
/datum/admins/proc/unprison(mob/M in GLOB.mob_list)
set category = "Admin"
set name = "Unprison"
- if (M.z == ZLEVEL_CENTCOM)
+ if (is_centcom_level(M.z))
SSjob.SendToLateJoin(M)
message_admins("[key_name_admin(usr)] has unprisoned [key_name_admin(M)]")
log_admin("[key_name(usr)] has unprisoned [key_name(M)]")
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index 2a3812be3b..1805cf327d 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -360,7 +360,7 @@
if(isdrone(M))
drones++
continue
- if(M.z == ZLEVEL_CENTCOM)
+ if(is_centcom_level(M.z))
living_skipped++
continue
living_players++
diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm
index 0753f942dc..14d94acf86 100644
--- a/code/modules/admin/secrets.dm
+++ b/code/modules/admin/secrets.dm
@@ -445,7 +445,7 @@
return
SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Egalitarian Station")
for(var/obj/machinery/door/airlock/W in GLOB.machines)
- if((W.z in GLOB.station_z_levels) && !istype(get_area(W), /area/bridge) && !istype(get_area(W), /area/crew_quarters) && !istype(get_area(W), /area/security/prison))
+ if(is_station_level(W.z) && !istype(get_area(W), /area/bridge) && !istype(get_area(W), /area/crew_quarters) && !istype(get_area(W), /area/security/prison))
W.req_access = list()
message_admins("[key_name_admin(usr)] activated Egalitarian Station mode")
priority_announce("CentCom airlock control override activated. Please take this time to get acquainted with your coworkers.", null, 'sound/ai/commandreport.ogg')
diff --git a/code/modules/admin/verbs/atmosdebug.dm b/code/modules/admin/verbs/atmosdebug.dm
index 05c839d3fd..8c564551ba 100644
--- a/code/modules/admin/verbs/atmosdebug.dm
+++ b/code/modules/admin/verbs/atmosdebug.dm
@@ -13,12 +13,12 @@
//Manifolds
for (var/obj/machinery/atmospherics/pipe/manifold/pipe in GLOB.machines)
- if (!pipe.NODE1 || !pipe.NODE2 || !pipe.NODE3)
+ if (!pipe.nodes[1] || !pipe.nodes[2] || !pipe.nodes[3])
to_chat(usr, "Unconnected [pipe.name] located at [pipe.x],[pipe.y],[pipe.z] ([get_area(pipe.loc)])")
//Pipes
for (var/obj/machinery/atmospherics/pipe/simple/pipe in GLOB.machines)
- if (!pipe.NODE1 || !pipe.NODE2)
+ if (!pipe.nodes[1] || !pipe.nodes[2])
to_chat(usr, "Unconnected [pipe.name] located at [pipe.x],[pipe.y],[pipe.z] ([get_area(pipe.loc)])")
/client/proc/powerdebug()
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index e2bb78c9ec..0fe79e10de 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -521,7 +521,7 @@ GLOBAL_PROTECT(LastAdminCalledProc)
for(var/area/A in world)
if(on_station)
var/turf/picked = safepick(get_area_turfs(A.type))
- if(picked && (picked.z in GLOB.station_z_levels))
+ if(picked && is_station_level(picked.z))
if(!(A.type in areas_all) && !is_type_in_typecache(A, station_areas_blacklist))
areas_all.Add(A.type)
else if(!(A.type in areas_all))
diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm
index ece3775872..9035a34317 100644
--- a/code/modules/admin/verbs/one_click_antag.dm
+++ b/code/modules/admin/verbs/one_click_antag.dm
@@ -35,7 +35,7 @@
return FALSE
if(onstation)
var/turf/T = get_turf(applicant)
- if(!(T.z in GLOB.station_z_levels))
+ if(!is_station_level(T.z))
return FALSE
if(conscious && applicant.stat) //incase you don't care about a certain antag being unconcious when made, ie if they have selfhealing abilities.
return FALSE
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index b26453b461..b37ff9ceb4 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -472,7 +472,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(!holder)
to_chat(src, "Only administrators may use this command.")
return
- var/input = input(usr, "Please enter anything you want. Anything. Serious.", "What?", "") as message|null
+ var/input = input(usr, "Enter a Command Report. Ensure it makes sense IC.", "What?", "") as message|null
if(!input)
return
diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm
index 6c335bf896..2a5d792a1b 100644
--- a/code/modules/atmospherics/machinery/atmosmachinery.dm
+++ b/code/modules/atmospherics/machinery/atmosmachinery.dm
@@ -60,8 +60,8 @@ Pipelines + Other Objects -> Pipe network
SetInitDirections()
/obj/machinery/atmospherics/Destroy()
- for(DEVICE_TYPE_LOOP)
- nullifyNode(I)
+ for(var/i in 1 to device_type)
+ nullifyNode(i)
SSair.atmos_machinery -= src
@@ -79,22 +79,22 @@ Pipelines + Other Objects -> Pipe network
// Called to build a network from this node
return
-/obj/machinery/atmospherics/proc/nullifyNode(I)
- if(NODE_I)
- var/obj/machinery/atmospherics/N = NODE_I
+/obj/machinery/atmospherics/proc/nullifyNode(i)
+ if(nodes[i])
+ var/obj/machinery/atmospherics/N = nodes[i]
N.disconnect(src)
- NODE_I = null
+ nodes[i] = null
/obj/machinery/atmospherics/proc/getNodeConnects()
var/list/node_connects = list()
node_connects.len = device_type
- for(DEVICE_TYPE_LOOP)
+ for(var/i in 1 to device_type)
for(var/D in GLOB.cardinals)
if(D & GetInitDirections())
if(D in node_connects)
continue
- node_connects[I] = D
+ node_connects[i] = D
break
return node_connects
@@ -109,10 +109,10 @@ Pipelines + Other Objects -> Pipe network
if(!node_connects) //for pipes where order of nodes doesn't matter
node_connects = getNodeConnects()
- for(DEVICE_TYPE_LOOP)
- for(var/obj/machinery/atmospherics/target in get_step(src,node_connects[I]))
- if(can_be_node(target, I))
- NODE_I = target
+ for(var/i in 1 to device_type)
+ for(var/obj/machinery/atmospherics/target in get_step(src,node_connects[i]))
+ if(can_be_node(target, i))
+ nodes[i] = target
break
update_icon()
@@ -171,8 +171,7 @@ Pipelines + Other Objects -> Pipe network
if(istype(reference, /obj/machinery/atmospherics/pipe))
var/obj/machinery/atmospherics/pipe/P = reference
P.destroy_network()
- var/I = nodes.Find(reference)
- NODE_I = null
+ nodes[nodes.Find(reference)] = null
update_icon()
/obj/machinery/atmospherics/update_icon()
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm
index ef6dd85afa..63af8e8aa2 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm
@@ -21,8 +21,8 @@
/obj/machinery/atmospherics/components/binary/circulator/proc/return_transfer_air()
- var/datum/gas_mixture/air1 = AIR1
- var/datum/gas_mixture/air2 = AIR2
+ var/datum/gas_mixture/air1 = airs[1]
+ var/datum/gas_mixture/air2 = airs[2]
var/output_starting_pressure = air1.return_pressure()
var/input_starting_pressure = air2.return_pressure()
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm
index 6f72724e1e..ec11ce588c 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm
@@ -49,8 +49,8 @@ Acts like a normal vent, but has an input AND output.
/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/New()
..()
- var/datum/gas_mixture/air1 = AIR1
- var/datum/gas_mixture/air2 = AIR2
+ var/datum/gas_mixture/air1 = airs[1]
+ var/datum/gas_mixture/air2 = airs[2]
air1.volume = 1000
air2.volume = 1000
@@ -73,8 +73,8 @@ Acts like a normal vent, but has an input AND output.
if(!on)
return
- var/datum/gas_mixture/air1 = AIR1
- var/datum/gas_mixture/air2 = AIR2
+ var/datum/gas_mixture/air1 = airs[1]
+ var/datum/gas_mixture/air2 = airs[2]
var/datum/gas_mixture/environment = loc.return_air()
var/environment_pressure = environment.return_pressure()
@@ -99,7 +99,7 @@ Acts like a normal vent, but has an input AND output.
loc.assume_air(removed)
air_update_turf()
- var/datum/pipeline/parent1 = PARENT1
+ var/datum/pipeline/parent1 = parents[1]
parent1.update = 1
else //external -> output
@@ -122,7 +122,7 @@ Acts like a normal vent, but has an input AND output.
air2.merge(removed)
air_update_turf()
- var/datum/pipeline/parent2 = PARENT2
+ var/datum/pipeline/parent2 = parents[2]
parent2.update = 1
//Radio remote control
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm
index ef4e487efd..00cdd6fca7 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm
@@ -41,8 +41,8 @@ Passive gate is similar to the regular pump except:
if(!on)
return
- var/datum/gas_mixture/air1 = AIR1
- var/datum/gas_mixture/air2 = AIR2
+ var/datum/gas_mixture/air1 = airs[1]
+ var/datum/gas_mixture/air2 = airs[2]
var/output_starting_pressure = air2.return_pressure()
var/input_starting_pressure = air1.return_pressure()
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
index 9d581fcb78..47dc2a2dae 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm
@@ -50,8 +50,8 @@ Thus, the two variables affect pump operation are set in New():
if(!on || !is_operational())
return
- var/datum/gas_mixture/air1 = AIR1
- var/datum/gas_mixture/air2 = AIR2
+ var/datum/gas_mixture/air1 = airs[1]
+ var/datum/gas_mixture/air2 = airs[2]
var/output_starting_pressure = air2.return_pressure()
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/valve.dm b/code/modules/atmospherics/machinery/components/binary_devices/valve.dm
index e613012e82..1a9c76cb4d 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/valve.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/valve.dm
@@ -31,7 +31,7 @@ It's like a regular ol' straight pipe, but you can turn it on and off.
open = TRUE
update_icon_nopipes()
update_parents()
- var/datum/pipeline/parent1 = PARENT1
+ var/datum/pipeline/parent1 = parents[1]
parent1.reconcile_air()
investigate_log("was opened by [usr ? key_name(usr) : "a remote signal"]", INVESTIGATE_ATMOS)
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
index 2803d1bf09..e21d5b2d8a 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm
@@ -48,8 +48,8 @@ Thus, the two variables affect pump operation are set in New():
if(!on || !is_operational())
return
- var/datum/gas_mixture/air1 = AIR1
- var/datum/gas_mixture/air2 = AIR2
+ var/datum/gas_mixture/air1 = airs[1]
+ var/datum/gas_mixture/air2 = airs[2]
// Pump mechanism just won't do anything if the pressure is too high/too low
@@ -150,7 +150,7 @@ Thus, the two variables affect pump operation are set in New():
on = !on
if("set_transfer_rate" in signal.data)
- var/datum/gas_mixture/air1 = AIR1
+ var/datum/gas_mixture/air1 = airs[1]
transfer_rate = CLAMP(text2num(signal.data["set_transfer_rate"]),0,air1.volume)
if(on != old_on)
diff --git a/code/modules/atmospherics/machinery/components/components_base.dm b/code/modules/atmospherics/machinery/components/components_base.dm
index 5fb4611d92..e7f4d7844a 100644
--- a/code/modules/atmospherics/machinery/components/components_base.dm
+++ b/code/modules/atmospherics/machinery/components/components_base.dm
@@ -15,10 +15,10 @@ On top of that, now people can add component-speciic procs/vars if they want!
airs = new(device_type)
..()
- for(DEVICE_TYPE_LOOP)
+ for(var/i in 1 to device_type)
var/datum/gas_mixture/A = new
A.volume = 200
- AIR_I = A
+ airs[i] = A
/*
Iconnery
*/
@@ -42,9 +42,9 @@ Iconnery
var/connected = 0 //Direction bitset
- for(DEVICE_TYPE_LOOP) //adds intact pieces
- if(NODE_I)
- connected |= icon_addintact(NODE_I)
+ for(var/i in 1 to device_type) //adds intact pieces
+ if(nodes[i])
+ connected |= icon_addintact(nodes[i])
icon_addbroken(connected) //adds broken pieces
@@ -53,52 +53,45 @@ Iconnery
Pipenet stuff; housekeeping
*/
-/obj/machinery/atmospherics/components/nullifyNode(I)
+/obj/machinery/atmospherics/components/nullifyNode(i)
..()
- if(NODE_I)
- nullifyPipenet(PARENT_I)
- qdel(AIR_I)
- AIR_I = null
+ if(nodes[i])
+ nullifyPipenet(parents[i])
+ QDEL_NULL(airs[i])
/obj/machinery/atmospherics/components/on_construction()
..()
update_parents()
/obj/machinery/atmospherics/components/build_network()
- for(DEVICE_TYPE_LOOP)
- if(!PARENT_I)
- PARENT_I = new /datum/pipeline()
- var/datum/pipeline/P = PARENT_I
+ for(var/i in 1 to device_type)
+ if(!parents[i])
+ parents[i] = new /datum/pipeline()
+ var/datum/pipeline/P = parents[i]
P.build_pipeline(src)
/obj/machinery/atmospherics/components/proc/nullifyPipenet(datum/pipeline/reference)
- var/I = parents.Find(reference)
- reference.other_airs -= AIR_I
+ var/i = parents.Find(reference)
+ reference.other_airs -= airs[i]
reference.other_atmosmch -= src
- PARENT_I = null
+ parents[i] = null
/obj/machinery/atmospherics/components/returnPipenetAir(datum/pipeline/reference)
- var/I = parents.Find(reference)
- return AIR_I
+ return airs[parents.Find(reference)]
/obj/machinery/atmospherics/components/pipeline_expansion(datum/pipeline/reference)
if(reference)
- var/I = parents.Find(reference)
- return list(NODE_I)
- else
- return ..()
+ return list(nodes[parents.Find(reference)])
+ return ..()
/obj/machinery/atmospherics/components/setPipenet(datum/pipeline/reference, obj/machinery/atmospherics/A)
- var/I = nodes.Find(A)
- PARENT_I = reference
+ parents[nodes.Find(A)] = reference
-/obj/machinery/atmospherics/components/returnPipenet(obj/machinery/atmospherics/A = NODE1) //returns PARENT1 if called without argument
- var/I = nodes.Find(A)
- return PARENT_I
+/obj/machinery/atmospherics/components/returnPipenet(obj/machinery/atmospherics/A = nodes[1]) //returns parents[1] if called without argument
+ return parents[nodes.Find(A)]
/obj/machinery/atmospherics/components/replacePipenet(datum/pipeline/Old, datum/pipeline/New)
- var/I = parents.Find(Old)
- PARENT_I = New
+ parents[parents.Find(Old)] = New
/obj/machinery/atmospherics/components/unsafe_pressure_release(var/mob/user, var/pressures)
..()
@@ -109,15 +102,15 @@ Pipenet stuff; housekeeping
var/datum/gas_mixture/environment = T.return_air()
var/lost = null
var/times_lost = 0
- for(DEVICE_TYPE_LOOP)
- var/datum/gas_mixture/air = AIR_I
+ for(var/i in 1 to device_type)
+ var/datum/gas_mixture/air = airs[i]
lost += pressures*environment.volume/(air.temperature * R_IDEAL_GAS_EQUATION)
times_lost++
var/shared_loss = lost/times_lost
var/datum/gas_mixture/to_release
- for(DEVICE_TYPE_LOOP)
- var/datum/gas_mixture/air = AIR_I
+ for(var/i in 1 to device_type)
+ var/datum/gas_mixture/air = airs[i]
if(!to_release)
to_release = air.remove(shared_loss)
continue
@@ -136,8 +129,8 @@ Helpers
*/
/obj/machinery/atmospherics/components/proc/update_parents()
- for(DEVICE_TYPE_LOOP)
- var/datum/pipeline/parent = PARENT_I
+ for(var/i in 1 to device_type)
+ var/datum/pipeline/parent = parents[i]
if(!parent)
throw EXCEPTION("Component is missing a pipenet! Rebuilding...")
build_network()
@@ -145,8 +138,8 @@ Helpers
/obj/machinery/atmospherics/components/returnPipenets()
. = list()
- for(DEVICE_TYPE_LOOP)
- . += returnPipenet(NODE_I)
+ for(var/i in 1 to device_type)
+ . += returnPipenet(nodes[i])
/*
UI Stuff
@@ -157,4 +150,3 @@ UI Stuff
return ..()
to_chat(user, "Access denied.")
return UI_CLOSE
-
diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
index a1d6dc8c7e..20e93a220e 100644
--- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
+++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm
@@ -50,7 +50,7 @@
..()
/obj/machinery/atmospherics/components/trinary/filter/update_icon_nopipes()
- if(on && NODE1 && NODE2 && NODE3 && is_operational())
+ if(on && nodes[1] && nodes[2] && nodes[3] && is_operational())
icon_state = "filter_on[flipped?"_f":""]"
return
icon_state = "filter_off[flipped?"_f":""]"
@@ -63,12 +63,12 @@
/obj/machinery/atmospherics/components/trinary/filter/process_atmos()
..()
- if(!on || !(NODE1 && NODE2 && NODE3) || !is_operational())
+ if(!on || !(nodes[1] && nodes[2] && nodes[3]) || !is_operational())
return
- var/datum/gas_mixture/air1 = AIR1
- var/datum/gas_mixture/air2 = AIR2
- var/datum/gas_mixture/air3 = AIR3
+ var/datum/gas_mixture/air1 = airs[1]
+ var/datum/gas_mixture/air2 = airs[2]
+ var/datum/gas_mixture/air3 = airs[3]
var/output_starting_pressure = air3.return_pressure()
diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
index b15df59662..df50437b4f 100644
--- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
+++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm
@@ -33,7 +33,7 @@
return ..()
/obj/machinery/atmospherics/components/trinary/mixer/update_icon_nopipes()
- if(on && NODE1 && NODE2 && NODE3 && is_operational())
+ if(on && nodes[1] && nodes[2] && nodes[3] && is_operational())
icon_state = "mixer_on[flipped?"_f":""]"
return
icon_state = "mixer_off[flipped?"_f":""]"
@@ -46,18 +46,18 @@
/obj/machinery/atmospherics/components/trinary/mixer/New()
..()
- var/datum/gas_mixture/air3 = AIR3
+ var/datum/gas_mixture/air3 = airs[3]
air3.volume = 300
- AIR3 = air3
+ airs[3] = air3
/obj/machinery/atmospherics/components/trinary/mixer/process_atmos()
..()
- if(!on || !(NODE1 && NODE2 && NODE3) && !is_operational())
+ if(!on || !(nodes[1] && nodes[2] && nodes[3]) && !is_operational())
return
- var/datum/gas_mixture/air1 = AIR1
- var/datum/gas_mixture/air2 = AIR2
- var/datum/gas_mixture/air3 = AIR3
+ var/datum/gas_mixture/air1 = airs[1]
+ var/datum/gas_mixture/air2 = airs[2]
+ var/datum/gas_mixture/air3 = airs[3]
var/output_starting_pressure = air3.return_pressure()
@@ -103,14 +103,14 @@
air3.merge(removed2)
if(transfer_moles1)
- var/datum/pipeline/parent1 = PARENT1
+ var/datum/pipeline/parent1 = parents[1]
parent1.update = TRUE
if(transfer_moles2)
- var/datum/pipeline/parent2 = PARENT2
+ var/datum/pipeline/parent2 = parents[2]
parent2.update = TRUE
- var/datum/pipeline/parent3 = PARENT3
+ var/datum/pipeline/parent3 = parents[3]
parent3.update = TRUE
return
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
index a7123dd97b..87d6387b99 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
@@ -174,7 +174,7 @@
open_machine()
return
- var/datum/gas_mixture/air1 = AIR1
+ var/datum/gas_mixture/air1 = airs[1]
if(air1.gases.len)
if(mob_occupant.bodytemperature < T0C) // Sleepytime. Why? More cryo magic.
@@ -196,9 +196,9 @@
if(!on)
return
- var/datum/gas_mixture/air1 = AIR1
+ var/datum/gas_mixture/air1 = airs[1]
- if(!NODE1 || !AIR1 || !air1.gases.len || air1.gases[/datum/gas/oxygen][MOLES] < 5) // Turn off if the machine won't work.
+ if(!nodes[1] || !airs[1] || !air1.gases.len || air1.gases[/datum/gas/oxygen][MOLES] < 5) // Turn off if the machine won't work.
on = FALSE
update_icon()
return
@@ -348,8 +348,7 @@
else
data["occupant"]["temperaturestatus"] = "bad"
-
- var/datum/gas_mixture/air1 = AIR1
+ var/datum/gas_mixture/air1 = airs[1]
data["cellTemperature"] = round(air1.temperature, 1)
data["isBeakerLoaded"] = beaker ? TRUE : FALSE
@@ -401,7 +400,7 @@
return 0 // you can't see the pipe network when inside a cryo cell.
/obj/machinery/atmospherics/components/unary/cryo_cell/return_temperature()
- var/datum/gas_mixture/G = AIR1
+ var/datum/gas_mixture/G = airs[1]
if(G.total_moles() > 10)
return G.temperature
@@ -411,13 +410,13 @@
. = ..()
if(.)
SetInitDirections()
- var/obj/machinery/atmospherics/node = NODE1
+ var/obj/machinery/atmospherics/node = nodes[1]
if(node)
node.disconnect(src)
- NODE1 = null
- nullifyPipenet(PARENT1)
+ nodes[1] = null
+ nullifyPipenet(parents[1])
atmosinit()
- node = NODE1
+ node = nodes[1]
if(node)
node.atmosinit()
node.addMember(src)
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/heat_exchanger.dm b/code/modules/atmospherics/machinery/components/unary_devices/heat_exchanger.dm
index c8daf29ad3..bd81d5c876 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/heat_exchanger.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/heat_exchanger.dm
@@ -15,9 +15,9 @@
pipe_state = "heunary"
/obj/machinery/atmospherics/components/unary/heat_exchanger/update_icon()
- if(NODE1)
+ if(nodes[1])
icon_state = "he_intact"
- var/obj/machinery/atmospherics/node = NODE1
+ var/obj/machinery/atmospherics/node = nodes[1]
add_atom_colour(node.color, FIXED_COLOUR_PRIORITY)
else
icon_state = "he_exposed"
@@ -42,8 +42,8 @@
update_cycle = SSair.times_fired
partner.update_cycle = SSair.times_fired
- var/datum/gas_mixture/air_contents = AIR1
- var/datum/gas_mixture/partner_air_contents = partner.AIR1
+ var/datum/gas_mixture/air_contents = airs[1]
+ var/datum/gas_mixture/partner_air_contents = partner.airs[1]
var/air_heat_capacity = air_contents.heat_capacity()
var/other_air_heat_capacity = partner_air_contents.heat_capacity()
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm
index 64e6e56504..9759de92f5 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm
@@ -32,7 +32,7 @@
if(showpipe)
add_overlay(getpipeimage(icon, "inje_cap", initialize_directions))
- if(!NODE1 || !on || !is_operational())
+ if(!nodes[1] || !on || !is_operational())
icon_state = "inje_off"
return
@@ -53,7 +53,7 @@
if(!on || !is_operational())
return
- var/datum/gas_mixture/air_contents = AIR1
+ var/datum/gas_mixture/air_contents = airs[1]
if(air_contents.temperature > 0)
var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.temperature * R_IDEAL_GAS_EQUATION)
@@ -70,7 +70,7 @@
if(on || injecting || !is_operational())
return
- var/datum/gas_mixture/air_contents = AIR1
+ var/datum/gas_mixture/air_contents = airs[1]
injecting = 1
@@ -130,7 +130,7 @@
if("set_volume_rate" in signal.data)
var/number = text2num(signal.data["set_volume_rate"])
- var/datum/gas_mixture/air_contents = AIR1
+ var/datum/gas_mixture/air_contents = airs[1]
volume_rate = CLAMP(number, 0, air_contents.volume)
if("status" in signal.data)
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm b/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm
index 051f3136ee..871aaeea13 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm
@@ -13,7 +13,7 @@
/obj/machinery/atmospherics/components/unary/portables_connector/New()
..()
- var/datum/gas_mixture/air_contents = AIR1
+ var/datum/gas_mixture/air_contents = airs[1]
air_contents.volume = 0
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm
index 4e9df101a6..b12eb59442 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/tank.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/tank.dm
@@ -13,7 +13,7 @@
/obj/machinery/atmospherics/components/unary/tank/New()
..()
- var/datum/gas_mixture/air_contents = AIR1
+ var/datum/gas_mixture/air_contents = airs[1]
air_contents.volume = volume
air_contents.temperature = T20C
if(gas_type)
@@ -43,7 +43,7 @@
/obj/machinery/atmospherics/components/unary/tank/air/New()
..()
- var/datum/gas_mixture/air_contents = AIR1
+ var/datum/gas_mixture/air_contents = airs[1]
air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrogen)
air_contents.gases[/datum/gas/oxygen][MOLES] = AIR_CONTENTS * 0.2
air_contents.gases[/datum/gas/nitrogen][MOLES] = AIR_CONTENTS * 0.8
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm
index 8d34d5adfa..f52483f1ae 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm
@@ -48,9 +48,9 @@
/obj/machinery/atmospherics/components/unary/thermomachine/process_atmos()
..()
- if(!on || !NODE1)
+ if(!on || !nodes[1])
return
- var/datum/gas_mixture/air_contents = AIR1
+ var/datum/gas_mixture/air_contents = airs[1]
var/air_heat_capacity = air_contents.heat_capacity()
var/combined_heat_capacity = heat_capacity + air_heat_capacity
@@ -88,14 +88,14 @@
if(!..())
return 0
SetInitDirections()
- var/obj/machinery/atmospherics/node = NODE1
+ var/obj/machinery/atmospherics/node = nodes[1]
if(node)
node.disconnect(src)
- NODE1 = null
- nullifyPipenet(PARENT1)
+ nodes[1] = null
+ nullifyPipenet(parents[1])
atmosinit()
- node = NODE1
+ node = nodes[1]
if(node)
node.atmosinit()
node.addMember(src)
@@ -123,7 +123,7 @@
data["target"] = target_temperature
data["initial"] = initial(target_temperature)
- var/datum/gas_mixture/air1 = AIR1
+ var/datum/gas_mixture/air1 = airs[1]
data["temperature"] = air1.temperature
data["pressure"] = air1.return_pressure()
return data
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm
index 2c9a308ec9..f9a87ace42 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm
@@ -81,7 +81,7 @@
/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/New()
..()
- var/datum/gas_mixture/air_contents = AIR1
+ var/datum/gas_mixture/air_contents = airs[1]
air_contents.volume = 1000
/obj/machinery/atmospherics/components/unary/vent_pump/update_icon_nopipes()
@@ -93,7 +93,7 @@
icon_state = "vent_welded"
return
- if(!NODE1 || !on || !is_operational())
+ if(!nodes[1] || !on || !is_operational())
if(icon_state == "vent_welded")
icon_state = "vent_off"
return
@@ -122,12 +122,12 @@
..()
if(!is_operational())
return
- if(!NODE1)
+ if(!nodes[1])
on = FALSE
if(!on || welded)
return
- var/datum/gas_mixture/air_contents = AIR1
+ var/datum/gas_mixture/air_contents = airs[1]
var/datum/gas_mixture/environment = loc.return_air()
var/environment_pressure = environment.return_pressure()
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
index f886f2ed2b..b882d21c98 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
@@ -77,7 +77,7 @@
icon_state = "scrub_welded"
return
- if(!NODE1 || !on || !is_operational())
+ if(!nodes[1] || !on || !is_operational())
icon_state = "scrub_off"
return
@@ -142,7 +142,7 @@
..()
if(welded || !is_operational())
return FALSE
- if(!NODE1 || !on)
+ if(!nodes[1] || !on)
on = FALSE
return FALSE
scrub(loc)
@@ -156,7 +156,7 @@
return FALSE
var/datum/gas_mixture/environment = tile.return_air()
- var/datum/gas_mixture/air_contents = AIR1
+ var/datum/gas_mixture/air_contents = airs[1]
var/list/env_gases = environment.gases
if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE)
diff --git a/code/modules/atmospherics/machinery/datum_pipeline.dm b/code/modules/atmospherics/machinery/datum_pipeline.dm
index ad7fdb921a..9191916d10 100644
--- a/code/modules/atmospherics/machinery/datum_pipeline.dm
+++ b/code/modules/atmospherics/machinery/datum_pipeline.dm
@@ -216,8 +216,8 @@
GL += P.return_air()
for(var/obj/machinery/atmospherics/components/binary/valve/V in P.other_atmosmch)
if(V.open)
- PL |= V.PARENT1
- PL |= V.PARENT2
+ PL |= V.parents[1]
+ PL |= V.parents[2]
for(var/obj/machinery/atmospherics/components/unary/portables_connector/C in P.other_atmosmch)
if(C.connected_device)
GL += C.portableConnectorReturnAir()
diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm
index e4df82073b..bfabe4e955 100644
--- a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm
+++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm
@@ -32,9 +32,9 @@
cut_overlays()
//Add non-broken pieces
- for(DEVICE_TYPE_LOOP)
- if(NODE_I)
- add_overlay(getpipeimage('icons/obj/atmospherics/pipes/heat.dmi', "manifold_intact[invis]", get_dir(src, NODE_I)))
+ for(var/i in 1 to device_type)
+ if(nodes[i])
+ add_overlay(getpipeimage('icons/obj/atmospherics/pipes/heat.dmi', "manifold_intact[invis]", get_dir(src, nodes[i])))
//4-way manifold
/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w
@@ -61,6 +61,6 @@
cut_overlays()
//Add non-broken pieces
- for(DEVICE_TYPE_LOOP)
- if(NODE_I)
- add_overlay(getpipeimage('icons/obj/atmospherics/pipes/heat.dmi', "manifold_intact[invis]", get_dir(src, NODE_I)))
+ for(var/i in 1 to device_type)
+ if(nodes[i])
+ add_overlay(getpipeimage('icons/obj/atmospherics/pipes/heat.dmi', "manifold_intact[invis]", get_dir(src, nodes[i])))
diff --git a/code/modules/atmospherics/machinery/pipes/layermanifold.dm b/code/modules/atmospherics/machinery/pipes/layermanifold.dm
index d2f85c7667..b193a7a8bc 100644
--- a/code/modules/atmospherics/machinery/pipes/layermanifold.dm
+++ b/code/modules/atmospherics/machinery/pipes/layermanifold.dm
@@ -107,14 +107,14 @@
P.destroy_network()
while(reference in get_all_connected_nodes())
if(reference in nodes)
- var/I = nodes.Find(reference)
- NODE_I = null
+ var/i = nodes.Find(reference)
+ nodes[i] = null
if(reference in front_nodes)
- var/I = front_nodes.Find(reference)
- front_nodes[I] = null
+ var/i = front_nodes.Find(reference)
+ front_nodes[i] = null
if(reference in back_nodes)
- var/I = back_nodes.Find(reference)
- back_nodes[I] = null
+ var/i = back_nodes.Find(reference)
+ back_nodes[i] = null
update_icon()
/obj/machinery/atmospherics/pipe/layer_manifold/relaymove(mob/living/user, dir)
diff --git a/code/modules/atmospherics/machinery/pipes/manifold.dm b/code/modules/atmospherics/machinery/pipes/manifold.dm
index 8560addc3a..ff4a4ea1ff 100644
--- a/code/modules/atmospherics/machinery/pipes/manifold.dm
+++ b/code/modules/atmospherics/machinery/pipes/manifold.dm
@@ -35,9 +35,9 @@
cut_overlays()
//Add non-broken pieces
- for(DEVICE_TYPE_LOOP)
- if(NODE_I)
- add_overlay(getpipeimage('icons/obj/atmospherics/pipes/manifold.dmi', "manifold_full[invis]", get_dir(src, NODE_I)))
+ for(var/i in 1 to device_type)
+ if(nodes[i])
+ add_overlay(getpipeimage('icons/obj/atmospherics/pipes/manifold.dmi', "manifold_full[invis]", get_dir(src, nodes[i])))
//Colored pipes, use these for mapping
/obj/machinery/atmospherics/pipe/manifold/general
diff --git a/code/modules/atmospherics/machinery/pipes/manifold4w.dm b/code/modules/atmospherics/machinery/pipes/manifold4w.dm
index f368c6bb0f..f9692da4ab 100644
--- a/code/modules/atmospherics/machinery/pipes/manifold4w.dm
+++ b/code/modules/atmospherics/machinery/pipes/manifold4w.dm
@@ -26,9 +26,9 @@
cut_overlays()
//Add non-broken pieces
- for(DEVICE_TYPE_LOOP)
- if(NODE_I)
- add_overlay(getpipeimage('icons/obj/atmospherics/pipes/manifold.dmi', "manifold_full[invis]", get_dir(src, NODE_I)))
+ for(var/i in 1 to device_type)
+ if(nodes[i])
+ add_overlay(getpipeimage('icons/obj/atmospherics/pipes/manifold.dmi', "manifold_full[invis]", get_dir(src, nodes[i])))
//Colored pipes, use these for mapping
/obj/machinery/atmospherics/pipe/manifold4w/general
diff --git a/code/modules/atmospherics/machinery/pipes/pipes.dm b/code/modules/atmospherics/machinery/pipes/pipes.dm
index cc01e6c4bd..8f6b3976bf 100644
--- a/code/modules/atmospherics/machinery/pipes/pipes.dm
+++ b/code/modules/atmospherics/machinery/pipes/pipes.dm
@@ -18,8 +18,8 @@
volume = 35 * device_type
..()
-/obj/machinery/atmospherics/pipe/nullifyNode(I)
- var/obj/machinery/atmospherics/oldN = NODE_I
+/obj/machinery/atmospherics/pipe/nullifyNode(i)
+ var/obj/machinery/atmospherics/oldN = nodes[i]
..()
if(oldN)
oldN.build_network()
@@ -33,11 +33,11 @@
parent.build_pipeline(src)
/obj/machinery/atmospherics/pipe/update_icon() //overridden by manifolds
- if(NODE1&&NODE2)
+ if(nodes[1] && nodes[2])
icon_state = "intact[invisibility ? "-f" : "" ]"
else
- var/have_node1 = NODE1?1:0
- var/have_node2 = NODE2?1:0
+ var/have_node1 = nodes[1] ? TRUE : FALSE
+ var/have_node2 = nodes[2] ? TRUE : FALSE
icon_state = "exposed[have_node1][have_node2][invisibility ? "-f" : "" ]"
/obj/machinery/atmospherics/pipe/atmosinit()
@@ -91,9 +91,9 @@
QDEL_NULL(parent)
/obj/machinery/atmospherics/pipe/proc/update_node_icon()
- for(DEVICE_TYPE_LOOP)
- if(NODE_I)
- var/obj/machinery/atmospherics/N = NODE_I
+ for(var/i in 1 to device_type)
+ if(nodes[i])
+ var/obj/machinery/atmospherics/N = nodes[i]
N.update_icon()
/obj/machinery/atmospherics/pipe/returnPipenets()
@@ -109,4 +109,3 @@
pipe_color = paint_color
update_node_icon()
return TRUE
-
diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm
index 7b6351e939..08b20f07bb 100644
--- a/code/modules/atmospherics/machinery/portable/canister.dm
+++ b/code/modules/atmospherics/machinery/portable/canister.dm
@@ -324,13 +324,13 @@
valve_open = !valve_open
timing = FALSE
if(!valve_open)
- pump.AIR1 = null
- pump.AIR2 = null
+ pump.airs[1] = null
+ pump.airs[2] = null
return
var/turf/T = get_turf(src)
- pump.AIR1 = air_contents
- pump.AIR2 = holding ? holding.air_contents : T.return_air()
+ pump.airs[1] = air_contents
+ pump.airs[2] = holding ? holding.air_contents : T.return_air()
pump.target_pressure = release_pressure
pump.process_atmos() // Pump gas.
diff --git a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm
index 590297820e..58846dc839 100644
--- a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm
+++ b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm
@@ -54,7 +54,7 @@
//Perform the connection
connected_port = new_port
connected_port.connected_device = src
- var/datum/pipeline/connected_port_parent = connected_port.PARENT1
+ var/datum/pipeline/connected_port_parent = connected_port.parents[1]
connected_port_parent.reconcile_air()
anchored = TRUE //Prevent movement
diff --git a/code/modules/atmospherics/machinery/portable/pump.dm b/code/modules/atmospherics/machinery/portable/pump.dm
index 36dd30731e..e94492ad2d 100644
--- a/code/modules/atmospherics/machinery/portable/pump.dm
+++ b/code/modules/atmospherics/machinery/portable/pump.dm
@@ -41,17 +41,17 @@
/obj/machinery/portable_atmospherics/pump/process_atmos()
..()
if(!on)
- pump.AIR1 = null
- pump.AIR2 = null
+ pump.airs[1] = null
+ pump.airs[2] = null
return
var/turf/T = get_turf(src)
if(direction == PUMP_OUT) // Hook up the internal pump.
- pump.AIR1 = holding ? holding.air_contents : air_contents
- pump.AIR2 = holding ? air_contents : T.return_air()
+ pump.airs[1] = holding ? holding.air_contents : air_contents
+ pump.airs[2] = holding ? air_contents : T.return_air()
else
- pump.AIR1 = holding ? air_contents : T.return_air()
- pump.AIR2 = holding ? holding.air_contents : air_contents
+ pump.airs[1] = holding ? air_contents : T.return_air()
+ pump.airs[2] = holding ? holding.air_contents : air_contents
pump.process_atmos() // Pump gas.
if(!holding)
diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm
index 7dca5d9b3e..0bfb212e29 100644
--- a/code/modules/clothing/glasses/_glasses.dm
+++ b/code/modules/clothing/glasses/_glasses.dm
@@ -11,7 +11,7 @@
materials = list(MAT_GLASS = 250)
var/vision_flags = 0
var/darkness_view = 2//Base human is 2
- var/invis_view = SEE_INVISIBLE_LIVING
+ var/invis_view = SEE_INVISIBLE_LIVING //admin only for now
var/invis_override = 0 //Override to allow glasses to set higher than normal see_invis
var/lighting_alpha
var/list/icon/current = list() //the current hud icons
@@ -261,7 +261,7 @@
icon_state = "thermal"
item_state = "glasses"
vision_flags = SEE_MOBS
- invis_view = 2
+ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
flash_protect = 0
glass_colour_type = /datum/client_colour/glass_colour/red
diff --git a/code/modules/clothing/glasses/engine_goggles.dm b/code/modules/clothing/glasses/engine_goggles.dm
index 78718c897c..a54ced0cbc 100644
--- a/code/modules/clothing/glasses/engine_goggles.dm
+++ b/code/modules/clothing/glasses/engine_goggles.dm
@@ -60,7 +60,7 @@
/obj/item/clothing/glasses/meson/engine/process()
if(mode == MODE_MESON)
var/turf/T = get_turf(src)
- if(T && T.z == ZLEVEL_MINING)
+ if(T && is_mining_level(T.z))
toggle_mode(loc)
return
diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm
index 877a3bb458..4d59a893ea 100644
--- a/code/modules/clothing/glasses/hud.dm
+++ b/code/modules/clothing/glasses/hud.dm
@@ -174,7 +174,7 @@
icon_state = "thermal"
hud_type = DATA_HUD_SECURITY_ADVANCED
vision_flags = SEE_MOBS
- invis_view = 2
+ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
glass_colour_type = /datum/client_colour/glass_colour/red
/obj/item/clothing/glasses/hud/toggle/thermal/attack_self(mob/user)
diff --git a/code/modules/clothing/gloves/_gloves.dm b/code/modules/clothing/gloves/_gloves.dm
index c230b14295..39767234e5 100644
--- a/code/modules/clothing/gloves/_gloves.dm
+++ b/code/modules/clothing/gloves/_gloves.dm
@@ -11,13 +11,21 @@
strip_delay = 20
equip_delay_other = 40
+/obj/item/clothing/gloves/ComponentInitialize()
+ . = ..()
+ AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT), CALLBACK(src, .proc/clean_blood))
+
+/obj/item/clothing/gloves/proc/clean_blood(strength)
+ if(strength < CLEAN_STRENGTH_BLOOD)
+ return
+ transfer_blood = 0
/obj/item/clothing/gloves/worn_overlays(isinhands = FALSE)
. = list()
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedgloves")
- if(blood_DNA)
+ IF_HAS_BLOOD_DNA(src)
. += mutable_appearance('icons/effects/blood.dmi', "bloodyhands")
/obj/item/clothing/gloves/update_clothes_damaged_state(damaging = TRUE)
diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm
index a9cb528f2e..86d4c3466c 100644
--- a/code/modules/clothing/gloves/color.dm
+++ b/code/modules/clothing/gloves/color.dm
@@ -202,8 +202,14 @@
/obj/item/clothing/gloves/color/green = 1,
/obj/item/clothing/gloves/color/grey = 1,
/obj/item/clothing/gloves/color/light_brown = 1,
- /obj/item/clothing/gloves/color/brown = 1)
+ /obj/item/clothing/gloves/color/brown = 1,
+ /obj/item/clothing/gloves/color/white = 1,
+ /obj/item/clothing/gloves/color/rainbow = 1)
var/obj/item/clothing/gloves/color/selected = pick(gloves)
- new selected(loc)
+ if(ishuman(loc))
+ var/mob/living/carbon/human/H = loc
+ H.equip_to_slot_or_del(new selected(H), slot_gloves)
+ else
+ new selected(loc)
return INITIALIZE_HINT_QDEL
diff --git a/code/modules/clothing/head/_head.dm b/code/modules/clothing/head/_head.dm
index 8bc8f12dec..9ec6542cf5 100644
--- a/code/modules/clothing/head/_head.dm
+++ b/code/modules/clothing/head/_head.dm
@@ -20,7 +20,7 @@
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedhelmet")
- if(blood_DNA)
+ IF_HAS_BLOOD_DNA(src)
. += mutable_appearance('icons/effects/blood.dmi', "helmetblood")
/obj/item/clothing/head/update_clothes_damaged_state(damaging = TRUE)
diff --git a/code/modules/clothing/masks/_masks.dm b/code/modules/clothing/masks/_masks.dm
index eacfa3faea..562375e897 100644
--- a/code/modules/clothing/masks/_masks.dm
+++ b/code/modules/clothing/masks/_masks.dm
@@ -15,7 +15,7 @@
if(body_parts_covered & HEAD)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask")
- if(blood_DNA)
+ IF_HAS_BLOOD_DNA(src)
. += mutable_appearance('icons/effects/blood.dmi', "maskblood")
/obj/item/clothing/mask/update_clothes_damaged_state(damaging = TRUE)
diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm
index 2baaf91135..b0f2a18a5b 100644
--- a/code/modules/clothing/neck/_neck.dm
+++ b/code/modules/clothing/neck/_neck.dm
@@ -12,7 +12,7 @@
if(body_parts_covered & HEAD)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask")
- if(blood_DNA)
+ IF_HAS_BLOOD_DNA(src)
. += mutable_appearance('icons/effects/blood.dmi', "maskblood")
/obj/item/clothing/neck/tie
diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm
index d71827df95..d058e82a3a 100644
--- a/code/modules/clothing/shoes/_shoes.dm
+++ b/code/modules/clothing/shoes/_shoes.dm
@@ -15,12 +15,16 @@
var/offset = 0
var/equipped_before_drop = FALSE
+/obj/item/clothing/shoes/ComponentInitialize()
+ . = ..()
+ AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT), CALLBACK(src, .proc/clean_blood))
+
/obj/item/clothing/shoes/worn_overlays(isinhands = FALSE)
. = list()
if(!isinhands)
- var/bloody = 0
- if(blood_DNA)
- bloody = 1
+ var/bloody = FALSE
+ IF_HAS_BLOOD_DNA(src)
+ bloody = TRUE
else
bloody = bloody_shoes[BLOOD_STATE_HUMAN]
@@ -53,8 +57,9 @@
var/mob/M = loc
M.update_inv_shoes()
-/obj/item/clothing/shoes/clean_blood()
- ..()
+/obj/item/clothing/shoes/proc/clean_blood(strength)
+ if(strength < CLEAN_STRENGTH_BLOOD)
+ return
bloody_shoes = list(BLOOD_STATE_HUMAN = 0,BLOOD_STATE_XENO = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0)
blood_state = BLOOD_STATE_NOT_BLOODY
if(ismob(loc))
@@ -62,4 +67,4 @@
M.update_inv_shoes()
/obj/item/proc/negates_gravity()
- return 0
\ No newline at end of file
+ return FALSE
\ No newline at end of file
diff --git a/code/modules/clothing/suits/_suits.dm b/code/modules/clothing/suits/_suits.dm
index e934b77f38..a2707de58b 100644
--- a/code/modules/clothing/suits/_suits.dm
+++ b/code/modules/clothing/suits/_suits.dm
@@ -14,7 +14,7 @@
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damaged[blood_overlay_type]")
- if(blood_DNA)
+ IF_HAS_BLOOD_DNA(src)
. += mutable_appearance('icons/effects/blood.dmi', "[blood_overlay_type]blood")
var/mob/living/carbon/human/M = loc
if(ishuman(M) && M.w_uniform)
diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm
index 43da19896b..62fd5b5f5a 100644
--- a/code/modules/clothing/under/_under.dm
+++ b/code/modules/clothing/under/_under.dm
@@ -19,10 +19,9 @@
/obj/item/clothing/under/worn_overlays(isinhands = FALSE)
. = list()
if(!isinhands)
-
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damageduniform")
- if(blood_DNA)
+ IF_HAS_BLOOD_DNA(src)
. += mutable_appearance('icons/effects/blood.dmi', "uniformblood")
if(accessory_overlay)
. += accessory_overlay
diff --git a/code/modules/clothing/under/color.dm b/code/modules/clothing/under/color.dm
index 4ccfd44b17..3a12f00a05 100644
--- a/code/modules/clothing/under/color.dm
+++ b/code/modules/clothing/under/color.dm
@@ -7,7 +7,11 @@
/obj/item/clothing/under/color/random/Initialize()
..()
var/obj/item/clothing/under/color/C = pick(subtypesof(/obj/item/clothing/under/color) - /obj/item/clothing/under/color/random - /obj/item/clothing/under/color/grey/glorf - /obj/item/clothing/under/color/black/ghost)
- new C(loc)
+ if(ishuman(loc))
+ var/mob/living/carbon/human/H = loc
+ H.equip_to_slot_or_del(new C(H), slot_w_uniform) //or else you end up with naked assistants running around everywhere...
+ else
+ new C(loc)
return INITIALIZE_HINT_QDEL
/obj/item/clothing/under/color/black
diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm
index 899219c227..7686ba54ca 100644
--- a/code/modules/clothing/under/miscellaneous.dm
+++ b/code/modules/clothing/under/miscellaneous.dm
@@ -274,6 +274,7 @@
icon_state = "burial"
item_state = "burial"
item_color = "burial"
+ has_sensor = NO_SENSORS
/obj/item/clothing/under/skirt/black
name = "black skirt"
diff --git a/code/modules/detectivework/detective_work.dm b/code/modules/detectivework/detective_work.dm
index d2d633d103..5bf4ad27b8 100644
--- a/code/modules/detectivework/detective_work.dm
+++ b/code/modules/detectivework/detective_work.dm
@@ -1,119 +1,102 @@
-//CONTAINS: Suit fibers and Detective's Scanning Computer
-
-/atom/var/list/suit_fibers
-
-/atom/proc/add_fibers(mob/living/carbon/human/M)
- if(M.gloves && istype(M.gloves, /obj/item/clothing/))
- var/obj/item/clothing/gloves/G = M.gloves
- if(G.transfer_blood > 1) //bloodied gloves transfer blood to touched objects
- if(add_blood(G.blood_DNA)) //only reduces the bloodiness of our gloves if the item wasn't already bloody
- G.transfer_blood--
- else if(M.bloody_hands > 1)
- if(add_blood(M.blood_DNA))
- M.bloody_hands--
- if(!suit_fibers)
- suit_fibers = list()
- var/fibertext
- var/item_multiplier = isitem(src)?1.2:1
- if(M.wear_suit)
- fibertext = "Material from \a [M.wear_suit]."
- if(prob(10*item_multiplier) && !(fibertext in suit_fibers))
- suit_fibers += fibertext
- if(!(M.wear_suit.body_parts_covered & CHEST))
- if(M.w_uniform)
- fibertext = "Fibers from \a [M.w_uniform]."
- if(prob(12*item_multiplier) && !(fibertext in suit_fibers)) //Wearing a suit means less of the uniform exposed.
- suit_fibers += fibertext
- if(!(M.wear_suit.body_parts_covered & HANDS))
- if(M.gloves)
- fibertext = "Material from a pair of [M.gloves.name]."
- if(prob(20*item_multiplier) && !(fibertext in suit_fibers))
- suit_fibers += fibertext
- else if(M.w_uniform)
- fibertext = "Fibers from \a [M.w_uniform]."
- if(prob(15*item_multiplier) && !(fibertext in suit_fibers))
- // "Added fibertext: [fibertext]"
- suit_fibers += fibertext
- if(M.gloves)
- fibertext = "Material from a pair of [M.gloves.name]."
- if(prob(20*item_multiplier) && !(fibertext in suit_fibers))
- suit_fibers += "Material from a pair of [M.gloves.name]."
- else if(M.gloves)
- fibertext = "Material from a pair of [M.gloves.name]."
- if(prob(20*item_multiplier) && !(fibertext in suit_fibers))
- suit_fibers += "Material from a pair of [M.gloves.name]."
-
-
-/atom/proc/add_hiddenprint(mob/living/M)
- if(!M || !M.key)
- return
-
- if(!fingerprintshidden) //Add the list if it does not exist
- fingerprintshidden = list()
-
- var/hasgloves = ""
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- if(H.gloves)
- hasgloves = "(gloves)"
-
- var/current_time = time_stamp()
- if(!fingerprintshidden[M.key])
- fingerprintshidden[M.key] = "First: [M.real_name]\[[current_time]\][hasgloves]. Ckey: [M.ckey]"
- else
- var/laststamppos = findtext(fingerprintshidden[M.key], " Last: ")
- if(laststamppos)
- fingerprintshidden[M.key] = copytext(fingerprintshidden[M.key], 1, laststamppos)
- fingerprintshidden[M.key] += " Last: [M.real_name]\[[current_time]\][hasgloves]. Ckey: [M.ckey]"
-
- fingerprintslast = M.ckey
-
-
-//Set ignoregloves to add prints irrespective of the mob having gloves on.
-/atom/proc/add_fingerprint(mob/living/M, ignoregloves = 0)
- if(!M || !M.key)
- return
-
- add_hiddenprint(M)
-
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
-
- add_fibers(H)
-
- if(H.gloves) //Check if the gloves (if any) hide fingerprints
- var/obj/item/clothing/gloves/G = H.gloves
- if(G.transfer_prints)
- ignoregloves = 1
-
- if(!ignoregloves)
- H.gloves.add_fingerprint(H, 1) //ignoregloves = 1 to avoid infinite loop.
- return
-
- if(!fingerprints) //Add the list if it does not exist
- fingerprints = list()
- var/full_print = md5(H.dna.uni_identity)
- fingerprints[full_print] = full_print
-
-
-
-
-/atom/proc/transfer_fingerprints_to(atom/A)
-
- // Make sure everything are lists.
- if(!islist(A.fingerprints))
- A.fingerprints = list()
- if(!islist(A.fingerprintshidden))
- A.fingerprintshidden = list()
-
- if(!islist(fingerprints))
- fingerprints = list()
- if(!islist(fingerprintshidden))
- fingerprintshidden = list()
-
- // Transfer
- if(fingerprints)
- A.fingerprints |= fingerprints.Copy() //detective
- if(fingerprintshidden)
- A.fingerprintshidden |= fingerprintshidden.Copy() //admin
- A.fingerprintslast = fingerprintslast
+//CONTAINS: Suit fibers and Detective's Scanning Computer
+
+/atom/proc/return_fingerprints()
+ GET_COMPONENT(D, /datum/component/forensics)
+ if(D)
+ . = D.fingerprints
+
+/atom/proc/return_hiddenprints()
+ GET_COMPONENT(D, /datum/component/forensics)
+ if(D)
+ . = D.hiddenprints
+
+/atom/proc/return_blood_DNA()
+ GET_COMPONENT(D, /datum/component/forensics)
+ if(D)
+ . = D.blood_DNA
+
+/atom/proc/blood_DNA_length()
+ GET_COMPONENT(D, /datum/component/forensics)
+ if(D)
+ . = length(D.blood_DNA)
+
+/atom/proc/return_fibers()
+ GET_COMPONENT(D, /datum/component/forensics)
+ if(D)
+ . = D.fibers
+
+/atom/proc/add_fingerprint_list(list/fingerprints) //ASSOC LIST FINGERPRINT = FINGERPRINT
+ if(length(fingerprints))
+ . = AddComponent(/datum/component/forensics, fingerprints)
+
+//Set ignoregloves to add prints irrespective of the mob having gloves on.
+/atom/proc/add_fingerprint(mob/living/M, ignoregloves = FALSE)
+ var/datum/component/forensics/D = AddComponent(/datum/component/forensics)
+ . = D.add_fingerprint(M, ignoregloves)
+
+/atom/proc/add_fiber_list(list/fibertext) //ASSOC LIST FIBERTEXT = FIBERTEXT
+ if(length(fibertext))
+ . = AddComponent(/datum/component/forensics, null, null, null, fibertext)
+
+/atom/proc/add_fibers(mob/living/carbon/human/M)
+ var/old = 0
+ if(M.gloves && istype(M.gloves, /obj/item/clothing))
+ var/obj/item/clothing/gloves/G = M.gloves
+ old = length(G.return_blood_DNA())
+ if(G.transfer_blood > 1) //bloodied gloves transfer blood to touched objects
+ if(add_blood_DNA(G.return_blood_DNA()) && length(G.return_blood_DNA()) > old) //only reduces the bloodiness of our gloves if the item wasn't already bloody
+ G.transfer_blood--
+ else if(M.bloody_hands > 1)
+ old = length(M.return_blood_DNA())
+ if(add_blood_DNA(M.return_blood_DNA()) && length(M.return_blood_DNA()) > old)
+ M.bloody_hands--
+ var/datum/component/forensics/D = AddComponent(/datum/component/forensics)
+ . = D.add_fibers(M)
+
+/atom/proc/add_hiddenprint_list(list/hiddenprints) //NOTE: THIS IS FOR ADMINISTRATION FINGERPRINTS, YOU MUST CUSTOM SET THIS TO INCLUDE CKEY/REAL NAMES! CHECK FORENSICS.DM
+ if(length(hiddenprints))
+ . = AddComponent(/datum/component/forensics, null, hiddenprints)
+
+/atom/proc/add_hiddenprint(mob/living/M)
+ var/datum/component/forensics/D = AddComponent(/datum/component/forensics)
+ . = D.add_hiddenprint(M)
+
+/atom/proc/add_blood_DNA(list/dna) //ASSOC LIST DNA = BLOODTYPE
+ return FALSE
+
+/obj/add_blood_DNA(list/dna)
+ . = ..()
+ if(length(dna))
+ . = AddComponent(/datum/component/forensics, null, null, dna)
+
+/obj/item/clothing/gloves/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
+ . = ..()
+ transfer_blood = rand(2, 4)
+
+/turf/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
+ var/obj/effect/decal/cleanable/blood/splatter/B = locate() in src
+ if(!B)
+ B = new /obj/effect/decal/cleanable/blood/splatter(src, diseases)
+ B.add_blood_DNA(blood_dna) //give blood info to the blood decal.
+ return TRUE //we bloodied the floor
+
+/mob/living/carbon/human/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
+ if(wear_suit)
+ wear_suit.add_blood_DNA(blood_dna)
+ update_inv_wear_suit()
+ else if(w_uniform)
+ w_uniform.add_blood_DNA(blood_dna)
+ update_inv_w_uniform()
+ if(gloves)
+ var/obj/item/clothing/gloves/G = gloves
+ G.add_blood_DNA(blood_dna)
+ else if(length(blood_dna))
+ AddComponent(/datum/component/forensics, null, null, dna)
+ bloody_hands = rand(2, 4)
+ update_inv_gloves() //handles bloody hands overlays and updating
+ return TRUE
+
+/atom/proc/transfer_fingerprints_to(atom/A)
+ A.add_fingerprint_list(return_fingerprints())
+ A.add_hiddenprint_list(return_hiddenprints())
+ A.fingerprintslast = fingerprintslast
diff --git a/code/modules/detectivework/evidence.dm b/code/modules/detectivework/evidence.dm
index 1400fdbe0c..9c98677291 100644
--- a/code/modules/detectivework/evidence.dm
+++ b/code/modules/detectivework/evidence.dm
@@ -23,7 +23,7 @@
icon_state = initial(icon_state)
desc = initial(desc)
-/obj/item/evidencebag/proc/evidencebagEquip(obj/item/I, mob/user)
+/obj/item/evidencebag/proc/evidencebagEquip(obj/item/I, mob/user)
if(!istype(I) || I.anchored == 1)
return
diff --git a/code/modules/detectivework/footprints_and_rag.dm b/code/modules/detectivework/footprints_and_rag.dm
index 793805977c..66405258b9 100644
--- a/code/modules/detectivework/footprints_and_rag.dm
+++ b/code/modules/detectivework/footprints_and_rag.dm
@@ -46,6 +46,5 @@
user.visible_message("[user] starts to wipe down [A] with [src]!", "You start to wipe down [A] with [src]...")
if(do_after(user,30, target = A))
user.visible_message("[user] finishes wiping off the [A]!", "You finish wiping off the [A].")
- A.clean_blood()
- A.wash_cream()
+ A.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
return
diff --git a/code/modules/detectivework/scanner.dm b/code/modules/detectivework/scanner.dm
index 8cb27ea4f3..fa6c1f88cb 100644
--- a/code/modules/detectivework/scanner.dm
+++ b/code/modules/detectivework/scanner.dm
@@ -67,20 +67,14 @@
//Make our lists
var/list/fingerprints = list()
- var/list/blood = list()
- var/list/fibers = list()
+ var/list/blood = A.return_blood_DNA()
+ var/list/fibers = A.return_fibers()
var/list/reagents = list()
var/target_name = A.name
// Start gathering
- if(A.blood_DNA && A.blood_DNA.len)
- blood = A.blood_DNA.Copy()
-
- if(A.suit_fibers && A.suit_fibers.len)
- fibers = A.suit_fibers.Copy()
-
if(ishuman(A))
var/mob/living/carbon/human/H = A
@@ -89,8 +83,7 @@
else if(!ismob(A))
- if(A.fingerprints && A.fingerprints.len)
- fingerprints = A.fingerprints.Copy()
+ fingerprints = A.return_fingerprints()
// Only get reagents from non-mobs.
if(A.reagents && A.reagents.reagent_list.len)
@@ -104,6 +97,7 @@
if(R.data["blood_DNA"] && R.data["blood_type"])
var/blood_DNA = R.data["blood_DNA"]
var/blood_type = R.data["blood_type"]
+ LAZYINITLIST(blood)
blood[blood_DNA] = blood_type
// We gathered everything. Create a fork and slowly display the results to the holder of the scanner.
@@ -112,7 +106,7 @@
add_log("[worldtime2text()][get_timestamp()] - [target_name]", 0)
// Fingerprints
- if(fingerprints && fingerprints.len)
+ if(length(fingerprints))
sleep(30)
add_log("Prints:")
for(var/finger in fingerprints)
@@ -120,7 +114,7 @@
found_something = 1
// Blood
- if (blood && blood.len)
+ if (length(blood))
sleep(30)
add_log("Blood:")
found_something = 1
@@ -128,7 +122,7 @@
add_log("Type: [blood[B]] DNA: [B]")
//Fibers
- if(fibers && fibers.len)
+ if(length(fibers))
sleep(30)
add_log("Fibers:")
for(var/fiber in fibers)
@@ -136,7 +130,7 @@
found_something = 1
//Reagents
- if(reagents && reagents.len)
+ if(length(reagents))
sleep(30)
add_log("Reagents:")
for(var/R in reagents)
diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm
index 1a8a174bff..4eae2cd194 100644
--- a/code/modules/events/alien_infestation.dm
+++ b/code/modules/events/alien_infestation.dm
@@ -2,9 +2,8 @@
name = "Alien Infestation"
typepath = /datum/round_event/ghost_role/alien_infestation
weight = 5
- earliest_start = 24000 //40 min
- min_players = 20 //Avoid lowpop rounds
+ min_players = 10
max_occurrences = 1
/datum/round_event/ghost_role/alien_infestation
@@ -16,6 +15,7 @@
// 50% chance of being incremented by one
var/spawncount = 1
var/successSpawn = 0 //So we don't make a command report if nothing gets spawned.
+ fakeable = TRUE
/datum/round_event/ghost_role/alien_infestation/setup()
@@ -40,8 +40,8 @@
for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in GLOB.machines)
if(QDELETED(temp_vent))
continue
- if((temp_vent.loc.z in GLOB.station_z_levels) && !temp_vent.welded)
- var/datum/pipeline/temp_vent_parent = temp_vent.PARENT1
+ if(is_station_level(temp_vent.loc.z) && !temp_vent.welded)
+ var/datum/pipeline/temp_vent_parent = temp_vent.parents[1]
//Stops Aliens getting stuck in small networks.
//See: Security, Virology
if(temp_vent_parent.other_atmosmch.len > 20)
@@ -74,3 +74,4 @@
else
// Like how did we get here?
return FALSE
+
diff --git a/code/modules/events/brand_intelligence.dm b/code/modules/events/brand_intelligence.dm
index c2f98be8d5..68ec168a1e 100644
--- a/code/modules/events/brand_intelligence.dm
+++ b/code/modules/events/brand_intelligence.dm
@@ -32,7 +32,7 @@
/datum/round_event/brand_intelligence/start()
for(var/obj/machinery/vending/V in GLOB.machines)
- if(!(V.z in GLOB.station_z_levels))
+ if(!is_station_level(V.z))
continue
vendingMachines.Add(V)
if(!vendingMachines.len)
diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm
index c1cea8224e..a41b4bfdde 100644
--- a/code/modules/events/disease_outbreak.dm
+++ b/code/modules/events/disease_outbreak.dm
@@ -33,7 +33,7 @@
var/turf/T = get_turf(H)
if(!T)
continue
- if(T.z != ZLEVEL_STATION_PRIMARY)
+ if(!is_station_level(T.z))
continue
if(!H.client)
continue
diff --git a/code/modules/events/grid_check.dm b/code/modules/events/grid_check.dm
index 2ae44a5f84..8006d63b97 100644
--- a/code/modules/events/grid_check.dm
+++ b/code/modules/events/grid_check.dm
@@ -15,5 +15,5 @@
/datum/round_event/grid_check/start()
for(var/P in GLOB.apcs_list)
var/obj/machinery/power/apc/C = P
- if(C.cell && (C.z in GLOB.station_z_levels))
+ if(C.cell && is_station_level(C.z))
C.energy_fail(rand(30,120))
\ No newline at end of file
diff --git a/code/modules/events/pirates.dm b/code/modules/events/pirates.dm
index 56b40ab57d..fa0d5aadf8 100644
--- a/code/modules/events/pirates.dm
+++ b/code/modules/events/pirates.dm
@@ -100,7 +100,7 @@
/obj/machinery/shuttle_scrambler/process()
if(active)
- if(z in GLOB.station_z_levels)
+ if(is_station_level(z))
var/siphoned = min(SSshuttle.points,siphon_per_tick)
SSshuttle.points -= siphoned
credits_stored += siphoned
@@ -208,7 +208,7 @@
/obj/docking_port/mobile/pirate/initiate_docking(obj/docking_port/stationary/new_dock, movement_direction, force=FALSE)
. = ..()
- if(. == DOCKING_SUCCESS && new_dock.z != ZLEVEL_TRANSIT)
+ if(. == DOCKING_SUCCESS && !is_transit_level(new_dock.z))
engines_cooling = TRUE
addtimer(CALLBACK(src,.proc/reset_cooldown),engine_cooldown,TIMER_UNIQUE)
@@ -252,7 +252,7 @@
var/list/results = list()
for(var/atom/movable/AM in world)
if(is_type_in_typecache(AM,GLOB.pirate_loot_cache))
- if(AM.z in GLOB.station_z_levels)
+ if(is_station_level(AM.z))
if(get_area(AM) == get_area(src)) //Should this be variable ?
continue
results += AM
diff --git a/code/modules/events/sentience.dm b/code/modules/events/sentience.dm
index bd08743aaf..b9815bf7cf 100644
--- a/code/modules/events/sentience.dm
+++ b/code/modules/events/sentience.dm
@@ -30,7 +30,7 @@
var/list/potential = list()
for(var/mob/living/simple_animal/L in GLOB.alive_mob_list)
var/turf/T = get_turf(L)
- if(!(T.z in GLOB.station_z_levels))
+ if(!is_station_level(T.z))
continue
if(!(L in GLOB.player_list) && !L.mind)
potential += L
diff --git a/code/modules/events/spider_infestation.dm b/code/modules/events/spider_infestation.dm
index d09aff976d..34d3f8a870 100644
--- a/code/modules/events/spider_infestation.dm
+++ b/code/modules/events/spider_infestation.dm
@@ -22,8 +22,8 @@
/datum/round_event/spider_infestation/start()
var/list/vents = list()
for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in world)
- if((temp_vent.loc.z in GLOB.station_z_levels) && !temp_vent.welded)
- var/datum/pipeline/temp_vent_parent = temp_vent.PARENT1
+ if(is_station_level(temp_vent.loc.z) && !temp_vent.welded)
+ var/datum/pipeline/temp_vent_parent = temp_vent.parents[1]
if(temp_vent_parent.other_atmosmch.len > 20)
vents += temp_vent
@@ -35,3 +35,4 @@
spawn_atom_to_turf(spawn_type, vent, 1, FALSE)
vents -= vent
spawncount--
+
diff --git a/code/modules/events/vent_clog.dm b/code/modules/events/vent_clog.dm
index 4aec0f8fe1..ec55b35b02 100644
--- a/code/modules/events/vent_clog.dm
+++ b/code/modules/events/vent_clog.dm
@@ -19,8 +19,8 @@
/datum/round_event/vent_clog/setup()
endWhen = rand(25, 100)
for(var/obj/machinery/atmospherics/components/unary/vent_scrubber/temp_vent in GLOB.machines)
- if((temp_vent.loc.z in GLOB.station_z_levels) && !temp_vent.welded)
- var/datum/pipeline/temp_vent_parent = temp_vent.PARENT1
+ if(is_station_level(temp_vent.loc.z) && !temp_vent.welded)
+ var/datum/pipeline/temp_vent_parent = temp_vent.parents[1]
if(temp_vent_parent.other_atmosmch.len > 20)
vents += temp_vent
if(!vents.len)
@@ -47,3 +47,4 @@
while(cockroaches)
new /mob/living/simple_animal/cockroach(get_turf(vent))
cockroaches--
+
diff --git a/code/modules/events/wizard/curseditems.dm b/code/modules/events/wizard/curseditems.dm
index 00d8c3b829..7bf92ffb0c 100644
--- a/code/modules/events/wizard/curseditems.dm
+++ b/code/modules/events/wizard/curseditems.dm
@@ -38,7 +38,7 @@
ruins_wizard_loadout = 1
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
- if(ruins_spaceworthiness && !(H.z in GLOB.station_z_levels) || isspaceturf(H.loc) || isplasmaman(H))
+ if(ruins_spaceworthiness && !is_station_level(H.z) || isspaceturf(H.loc) || isplasmaman(H))
continue //#savetheminers
if(ruins_wizard_loadout && iswizard(H))
continue
diff --git a/code/modules/events/wizard/greentext.dm b/code/modules/events/wizard/greentext.dm
index 1cf4858ce7..9ac7d89191 100644
--- a/code/modules/events/wizard/greentext.dm
+++ b/code/modules/events/wizard/greentext.dm
@@ -58,7 +58,7 @@
..()
/obj/item/greentext/process()
- if(new_holder && new_holder.z == ZLEVEL_CENTCOM)//you're winner!
+ if(new_holder && is_centcom_level(new_holder.z))//you're winner!
to_chat(new_holder, "At last it feels like victory is assured!")
if(!(new_holder in SSticker.mode.traitors))
SSticker.mode.traitors += new_holder.mind
diff --git a/code/modules/events/wizard/petsplosion.dm b/code/modules/events/wizard/petsplosion.dm
index 3459c80318..1624d3af31 100644
--- a/code/modules/events/wizard/petsplosion.dm
+++ b/code/modules/events/wizard/petsplosion.dm
@@ -8,7 +8,7 @@
/datum/round_event_control/wizard/petsplosion/preRunEvent()
for(var/mob/living/simple_animal/F in GLOB.alive_mob_list)
- if(!ishostile(F) && (F.z in GLOB.station_z_levels))
+ if(!ishostile(F) && is_station_level(F.z))
mobs_to_dupe++
if(mobs_to_dupe > 100 || !mobs_to_dupe)
return EVENT_CANT_RUN
@@ -24,7 +24,7 @@
if(activeFor >= 30 * countdown) // 0 seconds : 2 animals | 30 seconds : 4 animals | 1 minute : 8 animals
countdown += 1
for(var/mob/living/simple_animal/F in GLOB.alive_mob_list) //If you cull the heard before the next replication, things will be easier for you
- if(!ishostile(F) && (F.z in GLOB.station_z_levels))
+ if(!ishostile(F) && is_station_level(F.z))
new F.type(F.loc)
mobs_duped++
if(mobs_duped > 400)
diff --git a/code/modules/events/wizard/shuffle.dm b/code/modules/events/wizard/shuffle.dm
index d622f10c97..18bde5eb07 100644
--- a/code/modules/events/wizard/shuffle.dm
+++ b/code/modules/events/wizard/shuffle.dm
@@ -13,7 +13,7 @@
var/list/mobs = list()
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
- if(!(H.z in GLOB.station_z_levels))
+ if(!is_station_level(H.z))
continue //lets not try to strand people in space or stuck in the wizards den
moblocs += H.loc
mobs += H
diff --git a/code/modules/events/wormholes.dm b/code/modules/events/wormholes.dm
index dbaa8a1c22..3a25df10d4 100644
--- a/code/modules/events/wormholes.dm
+++ b/code/modules/events/wormholes.dm
@@ -21,7 +21,7 @@
/datum/round_event/wormholes/start()
for(var/turf/open/floor/T in world)
- if(T.z in GLOB.station_z_levels)
+ if(is_station_level(T.z))
pick_turfs += T
for(var/i = 1, i <= number_of_wormholes, i++)
diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm
index 40eae1b570..301585c13a 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm
@@ -93,8 +93,8 @@ God bless America.
else if(default_deconstruction_screwdriver(user, "fryer_off", "fryer_off" ,I)) //where's the open maint panel icon?!
return
else
- if(is_type_in_typecache(I, deepfry_blacklisted_items))
- . = ..()
+ if(is_type_in_typecache(I, deepfry_blacklisted_items) || (I.flags_1 & (ABSTRACT_1 | NODROP_1 | DROPDEL_1)))
+ return ..()
else if(!frying && user.transferItemToLoc(I, src))
to_chat(user, "You put [I] into [src].")
frying = new/obj/item/reagent_containers/food/snacks/deepfryholder(src, I)
diff --git a/code/modules/integrated_electronics/core/printer.dm b/code/modules/integrated_electronics/core/printer.dm
index 15f76281ef..c5336094f1 100644
--- a/code/modules/integrated_electronics/core/printer.dm
+++ b/code/modules/integrated_electronics/core/printer.dm
@@ -101,6 +101,7 @@
return
if(..())
return TRUE
+ add_fingerprint(usr)
if(href_list["category"])
current_category = href_list["category"]
diff --git a/code/modules/mapping/mapping_helpers.dm b/code/modules/mapping/mapping_helpers.dm
index 13e2264b29..120a000f07 100644
--- a/code/modules/mapping/mapping_helpers.dm
+++ b/code/modules/mapping/mapping_helpers.dm
@@ -67,7 +67,6 @@ GLOBAL_LIST_EMPTY(z_is_planet)
/obj/effect/mapping_helpers/planet_z/Initialize()
. = ..()
var/turf/T = get_turf(src)
- if(!turf_z_is_planet(T))
- GLOB.z_is_planet["[T.z]"] = list()
+ GLOB.z_is_planet["[T.z]"] = TRUE
return INITIALIZE_HINT_QDEL
diff --git a/code/modules/mining/aux_base.dm b/code/modules/mining/aux_base.dm
index 6b364e63e7..c1d90ed0c0 100644
--- a/code/modules/mining/aux_base.dm
+++ b/code/modules/mining/aux_base.dm
@@ -37,7 +37,7 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
var/list/options = params2list(possible_destinations)
var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId)
- var/dat = "[(z in GLOB.station_z_levels) ? "Docking clamps engaged. Standing by." : "Mining Shuttle Uplink: [M ? M.getStatusText() : "*OFFLINE*"]"]
"
+ var/dat = "[is_station_level(z) ? "Docking clamps engaged. Standing by." : "Mining Shuttle Uplink: [M ? M.getStatusText() : "*OFFLINE*"]"]
"
if(M)
var/destination_found
for(var/obj/docking_port/stationary/S in SSshuttle.stationary)
@@ -47,7 +47,7 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
continue
destination_found = 1
dat += "Send to [S.name]
"
- if(!destination_found && (z in GLOB.station_z_levels)) //Only available if miners are lazy and did not set an LZ using the remote.
+ if(!destination_found && is_station_level(z)) //Only available if miners are lazy and did not set an LZ using the remote.
dat += "Prepare for blind drop? (Dangerous)
"
if(LAZYLEN(turrets))
dat += "
Perimeter Defense System: Enable All / Disable All
\
@@ -86,7 +86,7 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
return
if(href_list["move"])
- if(!(z in GLOB.station_z_levels) && shuttleId == "colony_drop")
+ if(!is_station_level(z) && shuttleId == "colony_drop")
to_chat(usr, "You can't move the base again!")
return
var/shuttle_error = SSshuttle.moveShuttle(shuttleId, href_list["move"], 1)
@@ -128,7 +128,7 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
updateUsrDialog()
/obj/machinery/computer/auxillary_base/proc/set_mining_mode()
- if(z == ZLEVEL_MINING) //The console switches to controlling the mining shuttle once landed.
+ if(is_mining_level(z)) //The console switches to controlling the mining shuttle once landed.
req_one_access = list()
shuttleId = "mining" //The base can only be dropped once, so this gives the console a new purpose.
possible_destinations = "mining_home;mining_away;landing_zone_dock;mining_public"
@@ -140,7 +140,13 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
to_chat(user, "This station is not equipped with an auxillary base. Please contact your Nanotrasen contractor.")
return
if(!no_restrictions)
- if(T.z != ZLEVEL_MINING)
+ var/static/list/disallowed_turf_types = typecacheof(list(
+ /turf/open/lava,
+ /turf/closed/indestructible,
+ /turf/open/indestructible,
+ ))
+
+ if(!is_mining_level(T.z))
return BAD_ZLEVEL
var/colony_radius = max(base_dock.width, base_dock.height)*0.5
if(T.x - colony_radius < 1 || T.x + colony_radius >= world.maxx || T.y - colony_radius < 1 || T.y + colony_radius >= world.maxx)
@@ -200,7 +206,7 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
var/obj/machinery/computer/auxillary_base/AB
for (var/obj/machinery/computer/auxillary_base/A in GLOB.machines)
- if(A.z in GLOB.station_z_levels)
+ if(is_station_level(A.z))
AB = A
break
if(!AB)
@@ -267,7 +273,7 @@ obj/docking_port/stationary/public_mining_dock
var/turf/landing_spot = get_turf(src)
- if(landing_spot.z != ZLEVEL_MINING)
+ if(!is_mining_level(landing_spot.z))
to_chat(user, "This device is only to be used in a mining zone.")
return
var/obj/machinery/computer/auxillary_base/aux_base_console
diff --git a/code/modules/mining/aux_base_camera.dm b/code/modules/mining/aux_base_camera.dm
index 4270b54b0a..dd8e98823b 100644
--- a/code/modules/mining/aux_base_camera.dm
+++ b/code/modules/mining/aux_base_camera.dm
@@ -151,7 +151,7 @@
to_chat(owner, "You can only build within the mining base!")
return FALSE
- if(!(build_target.z in GLOB.station_z_levels))
+ if(!is_station_level(build_target.z))
to_chat(owner, "The mining base has launched and can no longer be modified.")
return FALSE
diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm
index 4f4b16e6d3..573c3dab71 100644
--- a/code/modules/mining/equipment/survival_pod.dm
+++ b/code/modules/mining/equipment/survival_pod.dm
@@ -60,7 +60,7 @@
playsound(get_turf(src), 'sound/effects/phasein.ogg', 100, 1)
var/turf/T = deploy_location
- if(T.z != ZLEVEL_MINING && T.z != ZLEVEL_LAVALAND)//only report capsules away from the mining/lavaland level
+ if(!is_mining_level(T.z)) //only report capsules away from the mining/lavaland level
message_admins("[ADMIN_LOOKUPFLW(usr)] activated a bluespace capsule away from the mining level! [ADMIN_JMP(T)]")
log_admin("[key_name(usr)] activated a bluespace capsule away from the mining level at [get_area(T)][COORD(T)]")
template.load(deploy_location, centered = TRUE)
diff --git a/code/modules/mining/equipment/wormhole_jaunter.dm b/code/modules/mining/equipment/wormhole_jaunter.dm
index e69c8fa05d..f714e3f471 100644
--- a/code/modules/mining/equipment/wormhole_jaunter.dm
+++ b/code/modules/mining/equipment/wormhole_jaunter.dm
@@ -20,7 +20,7 @@
/obj/item/device/wormhole_jaunter/proc/turf_check(mob/user)
var/turf/device_turf = get_turf(user)
- if(!device_turf || device_turf.z == ZLEVEL_CENTCOM || device_turf.z == ZLEVEL_TRANSIT)
+ if(!device_turf || is_centcom_level(device_turf.z) || is_transit_level(device_turf.z))
to_chat(user, "You're having difficulties getting the [src.name] to work.")
return FALSE
return TRUE
@@ -40,7 +40,7 @@
for(var/obj/item/device/radio/beacon/B in GLOB.teleportbeacons)
var/turf/T = get_turf(B)
- if(T.z in GLOB.station_z_levels)
+ if(is_station_level(T.z))
destinations += B
return destinations
diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm
index c081ff4bb3..fe6cd8239d 100644
--- a/code/modules/mining/lavaland/necropolis_chests.dm
+++ b/code/modules/mining/lavaland/necropolis_chests.dm
@@ -586,7 +586,7 @@
to_chat(user, "You unfold the ladder. It extends much farther than you were expecting.")
var/last_ladder = null
for(var/i in 1 to world.maxz)
- if(i == ZLEVEL_CENTCOM || i == ZLEVEL_TRANSIT || i == ZLEVEL_CITYOFCOGS)
+ if(is_centcom_level(i) || is_transit_level(i) || is_reebe(i))
continue
var/turf/T2 = locate(ladder_x, ladder_y, i)
last_ladder = new /obj/structure/ladder/unbreakable/jacob(T2, null, last_ladder)
diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm
index e16eb0e5b2..fe94d88168 100644
--- a/code/modules/mining/machine_redemption.dm
+++ b/code/modules/mining/machine_redemption.dm
@@ -102,7 +102,7 @@
smelt_ore(ore)
/obj/machinery/mineral/ore_redemption/proc/send_console_message()
- if(!(z in GLOB.station_z_levels))
+ if(!is_station_level(z))
return
message_sent = TRUE
var/area/A = get_area(src)
@@ -257,9 +257,8 @@
if("Release")
if(check_access(inserted_id) || allowed(usr)) //Check the ID inside, otherwise check the user
- var/out = get_step(src, output_dir)
if(params["id"] == "all")
- materials.retrieve_all(out)
+ materials.retrieve_all(get_step(src, output_dir))
else
var/mat_id = params["id"]
if(!materials.materials[mat_id])
@@ -277,7 +276,7 @@
desired = input("How many sheets?", "How many sheets would you like to smelt?", 1) as null|num
var/sheets_to_remove = round(min(desired,50,stored_amount))
- materials.retrieve_sheets(sheets_to_remove, mat_id, out)
+ materials.retrieve_sheets(sheets_to_remove, mat_id, get_step(src, output_dir))
else
to_chat(usr, "Required access not found.")
diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm
index 8d36922bdf..6d1ba30277 100644
--- a/code/modules/mining/mine_items.dm
+++ b/code/modules/mining/mine_items.dm
@@ -76,7 +76,7 @@
req_access = list(ACCESS_MINING) // should slow the ashwalkers down.
/obj/machinery/computer/shuttle/mining/attack_hand(mob/user)
- if((user.z in GLOB.station_z_levels) && user.mind && is_head_revolutionary(user) && !(user.mind in dumb_rev_heads))
+ if(is_station_level(user.z) && user.mind && is_head_revolutionary(user) && !(user.mind in dumb_rev_heads))
to_chat(user, "You get a feeling that leaving the station might be a REALLY dumb idea...")
dumb_rev_heads += user.mind
return
diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm
index efb7887da2..6d0fc988c7 100644
--- a/code/modules/mob/living/blood.dm
+++ b/code/modules/mob/living/blood.dm
@@ -251,8 +251,7 @@
drop.transfer_mob_blood_dna(src)
return
else
- temp_blood_DNA = list()
- temp_blood_DNA |= drop.blood_DNA.Copy() //we transfer the dna from the drip to the splatter
+ temp_blood_DNA = drop.return_blood_DNA() //we transfer the dna from the drip to the splatter
qdel(drop)//the drip is replaced by a bigger splatter
else
drop = new(T, get_static_viruses())
@@ -265,7 +264,7 @@
B = new /obj/effect/decal/cleanable/blood/splatter(T, get_static_viruses())
B.transfer_mob_blood_dna(src) //give blood info to the blood decal.
if(temp_blood_DNA)
- B.blood_DNA |= temp_blood_DNA
+ B.add_blood_DNA(temp_blood_DNA)
/mob/living/carbon/human/add_splatter_floor(turf/T, small_drip)
if(!(NOBLOOD in dna.species.species_traits))
@@ -277,7 +276,7 @@
var/obj/effect/decal/cleanable/xenoblood/B = locate() in T.contents
if(!B)
B = new(T)
- B.blood_DNA["UNKNOWN DNA"] = "X*"
+ B.add_blood_DNA(list("UNKNOWN DNA" = "X*"))
/mob/living/silicon/robot/add_splatter_floor(turf/T, small_drip)
if(!T)
diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm
index 5ef14d5d09..99bb6d2250 100644
--- a/code/modules/mob/living/carbon/examine.dm
+++ b/code/modules/mob/living/carbon/examine.dm
@@ -11,21 +11,18 @@
if (handcuffed)
msg += "[t_He] [t_is] [icon2html(handcuffed, user)] handcuffed!\n"
if (head)
- msg += "[t_He] [t_is] wearing [icon2html(head, user)] \a [src.head] on [t_his] head. \n"
+ msg += "[t_He] [t_is] wearing [head.get_examine_string(user)] on [t_his] head. \n"
if (wear_mask)
- msg += "[t_He] [t_is] wearing [icon2html(wear_mask, user)] \a [src.wear_mask] on [t_his] face.\n"
+ msg += "[t_He] [t_is] wearing [wear_mask.get_examine_string(user)] on [t_his] face.\n"
if (wear_neck)
- msg += "[t_He] [t_is] wearing [icon2html(wear_neck, user)] \a [src.wear_neck] around [t_his] neck.\n"
+ msg += "[t_He] [t_is] wearing [wear_neck.get_examine_string(user)] around [t_his] neck.\n"
for(var/obj/item/I in held_items)
if(!(I.flags_1 & ABSTRACT_1))
- if(I.blood_DNA)
- msg += "[t_He] [t_is] holding [icon2html(I, user)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in [t_his] [get_held_index_name(get_held_index_of_item(I))]!\n"
- else
- msg += "[t_He] [t_is] holding [icon2html(I, user)] \a [I] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
+ msg += "[t_He] [t_is] holding [I.get_examine_string(user)] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
if (back)
- msg += "[t_He] [t_has] [icon2html(back, user)] \a [src.back] on [t_his] back.\n"
+ msg += "[t_He] [t_has] [back.get_examine_string(user)] on [t_his] back.\n"
var/appears_dead = 0
if (stat == DEAD)
appears_dead = 1
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index bc4fd83334..4a2ac98dbf 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -21,54 +21,30 @@
if(U.attached_accessory)
accessory_msg += " with [icon2html(U.attached_accessory, user)] \a [U.attached_accessory]"
- if(w_uniform.blood_DNA)
- msg += "[t_He] [t_is] wearing [icon2html(w_uniform, user)] [w_uniform.gender==PLURAL?"some":"a"] blood-stained [w_uniform.name][accessory_msg]!\n"
- else
- msg += "[t_He] [t_is] wearing [icon2html(w_uniform, user)] \a [w_uniform][accessory_msg].\n"
-
+ msg += "[t_He] [t_is] wearing [w_uniform.get_examine_string(user)][accessory_msg].\n"
//head
if(head)
- if(head.blood_DNA)
- msg += "[t_He] [t_is] wearing [icon2html(head, user)] [head.gender==PLURAL?"some":"a"] blood-stained [head.name] on [t_his] head!\n"
- else
- msg += "[t_He] [t_is] wearing [icon2html(head, user)] \a [head] on [t_his] head.\n"
-
+ msg += "[t_He] [t_is] wearing [head.get_examine_string(user)] on [t_his] head.\n"
//suit/armor
if(wear_suit)
- if(wear_suit.blood_DNA)
- msg += "[t_He] [t_is] wearing [icon2html(wear_suit, user)] [wear_suit.gender==PLURAL?"some":"a"] blood-stained [wear_suit.name]!\n"
- else
- msg += "[t_He] [t_is] wearing [icon2html(wear_suit, user)] \a [wear_suit].\n"
-
+ msg += "[t_He] [t_is] wearing [wear_suit.get_examine_string(user)].\n"
//suit/armor storage
if(s_store)
- if(s_store.blood_DNA)
- msg += "[t_He] [t_is] carrying [icon2html(s_store, user)] [s_store.gender==PLURAL?"some":"a"] blood-stained [s_store.name] on [t_his] [wear_suit.name]!\n"
- else
- msg += "[t_He] [t_is] carrying [icon2html(s_store, user)] \a [s_store] on [t_his] [wear_suit.name].\n"
-
+ msg += "[t_He] [t_is] carrying [s_store.get_examine_string(user)] on [t_his] [wear_suit.name].\n"
//back
if(back)
- if(back.blood_DNA)
- msg += "[t_He] [t_has] [icon2html(back, user)] [back.gender==PLURAL?"some":"a"] blood-stained [back] on [t_his] back.\n"
- else
- msg += "[t_He] [t_has] [icon2html(back, user)] \a [back] on [t_his] back.\n"
+ msg += "[t_He] [t_has] [back.get_examine_string(user)] on [t_his] back.\n"
//Hands
for(var/obj/item/I in held_items)
if(!(I.flags_1 & ABSTRACT_1))
- if(I.blood_DNA)
- msg += "[t_He] [t_is] holding [icon2html(I, user)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in [t_his] [get_held_index_name(get_held_index_of_item(I))]!\n"
- else
- msg += "[t_He] [t_is] holding [icon2html(I, user)] \a [I] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
+ msg += "[t_He] [t_is] holding [I.get_examine_string(user)] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
+ GET_COMPONENT(FR, /datum/component/forensics)
//gloves
if(gloves && !(slot_gloves in obscured))
- if(gloves.blood_DNA)
- msg += "[t_He] [t_has] [icon2html(gloves, user)] [gloves.gender==PLURAL?"some":"a"] blood-stained [gloves.name] on [t_his] hands!\n"
- else
- msg += "[t_He] [t_has] [icon2html(gloves, user)] \a [gloves] on [t_his] hands.\n"
- else if(blood_DNA)
+ msg += "[t_He] [t_has] [gloves.get_examine_string(user)] on [t_his] hands.\n"
+ else if(FR && length(FR.blood_DNA))
var/hand_number = get_num_arms()
if(hand_number)
msg += "[t_He] [t_has] [hand_number > 1 ? "" : "a"] blood-stained hand[hand_number > 1 ? "s" : ""]!\n"
@@ -84,42 +60,33 @@
//belt
if(belt)
- if(belt.blood_DNA)
- msg += "[t_He] [t_has] [icon2html(belt, user)] [belt.gender==PLURAL?"some":"a"] blood-stained [belt.name] about [t_his] waist!\n"
- else
- msg += "[t_He] [t_has] [icon2html(belt, user)] \a [belt] about [t_his] waist.\n"
+ msg += "[t_He] [t_has] [belt.get_examine_string(user)] about [t_his] waist.\n"
//shoes
if(shoes && !(slot_shoes in obscured))
- if(shoes.blood_DNA)
- msg += "[t_He] [t_is] wearing [icon2html(shoes, user)] [shoes.gender==PLURAL?"some":"a"] blood-stained [shoes.name] on [t_his] feet!\n"
- else
- msg += "[t_He] [t_is] wearing [icon2html(shoes, user)] \a [shoes] on [t_his] feet.\n"
+ msg += "[t_He] [t_is] wearing [shoes.get_examine_string(user)] on [t_his] feet.\n"
//mask
if(wear_mask && !(slot_wear_mask in obscured))
- if(wear_mask.blood_DNA)
- msg += "[t_He] [t_has] [icon2html(wear_mask, user)] [wear_mask.gender==PLURAL?"some":"a"] blood-stained [wear_mask.name] on [t_his] face!\n"
- else
- msg += "[t_He] [t_has] [icon2html(wear_mask, user)] \a [wear_mask] on [t_his] face.\n"
+ msg += "[t_He] [t_has] [wear_mask.get_examine_string(user)] on [t_his] face.\n"
if (wear_neck && !(slot_neck in obscured))
- msg += "[t_He] [t_is] wearing [icon2html(wear_neck, user)] \a [src.wear_neck] around [t_his] neck.\n"
+ msg += "[t_He] [t_is] wearing [wear_neck.get_examine_string(user)] around [t_his] neck.\n"
//eyes
if(glasses && !(slot_glasses in obscured))
- if(glasses.blood_DNA)
- msg += "[t_He] [t_has] [icon2html(glasses, user)] [glasses.gender==PLURAL?"some":"a"] blood-stained [glasses] covering [t_his] eyes!\n"
- else
- msg += "[t_He] [t_has] [icon2html(glasses, user)] \a [glasses] covering [t_his] eyes.\n"
+ msg += "[t_He] [t_has] [glasses.get_examine_string(user)] covering [t_his] eyes.\n"
//ears
if(ears && !(slot_ears in obscured))
- msg += "[t_He] [t_has] [icon2html(ears, user)] \a [ears] on [t_his] ears.\n"
+ msg += "[t_He] [t_has] [ears.get_examine_string(user)] on [t_his] ears.\n"
//ID
if(wear_id)
- msg += "[t_He] [t_is] wearing [icon2html(wear_id, user)] \a [wear_id].\n"
+ msg += "[t_He] [t_is] wearing [wear_id.get_examine_string(user)].\n"
+
+ //Status effects
+ msg += status_effect_examines()
//Jitters
switch(jitteriness)
@@ -354,3 +321,16 @@
msg += "*---------*"
to_chat(user, msg)
+
+/mob/living/proc/status_effect_examines(pronoun_replacement) //You can include this in any mob's examine() to show the examine texts of status effects!
+ var/list/dat = list()
+ if(!pronoun_replacement)
+ pronoun_replacement = p_they(TRUE)
+ for(var/V in status_effects)
+ var/datum/status_effect/E = V
+ if(E.examine_text)
+ var/new_text = replacetext(E.examine_text, "SUBJECTPRONOUN", pronoun_replacement)
+ new_text = replacetext(new_text, "[pronoun_replacement] is", "[pronoun_replacement] [p_are()]") //To make sure something become "They are" or "She is", not "They are" and "She are"
+ dat += "[new_text]\n" //dat.Join("\n") doesn't work here, for some reason
+ if(dat.len)
+ return dat.Join()
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index f0c630421d..926d8e2e77 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -25,6 +25,7 @@
create_internal_organs() //most of it is done in set_species now, this is only for parent call
handcrafting = new()
+ AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT), CALLBACK(src, .proc/clean_blood))
. = ..()
@@ -683,19 +684,18 @@
if(..())
dropItemToGround(I)
-/mob/living/carbon/human/clean_blood()
- var/mob/living/carbon/human/H = src
- if(H.gloves)
- if(H.gloves.clean_blood())
- H.update_inv_gloves()
+/mob/living/carbon/human/proc/clean_blood(strength)
+ if(strength < CLEAN_STRENGTH_BLOOD)
+ return
+ if(gloves)
+ if(gloves.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
+ update_inv_gloves()
else
- ..() // Clear the Blood_DNA list
- if(H.bloody_hands)
- H.bloody_hands = 0
- H.update_inv_gloves()
+ if(bloody_hands)
+ bloody_hands = 0
+ update_inv_gloves()
update_icons() //apply the now updated overlays to the mob
-
/mob/living/carbon/human/wash_cream()
if(creamed) //clean both to prevent a rare bug
cut_overlay(mutable_appearance('icons/effects/creampie.dmi', "creampie_lizard"))
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index c90d1a0231..9480445ceb 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -51,8 +51,7 @@
FP.blood_state = S.blood_state
FP.entered_dirs |= dir
FP.bloodiness = S.bloody_shoes[S.blood_state] - BLOOD_LOSS_IN_SPREAD
- if(S.blood_DNA && S.blood_DNA.len)
- FP.transfer_blood_dna(S.blood_DNA)
+ FP.add_blood_DNA(S.return_blood_DNA())
FP.update_icon()
update_inv_shoes()
//End bloody footprints
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index a84683c5ae..b9b89ce991 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -72,6 +72,10 @@
else if(eye_blurry) //blurry eyes heal slowly
adjust_blurriness(-1)
+ if(has_disability(DISABILITY_PACIFISM) && a_intent == INTENT_HARM)
+ to_chat(src, "You don't feel like harming anybody.")
+ a_intent_change(INTENT_HELP)
+
/mob/living/carbon/human/handle_mutations_and_radiation()
if(!dna || !dna.species.handle_mutations_and_radiation(src))
..()
@@ -422,7 +426,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
if(drunkenness >= 91)
adjustBrainLoss(0.4, 60)
if(prob(20) && !stat)
- if(SSshuttle.emergency.mode == SHUTTLE_DOCKED && (z in GLOB.station_z_levels)) //QoL mainly
+ if(SSshuttle.emergency.mode == SHUTTLE_DOCKED && is_station_level(z)) //QoL mainly
to_chat(src, "You're so tired... but you can't miss that shuttle...")
else
to_chat(src, "Just a quick nap...")
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 5684d8eb68..266afffed2 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -175,7 +175,8 @@ There are several things that need to be remembered:
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_gloves]
inv.update_icon()
- if(!gloves && blood_DNA)
+ GET_COMPONENT(FR, /datum/component/forensics)
+ if(!gloves && FR && length(FR.blood_DNA))
var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER)
if(get_num_arms() < 2)
if(has_left_hand())
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index b54dfb9c32..964e1feef0 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -774,9 +774,9 @@
var/turf/T = get_turf(src)
if(!T)
return 0
- if(T.z == ZLEVEL_CENTCOM) //dont detect mobs on centcom
+ if(is_centcom_level(T.z)) //dont detect mobs on centcom
return 0
- if(T.z >= ZLEVEL_SPACEMAX)
+ if(is_away_level(T.z))
return 0
if(user != null && src == user)
return 0
@@ -1058,6 +1058,13 @@
if (client)
if (new_z)
SSmobs.clients_by_zlevel[new_z] += src
+ for (var/I in length(SSidlenpcpool.idle_mobs_by_zlevel[new_z]) to 1 step -1) //Backwards loop because we're removing (guarantees optimal rather than worst-case performance), it's fine to use .len here but doesn't compile on 511
+ var/mob/living/simple_animal/SA = SSidlenpcpool.idle_mobs_by_zlevel[new_z][I]
+ if (SA)
+ SA.toggle_ai(AI_ON) // Guarantees responsiveness for when appearing right next to mobs
+ else
+ SSidlenpcpool.idle_mobs_by_zlevel[new_z] -= SA
+
registered_z = new_z
else
registered_z = null
diff --git a/code/modules/mob/living/silicon/robot/examine.dm b/code/modules/mob/living/silicon/robot/examine.dm
index 788a8f4255..3f5b12ae20 100644
--- a/code/modules/mob/living/silicon/robot/examine.dm
+++ b/code/modules/mob/living/silicon/robot/examine.dm
@@ -6,6 +6,7 @@
var/obj/act_module = get_active_held_item()
if(act_module)
msg += "It is holding [icon2html(act_module, user)] \a [act_module].\n"
+ msg += status_effect_examines()
msg += ""
if (src.getBruteLoss())
if (src.getBruteLoss() < maxHealth*0.5)
diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm
index 98d4557037..917211736b 100644
--- a/code/modules/mob/living/simple_animal/bot/mulebot.dm
+++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm
@@ -472,8 +472,7 @@
if(isturf(next))
if(bloodiness)
var/obj/effect/decal/cleanable/blood/tracks/B = new(loc)
- if(blood_DNA && blood_DNA.len)
- B.blood_DNA |= blood_DNA.Copy()
+ B.add_blood_DNA(return_blood_DNA())
var/newdir = get_dir(next, loc)
if(newdir == dir)
B.setDir(newdir)
@@ -655,8 +654,7 @@
T.add_mob_blood(H)
var/list/blood_dna = H.get_blood_dna_list()
- if(blood_dna)
- transfer_blood_dna(blood_dna)
+ add_blood_DNA(blood_dna)
bloodiness += 4
// player on mulebot attempted to move
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
index 5266f44e98..0f265bdb07 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
@@ -177,24 +177,15 @@
//Hands
for(var/obj/item/I in held_items)
if(!(I.flags_1 & ABSTRACT_1))
- if(I.blood_DNA)
- msg += "It has [icon2html(I, user)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in its [get_held_index_name(get_held_index_of_item(I))]!\n"
- else
- msg += "It has [icon2html(I, user)] \a [I] in its [get_held_index_name(get_held_index_of_item(I))].\n"
+ msg += "It has [I.get_examine_string(user)] in its [get_held_index_name(get_held_index_of_item(I))].\n"
//Internal storage
if(internal_storage && !(internal_storage.flags_1&ABSTRACT_1))
- if(internal_storage.blood_DNA)
- msg += "It is holding [icon2html(internal_storage, user)] [internal_storage.gender==PLURAL?"some":"a"] blood-stained [internal_storage.name] in its internal storage!\n"
- else
- msg += "It is holding [icon2html(internal_storage, user)] \a [internal_storage] in its internal storage.\n"
+ msg += "It is holding [internal_storage.get_examine_string(user)] in its internal storage.\n"
//Cosmetic hat - provides no function other than looks
if(head && !(head.flags_1&ABSTRACT_1))
- if(head.blood_DNA)
- msg += "It is wearing [icon2html(head, user)] [head.gender==PLURAL?"some":"a"] blood-stained [head.name] on its head!\n"
- else
- msg += "It is wearing [icon2html(head, user)] \a [head] on its head.\n"
+ msg += "It is wearing [head.get_examine_string(user)] on its head.\n"
//Braindead
if(!client && stat != DEAD)
diff --git a/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm b/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm
index 2f3ee4cefb..f36a30ccae 100644
--- a/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm
+++ b/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm
@@ -31,16 +31,9 @@
for(var/obj/item/I in held_items)
if(!(I.flags_1 & ABSTRACT_1))
- if(I.blood_DNA)
- msg += "It has [icon2html(I, user)] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in its [get_held_index_name(get_held_index_of_item(I))]!\n"
- else
- msg += "It has [icon2html(I, user)] \a [I] in its [get_held_index_name(get_held_index_of_item(I))].\n"
-
+ msg += "It has [I.get_examine_string(user)] in its [get_held_index_name(get_held_index_of_item(I))].\n"
if(internal_storage && !(internal_storage.flags_1&ABSTRACT_1))
- if(internal_storage.blood_DNA)
- msg += "It is holding [icon2html(internal_storage, user)] [internal_storage.gender==PLURAL?"some":"a"] blood-stained [internal_storage.name] in its internal storage!\n"
- else
- msg += "It is holding [icon2html(internal_storage, user)] \a [internal_storage] in its internal storage.\n"
+ msg += "It is holding [internal_storage.get_examine_string(user)] in its internal storage.\n"
msg += "*---------*"
to_chat(user, msg)
else
diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm
index 2651065b75..f9c9ae6ae4 100644
--- a/code/modules/mob/living/simple_animal/hostile/alien.dm
+++ b/code/modules/mob/living/simple_animal/hostile/alien.dm
@@ -173,6 +173,6 @@
qdel(target)
return TRUE
var/atom/movable/M = target
- M.clean_blood()
+ M.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
visible_message("[src] polishes \the [target].")
return TRUE
diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm
index 6432eb0484..78021deadf 100644
--- a/code/modules/mob/living/simple_animal/hostile/hostile.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm
@@ -28,9 +28,6 @@
var/ranged_message = "fires" //Fluff text for ranged mobs
var/ranged_cooldown = 0 //What the current cooldown on ranged attacks is, generally world.time + ranged_cooldown_time
var/ranged_cooldown_time = 30 //How long, in deciseconds, the cooldown of ranged attacks is
- var/ranged_telegraph = "prepares to fire at *TARGET*!" //A message shown when the mob prepares to fire; use *TARGET* if you want to show the target's name
- var/ranged_telegraph_sound //A sound played when the mob prepares to fire
- var/ranged_telegraph_time = 0 //In deciseconds, how long between the telegraph and ranged shot
var/ranged_ignores_vision = FALSE //if it'll fire ranged attacks even if it lacks vision on its target, only works with environment smash
var/check_friendly_fire = 0 // Should the ranged mob check for friendlies when shooting
var/retreat_distance = null //If our mob runs from players when they're too close, set in tile distance. By default, mobs do not retreat.
@@ -231,9 +228,6 @@
if(!target || !CanAttack(target))
LoseTarget()
return 0
- if(ismob(target.loc))
- LoseTarget()
- return 0
if(target in possible_targets)
var/turf/T = get_turf(src)
if(target.z != T.z)
@@ -242,14 +236,7 @@
var/target_distance = get_dist(targets_from,target)
if(ranged) //We ranged? Shoot at em
if(!target.Adjacent(targets_from) && ranged_cooldown <= world.time) //But make sure they're not in range for a melee attack and our range attack is off cooldown
- if(!ranged_telegraph_time || client)
- OpenFire(target)
- else
- if(ranged_telegraph)
- visible_message("[src] [replacetext(ranged_telegraph, "*TARGET*", "[target]")]")
- if(ranged_telegraph_sound)
- playsound(src, ranged_telegraph_sound, 75, FALSE)
- addtimer(CALLBACK(src, .proc/OpenFire, target), ranged_telegraph_time)
+ OpenFire(target)
if(!Process_Spacemove()) //Drifting
walk(src,0)
return 1
@@ -289,7 +276,7 @@
if(search_objects)//Turn off item searching and ignore whatever item we were looking at, we're more concerned with fight or flight
target = null
LoseSearchObjects()
- if(AIStatus == AI_IDLE)
+ if(AIStatus != AI_ON && AIStatus != AI_OFF)
toggle_ai(AI_ON)
FindTarget()
else if(target != null && prob(40))//No more pulling a mob forever and having a second player attack it, it can switch targets now if it finds a more suitable one
@@ -413,7 +400,6 @@ mob/living/simple_animal/hostile/proc/DestroySurroundings() // for use with mega
DestroyObjectsInDirection(dir)
-
/mob/living/simple_animal/hostile/proc/EscapeConfinement()
if(buckled)
buckled.attack_animal(src)
@@ -480,6 +466,32 @@ mob/living/simple_animal/hostile/proc/DestroySurroundings() // for use with mega
/mob/living/simple_animal/hostile/consider_wakeup()
..()
- if(AIStatus == AI_IDLE && FindTarget(ListTargets(), 1))
+ var/list/tlist
+ var/turf/T = get_turf(src)
+
+ if (!T)
+ return
+
+ if (!length(SSmobs.clients_by_zlevel[T.z])) // It's fine to use .len here but doesn't compile on 511
+ toggle_ai(AI_Z_OFF)
+ return
+
+ if (isturf(T) && !is_station_level(T.z))
+ tlist = ListTargetsLazy(T.z)
+ else
+ tlist = ListTargets()
+
+ if(AIStatus == AI_IDLE && FindTarget(tlist, 1))
toggle_ai(AI_ON)
+/mob/living/simple_animal/hostile/proc/ListTargetsLazy(var/_Z)//Step 1, find out what we can see
+ var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha, /obj/structure/destructible/clockwork/ocular_warden))
+ . = list()
+ for (var/I in SSmobs.clients_by_zlevel[_Z])
+ var/mob/M = I
+ if (get_dist(M, src) < vision_range)
+ if (isturf(M.loc))
+ . += M
+ else if (M.loc.type in hostile_machines)
+ . += M.loc
+
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
index 03f466ddfd..d7ec60466e 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm
@@ -114,7 +114,7 @@ Difficulty: Medium
if(L.stat == DEAD)
visible_message("[src] butchers [L]!",
"You butcher [L], restoring your health!")
- if(!(z in GLOB.station_z_levels && !client)) //NPC monsters won't heal while on station
+ if(!is_station_level(z) || client) //NPC monsters won't heal while on station
if(guidance)
adjustHealth(-L.maxHealth)
else
@@ -163,7 +163,7 @@ Difficulty: Medium
// do not take my touching of it to be endorsement of it. ~mso
/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/quick_attack_loop()
while(!QDELETED(target) && next_move <= world.time) //this is done this way because next_move can change to be sooner while we sleep.
- stoplag(1)
+ stoplag(1)
sleep((next_move - world.time) * 1.5) //but don't ask me what the fuck this is about
if(QDELETED(target))
return
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
index 5c95c2ec26..e34fc76467 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
@@ -105,7 +105,7 @@
visible_message(
"[src] devours [L]!",
"You feast on [L], restoring your health!")
- if(!(z in GLOB.station_z_levels && !client)) //NPC monsters won't heal while on station
+ if(!is_station_level(z) || client) //NPC monsters won't heal while on station
adjustBruteLoss(-L.maxHealth/2)
L.gib()
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm
index 7a3a85c35b..bc4686fd42 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm
@@ -14,9 +14,6 @@
ranged = 1
ranged_message = "stares"
ranged_cooldown_time = 30
- ranged_telegraph = "gathers energy and stares at *TARGET*!"
- ranged_telegraph_sound = 'sound/magic/magic_missile.ogg'
- ranged_telegraph_time = 7
throw_message = "does nothing against the hard shell of"
vision_range = 2
speed = 3
@@ -74,11 +71,9 @@
melee_damage_lower = 15
melee_damage_upper = 15
attacktext = "impales"
- ranged_telegraph = "fixates on *TARGET* as its eye shines blue!"
- ranged_telegraph_sound = 'sound/magic/tail_swing.ogg'
- ranged_telegraph_time = 5
a_intent = INTENT_HARM
speak_emote = list("telepathically cries")
+ attack_sound = 'sound/weapons/bladeslice.ogg'
stat_attack = UNCONSCIOUS
movement_type = FLYING
robust_searching = 1
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 4c5b94f2e3..9a0a21e826 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -82,14 +82,14 @@
var/dextrous_hud_type = /datum/hud/dextrous
var/datum/personal_crafting/handcrafting
- var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever)
+ var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever), AI_Z_OFF (Temporarily off due to nonpresence of players)
var/shouldwakeup = FALSE //convenience var for forcibly waking up an idling AI on next check.
//domestication
var/tame = 0
-
no_vore = TRUE
+ var/my_z // I don't want to confuse this with client registered_z
/mob/living/simple_animal/Initialize()
. = ..()
@@ -544,7 +544,13 @@
/mob/living/simple_animal/proc/toggle_ai(togglestatus)
if (AIStatus != togglestatus)
- if (togglestatus > 0 && togglestatus < 4)
+ if (togglestatus > 0 && togglestatus < 5)
+ if (togglestatus == AI_Z_OFF || AIStatus == AI_Z_OFF)
+ var/turf/T = get_turf(src)
+ if (AIStatus == AI_Z_OFF)
+ SSidlenpcpool.idle_mobs_by_zlevel[T.z] -= src
+ else
+ SSidlenpcpool.idle_mobs_by_zlevel[T.z] += src
GLOB.simple_animals[AIStatus] -= src
GLOB.simple_animals[togglestatus] += src
AIStatus = togglestatus
@@ -559,4 +565,11 @@
. = ..()
if(!ckey && !stat)//Not unconscious
if(AIStatus == AI_IDLE)
- toggle_ai(AI_ON)
\ No newline at end of file
+ toggle_ai(AI_ON)
+
+
+/mob/living/simple_animal/onTransitZ(old_z, new_z)
+ ..()
+ if (AIStatus == AI_Z_OFF)
+ SSidlenpcpool[old_z] -= src
+ toggle_ai(initial(AIStatus))
diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm
index 471e103c26..2d3ed3d669 100644
--- a/code/modules/mob/living/ventcrawling.dm
+++ b/code/modules/mob/living/ventcrawling.dm
@@ -45,7 +45,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list(
if(vent_found)
- var/datum/pipeline/vent_found_parent = vent_found.PARENT1
+ var/datum/pipeline/vent_found_parent = vent_found.parents[1]
if(vent_found_parent && (vent_found_parent.members.len || vent_found_parent.other_atmosmch))
visible_message("[src] begins climbing into the ventilation system..." ,"You begin climbing into the ventilation system...")
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index a818a01764..1bc7552c3f 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -254,24 +254,43 @@
return 0
+// reset_perspective(thing) set the eye to the thing (if it's equal to current default reset to mob perspective)
+// reset_perspective() set eye to common default : mob on turf, loc otherwise
/mob/proc/reset_perspective(atom/A)
if(client)
- if(ismovableatom(A))
- client.perspective = EYE_PERSPECTIVE
- client.eye = A
+ if(A)
+ if(ismovableatom(A))
+ //Set the the thing unless it's us
+ if(A != src)
+ client.perspective = EYE_PERSPECTIVE
+ client.eye = A
+ else
+ client.eye = client.mob
+ client.perspective = MOB_PERSPECTIVE
+ else if(isturf(A))
+ //Set to the turf unless it's our current turf
+ if(A != loc)
+ client.perspective = EYE_PERSPECTIVE
+ client.eye = A
+ else
+ client.eye = client.mob
+ client.perspective = MOB_PERSPECTIVE
+ else
+ //Do nothing
else
- if(isturf(loc) && (!A || loc == A))
+ //Reset to common defaults: mob if on turf, otherwise current loc
+ if(isturf(loc))
client.eye = client.mob
client.perspective = MOB_PERSPECTIVE
else
client.perspective = EYE_PERSPECTIVE
- client.eye = A
+ client.eye = loc
return 1
/mob/living/reset_perspective(atom/A)
if(..())
update_sight()
- if(client.eye != src)
+ if(client.eye && client.eye != src)
var/atom/AT = client.eye
AT.get_remote_view_fullscreens(src)
else
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index 42a1ce725f..c501984de8 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -468,11 +468,7 @@
qdel(src)
/mob/proc/become_overmind(starting_points = 60)
- var/turf/T = get_turf(loc) //just to avoid messing up in lockers
- var/area/A = get_area(T)
- if(((A && !A.blob_allowed) || !(T.z in GLOB.station_z_levels)) && LAZYLEN(GLOB.blobstart))
- T = get_turf(pick(GLOB.blobstart))
- var/mob/camera/blob/B = new /mob/camera/blob(T, starting_points)
+ var/mob/camera/blob/B = new /mob/camera/blob(get_turf(src), starting_points)
B.key = key
. = B
qdel(src)
diff --git a/code/modules/modular_computers/file_system/programs/alarm.dm b/code/modules/modular_computers/file_system/programs/alarm.dm
index 616fd15dd3..310a0a5054 100644
--- a/code/modules/modular_computers/file_system/programs/alarm.dm
+++ b/code/modules/modular_computers/file_system/programs/alarm.dm
@@ -13,7 +13,6 @@
var/has_alert = 0
var/alarms = list("Fire" = list(), "Atmosphere" = list(), "Power" = list())
- var/alarm_z = list(ZLEVEL_STATION_PRIMARY,ZLEVEL_LAVALAND)
/datum/computer_file/program/alarm_monitor/process_tick()
..()
@@ -41,7 +40,7 @@
return data
/datum/computer_file/program/alarm_monitor/proc/triggerAlarm(class, area/A, O, obj/source)
- if(!(source.z in alarm_z))
+ if(!is_station_level(source.z) && !is_mining_level(source.z))
return
var/list/L = alarms[class]
diff --git a/code/modules/modular_computers/file_system/programs/sm_monitor.dm b/code/modules/modular_computers/file_system/programs/sm_monitor.dm
index 2141f4fdd7..c2cbd5afec 100644
--- a/code/modules/modular_computers/file_system/programs/sm_monitor.dm
+++ b/code/modules/modular_computers/file_system/programs/sm_monitor.dm
@@ -43,7 +43,7 @@
return
for(var/obj/machinery/power/supermatter_shard/S in GLOB.machines)
// Delaminating, not within coverage, not on a tile.
- if(!((S.z in GLOB.station_z_levels) || S.z == ZLEVEL_MINING || S.z == T.z || !isturf(S.loc)))
+ if (!isturf(S.loc) || !(is_station_level(S.z) || is_mining_level(S.z) || S.z == T.z))
continue
supermatters.Add(S)
diff --git a/code/modules/modular_computers/hardware/network_card.dm b/code/modules/modular_computers/hardware/network_card.dm
index 216d55fbd8..da10800055 100644
--- a/code/modules/modular_computers/hardware/network_card.dm
+++ b/code/modules/modular_computers/hardware/network_card.dm
@@ -47,7 +47,7 @@
if(holder)
var/turf/T = get_turf(holder)
- if((T && istype(T)) && ((T.z in GLOB.station_z_levels) || T.z == ZLEVEL_MINING))
+ if((T && istype(T)) && (is_station_level(T.z) || is_mining_level(T.z)))
// Computer is on station. Low/High signal depending on what type of network card you have
if(long_range)
return 2
diff --git a/code/modules/ninja/suit/gloves.dm b/code/modules/ninja/suit/gloves.dm
index c49ca072e8..ef02a8a792 100644
--- a/code/modules/ninja/suit/gloves.dm
+++ b/code/modules/ninja/suit/gloves.dm
@@ -40,26 +40,26 @@
/obj/item/clothing/gloves/space_ninja/Touch(atom/A,proximity)
if(!candrain || draining)
- return 0
+ return FALSE
if(!ishuman(loc))
- return 0 //Only works while worn
+ return FALSE //Only works while worn
var/mob/living/carbon/human/H = loc
var/obj/item/clothing/suit/space/space_ninja/suit = H.wear_suit
if(!istype(suit))
- return 0
+ return FALSE
if(isturf(A))
- return 0
+ return FALSE
if(!proximity)
- return 0
+ return FALSE
A.add_fingerprint(H)
- draining = 1
+ draining = TRUE
. = A.ninjadrain_act(suit,H,src)
- draining = 0
+ draining = FALSE
if(isnum(.)) //Numerical values of drained handle their feedback here, Alpha values handle it themselves (Research hacking)
if(.)
@@ -67,7 +67,7 @@
else
to_chat(H, "\The [A] has run dry of energy, you must find another source!")
else
- . = 0 //as to not cancel attack_hand()
+ . = FALSE //as to not cancel attack_hand()
/obj/item/clothing/gloves/space_ninja/proc/toggledrain()
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index 548651f9c8..e8588a4634 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -941,7 +941,7 @@
if(!malf.can_shunt)
to_chat(malf, "You cannot shunt!")
return
- if(!(src.z in GLOB.station_z_levels))
+ if(!is_station_level(z))
return
occupier = new /mob/living/silicon/ai(src, malf.laws, malf) //DEAR GOD WHY? //IKR????
occupier.adjustOxyLoss(malf.getOxyLoss())
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index ca424cb80d..3ada84d601 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -665,7 +665,7 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai
NC.d1 = 0
NC.d2 = fdirn
- NC.add_fingerprint()
+ NC.add_fingerprint(user)
NC.update_icon()
//create a new powernet with the cable, if needed it will be merged later
@@ -716,7 +716,7 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai
//updates the stored cable coil
C.update_stored(2, item_color)
- C.add_fingerprint()
+ C.add_fingerprint(user)
C.update_icon()
diff --git a/code/modules/power/generator.dm b/code/modules/power/generator.dm
index 6a8c6ec5ec..4681eabe20 100644
--- a/code/modules/power/generator.dm
+++ b/code/modules/power/generator.dm
@@ -99,11 +99,11 @@
// update icon overlays only if displayed level has changed
if(hot_air)
- var/datum/gas_mixture/hot_circ_air1 = hot_circ.AIR1
+ var/datum/gas_mixture/hot_circ_air1 = hot_circ.airs[1]
hot_circ_air1.merge(hot_air)
if(cold_air)
- var/datum/gas_mixture/cold_circ_air1 = cold_circ.AIR1
+ var/datum/gas_mixture/cold_circ_air1 = cold_circ.airs[1]
cold_circ_air1.merge(cold_air)
update_icon()
@@ -134,10 +134,10 @@
if(!powernet)
t += "Unable to connect to the power network!"
else if(cold_circ && hot_circ)
- var/datum/gas_mixture/cold_circ_air1 = cold_circ.AIR1
- var/datum/gas_mixture/cold_circ_air2 = cold_circ.AIR2
- var/datum/gas_mixture/hot_circ_air1 = hot_circ.AIR1
- var/datum/gas_mixture/hot_circ_air2 = hot_circ.AIR2
+ var/datum/gas_mixture/cold_circ_air1 = cold_circ.airs[1]
+ var/datum/gas_mixture/cold_circ_air2 = cold_circ.airs[2]
+ var/datum/gas_mixture/hot_circ_air1 = hot_circ.airs[1]
+ var/datum/gas_mixture/hot_circ_air2 = hot_circ.airs[2]
t += "