From 7c0b21012f8147a8c06063fd6f40310edac93851 Mon Sep 17 00:00:00 2001 From: AnturK Date: Thu, 14 Dec 2017 08:38:46 +0100 Subject: [PATCH 001/122] Adds blob roundend report. (#33463) * Adds blob roundend report. (Also adminabuse) * Old comment * Grammer * Moves antag to seperate file --- code/datums/antagonists/blob.dm | 59 ++++++++++++++++++++++++++++ code/game/gamemodes/blob/overmind.dm | 29 ++++++++++++-- code/game/gamemodes/blob/powers.dm | 29 +++++++------- code/modules/mob/transform_procs.dm | 6 +-- tgstation.dme | 1 + 5 files changed, 102 insertions(+), 22 deletions(-) create mode 100644 code/datums/antagonists/blob.dm 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/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm index 4f26563da1..58787fa6dc 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 loc = 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 aa1a3e7046..9365a02d8b 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/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 534307f727..abe68d3700 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -472,11 +472,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/tgstation.dme b/tgstation.dme index 11399a1b14..ed39c1c5ac 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -322,6 +322,7 @@ #include "code\datums\actions\ninja.dm" #include "code\datums\antagonists\abductor.dm" #include "code\datums\antagonists\antag_datum.dm" +#include "code\datums\antagonists\blob.dm" #include "code\datums\antagonists\brother.dm" #include "code\datums\antagonists\changeling.dm" #include "code\datums\antagonists\clockcult.dm" From 75753a4dfd6ccfa4417f6ddcb197e33e2a90ca7d Mon Sep 17 00:00:00 2001 From: oranges Date: Sat, 16 Dec 2017 12:00:40 +1300 Subject: [PATCH 003/122] Defines all subsystem priority values --- code/__DEFINES/subsystems.dm | 34 ++++++++++++++ code/controllers/subsystem.dm | 2 +- code/controllers/subsystem/acid.dm | 2 +- code/controllers/subsystem/air.dm | 2 +- code/controllers/subsystem/fire_burning.dm | 2 +- code/controllers/subsystem/garbage.dm | 2 +- code/controllers/subsystem/icon_smooth.dm | 2 +- code/controllers/subsystem/idlenpcpool.dm | 2 +- code/controllers/subsystem/inbounds.dm | 2 +- code/controllers/subsystem/input.dm | 12 +++++ code/controllers/subsystem/mobs.dm | 2 +- code/controllers/subsystem/npcpool.dm | 2 +- code/controllers/subsystem/orbit.dm | 47 +++++++++++++++++++ code/controllers/subsystem/overlays.dm | 2 +- code/controllers/subsystem/parallax.dm | 2 +- .../subsystem/processing/fields.dm | 2 +- .../subsystem/processing/flightpacks.dm | 2 +- .../subsystem/processing/networks.dm | 39 +++++++++++++++ code/controllers/subsystem/processing/obj.dm | 2 +- .../subsystem/processing/processing.dm | 2 +- .../subsystem/processing/projectiles.dm | 1 - code/controllers/subsystem/radiation.dm | 1 - code/controllers/subsystem/research.dm | 2 +- code/controllers/subsystem/server_maint.dm | 2 +- code/controllers/subsystem/spacedrift.dm | 2 +- code/controllers/subsystem/tgui.dm | 2 +- code/controllers/subsystem/throwing.dm | 2 +- code/controllers/subsystem/ticker.dm | 2 +- 28 files changed, 154 insertions(+), 24 deletions(-) create mode 100644 code/controllers/subsystem/input.dm 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/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/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..0ad2becde6 100644 --- a/code/controllers/subsystem/idlenpcpool.dm +++ b/code/controllers/subsystem/idlenpcpool.dm @@ -1,7 +1,7 @@ SUBSYSTEM_DEF(idlenpcpool) name = "Idling NPC Pool" flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND - priority = 10 + priority = FIRE_PRIORITY_IDLE_NPC wait = 60 runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME 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 new file mode 100644 index 0000000000..f553d66307 --- /dev/null +++ b/code/controllers/subsystem/input.dm @@ -0,0 +1,12 @@ +SUBSYSTEM_DEF(input) + name = "Input" + wait = 1 //SS_TICKER means this runs every tick + flags = SS_TICKER | SS_NO_INIT + priority = FIRE_PRIORITY_INPUT + runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY + +/datum/controller/subsystem/input/fire() + var/list/clients = GLOB.clients // Let's sing the list cache song + for(var/i in 1 to clients.len) + var/client/C = clients[i] + C.keyLoop() 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..9567fb95a2 100644 --- a/code/controllers/subsystem/orbit.dm +++ b/code/controllers/subsystem/orbit.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD SUBSYSTEM_DEF(orbit) name = "Orbits" priority = 35 @@ -42,3 +43,49 @@ SUBSYSTEM_DEF(orbit) 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 + + +>>>>>>> 0244b61... Merge pull request #33537 from ninjanomnom/priority-defines 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 39d07ee676..f86e3f8ea7 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..05c7d17364 100644 --- a/code/controllers/subsystem/processing/networks.dm +++ b/code/controllers/subsystem/processing/networks.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD PROCESSING_SUBSYSTEM_DEF(networks) name = "Networks" priority = 80 @@ -34,3 +35,41 @@ PROCESSING_SUBSYSTEM_DEF(networks) /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 +>>>>>>> 0244b61... Merge pull request #33537 from ninjanomnom/priority-defines 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 d1bcf31885..06b5889e58 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/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 97d84a0d3b..87153fbe93 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 881bb7fcb7..d3ef05bdf8 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 From 14128362014d209b1224dd79fbaf73c1ed0f7fbd Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 17:51:20 -0600 Subject: [PATCH 004/122] Update orbit.dm --- code/controllers/subsystem/orbit.dm | 49 ----------------------------- 1 file changed, 49 deletions(-) diff --git a/code/controllers/subsystem/orbit.dm b/code/controllers/subsystem/orbit.dm index 9567fb95a2..581b7821b2 100644 --- a/code/controllers/subsystem/orbit.dm +++ b/code/controllers/subsystem/orbit.dm @@ -1,49 +1,3 @@ -<<<<<<< HEAD -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 @@ -86,6 +40,3 @@ SUBSYSTEM_DEF(orbit) O.Check(targetloc) if (MC_TICK_CHECK) return - - ->>>>>>> 0244b61... Merge pull request #33537 from ninjanomnom/priority-defines From 69930a192d94a87323d37ebc43e453da68f811ff Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 17:51:28 -0600 Subject: [PATCH 005/122] Update networks.dm --- .../subsystem/processing/networks.dm | 39 ------------------- 1 file changed, 39 deletions(-) diff --git a/code/controllers/subsystem/processing/networks.dm b/code/controllers/subsystem/processing/networks.dm index 05c7d17364..a3f01efd0c 100644 --- a/code/controllers/subsystem/processing/networks.dm +++ b/code/controllers/subsystem/processing/networks.dm @@ -1,41 +1,3 @@ -<<<<<<< HEAD -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 @@ -72,4 +34,3 @@ PROCESSING_SUBSYSTEM_DEF(networks) /datum/controller/subsystem/processing/networks/proc/unregister_interface(datum/component/ntnet_interface/D) interfaces_by_id -= D.hardware_id return TRUE ->>>>>>> 0244b61... Merge pull request #33537 from ninjanomnom/priority-defines From 8cbad06f3543e43607b72e17af7f5d98856643a8 Mon Sep 17 00:00:00 2001 From: vuonojenmustaturska Date: Mon, 18 Dec 2017 03:35:37 +0200 Subject: [PATCH 006/122] Advanced mob laziness --- code/__DEFINES/mobs.dm | 1 + code/_globalvars/lists/mobs.dm | 2 +- code/controllers/subsystem/idlenpcpool.dm | 16 +++++++++- code/modules/mob/living/living.dm | 7 +++++ .../living/simple_animal/hostile/hostile.dm | 29 +++++++++++++++++-- .../mob/living/simple_animal/simple_animal.dm | 23 +++++++++++++-- 6 files changed, 71 insertions(+), 7 deletions(-) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 49e3c996fe..1cc5f7021d 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/_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/controllers/subsystem/idlenpcpool.dm b/code/controllers/subsystem/idlenpcpool.dm index 49846e6c9d..18c3b3cf30 100644 --- a/code/controllers/subsystem/idlenpcpool.dm +++ b/code/controllers/subsystem/idlenpcpool.dm @@ -1,15 +1,26 @@ SUBSYSTEM_DEF(idlenpcpool) name = "Idling NPC Pool" +<<<<<<< HEAD flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND priority = 10 +======= + flags = SS_POST_FIRE_TIMING|SS_BACKGROUND + priority = FIRE_PRIORITY_IDLE_NPC +>>>>>>> d03e4ef... Advanced mob laziness (#33574) 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 +35,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) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index f589ecbb20..04c9fef63b 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1048,6 +1048,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/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 10d9fd93d7..f5e69dc7a0 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -288,7 +288,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 @@ -479,6 +479,31 @@ 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) && !(T.z in GLOB.station_z_levels)) + 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/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index a4851bb432..020e105d9a 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -82,14 +82,18 @@ 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 +<<<<<<< HEAD no_vore = TRUE +======= + var/my_z // I don't want to confuse this with client registered_z +>>>>>>> d03e4ef... Advanced mob laziness (#33574) /mob/living/simple_animal/Initialize() . = ..() @@ -544,7 +548,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 +569,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)) \ No newline at end of file From 2205500863c8023e82e14698518e2ec53b8d2d1c Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 18 Dec 2017 15:15:21 -0600 Subject: [PATCH 007/122] Update idlenpcpool.dm --- code/controllers/subsystem/idlenpcpool.dm | 5 ----- 1 file changed, 5 deletions(-) diff --git a/code/controllers/subsystem/idlenpcpool.dm b/code/controllers/subsystem/idlenpcpool.dm index 18c3b3cf30..a15237e5a7 100644 --- a/code/controllers/subsystem/idlenpcpool.dm +++ b/code/controllers/subsystem/idlenpcpool.dm @@ -1,12 +1,7 @@ SUBSYSTEM_DEF(idlenpcpool) name = "Idling NPC Pool" -<<<<<<< HEAD - flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND - priority = 10 -======= flags = SS_POST_FIRE_TIMING|SS_BACKGROUND priority = FIRE_PRIORITY_IDLE_NPC ->>>>>>> d03e4ef... Advanced mob laziness (#33574) wait = 60 runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME From 8fde63e016f8bc0d65288c7020b4fb64242758e9 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 18 Dec 2017 15:15:34 -0600 Subject: [PATCH 008/122] Update simple_animal.dm --- code/modules/mob/living/simple_animal/simple_animal.dm | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 020e105d9a..04735178d3 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -88,12 +88,8 @@ //domestication var/tame = 0 - -<<<<<<< HEAD no_vore = TRUE -======= var/my_z // I don't want to confuse this with client registered_z ->>>>>>> d03e4ef... Advanced mob laziness (#33574) /mob/living/simple_animal/Initialize() . = ..() @@ -576,4 +572,4 @@ ..() if (AIStatus == AI_Z_OFF) SSidlenpcpool[old_z] -= src - toggle_ai(initial(AIStatus)) \ No newline at end of file + toggle_ai(initial(AIStatus)) From 0f2fd05e87ffd5efe39a7e9d2fd73ea419d0e500 Mon Sep 17 00:00:00 2001 From: duncathan salt Date: Tue, 19 Dec 2017 08:02:54 -0600 Subject: [PATCH 009/122] removes silly garbage defines --- code/__DEFINES/atmospherics.dm | 28 +------- code/game/objects/effects/spiders.dm | 2 +- code/modules/admin/verbs/atmosdebug.dm | 4 +- .../atmospherics/machinery/atmosmachinery.dm | 27 ++++--- .../components/binary_devices/circulator.dm | 4 +- .../components/binary_devices/dp_vent_pump.dm | 12 ++-- .../components/binary_devices/passive_gate.dm | 4 +- .../components/binary_devices/pump.dm | 4 +- .../components/binary_devices/valve.dm | 2 +- .../components/binary_devices/volume_pump.dm | 9 ++- .../machinery/components/components_base.dm | 70 ++++++++----------- .../components/trinary_devices/filter.dm | 10 +-- .../components/trinary_devices/mixer.dm | 20 +++--- .../components/unary_devices/cryo.dm | 20 +++--- .../unary_devices/heat_exchanger.dm | 8 +-- .../unary_devices/outlet_injector.dm | 11 ++- .../unary_devices/portables_connector.dm | 2 +- .../components/unary_devices/tank.dm | 4 +- .../components/unary_devices/thermomachine.dm | 14 ++-- .../components/unary_devices/vent_pump.dm | 8 +-- .../components/unary_devices/vent_scrubber.dm | 6 +- .../atmospherics/machinery/datum_pipeline.dm | 4 +- .../machinery/pipes/heat_exchange/manifold.dm | 12 ++-- .../machinery/pipes/layermanifold.dm | 12 ++-- .../atmospherics/machinery/pipes/manifold.dm | 6 +- .../machinery/pipes/manifold4w.dm | 6 +- .../atmospherics/machinery/pipes/pipes.dm | 17 +++-- .../machinery/portable/canister.dm | 8 +-- .../portable/portable_atmospherics.dm | 2 +- .../atmospherics/machinery/portable/pump.dm | 12 ++-- code/modules/events/alien_infestation.dm | 2 +- code/modules/events/spider_infestation.dm | 2 +- code/modules/events/vent_clog.dm | 2 +- code/modules/mob/living/ventcrawling.dm | 2 +- code/modules/power/generator.dm | 12 ++-- code/modules/shuttle/on_move.dm | 10 +-- code/modules/shuttle/shuttle_rotate.dm | 12 ++-- 37 files changed, 184 insertions(+), 206 deletions(-) diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index dacd09c995..e52dfd8a24 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -123,38 +123,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/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/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/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 f8204947f1..db42819b87 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 86c5375d07..e5ae5c718e 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 97bba0e534..32933f9275 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 b154c0d3e4..d7b8073c87 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 @@ -151,8 +151,13 @@ Thus, the two variables affect pump operation are set in New(): on = !on if("set_transfer_rate" in signal.data) +<<<<<<< HEAD var/datum/gas_mixture/air1 = AIR1 transfer_rate = Clamp(text2num(signal.data["set_transfer_rate"]),0,air1.volume) +======= + var/datum/gas_mixture/air1 = airs[1] + transfer_rate = CLAMP(text2num(signal.data["set_transfer_rate"]),0,air1.volume) +>>>>>>> 6a7dbaa... removes silly garbage defines (#33621) if(on != old_on) investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS) 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 4baeb3dd3e..0579ef2357 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 b706cd3cd9..bdaadd0ff6 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..74c2302ee9 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,12 @@ else data["occupant"]["temperaturestatus"] = "bad" +<<<<<<< HEAD var/datum/gas_mixture/air1 = AIR1 +======= + var/datum/gas_mixture/air1 = airs[1] +>>>>>>> 6a7dbaa... removes silly garbage defines (#33621) data["cellTemperature"] = round(air1.temperature, 1) data["isBeakerLoaded"] = beaker ? TRUE : FALSE @@ -401,7 +405,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 +415,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 37bfb5d952..e458e2a3fa 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,8 +130,13 @@ if("set_volume_rate" in signal.data) var/number = text2num(signal.data["set_volume_rate"]) +<<<<<<< HEAD var/datum/gas_mixture/air_contents = AIR1 volume_rate = Clamp(number, 0, air_contents.volume) +======= + var/datum/gas_mixture/air_contents = airs[1] + volume_rate = CLAMP(number, 0, air_contents.volume) +>>>>>>> 6a7dbaa... removes silly garbage defines (#33621) if("status" in signal.data) spawn(2) 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 ec1fcdfc52..cf93f94390 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 fa336c7a34..23cf9bad1d 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 a05a13217d..de4199a52a 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 b3ade6f0fb..8d1c28a928 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 fee00baf50..de8b411fc6 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 585b6e896a..21393fd321 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 db153d60a4..59e74d3215 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/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm index 1a8a174bff..b453e96198 100644 --- a/code/modules/events/alien_infestation.dm +++ b/code/modules/events/alien_infestation.dm @@ -41,7 +41,7 @@ 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 + 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) diff --git a/code/modules/events/spider_infestation.dm b/code/modules/events/spider_infestation.dm index d09aff976d..046208b5ac 100644 --- a/code/modules/events/spider_infestation.dm +++ b/code/modules/events/spider_infestation.dm @@ -23,7 +23,7 @@ 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 + 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/modules/events/vent_clog.dm b/code/modules/events/vent_clog.dm index 4aec0f8fe1..65bafaf401 100644 --- a/code/modules/events/vent_clog.dm +++ b/code/modules/events/vent_clog.dm @@ -20,7 +20,7 @@ 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 + var/datum/pipeline/temp_vent_parent = temp_vent.parents[1] if(temp_vent_parent.other_atmosmch.len > 20) vents += temp_vent if(!vents.len) 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/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 += "
" diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index c7a77f9457..332acb6816 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -209,9 +209,9 @@ All ShuttleMove procs go here /obj/machinery/atmospherics/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() var/missing_nodes = FALSE - for(DEVICE_TYPE_LOOP) - if(src.nodes[I]) - var/obj/machinery/atmospherics/node = src.nodes[I] + for(var/i in 1 to device_type) + if(nodes[i]) + var/obj/machinery/atmospherics/node = nodes[i] var/connected = FALSE for(var/D in GLOB.cardinals) if(node in get_step(src, D)) @@ -219,9 +219,9 @@ All ShuttleMove procs go here break if(!connected) - nullifyNode(I) + nullifyNode(i) - if(!src.nodes[I]) + if(!nodes[i]) missing_nodes = TRUE if(missing_nodes) diff --git a/code/modules/shuttle/shuttle_rotate.dm b/code/modules/shuttle/shuttle_rotate.dm index 49c7396dba..caf849ca3f 100644 --- a/code/modules/shuttle/shuttle_rotate.dm +++ b/code/modules/shuttle/shuttle_rotate.dm @@ -84,17 +84,17 @@ If ever any of these procs are useful for non-shuttles, rename it to proc/rotate /obj/machinery/atmospherics/shuttleRotate(rotation, params) var/list/real_node_connect = getNodeConnects() - for(DEVICE_TYPE_LOOP) - real_node_connect[I] = angle2dir(rotation+dir2angle(real_node_connect[I])) + for(var/i in 1 to device_type) + real_node_connect[i] = angle2dir(rotation+dir2angle(real_node_connect[i])) . = ..() SetInitDirections() var/list/supposed_node_connect = getNodeConnects() var/list/nodes_copy = nodes.Copy() - for(DEVICE_TYPE_LOOP) - var/new_pos = supposed_node_connect.Find(real_node_connect[I]) - nodes[new_pos] = nodes_copy[I] + for(var/i in 1 to device_type) + var/new_pos = supposed_node_connect.Find(real_node_connect[i]) + nodes[new_pos] = nodes_copy[i] //prevents shuttles attempting to rotate this since it messes up sprites /obj/machinery/gateway/shuttleRotate(rotation, params) @@ -104,4 +104,4 @@ If ever any of these procs are useful for non-shuttles, rename it to proc/rotate //prevents shuttles attempting to rotate this since it messes up sprites /obj/machinery/gravity_generator/shuttleRotate(rotation, params) params = NONE - return ..() \ No newline at end of file + return ..() From a912e1491267525981985b483719b13c89653a79 Mon Sep 17 00:00:00 2001 From: AnturK Date: Thu, 21 Dec 2017 14:13:11 +0100 Subject: [PATCH 010/122] Makes newscaster feedback messages and comments always a list. --- code/__HELPERS/roundend.dm | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 3b346f7e1c..e20be6332f 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -63,6 +63,35 @@ antag_info["objectives"] += list(list("objective_type"=O.type,"text"=O.explanation_text,"result"=result)) SSblackbox.record_feedback("associative", "antagonists", 1, antag_info) +<<<<<<< HEAD +======= +/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 + 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" = 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 + file_data["[pos]"]["messages"]["comments"] += list(list("author" = "[comment.author]", "time stamp" = "[comment.time_stamp]", "body" = "[comment.body]")) + 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)) +>>>>>>> e940102... Makes newscaster feedback messages and comments always a list. (#33682) /datum/controller/subsystem/ticker/proc/declare_completion() set waitfor = FALSE From e2ba458400517efcc408947aa3dbbb89af86a9cd Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 24 Dec 2017 02:40:05 -0600 Subject: [PATCH 011/122] Update roundend.dm --- code/__HELPERS/roundend.dm | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index e20be6332f..0482bb668e 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -62,9 +62,7 @@ var/result = O.check_completion() ? "SUCCESS" : "FAIL" antag_info["objectives"] += list(list("objective_type"=O.type,"text"=O.explanation_text,"result"=result)) SSblackbox.record_feedback("associative", "antagonists", 1, antag_info) - -<<<<<<< HEAD -======= + /datum/controller/subsystem/ticker/proc/gather_newscaster() var/json_file = file("[GLOB.log_directory]/newscaster.json") var/list/file_data = list() @@ -91,7 +89,6 @@ 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)) ->>>>>>> e940102... Makes newscaster feedback messages and comments always a list. (#33682) /datum/controller/subsystem/ticker/proc/declare_completion() set waitfor = FALSE From 269208f6871ca360651086d111a25876d1e43952 Mon Sep 17 00:00:00 2001 From: oranges Date: Thu, 28 Dec 2017 10:18:11 +1300 Subject: [PATCH 012/122] [READY]Component Forensics and Item Blood OverlayS! --- code/__DEFINES/cleaning.dm | 7 +- code/__DEFINES/components.dm | 7 + code/__DEFINES/forensics.dm | 2 + code/datums/components/cleaning.dm | 16 +- code/datums/components/decal.dm | 22 +-- code/datums/components/decals/blood.dm | 35 ++++ code/datums/components/forensics.dm | 158 ++++++++++++++++++ code/game/atoms.dm | 128 +++----------- .../gamemodes/devil/true_devil/_true_devil.dm | 5 +- code/game/gamemodes/wizard/artefact.dm | 21 ++- .../game/machinery/computer/buildandrepair.dm | 2 +- code/game/machinery/pipe/pipe_dispenser.dm | 3 - code/game/machinery/suit_storage_unit.dm | 3 +- code/game/machinery/washing_machine.dm | 15 +- code/game/objects/effects/decals/cleanable.dm | 5 +- .../effects/decals/cleanable/aliens.dm | 10 +- .../effects/decals/cleanable/humans.dm | 18 +- .../objects/effects/spawners/gibspawner.dm | 4 +- code/game/objects/items.dm | 14 -- code/game/objects/items/clown_items.dm | 2 +- .../objects/items/devices/radio/intercom.dm | 4 +- code/game/objects/items/melee/energy.dm | 4 +- code/game/objects/items/melee/misc.dm | 4 +- code/game/objects/items/mop.dm | 1 - code/game/objects/items/stacks/stack.dm | 8 +- code/game/objects/items/storage/book.dm | 2 +- code/game/objects/items/twohanded.dm | 2 +- code/game/objects/structures/watercloset.dm | 15 +- code/game/turfs/open.dm | 2 +- code/modules/clothing/gloves/_gloves.dm | 10 +- code/modules/clothing/head/_head.dm | 2 +- code/modules/clothing/masks/_masks.dm | 2 +- code/modules/clothing/neck/_neck.dm | 2 +- code/modules/clothing/shoes/_shoes.dm | 17 +- code/modules/clothing/suits/_suits.dm | 2 +- code/modules/clothing/under/_under.dm | 3 +- code/modules/detectivework/detective_work.dm | 105 ++++++++++++ code/modules/detectivework/evidence.dm | 2 +- .../detectivework/footprints_and_rag.dm | 3 +- code/modules/detectivework/scanner.dm | 22 +-- .../integrated_electronics/core/printer.dm | 1 + code/modules/mob/living/blood.dm | 7 +- code/modules/mob/living/carbon/examine.dm | 13 +- .../mob/living/carbon/human/examine.dm | 68 ++------ code/modules/mob/living/carbon/human/human.dm | 20 +-- .../mob/living/carbon/human/human_movement.dm | 3 +- .../mob/living/carbon/human/update_icons.dm | 3 +- .../mob/living/simple_animal/bot/mulebot.dm | 6 +- .../simple_animal/friendly/drone/_drone.dm | 15 +- .../simple_animal/guardian/types/dextrous.dm | 11 +- .../mob/living/simple_animal/hostile/alien.dm | 2 +- code/modules/ninja/suit/gloves.dm | 16 +- code/modules/power/cable.dm | 4 +- code/modules/projectiles/guns/ballistic.dm | 2 +- .../chemistry/reagents/other_reagents.dm | 21 ++- code/modules/shuttle/computer.dm | 1 + tgstation.dme | 3 + 57 files changed, 523 insertions(+), 362 deletions(-) create mode 100644 code/__DEFINES/forensics.dm create mode 100644 code/datums/components/decals/blood.dm create mode 100644 code/datums/components/forensics.dm 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/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 new file mode 100644 index 0000000000..55633a2087 --- /dev/null +++ b/code/datums/components/forensics.dm @@ -0,0 +1,158 @@ +/datum/component/forensics + var/list/fingerprints //assoc print = print + var/list/hiddenprints //assoc ckey = realname/gloves/ckey + var/list/blood_DNA //assoc dna = bloodtype + var/list/fibers //assoc print = print + +/datum/component/forensics/InheritComponent(datum/component/forensics/F, original) //Use of | and |= being different here is INTENTIONAL. + fingerprints = fingerprints | F.fingerprints + hiddenprints = hiddenprints | F.hiddenprints + blood_DNA = blood_DNA | F.blood_DNA + fibers = fibers | F.fibers + check_blood() + return ..() + +/datum/component/forensics/Initialize(new_fingerprints, new_hiddenprints, new_blood_DNA, new_fibers) + if(!isatom(parent)) + . = COMPONENT_INCOMPATIBLE + CRASH("Forensics datum applied incorrectly to non-atom of type [parent.type]!") + fingerprints = new_fingerprints + hiddenprints = new_hiddenprints + blood_DNA = new_blood_DNA + fibers = new_fibers + check_blood() + RegisterSignal(COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_act) + +/datum/component/forensics/proc/wipe_fingerprints() + fingerprints = null + return TRUE + +/datum/component/forensics/proc/wipe_hiddenprints() + return //no. + +/datum/component/forensics/proc/wipe_blood_DNA() + blood_DNA = null + if(isitem(parent)) + qdel(parent.GetComponent(/datum/component/decal/blood)) + return TRUE + +/datum/component/forensics/proc/wipe_fibers() + fibers = null + return TRUE + +/datum/component/forensics/proc/clean_act(strength) + if(strength >= CLEAN_STRENGTH_FINGERPRINTS) + wipe_fingerprints() + if(strength >= CLEAN_STRENGTH_BLOOD) + wipe_blood_DNA() + if(strength >= CLEAN_STRENGTH_FIBERS) + wipe_fibers() + +/datum/component/forensics/proc/add_fingerprint_list(list/_fingerprints) //list(text) + if(!length(_fingerprints)) + return + LAZYINITLIST(fingerprints) + for(var/i in _fingerprints) //We use an associative list, make sure we don't just merge a non-associative list into ours. + fingerprints[i] = i + return TRUE + +/datum/component/forensics/proc/add_fingerprint(mob/living/M, ignoregloves = FALSE) + if(!M) + 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 = TRUE + if(!ignoregloves) + H.gloves.add_fingerprint(H, TRUE) //ignoregloves = 1 to avoid infinite loop. + return + var/full_print = md5(H.dna.uni_identity) + LAZYSET(fingerprints, full_print, full_print) + return TRUE + +/datum/component/forensics/proc/add_fiber_list(list/_fibertext) //list(text) + if(!length(_fibertext)) + return + LAZYINITLIST(fibers) + for(var/i in _fibertext) //We use an associative list, make sure we don't just merge a non-associative list into ours. + fibers[i] = i + return TRUE + +/datum/component/forensics/proc/add_fibers(mob/living/carbon/human/M) + 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) && !LAZYACCESS(fibers, fibertext)) + LAZYSET(fibers, fibertext, 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) && !LAZYACCESS(fibers, fibertext)) //Wearing a suit means less of the uniform exposed. + LAZYSET(fibers, fibertext, 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) && !LAZYACCESS(fibers, fibertext)) + LAZYSET(fibers, fibertext, fibertext) + else if(M.w_uniform) + fibertext = "Fibers from \a [M.w_uniform]." + if(prob(15*item_multiplier) && !LAZYACCESS(fibers, fibertext)) + // "Added fibertext: [fibertext]" + LAZYSET(fibers, fibertext, fibertext) + if(M.gloves) + fibertext = "Material from a pair of [M.gloves.name]." + if(prob(20*item_multiplier) && !LAZYACCESS(fibers, fibertext)) + LAZYSET(fibers, fibertext, fibertext) + else if(M.gloves) + fibertext = "Material from a pair of [M.gloves.name]." + if(prob(20*item_multiplier) && !LAZYACCESS(fibers, fibertext)) + LAZYSET(fibers, fibertext, fibertext) + return TRUE + +/datum/component/forensics/proc/add_hiddenprint_list(list/_hiddenprints) //list(ckey = text) + if(!length(_hiddenprints)) + return + LAZYINITLIST(hiddenprints) + for(var/i in _hiddenprints) //We use an associative list, make sure we don't just merge a non-associative list into ours. + hiddenprints[i] = _hiddenprints[i] + return TRUE + +/datum/component/forensics/proc/add_hiddenprint(mob/living/M) + if(!M || !M.key) + return + var/hasgloves = "" + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(H.gloves) + hasgloves = "(gloves)" + var/current_time = time_stamp() + if(!LAZYACCESS(hiddenprints, M.key)) + LAZYSET(hiddenprints, M.key, "First: [M.real_name]\[[current_time]\][hasgloves]. Ckey: [M.ckey]") + else + var/laststamppos = findtext(LAZYACCESS(hiddenprints, M.key), " Last: ") + 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 + fingerprintslast = M.ckey + return TRUE + +/datum/component/forensics/proc/add_blood_DNA(list/dna) //list(dna_enzymes = type) + if(!length(dna)) + return + LAZYINITLIST(blood_DNA) + for(var/i in dna) + blood_DNA[i] = dna[i] + check_blood() + return TRUE + +/datum/component/forensics/proc/check_blood() + if(!isitem(parent)) + return + if(!length(blood_DNA)) + return + parent.LoadComponent(/datum/component/decal/blood) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 211f9dea59..67e5697916 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 @@ -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/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/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/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/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/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/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/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/items.dm b/code/game/objects/items.dm index 1cca673778..2eb573fd4d 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -553,20 +553,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) M.become_blind(EYE_DAMAGE) 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/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/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 6fb173b905..0ce53157b2 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -284,8 +284,8 @@ T.ChangeTurf(T.baseturf) 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 cef25a0a36..7463c69b4d 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/book.dm b/code/game/objects/items/storage/book.dm index a06d1a509e..46c3170349 100644 --- a/code/game/objects/items/storage/book.dm +++ b/code/game/objects/items/storage/book.dm @@ -213,5 +213,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/twohanded.dm b/code/game/objects/items/twohanded.dm index 293ef46197..7ac2a3fc3d 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/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/open.dm b/code/game/turfs/open.dm index 0eddbc411e..f7974d58b9 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/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/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/detectivework/detective_work.dm b/code/modules/detectivework/detective_work.dm index d2d633d103..51be073081 100644 --- a/code/modules/detectivework/detective_work.dm +++ b/code/modules/detectivework/detective_work.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD //CONTAINS: Suit fibers and Detective's Scanning Computer /atom/var/list/suit_fibers @@ -117,3 +118,107 @@ 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 +>>>>>>> 9d0e97f... Merge pull request #32311 from kevinz000/component_forensics 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/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/mob/living/blood.dm b/code/modules/mob/living/blood.dm index c1ea547b34..db04a02e4f 100644 --- a/code/modules/mob/living/blood.dm +++ b/code/modules/mob/living/blood.dm @@ -252,8 +252,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()) @@ -266,7 +265,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)) @@ -278,7 +277,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 b8d9d510fd..1c95059a91 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 39caec803b..a9e590c2ca 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,30 @@ //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" //Jitters switch(jitteriness) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index b153f914f3..caa25ca83b 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 6e5d8c7373..ae78e1e585 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/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 14f294fd90..969af98088 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/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 ea159a5749..4d45716983 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/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/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/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index 680c86ff5c..35599553d7 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -164,7 +164,7 @@ if(iscarbon(user)) var/mob/living/carbon/C = user user_dna = C.dna - B.add_blood(user_dna) + B.add_blood_DNA(user_dna) var/datum/callback/gibspawner = CALLBACK(GLOBAL_PROC, /proc/spawn_atom_to_turf, /obj/effect/gibspawner/generic, B, 1, FALSE, list(user_dna)) B.throw_at(target, BRAINS_BLOWN_THROW_RANGE, BRAINS_BLOWN_THROW_SPEED, callback=gibspawner) return(BRUTELOSS) diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 219d9df8ef..5c4cdcf7e0 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -79,8 +79,7 @@ if(!B) B = new(T) if(data["blood_DNA"]) - B.blood_DNA[data["blood_DNA"]] = data["blood_type"] - + B.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"])) /datum/reagent/liquidgibs name = "Liquid gibs" @@ -941,12 +940,12 @@ else if(O) O.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) - O.clean_blood() + O.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD) /datum/reagent/space_cleaner/reaction_turf(turf/T, reac_volume) if(reac_volume >= 1) T.remove_atom_colour(WASHABLE_COLOUR_PRIORITY) - T.clean_blood() + T.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD) for(var/obj/effect/decal/cleanable/C in T) qdel(C) @@ -964,26 +963,26 @@ H.lip_style = null H.update_body() for(var/obj/item/I in C.held_items) - I.clean_blood() + I.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD) if(C.wear_mask) - if(C.wear_mask.clean_blood()) + if(C.wear_mask.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)) C.update_inv_wear_mask() if(ishuman(M)) var/mob/living/carbon/human/H = C if(H.head) - if(H.head.clean_blood()) + if(H.head.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)) H.update_inv_head() if(H.wear_suit) - if(H.wear_suit.clean_blood()) + if(H.wear_suit.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)) H.update_inv_wear_suit() else if(H.w_uniform) - if(H.w_uniform.clean_blood()) + if(H.w_uniform.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)) H.update_inv_w_uniform() if(H.shoes) - if(H.shoes.clean_blood()) + if(H.shoes.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)) H.update_inv_shoes() H.wash_cream() - M.clean_blood() + M.SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD) /datum/reagent/space_cleaner/ez_clean name = "EZ Clean" diff --git a/code/modules/shuttle/computer.dm b/code/modules/shuttle/computer.dm index 3c40996029..216aea306a 100644 --- a/code/modules/shuttle/computer.dm +++ b/code/modules/shuttle/computer.dm @@ -14,6 +14,7 @@ if(..(user)) return add_fingerprint(usr) + var/list/options = params2list(possible_destinations) var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId) var/dat = "Status: [M ? M.getStatusText() : "*Missing*"]

" diff --git a/tgstation.dme b/tgstation.dme index cebbabd8da..907ff6b640 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -43,6 +43,7 @@ #include "code\__DEFINES\events.dm" #include "code\__DEFINES\flags.dm" #include "code\__DEFINES\food.dm" +#include "code\__DEFINES\forensics.dm" #include "code\__DEFINES\hud.dm" #include "code\__DEFINES\integrated_electronics.dm" #include "code\__DEFINES\inventory.dm" @@ -350,6 +351,7 @@ #include "code\datums\components\chasm.dm" #include "code\datums\components\cleaning.dm" #include "code\datums\components\decal.dm" +#include "code\datums\components\forensics.dm" #include "code\datums\components\infective.dm" #include "code\datums\components\jousting.dm" #include "code\datums\components\knockoff.dm" @@ -364,6 +366,7 @@ #include "code\datums\components\spooky.dm" #include "code\datums\components\squeek.dm" #include "code\datums\components\thermite.dm" +#include "code\datums\components\decals\blood.dm" #include "code\datums\diseases\_disease.dm" #include "code\datums\diseases\_MobProcs.dm" #include "code\datums\diseases\anxiety.dm" From ccdccb57af2d1b741e19c7d47235b5e8d3e11ad9 Mon Sep 17 00:00:00 2001 From: AnturK Date: Thu, 28 Dec 2017 21:22:29 +0100 Subject: [PATCH 013/122] Adds roundend nuke disk location tracking to feedback. --- code/__HELPERS/roundend.dm | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 1f1bab691e..6d5efe8287 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -1,5 +1,6 @@ /datum/controller/subsystem/ticker/proc/gather_roundend_feedback() var/clients = GLOB.player_list.len +<<<<<<< HEAD var/surviving_humans = 0 var/surviving_total = 0 var/ghosts = 0 @@ -36,6 +37,22 @@ gather_antag_success_rate() /datum/controller/subsystem/ticker/proc/gather_antag_success_rate() +======= + var/popcount = count_survivors() + SSblackbox.record_feedback("nested tally", "round_end_stats", clients, list("clients")) + SSblackbox.record_feedback("nested tally", "round_end_stats", popcount[POPCOUNT_GHOSTS], list("ghosts")) + SSblackbox.record_feedback("nested tally", "round_end_stats", popcount[POPCOUNT_HUMAN_SURVIVORS], list("survivors", "human")) + SSblackbox.record_feedback("nested tally", "round_end_stats", popcount[POPCOUNT_SURVIVORS], list("survivors", "total")) + SSblackbox.record_feedback("nested tally", "round_end_stats", popcount[POPCOUNT_HUMAN_ESCAPEES], list("escapees", "human")) + SSblackbox.record_feedback("nested tally", "round_end_stats", popcount[POPCOUNT_ESCAPEES], list("escapees", "total")) + //Antag information + gather_antag_data() + + //Nuke disk + record_nuke_disk_location() + +/datum/controller/subsystem/ticker/proc/gather_antag_data() +>>>>>>> d863eb4... Adds roundend nuke disk location tracking to feedback. (#33660) var/team_gid = 1 var/list/team_ids = list() @@ -63,6 +80,27 @@ antag_info["objectives"] += list(list("objective_type"=O.type,"text"=O.explanation_text,"result"=result)) SSblackbox.record_feedback("associative", "antagonists", 1, antag_info) +<<<<<<< HEAD +======= +/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) +>>>>>>> d863eb4... Adds roundend nuke disk location tracking to feedback. (#33660) /datum/controller/subsystem/ticker/proc/gather_newscaster() var/json_file = file("[GLOB.log_directory]/newscaster.json") From d8943d6a1eeea848f773c23d9a63c443d1a0f3eb Mon Sep 17 00:00:00 2001 From: XDTM Date: Fri, 29 Dec 2017 09:37:10 +0100 Subject: [PATCH 014/122] [Ready]Adds the Pax reagent, small tweaks to pacifism --- code/__DEFINES/stat.dm | 1 + code/_onclick/item_attack.dm | 7 +++++++ code/modules/mob/living/carbon/human/life.dm | 4 ++++ .../chemistry/reagents/other_reagents.dm | 20 +++++++++++++++++++ .../reagents/chemistry/recipes/others.dm | 6 ++++++ 5 files changed, 38 insertions(+) diff --git a/code/__DEFINES/stat.dm b/code/__DEFINES/stat.dm index 543ac4badf..e6486a4fcf 100644 --- a/code/__DEFINES/stat.dm +++ b/code/__DEFINES/stat.dm @@ -32,6 +32,7 @@ #define STASIS_MUTE "stasis" #define GENETICS_SPELL "genetics_spell" #define TRAUMA_DISABILITY "trauma" +#define CHEMICAL_DISABILITY "chemical" // bitflags for machine stat variable diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 2dddce8542..f9c3c9668d 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -58,8 +58,15 @@ SendSignal(COMSIG_ITEM_ATTACK, M, user) if(flags_1 & NOBLUDGEON_1) return +<<<<<<< HEAD if(user.disabilities & PACIFISM) +======= + + if(force && user.has_disability(DISABILITY_PACIFISM)) + to_chat(user, "You don't want to harm other living beings!") +>>>>>>> 5d761c5... [Ready]Adds the Pax reagent, small tweaks to pacifism (#33663) return + if(!force) playsound(loc, 'sound/weapons/tap.ogg', get_clamped_volume(), 1, -1) else if(hitsound) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 80db28b99d..6f305a694c 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)) ..() diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 219d9df8ef..bb504c316f 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -1688,3 +1688,23 @@ description = "blue sparkles that get everywhere" color = "#4040FF" //A blueish color glitter_type = /obj/effect/decal/cleanable/glitter/blue + +/datum/reagent/pax + name = "pax" + id = "pax" + description = "A colorless liquid that suppresses violence on the subjects." + color = "#AAAAAA55" + taste_description = "water" + metabolization_rate = 0.25 * REAGENTS_METABOLISM + +/datum/reagent/pax/on_mob_add(mob/M) + ..() + if(isliving(M)) + var/mob/living/L = M + L.add_disability(DISABILITY_PACIFISM, CHEMICAL_DISABILITY) + +/datum/reagent/pax/on_mob_delete(mob/M) + if(isliving(M)) + var/mob/living/L = M + L.remove_disability(DISABILITY_PACIFISM, CHEMICAL_DISABILITY) + ..() \ No newline at end of file diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm index 222f88ba8b..8ebc470c5f 100644 --- a/code/modules/reagents/chemistry/recipes/others.dm +++ b/code/modules/reagents/chemistry/recipes/others.dm @@ -671,3 +671,9 @@ var/location = get_turf(holder.my_atom) for(var/i in 1 to 10) new /obj/item/stack/sheet/plastic(location) + +/datum/chemical_reaction/pax + name = "pax" + id = "pax" + results = list("pax" = 3) + required_reagents = list("mindbreaker" = 1, "synaptizine" = 1, "water" = 1) From 0418ee4df64e0179306fc56a350e5075317769d0 Mon Sep 17 00:00:00 2001 From: Tad Hardesty Date: Fri, 29 Dec 2017 11:40:06 -0800 Subject: [PATCH 015/122] Replace explicit z-level checks with defines --- code/__HELPERS/level_traits.dm | 17 ++++++++++++++ code/__HELPERS/roundend.dm | 6 ++--- code/__HELPERS/unsorted.dm | 5 ----- code/controllers/subsystem/communications.dm | 2 +- code/controllers/subsystem/mapping.dm | 2 +- code/controllers/subsystem/minimap.dm | 2 +- code/controllers/subsystem/shuttle.dm | 2 +- code/datums/antagonists/cult.dm | 2 +- code/datums/antagonists/nukeop.dm | 2 +- code/datums/diseases/advance/advance.dm | 2 +- code/datums/mind.dm | 2 +- code/game/area/areas.dm | 2 +- code/game/atoms.dm | 16 +++++++------- code/game/atoms_movable.dm | 4 ++-- code/game/gamemodes/antag_spawner.dm | 4 ++-- code/game/gamemodes/blob/overmind.dm | 19 +++++++++++++++- .../clock_effects/spatial_gateway.dm | 4 ++-- .../clock_items/replica_fabricator.dm | 2 +- .../clock_cult/clock_mobs/_eminence.dm | 4 ++-- .../gamemodes/clock_cult/clock_scripture.dm | 4 ++-- .../clock_scriptures/scripture_drivers.dm | 2 +- code/game/gamemodes/cult/ritual.dm | 6 ++++- code/game/gamemodes/cult/runes.dm | 16 +++++++++++--- code/game/gamemodes/cult/talisman.dm | 5 +++++ code/game/gamemodes/events.dm | 12 +++++----- .../gamemodes/malfunction/Malf_Modules.dm | 14 ++++++------ .../gamemodes/miniantags/bot_swarm/swarmer.dm | 2 +- .../gamemodes/miniantags/monkey/monkey.dm | 2 +- .../gamemodes/nuclear/nuclear_challenge.dm | 2 +- code/game/gamemodes/nuclear/nuclearbomb.dm | 6 ++--- code/game/gamemodes/objective.dm | 2 +- code/game/gamemodes/revolution/revolution.dm | 2 +- code/game/machinery/camera/camera.dm | 2 +- code/game/machinery/computer/camera.dm | 2 +- .../machinery/computer/camera_advanced.dm | 2 +- .../game/machinery/computer/communications.dm | 9 ++++++-- code/game/machinery/computer/prisoner.dm | 2 +- code/game/machinery/computer/teleporter.dm | 17 +++++++++++++- code/game/machinery/firealarm.dm | 4 ++-- code/game/machinery/status_display.dm | 4 ++-- code/game/machinery/teleporter.dm | 2 +- .../game/mecha/equipment/tools/other_tools.dm | 4 ++-- code/game/objects/items/devices/PDA/cart.dm | 4 ++-- code/game/objects/items/storage/backpack.dm | 2 +- code/game/objects/items/teleportation.dm | 6 ++--- code/game/objects/structures/lattice.dm | 4 ++-- .../turfs/simulated/floor/plating/asteroid.dm | 2 +- code/game/turfs/simulated/river.dm | 2 +- code/modules/admin/admin.dm | 2 +- code/modules/admin/player_panel.dm | 2 +- code/modules/admin/secrets.dm | 2 +- code/modules/admin/verbs/debug.dm | 2 +- code/modules/admin/verbs/one_click_antag.dm | 2 +- .../clothing/glasses/engine_goggles.dm | 2 +- code/modules/events/alien_infestation.dm | 5 +++++ code/modules/events/brand_intelligence.dm | 2 +- code/modules/events/disease_outbreak.dm | 4 ++++ code/modules/events/grid_check.dm | 2 +- code/modules/events/pirates.dm | 6 ++--- code/modules/events/sentience.dm | 2 +- code/modules/events/spider_infestation.dm | 5 +++++ code/modules/events/vent_clog.dm | 5 +++++ code/modules/events/wizard/curseditems.dm | 2 +- code/modules/events/wizard/greentext.dm | 2 +- code/modules/events/wizard/petsplosion.dm | 4 ++-- code/modules/events/wizard/shuffle.dm | 2 +- code/modules/events/wormholes.dm | 2 +- code/modules/mapping/mapping_helpers.dm | 3 +-- code/modules/mining/aux_base.dm | 22 ++++++++++++++----- code/modules/mining/aux_base_camera.dm | 2 +- code/modules/mining/equipment/survival_pod.dm | 2 +- .../mining/equipment/wormhole_jaunter.dm | 4 ++-- .../mining/lavaland/necropolis_chests.dm | 2 +- code/modules/mining/machine_redemption.dm | 2 +- code/modules/mining/mine_items.dm | 2 +- code/modules/mob/living/carbon/human/life.dm | 2 +- code/modules/mob/living/living.dm | 4 ++-- .../living/simple_animal/hostile/hostile.dm | 19 ++++++++++++++++ .../hostile/megafauna/blood_drunk_miner.dm | 6 ++++- .../hostile/megafauna/megafauna.dm | 4 ++++ .../file_system/programs/alarm.dm | 3 +-- .../file_system/programs/sm_monitor.dm | 2 +- .../hardware/network_card.dm | 2 +- code/modules/power/apc.dm | 2 +- code/modules/power/singularity/narsie.dm | 2 +- .../mapGenerators/lava_river.dm | 4 ++-- .../mapGenerators/repair.dm | 4 ++-- code/modules/research/experimentor.dm | 2 +- .../security_levels/security_levels.dm | 8 +++---- code/modules/shuttle/on_move.dm | 2 +- code/modules/shuttle/shuttle.dm | 2 +- code/modules/shuttle/supply.dm | 2 +- code/modules/shuttle/syndicate.dm | 2 +- code/modules/spells/spell.dm | 2 +- code/modules/station_goals/shield.dm | 2 +- tgstation.dme | 1 + 96 files changed, 268 insertions(+), 145 deletions(-) create mode 100644 code/__HELPERS/level_traits.dm 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..91d104c43b 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -182,7 +182,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 +194,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() @@ -393,7 +393,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/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/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/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/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/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/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/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..7743d804cd 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -113,7 +113,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 +122,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 +141,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) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index ddb768488a..62efa887ea 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -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..9e4b29b5c3 100644 --- a/code/game/gamemodes/blob/overmind.dm +++ b/code/game/gamemodes/blob/overmind.dm @@ -53,7 +53,18 @@ GLOBAL_LIST_EMPTY(blob_nodes) SSshuttle.registerHostileEnvironment(src) +<<<<<<< HEAD .= ..() +======= +/mob/camera/blob/proc/validate_location() + var/turf/T = get_turf(src) + var/area/A = get_area(T) + if(((A && !A.blob_allowed) || !T || !is_station_level(T.z)) && LAZYLEN(GLOB.blobstart)) + T = get_turf(pick(GLOB.blobstart)) + if(!T) + CRASH("No blobspawnpoints and blob spawned in nullspace.") + forceMove(T) +>>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) /mob/camera/blob/Life() if(!blob_core) @@ -73,6 +84,12 @@ GLOBAL_LIST_EMPTY(blob_nodes) max_blob_points = INFINITY blob_points = INFINITY addtimer(CALLBACK(src, .proc/victory), 450) +<<<<<<< HEAD +======= + + if(!victory_in_progress && max_count < blobs_legit.len) + max_count = blobs_legit.len +>>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) ..() @@ -82,7 +99,7 @@ GLOBAL_LIST_EMPTY(blob_nodes) 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(L in GLOB.overminds || (L.pass_flags & PASSBLOB)) 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/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index f0934b524f..8a41741227 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) @@ -266,7 +266,11 @@ This file contains the arcane tome files. to_chat(user, "There is already a rune here.") return FALSE +<<<<<<< HEAD if(!(T.z in GLOB.station_z_levels) && T.z != ZLEVEL_MINING) +======= + if(!is_station_level(T.z) && !is_mining_level(T.z)) +>>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) 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..2eda39411d 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,14 @@ structure_check() searches for nearby cultist structures required for the invoca fail_invoke() return +<<<<<<< HEAD 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!") +>>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) log_game("Teleport rune failed - user in away mission") fail_invoke() return @@ -289,7 +295,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 +484,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 +820,13 @@ structure_check() searches for nearby cultist structures required for the invoca fail_invoke() log_game("Summon Cultist rune failed - target was deconverted") return +<<<<<<< HEAD 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!") +>>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) 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..898d6bc460 100644 --- a/code/game/gamemodes/cult/talisman.dm +++ b/code/game/gamemodes/cult/talisman.dm @@ -65,8 +65,13 @@ log_game("Teleport talisman failed - no other teleport runes") return ..(user, 0) +<<<<<<< HEAD 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!") +>>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) log_game("Teleport talisman failed - user in away mission") return ..(user, 0) 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/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/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/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..0229841aee 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,12 @@ to_chat(usr, "Arrays recycling. Please stand by.") playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) return +<<<<<<< HEAD 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.", "") +>>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) if(!input || !(usr in view(1,src))) return playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) 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 7261c44fc5..e95b2853c6 100644 --- a/code/game/machinery/computer/teleporter.dm +++ b/code/game/machinery/computer/teleporter.dm @@ -209,4 +209,19 @@ trg.teleporter_hub.update_icon() if(trg.teleporter_console) trg.teleporter_console.stat &= ~NOPOWER - trg.teleporter_console.update_icon() \ No newline at end of file +<<<<<<< HEAD + trg.teleporter_console.update_icon() +======= + 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 +>>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) 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/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/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/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/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/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/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/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/turfs/simulated/floor/plating/asteroid.dm b/code/game/turfs/simulated/floor/plating/asteroid.dm index 1419036d07..007a682ab8 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 ..() ChangeTurf(/turf/open/space) diff --git a/code/game/turfs/simulated/river.dm b/code/game/turfs/simulated/river.dm index 165af6ee68..9ce521a100 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/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/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/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm index 1a8a174bff..2bbbb33806 100644 --- a/code/modules/events/alien_infestation.dm +++ b/code/modules/events/alien_infestation.dm @@ -40,8 +40,13 @@ for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in GLOB.machines) if(QDELETED(temp_vent)) continue +<<<<<<< HEAD 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] +>>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) //Stops Aliens getting stuck in small networks. //See: Security, Virology if(temp_vent_parent.other_atmosmch.len > 20) 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..2f3555dd99 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -33,7 +33,11 @@ var/turf/T = get_turf(H) if(!T) continue +<<<<<<< HEAD if(T.z != ZLEVEL_STATION_PRIMARY) +======= + if(!is_station_level(T.z)) +>>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) 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..70ee38c93f 100644 --- a/code/modules/events/spider_infestation.dm +++ b/code/modules/events/spider_infestation.dm @@ -22,8 +22,13 @@ /datum/round_event/spider_infestation/start() var/list/vents = list() for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in world) +<<<<<<< HEAD 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] +>>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) if(temp_vent_parent.other_atmosmch.len > 20) vents += temp_vent diff --git a/code/modules/events/vent_clog.dm b/code/modules/events/vent_clog.dm index 4aec0f8fe1..4555588389 100644 --- a/code/modules/events/vent_clog.dm +++ b/code/modules/events/vent_clog.dm @@ -19,8 +19,13 @@ /datum/round_event/vent_clog/setup() endWhen = rand(25, 100) for(var/obj/machinery/atmospherics/components/unary/vent_scrubber/temp_vent in GLOB.machines) +<<<<<<< HEAD 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] +>>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) if(temp_vent_parent.other_atmosmch.len > 20) vents += temp_vent if(!vents.len) 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/mapping/mapping_helpers.dm b/code/modules/mapping/mapping_helpers.dm index a4d3986020..0b8c648817 100644 --- a/code/modules/mapping/mapping_helpers.dm +++ b/code/modules/mapping/mapping_helpers.dm @@ -63,7 +63,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..b635a22eb0 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,17 @@ 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) +<<<<<<< HEAD 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)) +>>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) 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 +210,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 +277,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..84e5bdeed1 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) 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/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index a84683c5ae..46b193cdec 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -422,7 +422,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/living.dm b/code/modules/mob/living/living.dm index b54dfb9c32..4ee2742492 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 diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 10d9fd93d7..a11640808c 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -479,6 +479,25 @@ mob/living/simple_animal/hostile/proc/DestroySurroundings() // for use with mega /mob/living/simple_animal/hostile/consider_wakeup() ..() +<<<<<<< HEAD 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)) +>>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) toggle_ai(AI_ON) 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..ccdcbbf8ef 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,11 @@ Difficulty: Medium if(L.stat == DEAD) visible_message("[src] butchers [L]!", "You butcher [L], restoring your health!") +<<<<<<< HEAD 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 +>>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) if(guidance) adjustHealth(-L.maxHealth) else @@ -163,7 +167,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..ed4bd471bc 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,11 @@ visible_message( "[src] devours [L]!", "You feast on [L], restoring your health!") +<<<<<<< HEAD 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 +>>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) adjustBruteLoss(-L.maxHealth/2) L.gib() 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/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/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index 15b76d2641..3465d354d4 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -61,7 +61,7 @@ var/mob/living/L = cult_mind.current L.narsie_act() for(var/mob/living/player in GLOB.player_list) - if(player.stat != DEAD && (player.loc.z in GLOB.station_z_levels) && !iscultist(player)) + if(player.stat != DEAD && is_station_level(player.loc.z) && !iscultist(player)) souls_needed[player] = TRUE soul_goal = round(1 + LAZYLEN(souls_needed) * 0.6) INVOKE_ASYNC(src, .proc/begin_the_end) diff --git a/code/modules/procedural_mapping/mapGenerators/lava_river.dm b/code/modules/procedural_mapping/mapGenerators/lava_river.dm index 4aadd48a58..373235e94e 100644 --- a/code/modules/procedural_mapping/mapGenerators/lava_river.dm +++ b/code/modules/procedural_mapping/mapGenerators/lava_river.dm @@ -1,5 +1,5 @@ /datum/mapGenerator/lavaland - var/start_z = 5 + var/start_z = ZLEVEL_LAVALAND var/min_x = 0 var/min_y = 0 var/max_x = 0 @@ -18,7 +18,7 @@ /datum/mapGeneratorModule/river var/river_type = /turf/open/lava/smooth var/river_nodes = 4 - var/start_z = 5 + var/start_z = ZLEVEL_LAVALAND /datum/mapGeneratorModule/river/generate() var/datum/mapGenerator/lavaland/L = mother diff --git a/code/modules/procedural_mapping/mapGenerators/repair.dm b/code/modules/procedural_mapping/mapGenerators/repair.dm index 9796535df7..d6264041f0 100644 --- a/code/modules/procedural_mapping/mapGenerators/repair.dm +++ b/code/modules/procedural_mapping/mapGenerators/repair.dm @@ -20,7 +20,7 @@ if(!istype(mother, /datum/mapGenerator/repair/reload_station_map)) return var/datum/mapGenerator/repair/reload_station_map/mother1 = mother - if(!(mother1.z in GLOB.station_z_levels)) + if(!is_station_level(mother1.z)) return //This is only for reloading station blocks! GLOB.reloading_map = TRUE var/static/dmm_suite/reloader = new @@ -87,7 +87,7 @@ /datum/mapGenerator/repair/reload_station_map/defineRegion(turf/start, turf/end) . = ..() - if(!(start.z in GLOB.station_z_levels) || !(end.z in GLOB.station_z_levels)) + if(!is_station_level(start.z) || !is_station_level(end.z)) return x_low = min(start.x, end.x) y_low = min(start.y, end.y) diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index 2c1536b26e..d90c7e5dcc 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -668,7 +668,7 @@ /obj/item/relic/proc/do_the_teleport(mob/user) var/turf/userturf = get_turf(user) - if(loc == user && userturf.z != ZLEVEL_CENTCOM) //Because Nuke Ops bringing this back on their shuttle, then looting the ERT area is 2fun4you! + if(loc == user && !is_centcom_level(userturf.z)) //Because Nuke Ops bringing this back on their shuttle, then looting the ERT area is 2fun4you! visible_message("[src] twists and bends, relocating itself!") throwSmoke(userturf) do_teleport(user, userturf, 8, asoundin = 'sound/effects/phasein.ogg') diff --git a/code/modules/security_levels/security_levels.dm b/code/modules/security_levels/security_levels.dm index 2c0ffd3a34..0818bf3e8c 100644 --- a/code/modules/security_levels/security_levels.dm +++ b/code/modules/security_levels/security_levels.dm @@ -29,7 +29,7 @@ GLOBAL_VAR_INIT(security_level, 0) SSshuttle.emergency.modTimer(2) GLOB.security_level = SEC_LEVEL_GREEN for(var/obj/machinery/firealarm/FA in GLOB.machines) - if(FA.z in GLOB.station_z_levels) + if(is_station_level(FA.z)) FA.update_icon() if(SEC_LEVEL_BLUE) if(GLOB.security_level < SEC_LEVEL_BLUE) @@ -43,7 +43,7 @@ GLOBAL_VAR_INIT(security_level, 0) GLOB.security_level = SEC_LEVEL_BLUE sound_to_playing_players('sound/misc/voybluealert.ogg') for(var/obj/machinery/firealarm/FA in GLOB.machines) - if(FA.z in GLOB.station_z_levels) + if(is_station_level(FA.z)) FA.update_icon() if(SEC_LEVEL_RED) if(GLOB.security_level < SEC_LEVEL_RED) @@ -58,7 +58,7 @@ GLOBAL_VAR_INIT(security_level, 0) GLOB.security_level = SEC_LEVEL_RED sound_to_playing_players('sound/misc/voyalert.ogg') for(var/obj/machinery/firealarm/FA in GLOB.machines) - if(FA.z in GLOB.station_z_levels) + if(is_station_level(FA.z)) FA.update_icon() for(var/obj/machinery/computer/shuttle/pod/pod in GLOB.machines) pod.admin_controlled = 0 @@ -72,7 +72,7 @@ GLOBAL_VAR_INIT(security_level, 0) GLOB.security_level = SEC_LEVEL_DELTA sound_to_playing_players('sound/misc/deltakalaxon.ogg') for(var/obj/machinery/firealarm/FA in GLOB.machines) - if(FA.z in GLOB.station_z_levels) + if(is_station_level(FA.z)) FA.update_icon() for(var/obj/machinery/computer/shuttle/pod/pod in GLOB.machines) pod.admin_controlled = 0 diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index c7a77f9457..b0e5c2dc00 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -187,7 +187,7 @@ All ShuttleMove procs go here /obj/machinery/computer/auxillary_base/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) . = ..() - if(z == ZLEVEL_MINING) //Avoids double logging and landing on other Z-levels due to badminnery + if(is_mining_level(z)) //Avoids double logging and landing on other Z-levels due to badminnery SSblackbox.record_feedback("associative", "colonies_dropped", 1, list("x" = x, "y" = y, "z" = z)) /obj/machinery/gravity_generator/main/beforeShuttleMove(turf/newT, rotation, move_mode) diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 962a17caeb..f2bbd96943 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -391,7 +391,7 @@ mode = SHUTTLE_RECALL /obj/docking_port/mobile/proc/enterTransit() - if((SSshuttle.lockdown && (z in GLOB.station_z_levels)) || !canMove()) //emp went off, no escape + if((SSshuttle.lockdown && is_station_level(z)) || !canMove()) //emp went off, no escape mode = SHUTTLE_IDLE return previous = null diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index c2d6de2651..eacacef933 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -45,7 +45,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list( SSshuttle.supply = src /obj/docking_port/mobile/supply/canMove() - if(z in GLOB.station_z_levels) + if(is_station_level(z)) return check_blacklist(shuttle_areas) return ..() diff --git a/code/modules/shuttle/syndicate.dm b/code/modules/shuttle/syndicate.dm index 283ac0f35c..e0daee6f04 100644 --- a/code/modules/shuttle/syndicate.dm +++ b/code/modules/shuttle/syndicate.dm @@ -40,7 +40,7 @@ /obj/machinery/computer/shuttle/syndicate/drop_pod/Topic(href, href_list) if(href_list["move"]) - if(z != ZLEVEL_CENTCOM) + if(!is_centcom_level(z)) to_chat(usr, "Pods are one way!") return 0 ..() diff --git a/code/modules/spells/spell.dm b/code/modules/spells/spell.dm index d13f56b2cd..832395b1f1 100644 --- a/code/modules/spells/spell.dm +++ b/code/modules/spells/spell.dm @@ -163,7 +163,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th return 0 var/turf/T = get_turf(user) - if(T.z == ZLEVEL_CENTCOM && !centcom_cancast) //Certain spells are not allowed on the centcom zlevel + if(is_centcom_level(T.z) && !centcom_cancast) //Certain spells are not allowed on the centcom zlevel to_chat(user, "You can't cast this spell here.") return 0 diff --git a/code/modules/station_goals/shield.dm b/code/modules/station_goals/shield.dm index b00dff2ef7..13216826a4 100644 --- a/code/modules/station_goals/shield.dm +++ b/code/modules/station_goals/shield.dm @@ -31,7 +31,7 @@ /datum/station_goal/proc/get_coverage() var/list/coverage = list() for(var/obj/machinery/satellite/meteor_shield/A in GLOB.machines) - if(!A.active || !(A.z in GLOB.station_z_levels)) + if(!A.active || !is_station_level(A.z)) continue coverage |= view(A.kill_range,A) return coverage.len diff --git a/tgstation.dme b/tgstation.dme index bc6f2fc007..f12e79325f 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -101,6 +101,7 @@ #include "code\__HELPERS\global_lists.dm" #include "code\__HELPERS\icon_smoothing.dm" #include "code\__HELPERS\icons.dm" +#include "code\__HELPERS\level_traits.dm" #include "code\__HELPERS\matrices.dm" #include "code\__HELPERS\mobs.dm" #include "code\__HELPERS\names.dm" From 0c84651ec45a8ee05ceeaa0c9625c90a4c34f1b3 Mon Sep 17 00:00:00 2001 From: ShizCalev Date: Thu, 28 Dec 2017 15:54:47 -0500 Subject: [PATCH 016/122] white and rainbow --- code/modules/clothing/gloves/color.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index 4f108a505f..11ae549e1b 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -202,7 +202,9 @@ /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) From a958de3d96d14dece4a8ba562b87ccf2e582f201 Mon Sep 17 00:00:00 2001 From: oranges Date: Sat, 30 Dec 2017 12:10:41 +1300 Subject: [PATCH 018/122] Fixes assistants spawning naked --- code/modules/clothing/gloves/color.dm | 9 +++++++++ code/modules/clothing/under/color.dm | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index 4f108a505f..83e8f817c5 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -205,9 +205,18 @@ /obj/item/clothing/gloves/color/brown = 1) var/obj/item/clothing/gloves/color/selected = pick(gloves) +<<<<<<< HEAD name = initial(selected.name) desc = initial(selected.desc) icon_state = initial(selected.icon_state) item_state = initial(selected.item_state) item_color = initial(selected.item_color) +======= + 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 +>>>>>>> c063902... Merge pull request #33930 from ShizCalev/undersuit-fix diff --git a/code/modules/clothing/under/color.dm b/code/modules/clothing/under/color.dm index 2ff546a6eb..975ca26061 100644 --- a/code/modules/clothing/under/color.dm +++ b/code/modules/clothing/under/color.dm @@ -6,11 +6,21 @@ /obj/item/clothing/under/color/random/New() ..() +<<<<<<< HEAD var/obj/item/clothing/under/color/C = pick(subtypesof(/obj/item/clothing/under/color) - /obj/item/clothing/under/color/random) name = initial(C.name) icon_state = initial(C.icon_state) item_state = initial(C.item_state) item_color = initial(C.item_color) +======= + 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) + 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 +>>>>>>> c063902... Merge pull request #33930 from ShizCalev/undersuit-fix /obj/item/clothing/under/color/black name = "black jumpsuit" From 86c5f3cb0b11a4c96652c4cc288c9fbb788741f3 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Fri, 29 Dec 2017 18:39:28 -0600 Subject: [PATCH 019/122] Update detective_work.dm --- code/modules/detectivework/detective_work.dm | 122 ------------------- 1 file changed, 122 deletions(-) diff --git a/code/modules/detectivework/detective_work.dm b/code/modules/detectivework/detective_work.dm index 51be073081..5bf4ad27b8 100644 --- a/code/modules/detectivework/detective_work.dm +++ b/code/modules/detectivework/detective_work.dm @@ -1,124 +1,3 @@ -<<<<<<< HEAD -//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() @@ -221,4 +100,3 @@ A.add_fingerprint_list(return_fingerprints()) A.add_hiddenprint_list(return_hiddenprints()) A.fingerprintslast = fingerprintslast ->>>>>>> 9d0e97f... Merge pull request #32311 from kevinz000/component_forensics From 6f8c2c1daf6cfd76ad1cd9309e385295c275cdc2 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Fri, 29 Dec 2017 18:40:58 -0600 Subject: [PATCH 020/122] Update item_attack.dm --- code/_onclick/item_attack.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index f9c3c9668d..8a5b9ba519 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -58,13 +58,9 @@ SendSignal(COMSIG_ITEM_ATTACK, M, user) if(flags_1 & NOBLUDGEON_1) return -<<<<<<< HEAD - if(user.disabilities & PACIFISM) -======= if(force && user.has_disability(DISABILITY_PACIFISM)) to_chat(user, "You don't want to harm other living beings!") ->>>>>>> 5d761c5... [Ready]Adds the Pax reagent, small tweaks to pacifism (#33663) return if(!force) From d306c8fa62cc51e41e8f84a3f87301a15245b43d Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 29 Dec 2017 22:35:40 -0500 Subject: [PATCH 021/122] Removes suit sensors from bural garbs (#33915) * Removes suit sensors from bural garbs * Dew it right --- code/modules/clothing/under/miscellaneous.dm | 1 + 1 file changed, 1 insertion(+) 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" From 8c6d660611b3fc7de3c453b721d0feb50ac65488 Mon Sep 17 00:00:00 2001 From: cebutris Date: Sat, 30 Dec 2017 10:04:03 -0500 Subject: [PATCH 023/122] adds functional cebusoap --- code/citadel/custom_loadout/custom_items.dm | 8 ++++++++ 1 file changed, 8 insertions(+) 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*/ From 90b67e2e134eaacec7278cc5623e29794d4402b4 Mon Sep 17 00:00:00 2001 From: cebutris Date: Sat, 30 Dec 2017 13:35:26 -0500 Subject: [PATCH 024/122] blacklists holoparasites from discounting --- modular_citadel/code/datums/uplink_items_cit.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/modular_citadel/code/datums/uplink_items_cit.dm b/modular_citadel/code/datums/uplink_items_cit.dm index 26591c72ef..18b3187ac6 100644 --- a/modular_citadel/code/datums/uplink_items_cit.dm +++ b/modular_citadel/code/datums/uplink_items_cit.dm @@ -38,6 +38,7 @@ item = /obj/item/gun/ballistic/automatic/pistol/antitank/syndicate cost = 14 surplus = 25 + cant_discount = TRUE include_modes = list(/datum/game_mode/nuclear) /* Commented out due to introduction of reskinnable stetchkins. May still have a niche if people decide it somehow has value. From 76a135fbb7cec5485de8e756df13062b79adcdf2 Mon Sep 17 00:00:00 2001 From: cebutris Date: Sat, 30 Dec 2017 13:50:59 -0500 Subject: [PATCH 025/122] WRONG THING OOPS --- modular_citadel/code/datums/uplink_items_cit.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modular_citadel/code/datums/uplink_items_cit.dm b/modular_citadel/code/datums/uplink_items_cit.dm index 18b3187ac6..392e26ba71 100644 --- a/modular_citadel/code/datums/uplink_items_cit.dm +++ b/modular_citadel/code/datums/uplink_items_cit.dm @@ -16,6 +16,7 @@ NOTE: The precise nature of the symbiosis required by the parasites renders them incompatible with changelings" //updated to actually describe what they do and warn traitorchans not to buy it item = /obj/item/storage/box/syndie_kit/holoparasite refundable = TRUE + cant_discount = TRUE cost = 15 surplus = 20 //Nobody needs a ton of parasites exclude_modes = list(/datum/game_mode/nuclear) @@ -38,7 +39,6 @@ item = /obj/item/gun/ballistic/automatic/pistol/antitank/syndicate cost = 14 surplus = 25 - cant_discount = TRUE include_modes = list(/datum/game_mode/nuclear) /* Commented out due to introduction of reskinnable stetchkins. May still have a niche if people decide it somehow has value. From 9ddc9fd7f9bbfb04fc26e7078315951e2a473bab Mon Sep 17 00:00:00 2001 From: gamedeviso Date: Sat, 30 Dec 2017 10:44:03 -0500 Subject: [PATCH 026/122] Changed BYOND Link to Secure HTTPS (#33918) * Changed BYOND Link to Secure HTTPS * Updated to direct link to download page --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 8452cc74d0f7992f261f92b847f93e4c34d06498 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Dec 2017 13:21:31 -0600 Subject: [PATCH 028/122] Update newscaster.dm --- code/game/machinery/newscaster.dm | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) 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" From 95714a0207f386007795412d5c90d4f3daac5d79 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Dec 2017 13:22:46 -0600 Subject: [PATCH 029/122] Update volume_pump.dm --- .../machinery/components/binary_devices/volume_pump.dm | 5 ----- 1 file changed, 5 deletions(-) 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 d7b8073c87..9e7a3403e6 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm @@ -151,13 +151,8 @@ Thus, the two variables affect pump operation are set in New(): on = !on if("set_transfer_rate" in signal.data) -<<<<<<< HEAD - var/datum/gas_mixture/air1 = AIR1 - transfer_rate = Clamp(text2num(signal.data["set_transfer_rate"]),0,air1.volume) -======= var/datum/gas_mixture/air1 = airs[1] transfer_rate = CLAMP(text2num(signal.data["set_transfer_rate"]),0,air1.volume) ->>>>>>> 6a7dbaa... removes silly garbage defines (#33621) if(on != old_on) investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS) From 70fea88a391608784e8dcac65e18c0d42fd52571 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Dec 2017 13:22:54 -0600 Subject: [PATCH 030/122] Update cryo.dm --- .../atmospherics/machinery/components/unary_devices/cryo.dm | 5 ----- 1 file changed, 5 deletions(-) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index 74c2302ee9..87d6387b99 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -348,12 +348,7 @@ else data["occupant"]["temperaturestatus"] = "bad" -<<<<<<< HEAD - - var/datum/gas_mixture/air1 = AIR1 -======= var/datum/gas_mixture/air1 = airs[1] ->>>>>>> 6a7dbaa... removes silly garbage defines (#33621) data["cellTemperature"] = round(air1.temperature, 1) data["isBeakerLoaded"] = beaker ? TRUE : FALSE From 35574263b1163b379219dbed56d7ab3386f24e3c Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Dec 2017 13:23:02 -0600 Subject: [PATCH 031/122] Update outlet_injector.dm --- .../machinery/components/unary_devices/outlet_injector.dm | 5 ----- 1 file changed, 5 deletions(-) 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 e458e2a3fa..eca11d613c 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm @@ -130,13 +130,8 @@ if("set_volume_rate" in signal.data) var/number = text2num(signal.data["set_volume_rate"]) -<<<<<<< HEAD - var/datum/gas_mixture/air_contents = AIR1 - volume_rate = Clamp(number, 0, air_contents.volume) -======= var/datum/gas_mixture/air_contents = airs[1] volume_rate = CLAMP(number, 0, air_contents.volume) ->>>>>>> 6a7dbaa... removes silly garbage defines (#33621) if("status" in signal.data) spawn(2) From dda430131aedded13fefa0fe838242e288f53f5c Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Dec 2017 13:28:58 -0600 Subject: [PATCH 032/122] Update roundend.dm --- code/__HELPERS/roundend.dm | 81 +++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 45 deletions(-) diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 7d95a30cb3..7bb5fa4e93 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -8,42 +8,6 @@ /datum/controller/subsystem/ticker/proc/gather_roundend_feedback() //Survivor numbers var/clients = GLOB.player_list.len - var/surviving_humans = 0 - var/surviving_total = 0 - var/ghosts = 0 - var/escaped_humans = 0 - var/escaped_total = 0 - - for(var/mob/M in GLOB.player_list) - if(ishuman(M)) - if(!M.stat) - surviving_humans++ - if(M.z == ZLEVEL_CENTCOM) - escaped_humans++ - if(!M.stat) - surviving_total++ - if(M.z == ZLEVEL_CENTCOM) - escaped_total++ - - if(isobserver(M)) - ghosts++ - - if(clients) - SSblackbox.record_feedback("nested tally", "round_end_stats", clients, list("clients")) - if(ghosts) - SSblackbox.record_feedback("nested tally", "round_end_stats", ghosts, list("ghosts")) - if(surviving_humans) - SSblackbox.record_feedback("nested tally", "round_end_stats", surviving_humans, list("survivors", "human")) - if(surviving_total) - SSblackbox.record_feedback("nested tally", "round_end_stats", surviving_total, list("survivors", "total")) - if(escaped_humans) - SSblackbox.record_feedback("nested tally", "round_end_stats", escaped_humans, list("escapees", "human")) - if(escaped_total) - SSblackbox.record_feedback("nested tally", "round_end_stats", escaped_total, list("escapees", "total")) - - gather_antag_success_rate() - -/datum/controller/subsystem/ticker/proc/gather_antag_success_rate() var/popcount = count_survivors() SSblackbox.record_feedback("nested tally", "round_end_stats", clients, list("clients")) SSblackbox.record_feedback("nested tally", "round_end_stats", popcount[POPCOUNT_GHOSTS], list("ghosts")) @@ -85,7 +49,6 @@ 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) @@ -105,17 +68,45 @@ 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.") - /*for(var/client/C in GLOB.clients) + for(var/client/C in GLOB.clients) if(!C.credits) C.RollCredits() - C.playtitlemusic(40)*/ + C.playtitlemusic(40) display_report() @@ -136,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 @@ -240,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 @@ -252,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() @@ -404,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] @@ -451,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]" From f0214dd06d019509d15df85de9ec829b78429c60 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Dec 2017 13:31:13 -0600 Subject: [PATCH 033/122] Update overmind.dm --- code/game/gamemodes/blob/overmind.dm | 7 ------- 1 file changed, 7 deletions(-) diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm index 9e4b29b5c3..22074392fc 100644 --- a/code/game/gamemodes/blob/overmind.dm +++ b/code/game/gamemodes/blob/overmind.dm @@ -53,9 +53,6 @@ GLOBAL_LIST_EMPTY(blob_nodes) SSshuttle.registerHostileEnvironment(src) -<<<<<<< HEAD - .= ..() -======= /mob/camera/blob/proc/validate_location() var/turf/T = get_turf(src) var/area/A = get_area(T) @@ -64,7 +61,6 @@ GLOBAL_LIST_EMPTY(blob_nodes) if(!T) CRASH("No blobspawnpoints and blob spawned in nullspace.") forceMove(T) ->>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) /mob/camera/blob/Life() if(!blob_core) @@ -84,12 +80,9 @@ GLOBAL_LIST_EMPTY(blob_nodes) max_blob_points = INFINITY blob_points = INFINITY addtimer(CALLBACK(src, .proc/victory), 450) -<<<<<<< HEAD -======= if(!victory_in_progress && max_count < blobs_legit.len) max_count = blobs_legit.len ->>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) ..() From 6c59d4134a98923ea781293d9a952f2087069e10 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Dec 2017 13:31:24 -0600 Subject: [PATCH 034/122] Update ritual.dm --- code/game/gamemodes/cult/ritual.dm | 5 ----- 1 file changed, 5 deletions(-) diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 8a41741227..30e78ff1af 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -265,12 +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 - -<<<<<<< HEAD - if(!(T.z in GLOB.station_z_levels) && T.z != ZLEVEL_MINING) -======= if(!is_station_level(T.z) && !is_mining_level(T.z)) ->>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) to_chat(user, "The veil is not weak enough here.") return FALSE From a8d6fa7fd720031aa429d3492c6c223e3f69f926 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Dec 2017 13:31:51 -0600 Subject: [PATCH 035/122] Update runes.dm --- code/game/gamemodes/cult/runes.dm | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 2eda39411d..4feee3f23b 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -277,14 +277,9 @@ structure_check() searches for nearby cultist structures required for the invoca fail_invoke() return -<<<<<<< HEAD - 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!") ->>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) log_game("Teleport rune failed - user in away mission") fail_invoke() return @@ -820,13 +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 -<<<<<<< HEAD - 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!") ->>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) fail_invoke() log_game("Summon Cultist rune failed - target in away mission") return From a16099758789bb321105dfcea385be300a3152dd Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Dec 2017 13:32:02 -0600 Subject: [PATCH 036/122] Update talisman.dm --- code/game/gamemodes/cult/talisman.dm | 5 ----- 1 file changed, 5 deletions(-) diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm index 898d6bc460..855dfa7255 100644 --- a/code/game/gamemodes/cult/talisman.dm +++ b/code/game/gamemodes/cult/talisman.dm @@ -65,13 +65,8 @@ log_game("Teleport talisman failed - no other teleport runes") return ..(user, 0) -<<<<<<< HEAD - 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!") ->>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) log_game("Teleport talisman failed - user in away mission") return ..(user, 0) From 47174097e190ffbab7dde6a1dd809f1931329f7f Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Dec 2017 13:32:19 -0600 Subject: [PATCH 037/122] Update communications.dm --- code/game/machinery/computer/communications.dm | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 0229841aee..e02a5f0e2a 100755 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -136,12 +136,9 @@ to_chat(usr, "Arrays recycling. Please stand by.") playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) return -<<<<<<< HEAD - 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.", "") ->>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) if(!input || !(usr in view(1,src))) return playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) @@ -744,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 From 7c69a835be2dca1e80ad3302db58c8b7de1120b8 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Dec 2017 13:32:29 -0600 Subject: [PATCH 038/122] Update teleporter.dm --- code/game/machinery/computer/teleporter.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/game/machinery/computer/teleporter.dm b/code/game/machinery/computer/teleporter.dm index e95b2853c6..ccd7b0ee13 100644 --- a/code/game/machinery/computer/teleporter.dm +++ b/code/game/machinery/computer/teleporter.dm @@ -209,9 +209,6 @@ trg.teleporter_hub.update_icon() if(trg.teleporter_console) trg.teleporter_console.stat &= ~NOPOWER -<<<<<<< HEAD - trg.teleporter_console.update_icon() -======= trg.teleporter_console.update_icon() /obj/machinery/computer/teleporter/proc/is_eligible(atom/movable/AM) @@ -224,4 +221,3 @@ if(!A || A.noteleport) return FALSE return TRUE ->>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) From 2fe40198a21116aa97840353aff9ddc79561e302 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Dec 2017 13:32:38 -0600 Subject: [PATCH 039/122] Update alien_infestation.dm --- code/modules/events/alien_infestation.dm | 5 ----- 1 file changed, 5 deletions(-) diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm index 2bbbb33806..662d938bd6 100644 --- a/code/modules/events/alien_infestation.dm +++ b/code/modules/events/alien_infestation.dm @@ -40,13 +40,8 @@ for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in GLOB.machines) if(QDELETED(temp_vent)) continue -<<<<<<< HEAD - 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] ->>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) //Stops Aliens getting stuck in small networks. //See: Security, Virology if(temp_vent_parent.other_atmosmch.len > 20) From f698fd532941287e64bbdc9e750ba80c2358c14b Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Dec 2017 13:32:46 -0600 Subject: [PATCH 040/122] Update disease_outbreak.dm --- code/modules/events/disease_outbreak.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index 2f3555dd99..a41b4bfdde 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -33,11 +33,7 @@ var/turf/T = get_turf(H) if(!T) continue -<<<<<<< HEAD - if(T.z != ZLEVEL_STATION_PRIMARY) -======= if(!is_station_level(T.z)) ->>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) continue if(!H.client) continue From de10a5b2236dbe9272b361801a8d09e121fcc183 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Dec 2017 13:32:53 -0600 Subject: [PATCH 041/122] Update spider_infestation.dm --- code/modules/events/spider_infestation.dm | 5 ----- 1 file changed, 5 deletions(-) diff --git a/code/modules/events/spider_infestation.dm b/code/modules/events/spider_infestation.dm index 70ee38c93f..a3c625e396 100644 --- a/code/modules/events/spider_infestation.dm +++ b/code/modules/events/spider_infestation.dm @@ -22,13 +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) -<<<<<<< HEAD - 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] ->>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) if(temp_vent_parent.other_atmosmch.len > 20) vents += temp_vent From 10643a192e0087fab8aee98064e043d04df24063 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Dec 2017 13:33:01 -0600 Subject: [PATCH 042/122] Update vent_clog.dm --- code/modules/events/vent_clog.dm | 5 ----- 1 file changed, 5 deletions(-) diff --git a/code/modules/events/vent_clog.dm b/code/modules/events/vent_clog.dm index 4555588389..5e91160575 100644 --- a/code/modules/events/vent_clog.dm +++ b/code/modules/events/vent_clog.dm @@ -19,13 +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) -<<<<<<< HEAD - 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] ->>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) if(temp_vent_parent.other_atmosmch.len > 20) vents += temp_vent if(!vents.len) From 96358f62f2cf76a3c4aa65bc48d3649b9613daf8 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Dec 2017 13:33:15 -0600 Subject: [PATCH 043/122] Update aux_base.dm --- code/modules/mining/aux_base.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/modules/mining/aux_base.dm b/code/modules/mining/aux_base.dm index b635a22eb0..c1d90ed0c0 100644 --- a/code/modules/mining/aux_base.dm +++ b/code/modules/mining/aux_base.dm @@ -140,9 +140,6 @@ 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) -<<<<<<< HEAD - if(T.z != ZLEVEL_MINING) -======= var/static/list/disallowed_turf_types = typecacheof(list( /turf/open/lava, /turf/closed/indestructible, @@ -150,7 +147,6 @@ interface with the mining shuttle at the landing site if a mobile beacon is also )) if(!is_mining_level(T.z)) ->>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) 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) From 449ae34621aac1c5085c745e5867997c387ff0a2 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Dec 2017 13:33:25 -0600 Subject: [PATCH 044/122] Update hostile.dm --- code/modules/mob/living/simple_animal/hostile/hostile.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index a11640808c..c677cd7035 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -479,9 +479,6 @@ mob/living/simple_animal/hostile/proc/DestroySurroundings() // for use with mega /mob/living/simple_animal/hostile/consider_wakeup() ..() -<<<<<<< HEAD - if(AIStatus == AI_IDLE && FindTarget(ListTargets(), 1)) -======= var/list/tlist var/turf/T = get_turf(src) @@ -498,6 +495,5 @@ mob/living/simple_animal/hostile/proc/DestroySurroundings() // for use with mega tlist = ListTargets() if(AIStatus == AI_IDLE && FindTarget(tlist, 1)) ->>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) toggle_ai(AI_ON) From 2994b4b7c251425e437ac0ff73863cd72958b766 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Dec 2017 13:33:37 -0600 Subject: [PATCH 045/122] Update blood_drunk_miner.dm --- .../simple_animal/hostile/megafauna/blood_drunk_miner.dm | 4 ---- 1 file changed, 4 deletions(-) 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 ccdcbbf8ef..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,11 +114,7 @@ Difficulty: Medium if(L.stat == DEAD) visible_message("[src] butchers [L]!", "You butcher [L], restoring your health!") -<<<<<<< HEAD - 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 ->>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) if(guidance) adjustHealth(-L.maxHealth) else From 32291c247bd14065ef2484ea15e9a33bb35f0b5e Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Dec 2017 13:33:45 -0600 Subject: [PATCH 046/122] Update megafauna.dm --- .../mob/living/simple_animal/hostile/megafauna/megafauna.dm | 4 ---- 1 file changed, 4 deletions(-) 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 ed4bd471bc..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,11 +105,7 @@ visible_message( "[src] devours [L]!", "You feast on [L], restoring your health!") -<<<<<<< HEAD - 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 ->>>>>>> f2dbe5c... Replace explicit z-level checks with defines (#33829) adjustBruteLoss(-L.maxHealth/2) L.gib() From 4d3b7ddcbd733bc4cfe36d458a627975b2832dc9 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Dec 2017 13:37:23 -0600 Subject: [PATCH 047/122] Update color.dm --- code/modules/clothing/gloves/color.dm | 9 --------- 1 file changed, 9 deletions(-) diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index 83e8f817c5..75d6c66077 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -205,18 +205,9 @@ /obj/item/clothing/gloves/color/brown = 1) var/obj/item/clothing/gloves/color/selected = pick(gloves) -<<<<<<< HEAD - - name = initial(selected.name) - desc = initial(selected.desc) - icon_state = initial(selected.icon_state) - item_state = initial(selected.item_state) - item_color = initial(selected.item_color) -======= 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 ->>>>>>> c063902... Merge pull request #33930 from ShizCalev/undersuit-fix From c1c67ced1a79ef7359743afbac4c806a0480fb72 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Dec 2017 13:37:30 -0600 Subject: [PATCH 048/122] Update color.dm --- code/modules/clothing/under/color.dm | 8 -------- 1 file changed, 8 deletions(-) diff --git a/code/modules/clothing/under/color.dm b/code/modules/clothing/under/color.dm index 975ca26061..a6ab5280c8 100644 --- a/code/modules/clothing/under/color.dm +++ b/code/modules/clothing/under/color.dm @@ -6,13 +6,6 @@ /obj/item/clothing/under/color/random/New() ..() -<<<<<<< HEAD - var/obj/item/clothing/under/color/C = pick(subtypesof(/obj/item/clothing/under/color) - /obj/item/clothing/under/color/random) - name = initial(C.name) - icon_state = initial(C.icon_state) - item_state = initial(C.item_state) - item_color = initial(C.item_color) -======= 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) if(ishuman(loc)) var/mob/living/carbon/human/H = loc @@ -20,7 +13,6 @@ else new C(loc) return INITIALIZE_HINT_QDEL ->>>>>>> c063902... Merge pull request #33930 from ShizCalev/undersuit-fix /obj/item/clothing/under/color/black name = "black jumpsuit" From 3802cf8586dab39f620cd9b55df8aa3ff4ae6dd1 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sat, 30 Dec 2017 14:56:23 -0500 Subject: [PATCH 049/122] Merge pull request #33805 from Cruix/shuttle_machines Fixed autolathes and ore redemption machines leaving things at previous shuttle locations --- code/game/machinery/autolathe.dm | 56 +++++++++++------------ code/modules/mining/machine_redemption.dm | 5 +- 2 files changed, 28 insertions(+), 33 deletions(-) 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/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index e16eb0e5b2..ddfcfa62e3 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -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.") From 3128c26698a74e9649c3011c9bbfd22353b67398 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sat, 30 Dec 2017 15:03:56 -0500 Subject: [PATCH 051/122] Merge pull request #33937 from AnturK/printplayerfix printplayer fix for jobless minds --- code/__HELPERS/roundend.dm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 52dd7c6358..8ab1e2fac6 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -385,7 +385,10 @@ /proc/printplayer(datum/mind/ply, fleecheck) - var/text = "[ply.key] was [ply.name] the [ply.assigned_role] and" + var/jobtext = "" + if(ply.assigned_role) + jobtext = " the [ply.assigned_role]" + var/text = "[ply.key] was [ply.name][jobtext] and" if(ply.current) if(ply.current.stat == DEAD) text += " died" From 1be3d30c43cec537b4d186836c64fcd79baa6721 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sat, 30 Dec 2017 14:13:25 -0600 Subject: [PATCH 053/122] Automatic changelog generation for PR #4579 [ci skip] --- html/changelogs/AutoChangeLog-pr-4579.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4579.yml diff --git a/html/changelogs/AutoChangeLog-pr-4579.yml b/html/changelogs/AutoChangeLog-pr-4579.yml new file mode 100644 index 0000000000..69327324f6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4579.yml @@ -0,0 +1,5 @@ +author: "XDTM" +delete-after: True +changes: + - rscadd: "Added a new reagent: Pax." + - rscadd: "Pax is made with Mindbreaker, Synaptizine and Water, and those affected by it are forced to be nonviolent against living beings. At least, not directly." From a89f221d35ff4193b9a9d77dbeb9fe6736c0fff6 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sat, 30 Dec 2017 17:04:11 -0500 Subject: [PATCH 054/122] Removes chemist job from omegastation (#33863) * Removes chemist job from omegastation * Remove chemist start points --- _maps/map_files/OmegaStation/OmegaStation.dmm | 4 +--- _maps/map_files/OmegaStation/job_changes.dm | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm index ffda1f471d..b38e7e8902 100644 --- a/_maps/map_files/OmegaStation/OmegaStation.dmm +++ b/_maps/map_files/OmegaStation/OmegaStation.dmm @@ -23737,7 +23737,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 +24228,6 @@ /obj/structure/chair/office/light{ dir = 4 }, -/obj/effect/landmark/start/chemist, /obj/effect/turf_decal/stripes/line{ dir = 6 }, @@ -74189,7 +74187,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) From 3aef84aa5eef9dfd1cde404b39767b50773e611f Mon Sep 17 00:00:00 2001 From: oranges Date: Sun, 31 Dec 2017 11:53:34 +1300 Subject: [PATCH 056/122] Merge pull request #33778 from MrDoomBringer/youre-still,-in-a-dream,-SPACE-HEATEEER Updates space-heater sprite to 3/4, updates icon --- icons/obj/atmos.dmi | Bin 30420 -> 30696 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/obj/atmos.dmi b/icons/obj/atmos.dmi index 1abc0b5ca719d91f0b6a56bd209f4686f67cd554..fcd971c674a65503d2c873a600f38dacde6e878e 100644 GIT binary patch literal 30696 zcmZsCbyQSQ+wU1VC8Zmrm7%*^IuxW!x+J7Kl~h!^yFpsIyQRCkd#HPS-|xmBcP&_J zW;5*b?0kOl%okNjQ*0RSTQ?-vCLY#ENtEdt*(dTMIBNPToRb+U4F zv2w5n0QZ#CUrG*vV%VXhrz||4KV`ZlCxaETt%P<9Z_ESMXeY=yN^qZjuxM<ESGVj=4JZz6d3`77(^X=9Z? zE5Bv5BW3uBPQLUaL^mk6j2=UAmgp@jx>IzUe%+f^fJn;=W3vCnYVbrYq+V|~y#A#< zW*d3mY`~l5Z0PHo2eQ7|jL#;naeX4u^2>{B`f~wPUhurhi$uR%+mW2czhMb5%ISWG zWS?5&D|g7dJ0O|uh~3yZ6iieoUi`X$Mtr7C-jg*W#d=P>E{YSyI`FP3%isRBt%tu3#>m`rT!iZ+ zs(lHMm5{p{N%7R@!e7ZX&+t>T_)^ZSp1%Nq3Xqo)*K|)gO!d&yyn1>z45CW5qhhQ7iY+?H zs(p|W7ypbsauUOt&bc#`lE}}Ql8AFBL>c2T^g$&3LZGU7`*H5&-rin@D&vn|;Z@lV z{u19hNTNb3=^l0W_R#pR{3=xaQifnjyHf;v`3xiR@BAKa&j|KT=4*;SG(GlM<^gNzpHwhWb7RZuG`j(5s}` zexhhlJVlNQP2{yplJ;1qYx&pLaNq|ks~1y#g8iB2aypm4C9mS*;>e3A>pn&(l__Ax zPOuU|s32m2iGEi^QK4TTRCW4g7?9-=4#R4gc($>e&WAl-OupuB+wu3{Q>m@Cq)Ok@ zGBEVoj(-ND#*k-WXa{~%A3ZWy<%)s5*%rW6bSdhq{){?lpZLSrP+9#()tWJOsl2@3Wk5U#JMkBiL*muS2wcuI{CrNmwh0G&257gmvxLDHIUUPdq z)kj@5CR#<*TW=KoxnMy`78136{E)m)$>-R%c^7Y3dqfJIRWy~GP7@~3k0GJT{Q$+W z#h>j|{L@#>bx6c6aV-t`S=oeEdM;Z`y_^s_X7)Qrn$2`%!oe&CPQE!U zA|j&SrN6&FLCE9xq1tLwjSUX37f;7 z-{ugM#7uBz-^;y*TL`?It9nHkpwRO8{@nE=yV&sQ4ly7ndK*`gN;%B#&ZkT5d6?0Z zsyxiDr;FpIx;;`hEWI*LXC2XAM?3piE;PFn(dgZPGWIK$z`)06TcynzUiGd>X^Y+5 z*uTJ6H9cAGt91rR<|7HmVI*K{&ZDM7^NkCMxz#c0oJn;6~p_Sb#GA(XC) zMLjc}F^e(zZLb_vvahAXqhz%_qRzAP4@1T*7ja)-Z6gC{0t5-?RCw9rP;sMs2;6o= z8+&eUpg>z*G!pgFo2RVT^GPggo@r)Ev40^vu3RWHN4b>uojh6yBF{0$2~|e~TFA41 z$Ek7_B6LcTfGX)#VXtc=*yWxcxsir!Q0$GUcB3dCIM1HAknhox+sl3=5OoS|x%}-5 zBSCRLtW^fi(l$YvNU@yhhv_IH<1-=?5m8Gn4E7d>Dt}sB0p5#Yhb^*IMZC)f{s5xz8tecN+?>|R=PmWL-O+!pc8PnFcyPp4d5RpuRd%m{U+Cq@%@Pq8; z;4l(iBQ5+!B!U`Z)Jmf}!Vc#WF7HnOZCaPJ^T4<&&Wy2Nw!{YhGqd46^EzD9({O-& zna;;+*uTEeG+h0=dt(+B5tKajel;K{^=gtE_2i-@CubB2v@O&*EOa4gqS#RlLN7`~aZ&#ybcjiTITOWF$K2IB{4 zg%VLrirS;g;qX~{es5<7i0GZqv?$dPrY*UUdV#x$R&Vum@9)W*R7o>L9c%=;0(Jy; z2$@1--lGc!sMEK&-ah=ahlV;|)2q#IW-^;_{u6Gan~LQW_l*gr?UL+qY9zS@{JQ2`2bs z;R#-^Da6)XB<(2J{4znOq$0oDNesEl*^Er=-&ll>2LuFKRV{yqh7kN4pi*Etn?;~W z=PF!A1aSAw$V?}R>TUI}8A%sP}f5SF4MJ64majc<;Z0vX43-XkD6(YsH{k+cxwF3MFD!wtm%cGCUP{W7}#cQ{l4t6%>l{f(+!&byzKkooWSGSL^bVhWkA z;Kex1WN0Xk;J%1ND_#aiWU{$9fW2yGfWYWQNF+S1cnl&BUp&X#6LSC7lVHDeRA3gR zVl#zjzxaoPl$^eP>bNtk+gKghk~t=qh*JbW`tKVo%71rmjP|C5itXI#*?XsNb6hEV zXJ@u-Oy&3_BqWMygb@$cHTr6Y0o>mx14yVsCNy6xkK2tp*x;c)%k5#Jp|=)urT6vl z3G!muSW&piTUBFle zHCDCKvCt5L9_G*5G)^8u>QglkUW&DY35O7S-H~W8IqNdb+e$9&$ z_}5d|{|M{$Q|(>uH%kQY&TYcf*W3yBY;6q=cMC=WFlGpRJbJ5aD>zcLWi7oj-xo^@ zN-U5J&)3MM3zN2wNxSClKf)2P#(LWckP~bLn17M!RNOq$<)C#j(;*=kgpyAiy64e< zl(97NUU{o6Gf5UmY;5E!!0L;`XEi?fTQN+UMy&0@Mf)Ms5zGkx-kS%X`5m(J)meXx z?djK;Ig-s(buN)(C&_+T1Gq6AkBiWXz`e@9j0>%!hl;=1n3Ua5 zs&*ny7g682jvKta{3cMBuGf>PJ>*lSOg9n}2>X4Mq6wO+j;(CRBv$yB8fVWmK`u+q;+`O6DUz+<1z@%0Jnw2zU< z|wU1b=I-$)HXAFp#TjN23Vd}tZBe!iE*AvD=cPI0u@ZYJRBCCa+whF>P*8KJ?5 zkJi49;&`^+O+Q+0*t)!*{H=qK*g`QaCc=F_4~CDnwbs5aAm$wDdCY(Kyz&et^Ly9R zcCbH2VclfKI+qnSRy3^KD0(1IIduSNn=aM0vf&G%36#dk_zNcT-I;b-b)19_Tx@K> zpM*NZ1fzHxUU9taudiU>((^!&&y&yb2@$t7{`JWU+u$&9w$t+`wa1$Xq)#|h(z5s0 zN8_`z;e{Ic9Dfm*@X3E;g;dqtB?cv>MwFIqf)Ro$P&AB>#Qw*3+z36}EG$XEXO<8AKT zrFvd6jfPTl#yAEVJjS+={eY&XP2_IzvNs-ZI>^?#8o}103bf6BOUmXn@N#y1+DS*B zXqiIrVVYF>R+z^{+l!QSj}r8eIf>)t&mVhvw;D=cavi`<{@bs#6<4bwB3I9duB4(O zM*hj#8pOiF!rk3Hqo4q#rl!Wx*;&%VgMWX2e|2;7QY+NB1qld|I7_Xnauy^cj4wNw zErX8inotVA*y<-ruap$bBO)TFq+~Y{%QsPYH&$b^SX2@a zLn^qIS?Jj&y_TuRn^2eT*VLU%_2qW|;9xB)6{;TjiUd<~dMsQ~0Z(6LV{0PcM#1wGL^U{s(gRk&u9E*27ZXWD>jG762dU zQ_0QS6GJ%){{0~_e#3l}Al1p&TN<&)sxBR_zD5A}JnspFPg)Y$C_?G!LqBAs4){(L zy}Q*riNOSFZRY~TgOH3nLov1gxa|D`w}`K>X%B|W!SvCq?>!S43hLxW;8X)t)YK5! zXfpO>5pM2xMJ;q4e}0b-X4-TwcH*Zu5z!a>ItLS_*VWa{ReN91O6BFQ3He_GeG)O9 z)ltmsB$yYMlc7sd9o3xdy>cn_--%wWJfOsV_t#h!^G6Hb6YI;T4X@#g^>ac$YUb&TGvYY%;?P(7~X6p zQyO1v4_hw%;nvgFAOFL>a6t`)#zw%>Jhq7+&Ij4x@aQ<%bp<{#tvpOvj3Tv_HCIv| z?x<|9i1b4F+)t@OJ>8*_G31@s?LiPAuKHC+_k1nne>&bCN_5}+CYzzjytc6c4-n;~ zo;Cicn@?wR_SKmW{Rr#Ik|<^W?raPKKQ5EtaZ9xoj1{Mk z5p7W(hzWV)(3TkCQ0|)ai0iP4QS{wNHPH?(g4ej5dQacqz)WYhl*A<@;NXG1eEW>% z^>?>2_SnONVMN)!!B(s~_z_RQ>SBZQ;&rpvjnrhgbVwIbf5YacnPQsI9F-2;wk(aH zZ!qsqW5?$hQRv^!&NjWbBfGF|q=VGS68#9i<^%H}{hDFz>H>#Q6QbflU+|U|~TZTTh9b(WTFAuob+@M5XM5$0d?#3j%Y%EnE zh0PhwtV|gOo(qP+Er6S0t%wtUdl3TtcY zAsJr~ebeSuE#BVgc^WN~FQLxocjAhW6}P2!@9El%n>rCzaJ)IX30V zv1w)4uW2kQ^W4N5Psbq3a8iC?Oe6EthiHa|bcRY02^VwuU)Bm&A#zn1V@IT`)()TV zOD|nQv~l=1)DcGD?XA#xw+Cz|Hp?R;t@MH%DCOu(C}+i-w8W zeY8-AdG38N%uB@YLl2Y(IrI2W?*5+>AGnICooN2P!-cwNv1sx$jsQg=T#% zSuW3E)|hv9b5);g2MGY%O0AOcMKDVbrSQjH{Ir_P+hb_2wwi=GZ!6*x5SUEl$VX0$ zVl{hSts7KnQ=G%%SwFz}zrH??=rhMWy*=B|oAUzi!$nNx=L5say@T?9>sF%QNPvTb zquu!Vbx$<;VB%_iy07)|xjDbSW~eXutbo5^*PiLs^}8>?t+R0wU*nRE|v z6Z;|ikiy+hPVt5w1X*cmcIKaG7Ncq1mwS^N5F?NYV+EroafpiP>{zf*u50u{>j$B` z93azJu7pno7PqBIA0C>kuQ-%0s?(~1qm$|5$SpMo@ zld;Keb#9WEJ6h`V+)bzAf~jpxPZE9o)O(YF(XoUb(=ZZ~3p zwkgc>i|5l$EC2u#XK+}U!k@Itchk3;P>k=b_b-6cqI5`bu*;? z)mjdJGz(Si>|Up&%r1Mmg7?`>8Tn+HzM$_QAF%pOmZF`|(A)Uh(;U-rzS>IfV32cE z$kg%ac&RZwJlwyvRg{K?rhX&c7siyQlpOlZU1?|pPMYoDpKxDtZ>g|$kA^>vI8>sz zdVfwBvm`v%S{a;@a#qNwUHyK2_EbK-+9IHs$p--6`zV%e`{FVllGhv<@RT82m?to4 z!zq?>BNZo(uMsS(TU&@f;XBY>YbKrfm=gI2a0tENB^W z{^7fG2*X+{#4&w6J!8o=W|&j*`!_CH2pq*c<6vhe{MOdi>G`>YWr2J8%=)^CJ$~#f zDP$xk^q7N-sB}sL3Lzqv=*n-0*QC7IDS%dDof;43(w_S_LhmRCII*E20`9BdsZ%sUHU4hPKP_9vlZG%&)b&wN79Ftjy6JJ(Co^L=i7O-%_Qa?3 zy`{GBJ(ww%4STU}2l4Rm0Q~dQJm03FU;_gKk$$^2Gi6(f4%dfsdS~&QpE$;E6kmkj zL2MCbC(MJ+uCEEIQQq!d)BNP-=C&jyMg`mlhcV005MlAZvIPBE0A=DY055|sAp|#& z*)#jRH+YT&1DG_^8IFK0~RKn3}d^VxjsH4o-tL2I!uxG(~QK?X#54 zl44`~&lvipqBmXcEjDo4hpot<qe5C#WV4d-r_o*z5qI9zJHV1f1%6Iq^dqyU1u~Hipdu@xc|q!R=hO;e(hwx zJJDcFHvZGoBSn^npVtv@G1uheWJ6eEqu}D=;_2hfie#at)3&UlN=dzR5Hh z^UKW>j+4B+b$z>UH=@t?lpTvpmDls!BbSOV;~`Wx9f;XGIZpT2cHUQ0TEOg|V}F03 zM7QpRKlGFagMbEiO7j*}{QyXs?E8Jt&;Q!^N#Wm7>l@`z)CH#>9Gq#J z(H$SoLbM18`Izu`Ul^HKF*((YE=iy3UtV=f8yf1JS7ixKoYvm%ZoFGO4zA2T6DKvE zAvW>s87eo%zHi%5@bu{E8-0U36>`dspgqX~CWq`WUSdZIcbi8)KAPijrW-~g=^w|BZ|KwDxO`-LC@ zQTSlC%-VT@+WP}MT1ogWk)St)*a`E+fRq{H45sFlvM4&-OukPQB>RK z9Me*8LUMJ4fcXv_*Uxy96g!&IKI4%QRZG#vd6*{`6r&8dU7jHfnBQTcxs%tlWEH>< zI{El`f3s7&;<+PSt$$feRjSQP?CU!k*I~hwGCBa|%R4T#*&1$e`LblW6`GOjA?EY) zesN%!>iN#krMDQlapOU>>xrVP;nN0EozhTwlOAtd>PluRCFJYYN|i;->IXEmX6vHj zZ{LUm*jgBqeo;c;#8@00GAh3biYnSfb}CAR!H5n7hy1X>e28vnXqc0elaZ5y0A5?C zlTZEMA9`abd%+wB@%Q2hn-dW8Ew`qOS z_f-I8g%gWi-`RdwSNGAS)MEI5%H7T465?I$)U;FY?T*2Q9VscjtYQhsE(J-BKJwHORntfjLCR2Yk_-v_BOx6YfZSf`0uPU(@(Kb&^93PYsj(M-?y+z% zzidoaPA%C}nXUB0-HjK3$AdD=#sZ&EFMo>x&}um?^n~^=)qjGwu1VtL1hZmU<6sCn zp{kY^a*fXGaNuqal97=Cw70hhS^(~s+inN#aY}lNaTjfL0@k*nL{4@P)!4#d zHVVH7IyjdWjCH4_!8~d?18cEcsAW38xBwYSkWw;FxBYxI)3x|6JR@?%Olu7I=J1|Bx&c7308D$(%fZrqNe7k2gFU zeXTeI1fkY!Jby@@yTurz}iJWj6r;A(iCsufSwyN_3NO%`jh={33I5V9HI5A(he)<3&hH3G$H z8Zp8{_fVUt?WOjhGo`m^$JR>r%hgtk@BrGc*YJS1=QXQEbnthF*6#1ZUKQ>`M648? zNbOKE=J?pyv3c#-F09&Rzh|G|;9#-R_on-Q3vaI%91yKEG&I=d@AbDN&GRX*7Mo@R9xY<9B2C2m_fF12Fuk?;mt<4|u&FJAQ1L@rd>nmB7N zmqV1%0SS8(1i)P-2ck0sD7B|!h#M(-%3RxyPT$^X)rw$<=tJB@;c4*(EnYmCp?I6p zgt|XJ`PA3fXOxw_0NEy(t%D*W&{I-V#|z`u+9cU&xe@(1f@7+xAONpcDJ~IlA+opI zsgW5o{^`v7h?2ELjkZ8UM<=)5XLPjRa_PLp9avsB$6Er*xRRSHp%r!uJZ}t*jHr+> zNrIvEy-ttRL+6Lu@JRM!8vqE#UkG>apRy$l;x3KcUD(-@8s`_(}wV`&dH)^Xo_Z%WSk8 zq@T&`NOM_gU8Y{v#s4JX6}QRnTvt50BxsMV|1(cQruYOmGx8Kb&R}yoI!k;D_03kp ztNtv&Y7)rL&mSl^ys$tD5{urERKc~at&rGQ>=Yr7i2_s|L2?52_EuzMXIJkX5>j@7 zSBL;ME&8WE-PEy7HPy`{0(!k9S`q z8jS1a7EH=ibYV3RTmTE7nki&@%n=7wCeuIr2mfuHCE*wr&YJ7j@Y8(AUuv2MtES3TojBQ= zS;_QhgiKXNf{RbzIpKk0isjQwT*FY~?O?rRX@93Z(Nm<`Ig505!sD~5{)x?>?VjD@5pTGnyrnq>?_=o40epME z)wY1Zi=JzcKq_BR!ubpYb*`(NK;6DNkI^y?StbqcU{P-t_Vaym!D{jr0PucbRX@Qy z_y?z7KcoD78zM{Th3}VkhX;U6p<5~Wao03vedqZx^3NXuA=qxV<}>vK8#A-#V3N0! zlFq`!6@=&fk46f-g@wwd!3cqp^Rw?O3lT|4!H&*Jg*P6_d*~Rd11=h7MTP&=Q4#x4 z1%r8O<{}m?=TB!7A0NK^#tL5d2-yy2{O?)-Quf>R2m}C|tS$ti>T`b(78=R{RDkez zHg8kZ^RnRGN`FNK6bVq*&?uc?xWghB_{(~Qnlrn1c=)A_qP^bRfEUX!CIbpa!vm${ zugn#(@OP%^;dpT6>f=fON&M$$+40nJF9RD%XqHA#vUc=t;74V4LInd7vEE_oGsXId0#3Zi z55hNkZJ<2)ZzfXiE=tBxg4>`N6h4<~$6>RY1uc(P@|!Yw?xG&&W=+0HRTiU8oN*U* zcd>GRC*)$KlsCDxiz!J+nCsL2$_m`RPhoq8hND z12jL1+1gq18IWqdMworZ1;i?Mv4HQRFKMW$1DJ{mLNq#k#<@(?sM%$lj=}gk7}!Fo zWwMQPl+(+OmoY&%xQkYwvi-_t=F|RPCcW0r`@v{V_KzM|g!)Ua#!XGuv(ViRwzvI=yEucgmP>FJ}d+uK&Q zCC@L)?M4tfJ35F=gf>M=re+MYX<1n#*)1fZrwM}+Mtl5JByJNJ5fGGnQj?KC@%nKN z3=FJ-IXunhNlfYLHE>QsWhnYt8H-F9h8&%8*?Ht8x^{eL$GD=8#AZl|Fmz=7v!%-S z@@B*jtG#y^@gsK!;&6lMjx#nf@fTCs7@&EcWOFhsfqbs^R|<<3j@vF&0z2^YfDPbZ zxzS@XgLOFJKF2T{VniI;o*^DOZl%%R;PmocI(d(u1n^NXSMrjOtq3yaA98a1Is7TA z$=lt-BeSAnj2`BF0q>8#Gs?S{CJ!?GIc`s|W51n%E{7zK#(>6QA% zVJ3g4H9;qNn|@=UW-UCD=nF9?y>ZV$AtMV*kdqYE*GVVo3!cSth|w>4!- zZtQ~QZ{{VMB;Qb)(r;S&I3F%lVS;jZ?yt!FLJk4!|B->yPTn+E?P(jy1&rt z_RLI`Rik-j3`%wg^0gn<42^^P9V|oW_Dz$w&#KO353`R2kd@cH<7-M=bU->*X~X;Q z+l|3{QEx1+?txD9S@wQz3vVeU^>m~P9<%HtQ_hQhSd`GFLF0%tiT@k8{^rm6s=QNG z7AoS%`utZhho3W^>SijB7FNjf9kOrydZWoP3d=cqStbqJK}@UmDUS$!#YgKhMROQb zZV>^!;n9yBMokXH=>=*yv$dj#bt7BGFt_sdhI!N{-q{*~bjm9s-}&dboP!hrx37CE z`K{gEY7LjU>hBETfP^zoX8Uc5HjrT9VE29IcpqkqJ*)u^9xx&~kRH{|rc8GsmPCTq zYbC|dGCYo+Erw zPN<`s)yMaXxSlurUqCG~+wj@9-uFnrezCrNO5AmCBBVGO^gOWYP11U3A2eb0* zlv$sc5Ab0(d!yu|gM(GYEwAc5KFca?z5I8oBWE-kOc4o1#PXLZGgdp0cjv-{m51^( zD+%5>R>}3IJbjDv<#Rg!tx8!U@<%7%VGITLqU*2ZYRP~fOczjLf2bGG749vBxxfj4_4Ubq;QChRp( z^g6G+Z=eI2vPtFY0cQystSu-KUwK>dL-B2K<%hEhHpq8-1OXl!#p-Qgp&fuau$@`umvL+Hh=zhfXQT z*A6#>w~&92PiJ!5mz~m4W^z*s5&!39el0gfz>nDrWShJT~z}{XmAwUNEX(xyNe1I@S zH2P+!`O^$R!Ibqe86`Vjv(pyZkGD(MOuW3jBi?s;wA1ltH@5iKn-#Dcu| zP87>hIDQ|Ha<}~nmHDArfv%P=w-CWZEnN8^#zPQ|A+x?FTIpy8tt$szW}p*#yMs>s zzL`h_=BkQ!y)-T3Kg0fcQQP}80IdVXOt2@0)TT-RnpNH>pnUc5?~KFQ6tAR@@32Uu zaf}GlY*~5v4#DJh_6oU-VX;cO2-52^n0Z&ea8t$oOtX903KUqaJy~hRvask(|M7Id z=dq5E=Dv;^WP1IV5})R%?!!A*xi9I-H5z)Kw|BTwZ&qt;0{){gtH=QQ2&=`>l!;mJj|Q zRz=YFD*MIl^KS)X+Afw%pefOFA{z|{EotMfVY9%A-CriAWDiI~thyfWf8yejd=B}BNP6ImL$%U{ z64LPJ4I#t%*E4Tbi?SDvcLBCSlz%_OvK{o;9TPn-PVPr9*1qxqAbj4+{6!9+kF{$l zZDK;h$ymSVmz2ksmKp`N1kGI5wLU7H{e#Y(X}(|~0T=@_EKNXXg$QF329i(DsSDU9a)6!biDP5~2?iz|2wMh4&S89zXb*$`hT)@~K z>K%u{nl8%8LdR>1JZtv=knb>Z$hmD;lYo|kBm`h<=1PS4pR_30pF1o}!?KXvSu)yHAh{_bwQ%vTG0$m$SW@hG!kAno=Lwl32 znfXgrs^v5NFcr>QFDDctK`FYZsOWUbZG|aMG0pbd)AgoV$P;%`oQU!9LMzlQ;+ZQs zIw59pRwq3fH{BsH-hPQ2T0fF1ux4As`SndoaB&2B(f%=QK~Q-+B4_zZR*%fL5b&Yw zzewU!X59C3_w=A*=4!TIGWP=r1W zb}Z;`p1+@UTeYzE1#4VBoVKxjl>+Hct;F(~^*{a<`9J(?*!&$IT8IgVWJwZ0kDXdn zv{mh}>20plKwqC&@%vI+^_9^{Lg8}tLaKO?D3D^I$x2GXXM>eOQ86((rS`U#mK6my z(TFhf$-*h?zRYJaogcO@1 zh)9B~zw=OvN)}8reSZ+Ob$R&5KP6sn0)vzXgP53DQA0^pWu@TG>Z*ZDX)3-O$X9$6 zJ((hDQ>Pi0k$1>8@(5^f~CAZe`k(oPMHYj_p2{8RQ-Q#f1MwM_4+1RRr6P z(1S|Ni*l?H%USeAVz}}E?(WBcsnO~fp~naE)4PkP;g0Ix)vx5(MQtXMBnaSb|3ADl z>F{NaH+~-+7l~Swi=bk~e+D+~r(H1*h$=go18qy4r0tyqrjN=fB9W`c5#u>~6*~Y5 zob%daiQbXB_emdN`d-UIG9ujM!&0{AHG~qsib84JW9p2 z+9CVE?m9EmTXVa5dUzIx2A$D%7aMSZzR%v?O-;qw#4{H5+gsFPjgi3Iwu(1PXgAXB zc#_Vx`4dyso>yRF$-p6cr6k)}A3;k;;|s z@0JkF_@Ah0{hw`ZZG(gr$AU#n2M}I!v~{O18z1BEWXQ&zaci=riw4K$({FT*3!k3v z0g9?5N;WT~)d_A?^5xz_;tGnNjj?Iw(elQ@vh5ZGa3$-^d~BFl*xb&~&ev(gy%MQZ zC`Ako19y2Z&J~j~HU|b{rvGw)EP53rnu~*TSy(N1n3zZ5)YLpl^a}`J*(2KdiQIpB z((qYOe{XQy?I%Xp<31jv2;!;H_9`kAzOrhlbTmni@WSA4nmDUUFq)AYxH%By02f?)}|1_ zR;Q*H)YON_qf>t2MkO1JLD+QpdWfBamhuc5|K_*J7jHH#sfbG2Se>kvLC5FT-Q!cY zG5e5=f0=z+K~YgBNWu_%7mzSybAO|3?JJxP?0pG1N{i!$ZNyF-DZE`_v=NL^_bFNl zyt)eOl;5N6%P+*qcyi=ZxPMHH0A9Te_;QCy>_`ZLb}ErQ4*QjRRJTzF$-83?5VTVn z*=zmPT!EvCgPaSbFcazDi|(N)z{Ed2JDM2&u)OB@GVMZPw+0&@7Z_$WIE!!z_MJ8K zid_EERKdfneaGV=tS5!XV=paqLDtae=%V9%TL2nzFhk6g{2r$beg{SH?Mbu_b zq9;dx$FyYsd+g5H#hnY#RwYhSW!3M#P8}oq#u6XgMY5Vw2+nkzRpZ~!I$y=STi-XV zE^hN#5HAu56?)>b!B zWU9JDphs;zv&R?D*gx?@K>Zp5WM$1BG2P+=t(5pDx|uT$%oWzA^4FSMlli6d?Wu7U{jOh69H+=LXPWwzu>_^JPZg5( zJA)2`(;P|($vM+A`S@|PvfY=}kXOx5!EOdxw?Fs4wp`WZ0zh8n@~Wr$m#<$ zFMd@zHrm(MR$<&(f7W)uYYXLPV)lbE+ZouWoPutmacoS=q_U;8VtVlb=lji9aakne zVQ+H-aeSVFizaBqct?*53Y!9Na|VHj`v0&725l@^8FGmx(+wN~{{+%QW1AUAUkIN?j7?ZzO zv>YqjG|kYaG)YtO`w7VQK+G4+EW!UVcpdjC*5b8UDD@36?SyR9auL|9*C~yvps{Xe$h= zP&ITMvX$K}DiSPUZZ*CZUrk;~6#f3H8Rf&+XOdUrvKsq_1-=)5<6R>6Nk5uBuSH$p z61=6L5M(o^wn%_QzQB_GWK1mrn^AxGB!t`@5`q*;mlflIivDWlq$xNg#h7H$kBJ7i z=*?2({vZM5{f{azzmB9L0Y40MgLS1tfD$h8iNM@PEz=zDBJRa^>xtk742@7f5|v>ranwQR_^D zzF>9b!E=PAwBi-5JX~&ZeI>~8qY+HDdE6pR<_A%ThV@&t+Wb7`OD(H~Itx-Bd%c)7 zT6!vPMf@}(vnK80DOq3NmbO{C-OdDG%UwLagj&2#S;e-1$CZd}UK{`apxOsTo~Wyj z1;uzL*mke;z{l;PI>3W-J7IxKnGbu<0p%mIS>HH&Z(CyY)>}hz4Seim(ycoN#*6Lr zozU{`AE(3F}1(|k6b z+)1Y5&lANz?tQ#(aE5J5_KlAID|M=LJ27AsggbdQ#rZ)lXmYtbPTzZet`wUAe)Oi? zrL-MBCs_hF|s51oTz%*N5?St;hAU59juhZW6 zzqWUFoO7Pwtw0l^o4so!)kf`$@=#Yv{|=+if87R}!LP^va4{K<9fFmmrO~a%#BOJ@ zau5BIo;!>_f4%ajNQg`Vihy zfO<|VsgO65r<&A}SAGM9i3<5lmo31#nHX=xS#2#=eIsVOl~pBNwJKa#q({0Y_bdM`|2M>*Rf-S@qI+-9@OF_+0C0q5pCfK5rs zcGxC=MP9@fGBKfUW=MHM6R#{}y@W!lK9HhXGSlQ$$1PZ@Xc_ z;kS>W$sQickW@il>#I~a0XO@|m>6Ecc)|v^-{DTKABYzP(fq`w+eUTu-}eZ||BR>Q z;rT^Y^Tg^bUdT1Ufy?aUj9f)Y)8d!sp-BfWLR2J|VZDgfvy5t#8@t+5BfLUdEGZmX zsXl+YU8Zy#J<-3z1}aMKMV0ndeFiVxnppKz8P1b)fA8yl)h5?W7x6hV4~)6L|Flr{ zru5UAZ_pAg)F&ysWmqQwjD#?B%L49SuHszWAmQ*DJ5EJ@82VVT1|l@4^foR(4Ka-VIix;Q)bBj zcn$>}zf6gBqD81y?j4w-?GaO#n@IrgNzmIbZPlBT)Ndh~&}f>eY{vHsicH;`s7uhBV*c0ku=y;|>9F5K~+j3L`CF1hapDErxez;e^imn`0@_D}hFo&_bi=vucuwA=Q{kahkJ!CGJ5~Z zQP<(8h$&2&{xY@e^2*Qsm2~3iiIH#WJJ&v>_Lj;&1&fl2s=>kGPi>`BH>}6NyIH5d z)vrSr$X^LX2)0!r?!lioKmS_aMS-S%nmPIl_f}A=2K^E;%liax{})xzRlC^1$RCsh zR#if+OZpV(rMFblyGM)F3r~9~{fIVccdGG{NK$4Df=IE1_M7#}PzHHLIhcxY9%X*M z-7=GE{l=SFv}-dc{G;EFP){`KdzRw3%eJHayBBTfV5qynkna~Ca>_ABY#iaa>&MS8 zm5fST@WF%lRNOk|zkZ~Lx?}mcCmalGEF}xDF!KLby@RWLievcR7mezPVWWiQ zChP0#2uL%Prn2H`9UT%QR97>*eDm~d3x+Gb%?lG(E(@3KKh7u*0AF0bHs!pM`@VRa}{MN zI)oqo@V^MStM923BF6Ox?;ot)1>3l9j!~oC4rg()J42jZj+W}MLPA2aX2$mgqYg!z z)QZ^(^`F6yDiiFZN4iQH(HacD^gQa3ZzsBns(9(L(aK=F(W9={@IErRp&tb$Whhkx z`m;VUIg({2l$OJU&U`2#n7BNjMDJosZ>`w@#mq1Z|B)L0xMM*pWcp2Fce`8?v!+o6O%KMY&tAh$OaAC^3((w)# z8edM2!y@WXS`DZ7(Z9CQ-edKGXgWON!y6_}d6wFB*zTz#J|Tfg+iE^G2@K)8NK7x- zQnFGZzWFxAcLV&a@+bDeSBaGJ$#HR}*spOPgI!6nMd;C%1U$p{TaymD9n*m%EfGm_C7C)2$-UWHvuK?rn-% zN|&FplB`%xdlgI(?$djYGGOnGK(C9iitHb=7#QMxTlpf-c{y?`D-;rxF7XsqjASKM zHpj#M`!YMwRE;O-iNgy2qa_h3N+2_7^^aEIXTl8_KIxCM8D4-UaYa2eb+*x-Bke&4-& zcc0z)W1fMTKHaBJSJhk9Rd2rsg1z&vP{t_%a6yKTjrshUyj(sH-F1T?~7v2U=TYoR@XF=82rGef%04D733LvTNmeKXG?Ld z1p56s{*I3LXIErnYfC^W7O1;c?L9ls4Pr!5WSu(w@lzYkavJBSk^bX~a+cr#{{WmD z4{qw@9v7Y*!$>*hn5U5-|L1{UL7fSzv0m5ms@G1Rlaj@4UitA){I{qaMO@4~?N1^_5#_Q}jv<&J9^gQ1WA@<_fg-zDo-tXi88gX=%io>J_m_vT*a zog>xtJr536MVHC!kpvW7)zR4+Sx{(g>D^~^p%VL!Mm}#9vn>d8z5>x>Sk$OL-AlT5AdKLk)|8ho;xizcDiOwby+`Aojg~q*uSH$^hXm z+p*n0--dECO%04P6WyBgX=-Xzf_Oi026R!lnQ0LMR-9A8i4E^;y*~1qJ%9et_!3X( z5Pr;#49KcH1nn#wD86|ciJIpT6^8)KxufxY^aH)2S0H}r+tt+LKtVyPWRQjDT(H_R z88kSEEMreUtbyf#oTici<;X&ejN#2w&}HKer-blzfdYwzJ-a{%6`RoqLSM6%dSd}i zy#yPMl-K?7qk2VcX6MYf0_l)m(4i>3U&RbY@;7SG!GrjT+C)mFUOBV`!a3V{i-LJj zVF58aMoaglP{8}u)hq*8RhhrhK~7`55b{cDsPFgftq*RLI9O$>i-v_~tkRu;8Ih9A zcSS|y3wj>TTwIbE;CIY3?;k_*(jRbiS{eF5X8cy|w_HvM^tpb3ameDf9u$QT z%TX^mN1ubH;a8gWA&&tlwey2Ahu4(L|M(A`*I;GDtc3#t7=H)-s=*%)Z}DfQwSD9Y ze*eZ8Uvrjuyi(z{^S1sw)a3MPwMq#g+64urc`!!(_eHy`=+B=& z+dCTmc=O~HAsypCZdx&CVVfL^j-FoB(2yAu2M2#Lz5vfD*;gfcCFL@M@BcNRQU^Eu znQ@*~jk|AUu)E=RWW1q^;%$^aFAqxGC*uWcG5Z>7=7S4>9m0c(OztE~Qi=UR%Y$-Q zn-SZt(#&Lp{td2_*~*l~4~IHPR9R$Yl^QCRkjK=VG8p0HOkvH8?@JtYyHUy~h%dWA z+6s%Si}q8R@my*Z)RLfQTROaMQ0?1u$B5(C_tkw4CEtpY)tEymKGN}h;13(bo6~If zZP(eq{i_Q=LmDM=s~lNJhP?XhuiL5TLf_6EAOpQBK9h&nnsxZwQ_L6BNB5f?Z}MvJ zttf_TeqNUOp3h%K6YuNaTuq>T+SQj+l*>0Z+S#<%zSA#UJ9(eXfl=v!^p{Qo!KL#4 z3r>V&g-`iJyW3m`K2xdxofbt_d~;d{xA#jRZpyJ#rm}DXxq(%vMf{AS-aBV$jzi@7dVIn z8|9uUQf7(amjv6yU4y-37MkfpD9d2=vA)>anfG>~_{j%eMvx`JD zZUGmvV6RKp*Z+RXh?s=v1y7=QHfWFqGA$n1D8x;*Yd(AGp6klPmN1{7>G6~z@UG$b zo6PzD?l;p_5{X3%)k>{<7bxqnMm%$~v9r_Cb*%MEnkqxOsn^GT`!rU%$g?1HXTmR_ zmO4x32J&s{5Bf!-I|sh7-owjx!RoNKzY3NM`nBR^h7l1uIV=8SmI9kTub1)_*v<`m?&uw?iYgk#BB7o2hbfN$jwO1F(9WomoC2gmM1@ufNZiq0Vt=$E7TQHNd#+y<3CN zZ#b&j{VoW;i{toie;Unr^ECZV9YS{cnak6MP$xuuaqFJ6uj zoR5B=;Hqfdba%EnM6BoTcQe`u$h(XETcClw{cwu{!fvnLjFk86}!x5qy} z6rxw$mOoCtV)8=L=I?97yyUK8+RBOw_r4~g7rQfjk>gpb+CPX7Fg#?Kc+C_L`ad+|%eRS@5uZ~&Vu4yJKfgZhNn8FN zqNJy1MVP*Oazvikzb?gP!w8wh!1CF1UQ*@8| zU9<_#5iRTyfdvC8?_J)cu74_aMVMjQ&x9MT{1&bLo)q8f+RPKW1N| zfsyaFO)a8Rw^|h!TT}rn@zln9bkrY1d`tEF#Mk!=i*!$DgWbdekCX#+lL98Mm<9w| zfg5jDSYP${k+nmu`d=o3VGg@@noGu6Dy;B|C;ei;$#nb`%QC+9MO8UtWjW(PArs;w zbpiqc0v;)8VMKJaX2j%8V`Jk$4!zAkb_TJQ@o`R9`>5UKYb+p==pOr_q-PUss9kI! z(p67SHx--3BYmzfrzz7UGWqlf?oM=D^%_tdH4+Z5LP-PA3G>p**SF95nwt)ElhlKh zo6I=j=)c*zs9L6zBg|FDOQjS8qHnMFI+qfV8G-E_32_mvtzGv7``rwqV?>5)W&U?U zVY|cMMUt+-B6{lLBF&-Wda&eq%mFV&*o|f4&r5vJauye3ylv_4>*{j7L~4BI77+KF z(JcVUM!P_uPoBDJ6ny4KHYE)&<1H=;31_!$p#cO-;`8`(8rPSoVU>IsI+X#w84^ZT zeqvr^PxK9`yyLsk`eJ!nE{flF?%f|F9?#j_|7Ng-ZwuduG6J3t`0n0knb33q&KL#& zN+@|QHwN-n$~#BsSSO|pb-m<566&91C)Oxs%myijmY#EWR@q@!vPPL1lrD^%E;^8E7z_Bbc8)wk2MsWb(ZG=@Gd|yET3OXL0^q??gPR zYjQKc_K#yCNoxr3HLqeaD?W(?bTo`wcm_$Odac3f& zFaGi)c3MUT9+4d(;oXU*271$n=3WEyQX6zCu_vAvy2dc^i#{RqUo|Kn`h_}gujq?P z|14&DO7sv6rON&Nw!G*uL7ZUOu(Q{Zipnh!V3)p3Yml#~lTyqCRZ{zgNc?1p}SlOc^hGw`(Z`(iIyFzO!G ztqB{!o(ou_(sA+UhbB2Fp*p8cW%fuX$H$U4epOa5&Z)y5wVX!;yA6UsFum3tL#{jf zT?B|=+rCTN705)z0~Au9!_YP4x5}A1-rAKMzwM=7Bx;IK`(^d%r{L6W_p+SCOxvC1 zIIp5&({1-{!K;s2ejJ!AScnh|RqrL6Ok|?aHV(a)sk3;N61Lgu`BGi`s(6&YvArJpF4E9*E_MbM026t)wziu5 zxPpMFc5%%-)LL5PxdEMsp} zc4%^tUpmEU@M6g1dV1ub@7nK%vVfBjB%XLaE_=R5L2gH6RU$0e{K=K@-m7abW?ZkL zZ9J2F?O0e+pOA{m{%uI3157-PtcLqb%|}*85M|nkh9WzgbLxdeqLr}y(F*4X>5JCcu2Fv=`mH&^gqWQ z8|Lnq^0Xr-!&YC>P*z{<#MVC%-~l-#N;wP#=qp+)1rgX-Sdf79ekJcPe;?!i2%~-> z{oe^^UlL|MlOXv$kI)H5%bYBkU2)tTJ7-Q0-rn9&c=dkR@x~o6)|VoVBH$X5HZX^} z)o_1%9sRK!XVXOw=eNNgA`gvWj>i;Dj$v=r72&8%90@)6nimt?ynVHyD25nf;T_k50l|9if&_+&+tsyPVHzODa zm_M|)+Qfrp@4tyOi+=nEu|5AD9E@0Ne%iiJm6GcK4arxi91 zVH9QtxCwY?7XZR-#CBA|*Q^75kHx7MJ?Z{cGQnlBSa8lGI)M zrdHU|bo*g(Q$t&E0sK1MdsK+jD4N7$dmpsAE=90-iMfXpCxQ3u(TXd2$1bjYv1W*I ziUu^y8pb%QaReo*`FhdM5C5;fgXm1h@fHH7UP#bOvU zqT&~ZAZ7iWA##0XVM|EpfKeZaHS$-#i6~io(XRv2Db=mUmXv&?RG6RdBn_X^w`nv> z6Buk3VD7;abW%b?hzd^$ic?%LT*dEjXW$urf7LokEnhG@N=W}S-70E>;M8EJww6~F z?bN?@&eb-$#mQI=Pr?C}SP~bg3W*T0W9UX^!T4*2%Wo+nM7t(HsC0yQ#r zzJ=WL&g~g2$p`_Hl%<_U#1fsrW5xh!xJ*1ZKoMUeZf!ycYm2{q64u#CmqKaa-v2F7 zC#A{&8vgJBAUV(N+?2{f*p{N~aw@l1O7I zMN?B742$1)qv*0lHn7XXk+!xL+vS+cIv@%+^GxNrEdw!Vkdb?yV}?gR zQwLw3!bO0Fy1Hn!qafk>Yni14QQd4{mZGNBnoXhEI|$sVdvU{h)Z|~*Qm48fy5#w! zHs$D7^Fx`#$L>2#$k%`t`j11qKmPtI-C`RsX^}&!Yi8ske=)5;z01J0L>r`6_HAHz zIB~I0UsgTsisQ@Y27Qan*%-zM8e+-FerCVg>9q5010!S_ZJ-sqX@B;x4XH2yBTKeB zL_WKqe5%|gt${B7nO!UT6CknjXwKS0%~(O-LE6CJDY##|Z<%OShxK9aE!q8x<3*0< z@-qI@cVV^XNa~QU=#6H9ODO-x+jq)00DVqDIf;aFe6W#Kz_7dBIXm1YFzN0(xNe)} z#Y>sos)=#}va%A#0lr28&>`R=BBG&#UclO;^+xPFY%j3d^`kX=8S-=;VH*Tfo z6Qvp-Aw3+bGjY~WF?;946`e9!gBh_gEsIoU$QqEZ5tyiH^vzJUJ3&JKP>qt#_4Zu3TRn zL_hYeRQ}u=_eSemV^p!Gsa~kI3c;_ihUiQ&&jdKc&>k$j*U=%Ho1dqwN9pM_G~Ft* zgvHK}9>=wQdZ1$r`l$T(=`R%gwU#+&WNO>R;_Ar}@)Sl>6Hbr%>gLS^fDlnNwFroLbqzf3vTz+iMfuz9)MC0-m_UX z2=aU(r|ydD!}1dUv{#ac_PEHCW5(5YSbjn+yj@x*SjaeRx@WY%p;;%X7$=wILV)5S z4Ev#~>fhCrS3@?VOw5mR#tkl3TCwk#w)G9-y?c#~22=gPUl>TyC(?^21MfTc>8YT|K*~8`<9FP;YD4%i6*9m1tOK z@bJPFkYxk~#>G!6suR<2OUu?ro`ovMslOn9894q{(vq_$_cxOQPF@gN_o!gBEr$=u zbT6T@GY+$Xb4Yc5DVBg*=1W;G;i#B3|0(r1Z$d7LS)hHW2kgJK(AJ}2@6Fuib8=|A z5e0{B`na$jSw%!a`WewyQ)G)WeNxHvuLC ziack7bjqtZy!nqOKF~15_(Bwv&$i}l2&ozbaq$g*bj-=ux8?t}hR~V$Umn5ar_0|_ z3ip9G72%)w{VFXZzXKlftn{bbYeb-Y@ddj-86T9oPFwG_cRsPCz}c1cr>=A$%}-uZ zV~@nr;sqdC+FtK9Awk|Q2Gt9rdm8?<b<@x zI3p;8Cxppqy)JV^f;^{R2gruepFeozb^%0a_OcV01>SpH;2eY1)UJoP*L<29)>3vQg|EGaXH^b zMVz^IRDn4r+vi?a$P_WsR(1?JKgf-_A(K1N5F!(hoe2wgdUb&s^20CkQ!Vbn<%VwF z`!t`D-HZ@R0Q>mT%>TT+-k@W3=+(;u!Z7^<3G#}*_jh&mbr>V^-SJ1N zA{Yb{@*(OpK^C;5 z(V&b>Xa^plHV^LTIAQUb)LNuboTM};Wm!PP5wQQ6_?+Z^D&Nn)*IEtMS~D-H(fXoH`U%>zr9KYJ|i!W-rku!amh&gEVFU zZ*toU0|^0~`mj+D#qZ&3II*$m_k$|8xu4w>8L^*+Qdl7Xf%w%>$krD>hA$`dGW zDEjq-SO1u#^QL$6Ey%(QTh;Xp0;UCS8G&Vh<>c4QhoIBi(CVDl18x8AoYn`F05@-u zgux+P`>A6Vs^dk|M)Mlk*XYrnUB8rQ&YZ!Rj_*45np|?6emCQjhVa<(Zt}22!Ri&( z#5bh6SgFXEf`O~?<0p%z@+G}+_njc{A&*x{1eGf){xmWi0idOBdyf(&#;PSr+#d&F zT;HS(oX+TGQ&m-yzv6JmI_m%Yyf|*1hmcgzJ!8a_8lW3=^+#9Ycq8riMJd7G=$=ioN675ACn6dz8n#96kDGAOb%#b6IXYGr zO?up2yM^~04be|H>>l(oym}&t@dYJrRkq^zkBNN_EvOQuW=n~0wE9=0&?0NSVjNbm zkL(C~y|H71+$ZOgT%4kmpbK~tRx?R)jDF-Vs|Lo<1}z%%LcU$CN2nr~sWwKcx5>Rk zV&UUUBy0usLwbA^0sy`dpk=+`K0Ej=r_p?~u`l5?ok!OV5*pn2`lz@M^)49L4h{E& zD}}Bdmo$Oqz3S98;(OtmY&@qP_z{6s*_uBh*(znNP{xK!N(3KV7&&=PT!*3-PYhQt zD-6j;+Wc7UxIN;l0I<-z-*%}*7dg4KwZ5Jo{^S8}U8gq&<|I%7V{>zJ&jybYt0pSf z;DuxtvTUF%Ae6)eaE2kVUX(#u%?f9~^Ww|QMGOS_sX$Z&-B!o|W1rg^t_5D>otE>W z*56TW7MEqbFJeqB#n1Y}Rl5oP?7Z^bkj|}2zeR)hqIy7T>FQnVN)0~+(U@A=TzELz zl`T^m_r!C4b^h5srdIZHI)_#j$tAXCSX@e~;6wp<@Hl)5&{+554YbrlBNva8%JeLK zxar2sM@i7~**Nfz-z`%lwe`d*SLnB9R6IBlsi|By(y7MdLxZ`4++zSov_$($*g#vfFd0hMEtxwOAH}j65snJRy%H_+E9k;iW^E{uvZO1E1 zkl~3O5jNko-}k-N^`Y88m?vllOPsT-sy=%&Gy6@2;Nt1ogcjnsm<7~dEA&wRx{sm$ z^=oVo5*+k#Z~W9mjVMEy4Nv!;tybid$srCaH;R?4IX&L%AJP@5SiIy|4Qj@eO^ts+ zTEb!|!kc1e-YTSKhLqxp_07$kqN0eJdqJ+wXRQYxw}={1n7KT{8_{E%DM!&xCLdxj zeH(dViQ9M61B*uDB;7_N$Hmpe#HiHlJ}L=^{|VD9c!f_XDCWBTNq_I&gPTI)_1x|k z1k*C+z~g0aE}WCK^6~E}ynFP4p^8i4X617J2}vKCtv*-xtN+H{_|BS>aHsi%7Yi$q zVOj^w2%x!qAVuaJpt4mlPzY7~G?vdeV4m4Z%dFtP|B_}zWV9|@si8XgUaiVYvPsx{+e}z6C|#;S z1&;RuSG5utm;0#wB9VJZzVgw35ZFkgd)BSw{qJe9w<8y@j_W_^x{-KEA&ALc#>0 z#GO^W_Rl7JO9^SjeMGe*RzhzXt9-EZQ@lDdm)5K0o<>4S$6{Vu&{I4x_Du};gH%f| zMMwf{(^ocN5;U~{-{ynp-;8-ZD75xSSkK6n1&6 zD<~ekWl5B?edZKsW;P4;YBh`p=ihm2dhgue0v!O$z)W)uae0IT@Lm=dBv3VbW zBk&elPh4n;quK*<9BK7O;31yI5;Uk58jfC&~GhnvJaR|ZO=G~ zSxDSq!cE1~U{{q!5BZd15Cn}sZbhI)XG&$>>n~=(7sVz zaVIB|g94AEk++5XYN2UDE(OCjYf;aRO=2)>8A3KwXh5I$w{`-LOeq7oS@AcstwN)0 zHK=b9?0x%l?�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%0A=j(P2Fp^QgTlrLq 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 PQ;>?ns~1&rCL#X^3LR{y From 3208404f14a7526887199af041912da5929c9543 Mon Sep 17 00:00:00 2001 From: oranges Date: Sun, 31 Dec 2017 11:58:41 +1300 Subject: [PATCH 058/122] Merge pull request #33580 from Xhuis/defenses_balancing Some modest clockcult balancing - vitality matrices, brass skewers, pressure sensors --- code/__DEFINES/status_effects.dm | 2 ++ code/datums/status_effects/debuffs.dm | 24 +++++++++++++++ code/datums/status_effects/status_effect.dm | 1 + .../clock_cult/clock_effects/clock_sigils.dm | 27 ++++++++++------ .../clock_scriptures/scripture_scripts.dm | 6 ++++ .../trap_triggers/pressure_sensor.dm | 2 +- .../clock_structures/traps/brass_skewer.dm | 29 ++++++++++++------ .../mob/living/carbon/human/examine.dm | 16 ++++++++++ .../mob/living/silicon/robot/examine.dm | 1 + icons/mob/screen_alert.dmi | Bin 75852 -> 77077 bytes 10 files changed, 87 insertions(+), 21 deletions(-) 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/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/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_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/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index bc4fd83334..9999d8c330 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -121,6 +121,9 @@ if(wear_id) msg += "[t_He] [t_is] wearing [icon2html(wear_id, user)] \a [wear_id].\n" + //Status effects + msg += status_effect_examines() + //Jitters switch(jitteriness) if(300 to INFINITY) @@ -354,3 +357,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/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/icons/mob/screen_alert.dmi b/icons/mob/screen_alert.dmi index ef680c266a9ce8e5ae33d7eccc7e83e972c3d7ce..e6d40977a7accd2dbc7ed07ab77a71fe991ef0e6 100644 GIT binary patch delta 5764 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 Date: Sat, 30 Dec 2017 18:23:25 -0500 Subject: [PATCH 060/122] Fixes vore not functioning --- .../code/modules/mob/living/carbon/human/human_defense.dm | 5 +++++ tgstation.dme | 1 + 2 files changed, 6 insertions(+) create mode 100644 modular_citadel/code/modules/mob/living/carbon/human/human_defense.dm diff --git a/modular_citadel/code/modules/mob/living/carbon/human/human_defense.dm b/modular_citadel/code/modules/mob/living/carbon/human/human_defense.dm new file mode 100644 index 0000000000..b61df944d1 --- /dev/null +++ b/modular_citadel/code/modules/mob/living/carbon/human/human_defense.dm @@ -0,0 +1,5 @@ +/mob/living/human/grabbedby(mob/living/carbon/user, supress_message = 0) + if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && isliving(pulling)) + vore_attack(user, pulling) + else + ..() \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index 30c5ff3848..1f3ea9671d 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -2473,4 +2473,5 @@ #include "modular_citadel\code\game\objects\items\melee\eutactic_blades.dm" #include "modular_citadel\code\modules\crafting\recipes.dm" #include "modular_citadel\code\modules\mob\living\silicon\robot\robot_modules.dm" +#include "modular_citadel\code\modules\mob\living\carbon\human\human_defense.dm" // END_INCLUDE From 06901e1edca86c3cd44cefa1ce8e125ee49e9f41 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sat, 30 Dec 2017 17:43:28 -0600 Subject: [PATCH 061/122] Automatic changelog generation for PR #4610 [ci skip] --- html/changelogs/AutoChangeLog-pr-4610.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4610.yml diff --git a/html/changelogs/AutoChangeLog-pr-4610.yml b/html/changelogs/AutoChangeLog-pr-4610.yml new file mode 100644 index 0000000000..cdcfbde61b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4610.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - bugfix: "Vore is no longer restricted to monkeys." From 38870f4056daa2c0a7e2a44315a1c266d00ad0b0 Mon Sep 17 00:00:00 2001 From: Tad Hardesty Date: Sat, 30 Dec 2017 19:26:47 -0800 Subject: [PATCH 062/122] Fix PDA message photos not being viewable --- code/game/machinery/computer/message.dm | 2 +- .../telecomms/machines/message_server.dm | 180 ++++++++++++++++++ 2 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 code/game/machinery/telecomms/machines/message_server.dm diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index a3ec6ba6ec..13ad75d7cc 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -126,7 +126,7 @@ break // Del - Sender - Recepient - Message // X - Al Green - Your Mom - WHAT UP!? - dat += "
X
[pda.sender][pda.recipient][pda.message][pda.photo ? "(Photo)":""]" + dat += "
X
[pda.sender][pda.recipient][pda.message][pda.photo ? " (Photo)":""]" dat += "" //Hacking screen. if(2) diff --git a/code/game/machinery/telecomms/machines/message_server.dm b/code/game/machinery/telecomms/machines/message_server.dm new file mode 100644 index 0000000000..e0e88cce65 --- /dev/null +++ b/code/game/machinery/telecomms/machines/message_server.dm @@ -0,0 +1,180 @@ +/* + The equivalent of the server, for PDA and request console messages. + Without it, PDA and request console messages cannot be transmitted. + PDAs require the rest of the telecomms setup, but request consoles only + require the message server. +*/ + +// A decorational representation of SSblackbox, usually placed alongside the message server. +/obj/machinery/blackbox_recorder + icon = 'icons/obj/stationobjs.dmi' + icon_state = "blackbox" + name = "Blackbox Recorder" + density = TRUE + anchored = TRUE + use_power = IDLE_POWER_USE + idle_power_usage = 10 + active_power_usage = 100 + armor = list(melee = 25, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 70) + + +// The message server itself. +/obj/machinery/telecomms/message_server + icon = 'icons/obj/machines/research.dmi' + icon_state = "server" + name = "Messaging Server" + desc = "A machine that attempts to gather the secret knowledge of the universe." + density = TRUE + anchored = TRUE + use_power = IDLE_POWER_USE + idle_power_usage = 10 + active_power_usage = 100 + + id = "Messaging Server" + network = "tcommsat" + autolinkers = list("common") + + var/list/datum/data_pda_msg/pda_msgs = list() + var/list/datum/data_rc_msg/rc_msgs = list() + var/decryptkey + +/obj/machinery/telecomms/message_server/Initialize() + . = ..() + if (!decryptkey) + decryptkey = GenerateKey() + pda_msgs += new /datum/data_pda_msg("System Administrator", "system", "This is an automated message. The messaging system is functioning correctly.") + +/obj/machinery/telecomms/message_server/proc/GenerateKey() + var/newKey + newKey += pick("the", "if", "of", "as", "in", "a", "you", "from", "to", "an", "too", "little", "snow", "dead", "drunk", "rosebud", "duck", "al", "le") + newKey += pick("diamond", "beer", "mushroom", "assistant", "clown", "captain", "twinkie", "security", "nuke", "small", "big", "escape", "yellow", "gloves", "monkey", "engine", "nuclear", "ai") + newKey += pick("1", "2", "3", "4", "5", "6", "7", "8", "9", "0") + return newKey + +/obj/machinery/telecomms/message_server/process() + if(toggled && (stat & (BROKEN|NOPOWER))) + toggled = FALSE + update_icon() + +/obj/machinery/telecomms/message_server/receive_information(datum/signal/subspace/pda/signal, obj/machinery/telecomms/machine_from) + // can't log non-PDA signals + if(!istype(signal) || !signal.data["message"] || !toggled) + return + + // log the signal + var/datum/data_pda_msg/M = new(signal.format_target(), "[signal.data["name"]] ([signal.data["job"]])", signal.data["message"], signal.data["photo"]) + pda_msgs += M + signal.logged = M + + // pass it along to either the hub or the broadcaster + if(!relay_information(signal, /obj/machinery/telecomms/hub)) + relay_information(signal, /obj/machinery/telecomms/broadcaster) + +/obj/machinery/telecomms/message_server/update_icon() + if((stat & (BROKEN|NOPOWER))) + icon_state = "server-nopower" + else if (!toggled) + icon_state = "server-off" + else + icon_state = "server-on" + + +// Repath for maps +/obj/machinery/message_server + parent_type = /obj/machinery/telecomms/message_server + + +// PDA signal datum +/datum/signal/subspace/pda + frequency = FREQ_COMMON + server_type = /obj/machinery/telecomms/message_server + var/datum/data_pda_msg/logged + +/datum/signal/subspace/pda/New(source, data) + src.source = source + src.data = data + var/turf/T = get_turf(source) + levels = list(T.z) + +/datum/signal/subspace/pda/copy() + var/datum/signal/subspace/pda/copy = new(source, data.Copy()) + copy.original = src + copy.levels = levels + return copy + +/datum/signal/subspace/pda/proc/format_target() + if (length(data["targets"]) > 1) + return "Everyone" + return data["targets"][1] + +/datum/signal/subspace/pda/proc/format_message() + if (logged && data["photo"]) + return "\"[data["message"]]\" (Photo)" + return "\"data["message"]\"" + +/datum/signal/subspace/pda/broadcast() + if (!logged) // Can only go through if a message server logs it + return + for (var/obj/item/device/pda/P in GLOB.PDAs) + if ("[P.owner] ([P.ownjob])" in data["targets"]) + P.receive_message(src) + + +// Log datums stored by the message server. +/datum/data_pda_msg + var/sender = "Unspecified" + var/recipient = "Unspecified" + var/message = "Blank" // transferred message + var/icon/photo // attached photo + +/datum/data_pda_msg/New(param_rec, param_sender, param_message, param_photo) + if(param_rec) + recipient = param_rec + if(param_sender) + sender = param_sender + if(param_message) + message = param_message + if(param_photo) + photo = param_photo + +/datum/data_pda_msg/Topic(href,href_list) + ..() + if(href_list["photo"]) + var/mob/M = usr + M << browse_rsc(photo, "pda_photo.png") + M << browse("PDA Photo" \ + + "" \ + + "" \ + + "", "window=pdaphoto;size=192x192") + onclose(M, "pdaphoto") + +/datum/data_rc_msg + var/rec_dpt = "Unspecified" // receiving department + var/send_dpt = "Unspecified" // sending department + var/message = "Blank" + var/stamp = "Unstamped" + var/id_auth = "Unauthenticated" + var/priority = "Normal" + +/datum/data_rc_msg/New(param_rec, param_sender, param_message, param_stamp, param_id_auth, param_priority) + if(param_rec) + rec_dpt = param_rec + if(param_sender) + send_dpt = param_sender + if(param_message) + message = param_message + if(param_stamp) + stamp = param_stamp + if(param_id_auth) + id_auth = param_id_auth + if(param_priority) + switch(param_priority) + if(1) + priority = "Normal" + if(2) + priority = "High" + if(3) + priority = "Extreme" + else + priority = "Undetermined" + From 9c8959f2ff197f7c8b8f65a4870f8564e2bc79ab Mon Sep 17 00:00:00 2001 From: F-OS Date: Sun, 31 Dec 2017 01:23:42 -0700 Subject: [PATCH 063/122] Last resort now requires a confirmation. (#33947) * Update headcrab.dm * fixed * fuck * Update headcrab.dm * Update headcrab.dm --- code/game/gamemodes/changeling/powers/headcrab.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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!") From 9dd9d9413add613e6d36c1080a2f366062bab88d Mon Sep 17 00:00:00 2001 From: vuonojenmustaturska Date: Sun, 31 Dec 2017 10:26:43 +0200 Subject: [PATCH 065/122] Improves loot drop spawners, adds AI law spawners to cores (#33945) * hymn to breaking strain * remove subtypes as requested * no-one saw that --- _maps/map_files/BoxStation/BoxStation.dmm | 5 ++- .../map_files/Deltastation/DeltaStation2.dmm | 40 +++++++++---------- _maps/map_files/MetaStation/MetaStation.dmm | 5 ++- _maps/map_files/OmegaStation/OmegaStation.dmm | 40 +++++++++---------- _maps/map_files/PubbyStation/PubbyStation.dmm | 5 ++- .../game/objects/effects/spawners/lootdrop.dm | 16 ++++++-- 6 files changed, 58 insertions(+), 53 deletions(-) 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..0352106ad4 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 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/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 From 7dac76651e0d918027425d4985d3a8728b17aba7 Mon Sep 17 00:00:00 2001 From: BeeSting12 Date: Sun, 31 Dec 2017 03:27:37 -0500 Subject: [PATCH 067/122] Makes it clear that command reports are IC. (#33949) * fixes #33936 * sticky's idea was better --- code/modules/admin/verbs/randomverbs.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From a57eba6a16e49194a9798702e2f39905a95fb9eb Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sun, 31 Dec 2017 03:32:38 -0500 Subject: [PATCH 069/122] Explosions now cause camera shake based on distance (#33570) * Explosions now cause camera shake based on distance * Explosion close camera shake down to 2.5s * Explosion camera shake max 100 close intensity, 50 far --- code/datums/explosion.dm | 4 ++++ 1 file changed, 4 insertions(+) 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 From 3e5c7eb8978492cf0b8ccbd4efba5b00c2f466ba Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 31 Dec 2017 02:50:56 -0600 Subject: [PATCH 071/122] Automatic changelog generation for PR #4607 [ci skip] --- html/changelogs/AutoChangeLog-pr-4607.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4607.yml diff --git a/html/changelogs/AutoChangeLog-pr-4607.yml b/html/changelogs/AutoChangeLog-pr-4607.yml new file mode 100644 index 0000000000..1ce8e2136e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4607.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - tweak: "The chemistry job has been removed from Omegastation. Medical doctors still have full chemistry access" From 305d07faa291fb3877cd718b039a9620d90a45ac Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 31 Dec 2017 02:51:29 -0600 Subject: [PATCH 072/122] Automatic changelog generation for PR #4608 [ci skip] --- html/changelogs/AutoChangeLog-pr-4608.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4608.yml diff --git a/html/changelogs/AutoChangeLog-pr-4608.yml b/html/changelogs/AutoChangeLog-pr-4608.yml new file mode 100644 index 0000000000..dc7a2844d9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4608.yml @@ -0,0 +1,4 @@ +author: "MrDoomBringer" +delete-after: True +changes: + - imageadd: "NanoTrasen has sent the station new spaceheaters! They look nicer now!" From 92a7555322e59eec3a001e829c612fd7ae03a7c9 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 31 Dec 2017 02:51:47 -0600 Subject: [PATCH 073/122] Automatic changelog generation for PR #4609 [ci skip] --- html/changelogs/AutoChangeLog-pr-4609.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4609.yml diff --git a/html/changelogs/AutoChangeLog-pr-4609.yml b/html/changelogs/AutoChangeLog-pr-4609.yml new file mode 100644 index 0000000000..9f47aa2917 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4609.yml @@ -0,0 +1,8 @@ +author: "Xhuis" +delete-after: True +changes: + - balance: "Vitality matrices now apply Ichorial Stain when reviving a dead servant, which prevents that servant from being revived again by vitality matrices for a full minute." + - balance: "Vitality matrices can't be placed adjacent to one another." + - balance: "Brass skewers now damage and stun cyborgs." + - balance: "Vitality matrices no longer drain people impaled on brass skewers." + - balance: "Pressure sensors have 5 health again (down from 25.)" From cf1dc29d3bd4182bd328e009a10b2f0a82b3047b Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 31 Dec 2017 02:52:05 -0600 Subject: [PATCH 074/122] Automatic changelog generation for PR #4611 [ci skip] --- html/changelogs/AutoChangeLog-pr-4611.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4611.yml diff --git a/html/changelogs/AutoChangeLog-pr-4611.yml b/html/changelogs/AutoChangeLog-pr-4611.yml new file mode 100644 index 0000000000..135f53690f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4611.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Viewing photos sent by PDA message works again." From 01e744041be6bad0be7de920d4d108a17ab051d0 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 31 Dec 2017 02:52:32 -0600 Subject: [PATCH 075/122] Automatic changelog generation for PR #4612 [ci skip] --- html/changelogs/AutoChangeLog-pr-4612.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4612.yml diff --git a/html/changelogs/AutoChangeLog-pr-4612.yml b/html/changelogs/AutoChangeLog-pr-4612.yml new file mode 100644 index 0000000000..1bb68ce590 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4612.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Last resort now requires a confirmation" From 2268a2e53c1d1a67db8c3eb8291d8dbcc90180a8 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 31 Dec 2017 02:52:46 -0600 Subject: [PATCH 076/122] Automatic changelog generation for PR #4613 [ci skip] --- html/changelogs/AutoChangeLog-pr-4613.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4613.yml diff --git a/html/changelogs/AutoChangeLog-pr-4613.yml b/html/changelogs/AutoChangeLog-pr-4613.yml new file mode 100644 index 0000000000..871d1fc7ac --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4613.yml @@ -0,0 +1,5 @@ +author: "Naksu" +delete-after: True +changes: + - code_imp: "loot drop spawners now assign their pixel offsets to the items they spawn, also have a \"fanout\" setting to distribute items in a neat fashion like in omega/delta's core and some tech storages." + - tweak: "replaced several law boards in uploads with spawners, the net result being one more board in uploads that may be a duplicate asimov (but hopefully isn't)" From 38ddc2c0e32ece50d64d5b935d3afc38de0324c3 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 31 Dec 2017 02:53:36 -0600 Subject: [PATCH 077/122] Automatic changelog generation for PR #4615 [ci skip] --- html/changelogs/AutoChangeLog-pr-4615.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4615.yml diff --git a/html/changelogs/AutoChangeLog-pr-4615.yml b/html/changelogs/AutoChangeLog-pr-4615.yml new file mode 100644 index 0000000000..f7e0e15470 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4615.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "Explosions now cause camera shake based on intensity and distance" From bbca0afa37c3bb5bdc169cd56c6969e18029715e Mon Sep 17 00:00:00 2001 From: AnturK Date: Sun, 31 Dec 2017 13:30:00 +0100 Subject: [PATCH 078/122] Fixes thermals, also drops the see invisible from thermals. (#33950) --- code/modules/clothing/glasses/_glasses.dm | 4 ++-- code/modules/clothing/glasses/hud.dm | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) 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/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) From 7a6cf002d344f11119459ab3723ac5df3eef0c9f Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 31 Dec 2017 06:41:03 -0600 Subject: [PATCH 080/122] Revert "[MIRROR] Fix PDA message photos not being viewable" --- code/game/machinery/computer/message.dm | 2 +- .../telecomms/machines/message_server.dm | 180 ------------------ 2 files changed, 1 insertion(+), 181 deletions(-) delete mode 100644 code/game/machinery/telecomms/machines/message_server.dm diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index 13ad75d7cc..a3ec6ba6ec 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -126,7 +126,7 @@ break // Del - Sender - Recepient - Message // X - Al Green - Your Mom - WHAT UP!? - dat += "
X
[pda.sender][pda.recipient][pda.message][pda.photo ? " (Photo)":""]" + dat += "
X
[pda.sender][pda.recipient][pda.message][pda.photo ? "(Photo)":""]" dat += "" //Hacking screen. if(2) diff --git a/code/game/machinery/telecomms/machines/message_server.dm b/code/game/machinery/telecomms/machines/message_server.dm deleted file mode 100644 index e0e88cce65..0000000000 --- a/code/game/machinery/telecomms/machines/message_server.dm +++ /dev/null @@ -1,180 +0,0 @@ -/* - The equivalent of the server, for PDA and request console messages. - Without it, PDA and request console messages cannot be transmitted. - PDAs require the rest of the telecomms setup, but request consoles only - require the message server. -*/ - -// A decorational representation of SSblackbox, usually placed alongside the message server. -/obj/machinery/blackbox_recorder - icon = 'icons/obj/stationobjs.dmi' - icon_state = "blackbox" - name = "Blackbox Recorder" - density = TRUE - anchored = TRUE - use_power = IDLE_POWER_USE - idle_power_usage = 10 - active_power_usage = 100 - armor = list(melee = 25, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 70) - - -// The message server itself. -/obj/machinery/telecomms/message_server - icon = 'icons/obj/machines/research.dmi' - icon_state = "server" - name = "Messaging Server" - desc = "A machine that attempts to gather the secret knowledge of the universe." - density = TRUE - anchored = TRUE - use_power = IDLE_POWER_USE - idle_power_usage = 10 - active_power_usage = 100 - - id = "Messaging Server" - network = "tcommsat" - autolinkers = list("common") - - var/list/datum/data_pda_msg/pda_msgs = list() - var/list/datum/data_rc_msg/rc_msgs = list() - var/decryptkey - -/obj/machinery/telecomms/message_server/Initialize() - . = ..() - if (!decryptkey) - decryptkey = GenerateKey() - pda_msgs += new /datum/data_pda_msg("System Administrator", "system", "This is an automated message. The messaging system is functioning correctly.") - -/obj/machinery/telecomms/message_server/proc/GenerateKey() - var/newKey - newKey += pick("the", "if", "of", "as", "in", "a", "you", "from", "to", "an", "too", "little", "snow", "dead", "drunk", "rosebud", "duck", "al", "le") - newKey += pick("diamond", "beer", "mushroom", "assistant", "clown", "captain", "twinkie", "security", "nuke", "small", "big", "escape", "yellow", "gloves", "monkey", "engine", "nuclear", "ai") - newKey += pick("1", "2", "3", "4", "5", "6", "7", "8", "9", "0") - return newKey - -/obj/machinery/telecomms/message_server/process() - if(toggled && (stat & (BROKEN|NOPOWER))) - toggled = FALSE - update_icon() - -/obj/machinery/telecomms/message_server/receive_information(datum/signal/subspace/pda/signal, obj/machinery/telecomms/machine_from) - // can't log non-PDA signals - if(!istype(signal) || !signal.data["message"] || !toggled) - return - - // log the signal - var/datum/data_pda_msg/M = new(signal.format_target(), "[signal.data["name"]] ([signal.data["job"]])", signal.data["message"], signal.data["photo"]) - pda_msgs += M - signal.logged = M - - // pass it along to either the hub or the broadcaster - if(!relay_information(signal, /obj/machinery/telecomms/hub)) - relay_information(signal, /obj/machinery/telecomms/broadcaster) - -/obj/machinery/telecomms/message_server/update_icon() - if((stat & (BROKEN|NOPOWER))) - icon_state = "server-nopower" - else if (!toggled) - icon_state = "server-off" - else - icon_state = "server-on" - - -// Repath for maps -/obj/machinery/message_server - parent_type = /obj/machinery/telecomms/message_server - - -// PDA signal datum -/datum/signal/subspace/pda - frequency = FREQ_COMMON - server_type = /obj/machinery/telecomms/message_server - var/datum/data_pda_msg/logged - -/datum/signal/subspace/pda/New(source, data) - src.source = source - src.data = data - var/turf/T = get_turf(source) - levels = list(T.z) - -/datum/signal/subspace/pda/copy() - var/datum/signal/subspace/pda/copy = new(source, data.Copy()) - copy.original = src - copy.levels = levels - return copy - -/datum/signal/subspace/pda/proc/format_target() - if (length(data["targets"]) > 1) - return "Everyone" - return data["targets"][1] - -/datum/signal/subspace/pda/proc/format_message() - if (logged && data["photo"]) - return "\"[data["message"]]\" (Photo)" - return "\"data["message"]\"" - -/datum/signal/subspace/pda/broadcast() - if (!logged) // Can only go through if a message server logs it - return - for (var/obj/item/device/pda/P in GLOB.PDAs) - if ("[P.owner] ([P.ownjob])" in data["targets"]) - P.receive_message(src) - - -// Log datums stored by the message server. -/datum/data_pda_msg - var/sender = "Unspecified" - var/recipient = "Unspecified" - var/message = "Blank" // transferred message - var/icon/photo // attached photo - -/datum/data_pda_msg/New(param_rec, param_sender, param_message, param_photo) - if(param_rec) - recipient = param_rec - if(param_sender) - sender = param_sender - if(param_message) - message = param_message - if(param_photo) - photo = param_photo - -/datum/data_pda_msg/Topic(href,href_list) - ..() - if(href_list["photo"]) - var/mob/M = usr - M << browse_rsc(photo, "pda_photo.png") - M << browse("PDA Photo" \ - + "" \ - + "" \ - + "", "window=pdaphoto;size=192x192") - onclose(M, "pdaphoto") - -/datum/data_rc_msg - var/rec_dpt = "Unspecified" // receiving department - var/send_dpt = "Unspecified" // sending department - var/message = "Blank" - var/stamp = "Unstamped" - var/id_auth = "Unauthenticated" - var/priority = "Normal" - -/datum/data_rc_msg/New(param_rec, param_sender, param_message, param_stamp, param_id_auth, param_priority) - if(param_rec) - rec_dpt = param_rec - if(param_sender) - send_dpt = param_sender - if(param_message) - message = param_message - if(param_stamp) - stamp = param_stamp - if(param_id_auth) - id_auth = param_id_auth - if(param_priority) - switch(param_priority) - if(1) - priority = "Normal" - if(2) - priority = "High" - if(3) - priority = "Extreme" - else - priority = "Undetermined" - From 19c35c63d6b0a91fa3906f4b2a0a6f86f2c7dc23 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sun, 31 Dec 2017 10:57:03 -0500 Subject: [PATCH 081/122] Merge pull request #33951 from AnturK/perspective_fix Fixes reset_perspective runtimes --- code/modules/mob/mob.dm | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) 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 From d0e5a38c290ece0bc5d2fc6612be5d884dcd6ed8 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sun, 31 Dec 2017 10:58:22 -0500 Subject: [PATCH 083/122] Merge pull request #33954 from jammer312/components_fix fixes component's dupe --- code/datums/components/_component.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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) From 159fe41ab88076c7c50a00032932658af00163e8 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sun, 31 Dec 2017 11:01:16 -0500 Subject: [PATCH 085/122] Merge pull request #33948 from ShizCalev/abstract-frying stops frying abstract or nodrop items --- code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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) From 4e0efc64d599cb289668af99e24e69ce7df0a867 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sun, 31 Dec 2017 11:00:57 -0500 Subject: [PATCH 087/122] Merge pull request #33957 from ninjanomnom/helper-cleanup cleans up some behaviour for PlaceOnTop/Bottom --- code/game/turfs/ChangeTurf.dm | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/code/game/turfs/ChangeTurf.dm b/code/game/turfs/ChangeTurf.dm index 2f165d9a20..b3e542ca0f 100644 --- a/code/game/turfs/ChangeTurf.dm +++ b/code/game/turfs/ChangeTurf.dm @@ -119,27 +119,42 @@ // 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) + 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.Insert(1, 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 += new_baseturfs + // Copy an existing turf and put it on top /turf/proc/CopyOnTop(turf/copytarget, ignore_bottom=1, depth=INFINITY) // x, 1, 0 From 54032f9c6d9c124266ebeadfe7119f1d3f12f16a Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sun, 31 Dec 2017 11:02:40 -0500 Subject: [PATCH 089/122] Merge pull request #33960 from ShizCalev/flamer Corrects flamethrower capitalization --- code/game/objects/items/flamethrower.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) From cf978b0f52719238c60a0e1cd38eab31897610e6 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Mon, 1 Jan 2018 01:23:00 -0500 Subject: [PATCH 091/122] Adds a note on config changes to CONTRIBUTING (#33964) --- .github/CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index a4d6c07526..826a0dc4eb 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -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: From 2c350fcb6cfa399b75620a1951167efebc6c84bf Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sun, 31 Dec 2017 15:25:56 -0500 Subject: [PATCH 093/122] Autotag .github => GitHub (#33965) --- tools/WebhookProcessor/github_webhook_processor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/WebhookProcessor/github_webhook_processor.php b/tools/WebhookProcessor/github_webhook_processor.php index a97b9db1c2..e6956dfb85 100644 --- a/tools/WebhookProcessor/github_webhook_processor.php +++ b/tools/WebhookProcessor/github_webhook_processor.php @@ -220,7 +220,7 @@ function tag_pr($payload, $opened) { else if ($mergeable === FALSE) $tags[] = 'Merge Conflict'; - $treetags = array('_maps' => 'Map Edit', 'tools' => 'Tools', 'SQL' => 'SQL'); + $treetags = array('_maps' => 'Map Edit', 'tools' => 'Tools', 'SQL' => 'SQL', '.github' => 'GitHub'); $addonlytags = array('icons' => 'Sprites', 'sound' => 'Sound', 'config' => 'Config Update', 'code/controllers/configuration/entries' => 'Config Update', 'tgui' => 'UI'); foreach($treetags as $tree => $tag) if(has_tree_been_edited($payload, $tree)) From a881de18b9d054496f72b56fda196bd2b87361a4 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 1 Jan 2018 04:25:40 -0600 Subject: [PATCH 095/122] Automatic changelog generation for PR #4596 [ci skip] --- html/changelogs/AutoChangeLog-pr-4596.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4596.yml diff --git a/html/changelogs/AutoChangeLog-pr-4596.yml b/html/changelogs/AutoChangeLog-pr-4596.yml new file mode 100644 index 0000000000..17bb98f350 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4596.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - tweak: "Burial jumpsuits no longer have suit sensors" From 0fbe251dfe554baa8ebc6dafe30c5be28f730fcc Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 1 Jan 2018 04:26:36 -0600 Subject: [PATCH 096/122] Automatic changelog generation for PR #4599 [ci skip] --- html/changelogs/AutoChangeLog-pr-4599.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4599.yml diff --git a/html/changelogs/AutoChangeLog-pr-4599.yml b/html/changelogs/AutoChangeLog-pr-4599.yml new file mode 100644 index 0000000000..a458b7dcf2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4599.yml @@ -0,0 +1,4 @@ +author: "Cebutris" +delete-after: True +changes: + - bugfix: "Holoparasite injectors can no longer be discounted" From 5486f71010b7c8c54a5adac1f9c5697e71e14044 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 1 Jan 2018 07:30:50 -0600 Subject: [PATCH 097/122] woo --- code/citadel/cit_reagents.dm | 9 ++++----- code/citadel/dogborgstuff.dm | 4 ++-- code/game/atoms_movable.dm | 12 ++++++------ .../code/game/objects/items/melee/eutactic_blades.dm | 2 +- tgstation.dme | 2 +- 5 files changed, 14 insertions(+), 15 deletions(-) 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/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/game/atoms_movable.dm b/code/game/atoms_movable.dm index ddb768488a..e494009e35 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() diff --git a/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm b/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm index 385e9cd9d4..3c564f1807 100644 --- a/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm +++ b/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm @@ -273,7 +273,7 @@ var/mob/M = loc M.update_inv_hands() - clean_blood()//blood overlays get weird otherwise, because the sprite changes. (retained from original desword because I have no idea what this is) + SendSignal(COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)//blood overlays get weird otherwise, because the sprite changes. (retained from original desword because I have no idea what this is) /obj/item/twohanded/hypereutactic/AltClick(mob/living/user) if(!in_range(src, user)) //Basic checks to prevent abuse diff --git a/tgstation.dme b/tgstation.dme index 8217c8adbd..4d7f43a3e4 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -2475,6 +2475,6 @@ #include "modular_citadel\code\game\objects\items\devices\PDA\PDA.dm" #include "modular_citadel\code\game\objects\items\melee\eutactic_blades.dm" #include "modular_citadel\code\modules\crafting\recipes.dm" -#include "modular_citadel\code\modules\mob\living\silicon\robot\robot_modules.dm" #include "modular_citadel\code\modules\mob\living\carbon\human\human_defense.dm" +#include "modular_citadel\code\modules\mob\living\silicon\robot\robot_modules.dm" // END_INCLUDE From 73537f2951321d1efea10a5ba340c5b154887451 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 1 Jan 2018 07:40:00 -0600 Subject: [PATCH 098/122] Automatic changelog generation for PR #4555 [ci skip] --- html/changelogs/AutoChangeLog-pr-4555.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4555.yml diff --git a/html/changelogs/AutoChangeLog-pr-4555.yml b/html/changelogs/AutoChangeLog-pr-4555.yml new file mode 100644 index 0000000000..6197224d10 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4555.yml @@ -0,0 +1,5 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - code_imp: "Forensics is now a datum component." + - balance: "NPC humans will now start leaving fingerprints on things they touch!" From ea3652c30e0346f2f7e08c8bff2ccfcc50938307 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 1 Jan 2018 11:07:40 -0600 Subject: [PATCH 099/122] fuk --- code/__HELPERS/roundend.dm | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 0ba19e795e..d7a51663a5 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -103,10 +103,10 @@ if(LAZYLEN(GLOB.round_end_notifiees)) send2irc("Notice", "[GLOB.round_end_notifiees.Join(", ")] the round has ended.") - for(var/client/C in GLOB.clients) + /*for(var/client/C in GLOB.clients) if(!C.credits) C.RollCredits() - C.playtitlemusic(40) + C.playtitlemusic(40)*/ display_report() @@ -434,10 +434,7 @@ /proc/printplayer(datum/mind/ply, fleecheck) - var/jobtext = "" - if(ply.assigned_role) - jobtext = " the [ply.assigned_role]" - var/text = "[ply.key] was [ply.name][jobtext] and" + var/text = "[ply.key] was [ply.name] the [ply.assigned_role] and" if(ply.current) if(ply.current.stat == DEAD) text += " died" @@ -445,7 +442,7 @@ text += " survived" if(fleecheck) var/turf/T = get_turf(ply.current) - if(!T || !is_station_level(T.z)) + if(!T || !(T.z in GLOB.station_z_levels)) text += " while fleeing the station" if(ply.current.real_name != ply.name) text += " as [ply.current.real_name]" From 3ee25693794765b2a9266b1e5a39c8a8161a1459 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 1 Jan 2018 14:07:17 -0600 Subject: [PATCH 100/122] Update borer_event.dm --- code/game/gamemodes/miniantags/borer/borer_event.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 04f19ea53d56c74fd06511530393978e1dacdcfd Mon Sep 17 00:00:00 2001 From: deathride58 Date: Mon, 1 Jan 2018 20:18:43 -0500 Subject: [PATCH 101/122] ACTUALLY FIXES VORE --- .../code/modules/mob/living/carbon/human/human_defense.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modular_citadel/code/modules/mob/living/carbon/human/human_defense.dm b/modular_citadel/code/modules/mob/living/carbon/human/human_defense.dm index b61df944d1..1952b3a3b8 100644 --- a/modular_citadel/code/modules/mob/living/carbon/human/human_defense.dm +++ b/modular_citadel/code/modules/mob/living/carbon/human/human_defense.dm @@ -1,4 +1,4 @@ -/mob/living/human/grabbedby(mob/living/carbon/user, supress_message = 0) +/mob/living/carbon/human/grabbedby(mob/living/carbon/user, supress_message = 0) if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && isliving(pulling)) vore_attack(user, pulling) else From bed61a6676e21d9a201687b56b9845245142f5bc Mon Sep 17 00:00:00 2001 From: FrozenGuy5 <31222036+praisenarsie@users.noreply.github.com> Date: Tue, 2 Jan 2018 02:46:21 +0000 Subject: [PATCH 102/122] removes some dots (#33987) --- .github/CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index a4d6c07526..86046504df 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 / From 946bba6b98da35951e3ce5ce7e76dc7e154a5245 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 1 Jan 2018 21:34:29 -0600 Subject: [PATCH 104/122] Automatic changelog generation for PR #4628 [ci skip] --- html/changelogs/AutoChangeLog-pr-4628.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4628.yml diff --git a/html/changelogs/AutoChangeLog-pr-4628.yml b/html/changelogs/AutoChangeLog-pr-4628.yml new file mode 100644 index 0000000000..08311f545a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4628.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - bugfix: "Vore is now actually fixed. Fuck." From 3144b97ae4b1d131aaaf6cb1d1079af0bc2b51db Mon Sep 17 00:00:00 2001 From: FrozenGuy5 <31222036+praisenarsie@users.noreply.github.com> Date: Tue, 2 Jan 2018 05:16:37 +0000 Subject: [PATCH 105/122] Adds goonbee and cult plus improves several emojis. (#33983) -Adds :goon: -Adds :cult: -Improves :gear: -Improves :tophat: --- icons/emoji.dmi | Bin 31335 -> 31896 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/emoji.dmi b/icons/emoji.dmi index b0434f431ffbf26561aac7a8efaf9d17a78fbd72..e8ed3aaa7bfa19e1021bcfb10e4f70d3b2129d38 100644 GIT binary patch literal 31896 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 k9QKV7fU_F(eL&+^J>SCqlc59_kcN Date: Tue, 2 Jan 2018 19:11:50 +1300 Subject: [PATCH 107/122] Merge pull request #34035 from ninjanomnom/actually-changeturf Puts back the changeturf part of PlaceOnTop() --- code/game/turfs/ChangeTurf.dm | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/code/game/turfs/ChangeTurf.dm b/code/game/turfs/ChangeTurf.dm index b3e542ca0f..26bbc84078 100644 --- a/code/game/turfs/ChangeTurf.dm +++ b/code/game/turfs/ChangeTurf.dm @@ -139,22 +139,33 @@ // Make a new turf and put it on top // 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(!new_baseturfs) // If no baseturfs list then we want to create one from the turf type var/list/old_baseturfs = baseturfs.Copy() - assemble_baseturfs(fake_turf_type) + newT = ChangeTurf(fake_turf_type) + newT.assemble_baseturfs(initial(fake_turf_type.baseturfs)) // The baseturfs list is created like roundstart if(!length(baseturfs)) - baseturfs = list(baseturfs) - baseturfs.Insert(1, old_baseturfs) - return - else if(!length(new_baseturfs)) - new_baseturfs = list(new_baseturfs, fake_turf_type) - else - new_baseturfs += fake_turf_type + 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 += new_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 From e395cded9d2d71a10a21e0272a44f9bf126632d4 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 2 Jan 2018 04:34:21 -0600 Subject: [PATCH 109/122] cl --- html/changelogs/AutoChangeLog-pr-4628.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4628.yml diff --git a/html/changelogs/AutoChangeLog-pr-4628.yml b/html/changelogs/AutoChangeLog-pr-4628.yml new file mode 100644 index 0000000000..08311f545a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4628.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - bugfix: "Vore is now actually fixed. Fuck." From c5a70ff34c1899341195f2a6985d4b939b8f68e2 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Tue, 2 Jan 2018 04:52:40 -0600 Subject: [PATCH 110/122] Automatic changelog generation for PR #4430 [ci skip] --- html/changelogs/AutoChangeLog-pr-4430.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4430.yml diff --git a/html/changelogs/AutoChangeLog-pr-4430.yml b/html/changelogs/AutoChangeLog-pr-4430.yml new file mode 100644 index 0000000000..11fd6bb4a7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4430.yml @@ -0,0 +1,4 @@ +author: "Naksu" +delete-after: True +changes: + - tweak: "Hostile mobs on z-levels without living players will now conserve their efforts and simply not run AI routines at all. Also, idling mob routines should be significantly cheaper on non-station Z-levels." From d035f16aca2238eb381cc683f4d76d84c57e2981 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 2 Jan 2018 05:24:47 -0600 Subject: [PATCH 111/122] Update basilisk.dm --- .../living/simple_animal/hostile/mining_mobs/basilisk.dm | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) 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 From bf35f19aca5f32f904c86e5aede743d5b2fc3097 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Tue, 2 Jan 2018 08:02:05 -0600 Subject: [PATCH 112/122] Automatic changelog generation for PR #4633 [ci skip] --- html/changelogs/AutoChangeLog-pr-4633.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4633.yml diff --git a/html/changelogs/AutoChangeLog-pr-4633.yml b/html/changelogs/AutoChangeLog-pr-4633.yml new file mode 100644 index 0000000000..2a9d05d984 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4633.yml @@ -0,0 +1,4 @@ +author: "ninjanomnom" +delete-after: True +changes: + - bugfix: "Turfs are construct-able again" From 0ebd16f5092f00d2aa8e80080db4ec5251c07937 Mon Sep 17 00:00:00 2001 From: Dax Dupont Date: Tue, 2 Jan 2018 15:20:04 +0100 Subject: [PATCH 113/122] Solar control fixes (#33985) * Solar fixes * Also removing the solcon-o icon --- code/modules/power/solar.dm | 10 +++------- icons/obj/computer.dmi | Bin 111089 -> 108650 bytes 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index af81b632d7..f0085d1c5f 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -345,9 +345,6 @@ add_overlay("[icon_state]_broken") else add_overlay(icon_screen) - if(currentdir > -1) - setDir(angle2dir(currentdir)) - add_overlay(mutable_appearance(icon, "solcon-o", FLY_LAYER)) /obj/machinery/power/solar_control/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) @@ -375,7 +372,7 @@ if(..()) return switch(action) - if("direction") + if("angle") var/adjust = text2num(params["adjust"]) if(adjust) currentdir = CLAMP((360 + adjust + currentdir) % 360, 0, 359) @@ -391,9 +388,7 @@ . = TRUE if("tracking") var/mode = text2num(params["mode"]) - if(mode) - track = mode - . = TRUE + track = mode if(mode == 2 && connected_tracker) connected_tracker.set_angle(SSsun.angle) set_panels(currentdir) @@ -402,6 +397,7 @@ if(trackrate) nexttime = world.time + 36000 / abs(trackrate) set_panels(targetdir) + . = TRUE if("refresh") search_for_connected() if(connected_tracker && track == 2) diff --git a/icons/obj/computer.dmi b/icons/obj/computer.dmi index d4d9d0106954edba8fd0fb8aa9a0565fac4a97f0..fb1ae63b4e51a877a2e59f0ceb242c57de3066f9 100644 GIT binary patch delta 84788 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 delta 87896 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 rCBMzj>@}2`2U4fs7asbn From bae882bf46f6d9a7ed44be4db862c0d2731e1975 Mon Sep 17 00:00:00 2001 From: XDTM Date: Tue, 2 Jan 2018 15:22:09 +0100 Subject: [PATCH 115/122] Fixes Abyssal Gaze blinding forever --- code/__DEFINES/stat.dm | 7 +++++-- code/modules/spells/spell_types/construct_spells.dm | 6 +++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/code/__DEFINES/stat.dm b/code/__DEFINES/stat.dm index ecb3fcc611..96dceb6db2 100644 --- a/code/__DEFINES/stat.dm +++ b/code/__DEFINES/stat.dm @@ -25,8 +25,6 @@ // 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" @@ -34,6 +32,11 @@ #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 #define NOPOWER 2 diff --git a/code/modules/spells/spell_types/construct_spells.dm b/code/modules/spells/spell_types/construct_spells.dm index eca4990290..b4e3d43272 100644 --- a/code/modules/spells/spell_types/construct_spells.dm +++ b/code/modules/spells/spell_types/construct_spells.dm @@ -209,14 +209,18 @@ to_chat(target, "A freezing darkness surrounds you...") target.playsound_local(get_turf(target), 'sound/hallucinations/i_see_you1.ogg', 50, 1) user.playsound_local(get_turf(user), 'sound/effects/ghost2.ogg', 50, 1) +<<<<<<< HEAD target.adjust_blindness(5) +======= + target.become_blind(ABYSSAL_GAZE_BLIND) +>>>>>>> b85776f... Fixes Abyssal Gaze (#34003) addtimer(CALLBACK(src, .proc/cure_blindness, target), 40) target.bodytemperature -= 200 /obj/effect/proc_holder/spell/targeted/abyssal_gaze/proc/cure_blindness(mob/target) if(isliving(target)) var/mob/living/L = target - L.cure_blind(DISABILITY_BLIND, "abyssal_gaze") + L.cure_blind(ABYSSAL_GAZE_BLIND) /obj/effect/proc_holder/spell/targeted/dominate name = "Dominate" From 6c606654c3f8acd7e77d993edb7ccb8bac0bd916 Mon Sep 17 00:00:00 2001 From: Dax Dupont Date: Tue, 2 Jan 2018 20:31:04 +0100 Subject: [PATCH 116/122] Removes icky ocky from the vault (#34021) --- code/game/machinery/bank_machine.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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
" From 147bc88ff97940abceaa72017a5da061eabfb906 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Tue, 2 Jan 2018 15:46:20 -0600 Subject: [PATCH 118/122] Automatic changelog generation for PR #4632 [ci skip] --- html/changelogs/AutoChangeLog-pr-4632.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4632.yml diff --git a/html/changelogs/AutoChangeLog-pr-4632.yml b/html/changelogs/AutoChangeLog-pr-4632.yml new file mode 100644 index 0000000000..7c2be79d90 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4632.yml @@ -0,0 +1,4 @@ +author: "Frozenguy5" +delete-after: True +changes: + - rscadd: "Adds a goon and cult emoji. Improves gear and tophat. (Credits to GoonStation for creating the goon bee sprite.)" From a525c160181131faaed8110069aa8b0467a83e7b Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Tue, 2 Jan 2018 15:46:37 -0600 Subject: [PATCH 119/122] Automatic changelog generation for PR #4634 [ci skip] --- html/changelogs/AutoChangeLog-pr-4634.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4634.yml diff --git a/html/changelogs/AutoChangeLog-pr-4634.yml b/html/changelogs/AutoChangeLog-pr-4634.yml new file mode 100644 index 0000000000..bcc48e9842 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4634.yml @@ -0,0 +1,4 @@ +author: "DaxDupont" +delete-after: True +changes: + - bugfix: "Solar control consoles are no longer pointing to the wrong direction, you can now turn tracking off again and manual positioning of solar panels have been fixed." From 4adbd0fbf43d7aa53f25a4a9459409dff90e6c1b Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 2 Jan 2018 15:46:51 -0600 Subject: [PATCH 120/122] Update construct_spells.dm --- code/modules/spells/spell_types/construct_spells.dm | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/code/modules/spells/spell_types/construct_spells.dm b/code/modules/spells/spell_types/construct_spells.dm index b4e3d43272..a88322d5ee 100644 --- a/code/modules/spells/spell_types/construct_spells.dm +++ b/code/modules/spells/spell_types/construct_spells.dm @@ -209,11 +209,7 @@ to_chat(target, "A freezing darkness surrounds you...") target.playsound_local(get_turf(target), 'sound/hallucinations/i_see_you1.ogg', 50, 1) user.playsound_local(get_turf(user), 'sound/effects/ghost2.ogg', 50, 1) -<<<<<<< HEAD - target.adjust_blindness(5) -======= target.become_blind(ABYSSAL_GAZE_BLIND) ->>>>>>> b85776f... Fixes Abyssal Gaze (#34003) addtimer(CALLBACK(src, .proc/cure_blindness, target), 40) target.bodytemperature -= 200 @@ -283,4 +279,4 @@ /obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift/golem charge_max = 800 jaunt_in_type = /obj/effect/temp_visual/dir_setting/cult/phase - jaunt_out_type = /obj/effect/temp_visual/dir_setting/cult/phase/out \ No newline at end of file + jaunt_out_type = /obj/effect/temp_visual/dir_setting/cult/phase/out From 10bb4f71ec9a6e60d5302f3d44f705cca7ec4b68 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Tue, 2 Jan 2018 15:47:04 -0600 Subject: [PATCH 121/122] Automatic changelog generation for PR #4636 [ci skip] --- html/changelogs/AutoChangeLog-pr-4636.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4636.yml diff --git a/html/changelogs/AutoChangeLog-pr-4636.yml b/html/changelogs/AutoChangeLog-pr-4636.yml new file mode 100644 index 0000000000..bd34963deb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4636.yml @@ -0,0 +1,4 @@ +author: "Dax Dupont" +delete-after: True +changes: + - bugfix: "The bank vault is no longer metagaming. It will now display the IC station name." From 871da8f3314e06f84f696de4beb228d008b96e7e Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Tue, 2 Jan 2018 17:13:33 -0600 Subject: [PATCH 122/122] Automatic changelog generation for PR #4635 [ci skip] --- html/changelogs/AutoChangeLog-pr-4635.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4635.yml diff --git a/html/changelogs/AutoChangeLog-pr-4635.yml b/html/changelogs/AutoChangeLog-pr-4635.yml new file mode 100644 index 0000000000..7eff97850e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4635.yml @@ -0,0 +1,4 @@ +author: "XDTM" +delete-after: True +changes: + - bugfix: "Fixed Runic Golem's Abyssal Gaze blinding permanently."