diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000000..3eee43dc71
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+patreon: citadelstation
diff --git a/.gitignore b/.gitignore
index dd20fecd22..91a0ef08eb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,10 @@
#Ignore byond config folder.
/cfg/**/*
+#Ignore rust-g and auxmos libraries which are compiled with scripts
+*.so
+/tools/build/binaries/**/*
+
#Ignore compiled files and other files generated during compilation.
*.mdme
*.dmb
diff --git a/Build.sh b/Build.sh
new file mode 100755
index 0000000000..6fd691921e
--- /dev/null
+++ b/Build.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+cd "$(dirname "$(readlink -f "$0")")"
+cd ./tools/build
+sudo bash ./build.sh
diff --git a/_maps/RandomRuins/SpaceRuins/shuttlerelic.dmm b/_maps/RandomRuins/SpaceRuins/shuttlerelic.dmm
index a0fc5fa8a7..347d0a093f 100644
--- a/_maps/RandomRuins/SpaceRuins/shuttlerelic.dmm
+++ b/_maps/RandomRuins/SpaceRuins/shuttlerelic.dmm
@@ -64,11 +64,7 @@
dir = 1;
icon_state = "chairold"
},
-/obj/item/crowbar/large{
- desc = "It's a big crowbar. It doesn't fit in your pockets, because it's big. It feels oddly heavy..";
- force = 20;
- name = "heavy crowbar"
- },
+/obj/item/crowbar/large/heavy,
/turf/open/floor/oldshuttle,
/area/ruin/powered)
"o" = (
diff --git a/_maps/RandomRuins/StationRuins/Box/Engine/engine_am.dmm b/_maps/RandomRuins/StationRuins/Box/Engine/engine_am.dmm
index db2a4f6cd7..f7fa98fcf7 100644
--- a/_maps/RandomRuins/StationRuins/Box/Engine/engine_am.dmm
+++ b/_maps/RandomRuins/StationRuins/Box/Engine/engine_am.dmm
@@ -1367,7 +1367,7 @@ JZ
kK
Ch
Ch
-MJ
+Ch
MJ
MJ
MJ
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 0f41cd3b1a..57a4831073 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -36739,14 +36739,12 @@
dir = 1
},
/turf/open/floor/plasteel,
-/area/science/misc_lab)
+/area/science/mixing)
"cAJ" = (
-/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
- dir = 8
- },
/obj/structure/cable/yellow{
icon_state = "1-2"
},
+/obj/machinery/atmospherics/pipe/manifold4w/supplymain/hidden,
/turf/open/floor/plasteel,
/area/science/mixing)
"cAK" = (
@@ -36755,7 +36753,7 @@
dir = 4
},
/turf/open/floor/plasteel,
-/area/science/misc_lab)
+/area/science/mixing)
"cAL" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
@@ -37139,7 +37137,7 @@
dir = 8
},
/turf/open/floor/plasteel,
-/area/science/misc_lab)
+/area/science/mixing)
"cBE" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/structure/cable/yellow{
@@ -37149,7 +37147,7 @@
dir = 4
},
/turf/open/floor/plasteel,
-/area/science/misc_lab)
+/area/science/mixing)
"cBF" = (
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
dir = 4
@@ -37158,7 +37156,7 @@
pixel_x = 32
},
/turf/open/floor/plasteel,
-/area/science/misc_lab)
+/area/science/mixing)
"cBG" = (
/obj/machinery/door/airlock/research{
name = "Toxins Launch Room";
@@ -37556,6 +37554,9 @@
/obj/machinery/light{
dir = 8
},
+/obj/machinery/atmospherics/components/unary/vent_pump/on{
+ dir = 4
+ },
/turf/open/floor/plasteel,
/area/science/mixing)
"cCE" = (
@@ -54495,7 +54496,7 @@
"gLC" = (
/obj/structure/reagent_dispensers/water_cooler,
/turf/open/floor/plasteel,
-/area/science/misc_lab)
+/area/science/mixing)
"gLD" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
@@ -70548,11 +70549,11 @@
/turf/open/floor/grass,
/area/service/hydroponics/garden)
"qqg" = (
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
- dir = 6
+/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
+ dir = 1
},
/turf/open/floor/plasteel,
-/area/science/misc_lab)
+/area/science/mixing)
"qqK" = (
/obj/structure/cable/yellow{
icon_state = "1-2"
@@ -78267,7 +78268,7 @@
dir = 4
},
/turf/open/floor/plasteel,
-/area/science/misc_lab)
+/area/science/mixing)
"vhM" = (
/obj/machinery/teleport/hub,
/turf/open/floor/plating,
@@ -81108,7 +81109,7 @@
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plasteel,
-/area/science/misc_lab)
+/area/science/mixing)
"wRz" = (
/obj/effect/landmark/xeno_spawn,
/obj/machinery/atmospherics/components/unary/vent_pump/on{
@@ -82282,8 +82283,12 @@
/area/service/library)
"xAp" = (
/obj/structure/chair/comfy,
+/obj/machinery/airalarm{
+ dir = 4;
+ pixel_x = -22
+ },
/turf/open/floor/plasteel,
-/area/science/misc_lab)
+/area/science/mixing)
"xAs" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/grunge{
@@ -82583,6 +82588,16 @@
/obj/effect/turf_decal/tile/neutral,
/turf/open/floor/plasteel,
/area/commons/dorms)
+"xHe" = (
+/obj/structure/cable/yellow{
+ icon_state = "1-2"
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
+ dir = 4
+ },
+/turf/open/floor/plasteel,
+/area/science/mixing)
"xHm" = (
/obj/machinery/holopad,
/obj/structure/cable/yellow{
@@ -118574,7 +118589,7 @@ cJa
cJa
gHh
wRy
-wRy
+xHe
wRy
cBE
cAJ
diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm
index d749c51798..3f07daecc2 100644
--- a/_maps/map_files/PubbyStation/PubbyStation.dmm
+++ b/_maps/map_files/PubbyStation/PubbyStation.dmm
@@ -9531,6 +9531,9 @@
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
+/obj/structure/mirror{
+ pixel_y = 30
+ },
/turf/open/floor/plasteel/freezer,
/area/command/heads_quarters/captain)
"avJ" = (
@@ -16873,10 +16876,10 @@
dir = 4
},
/obj/effect/landmark/start/assistant,
+/obj/machinery/light/small,
/turf/open/floor/plasteel/freezer,
/area/commons/toilet/auxiliary)
"aNd" = (
-/obj/machinery/light/small,
/obj/machinery/atmospherics/components/unary/vent_pump/on{
dir = 1
},
@@ -24652,12 +24655,6 @@
},
/turf/open/space,
/area/solars/starboard)
-"beW" = (
-/obj/machinery/atmospherics/pipe/simple/general/visible{
- dir = 5
- },
-/turf/open/floor/plasteel,
-/area/engineering/atmos)
"beY" = (
/obj/machinery/camera{
c_tag = "Arrivals Central";
@@ -34476,7 +34473,7 @@
dir = 8
},
/obj/structure/cable{
- icon_state = "4-8"
+ icon_state = "0-4"
},
/turf/open/floor/plasteel/dark,
/area/command/heads_quarters/rd)
@@ -40389,8 +40386,8 @@
icon_state = "1-2"
},
/obj/machinery/atmospherics/components/binary/pump/on{
- dir = 8;
- name = "Unfiltered to Mix"
+ dir = 4;
+ name = "Ports to Mix"
},
/turf/open/floor/plasteel,
/area/engineering/atmos)
@@ -41430,6 +41427,9 @@
/obj/structure/cable{
icon_state = "1-2"
},
+/obj/machinery/atmospherics/pipe/simple/general/visible{
+ dir = 10
+ },
/turf/open/floor/plasteel,
/area/engineering/atmos)
"bPW" = (
@@ -42132,7 +42132,9 @@
/turf/open/floor/plasteel,
/area/engineering/atmos)
"bRw" = (
-/obj/machinery/atmospherics/pipe/simple/general/visible,
+/obj/machinery/atmospherics/pipe/simple/general/visible{
+ dir = 5
+ },
/turf/open/floor/plasteel,
/area/engineering/atmos)
"bRx" = (
@@ -55286,15 +55288,6 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/turf/open/floor/plasteel,
/area/construction/mining/aux_base)
-"hEi" = (
-/obj/structure/cable{
- icon_state = "1-2"
- },
-/obj/machinery/atmospherics/pipe/simple/general/visible{
- dir = 10
- },
-/turf/open/floor/plasteel,
-/area/engineering/atmos)
"hEX" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 6
@@ -61354,12 +61347,6 @@
},
/turf/open/floor/engine,
/area/engineering/main)
-"uST" = (
-/obj/machinery/atmospherics/components/binary/pump{
- name = "Mix to Ports"
- },
-/turf/open/floor/plasteel,
-/area/engineering/atmos)
"uUQ" = (
/obj/machinery/door/airlock/maintenance{
name = "Engineering Maintenance";
@@ -100505,7 +100492,7 @@ bOr
bPU
kWG
bRw
-beW
+bMf
bMf
bMf
bMf
@@ -100761,9 +100748,9 @@ bKV
bOX
eEd
bQL
-uST
pEM
bMf
+bMf
qQu
qQu
bSU
@@ -101019,7 +101006,7 @@ bMg
bNj
bOp
bPV
-hEi
+sGJ
sGJ
bUw
bUw
diff --git a/_maps/templates/shelter_5.dmm b/_maps/templates/shelter_5.dmm
index 60066dc0c0..643f744fb9 100644
--- a/_maps/templates/shelter_5.dmm
+++ b/_maps/templates/shelter_5.dmm
@@ -253,6 +253,10 @@
/obj/machinery/dish_drive,
/turf/open/floor/pod/dark,
/area/survivalpod/nonpowered)
+"Vv" = (
+/obj/machinery/biogenerator,
+/turf/open/floor/pod/dark,
+/area/survivalpod/nonpowered)
"Ws" = (
/obj/structure/dresser,
/turf/open/floor/pod/dark,
@@ -274,12 +278,8 @@
/obj/structure/table/survival_pod,
/obj/item/shovel,
/obj/item/pickaxe,
-/obj/item/clothing/gloves/chameleon/insulated,
/obj/item/storage/toolbox/electrical,
-/turf/open/floor/pod/dark,
-/area/survivalpod/nonpowered)
-"Zd" = (
-/obj/machinery/seed_extractor,
+/obj/item/clothing/gloves/color/yellow,
/turf/open/floor/pod/dark,
/area/survivalpod/nonpowered)
@@ -453,8 +453,8 @@ FZ
Ng
wI
Ng
-FZ
-Zd
+Vv
+Lv
xC
td
FZ
diff --git a/code/__DEFINES/maths.dm b/code/__DEFINES/maths.dm
index 9e96c6a559..f56cd76a71 100644
--- a/code/__DEFINES/maths.dm
+++ b/code/__DEFINES/maths.dm
@@ -4,6 +4,8 @@
#define NUM_E 2.71828183
+#define SQRT_2 1.414214
+
#define PI 3.1416
#define INFINITY 1e31 //closer then enough
diff --git a/code/__HELPERS/do_after.dm b/code/__HELPERS/do_after.dm
index c0c07e3620..3ec1aa9b08 100644
--- a/code/__HELPERS/do_after.dm
+++ b/code/__HELPERS/do_after.dm
@@ -75,7 +75,7 @@
while(timeleft > 0)
stoplag(1)
var/timepassed = world.time - tick_time
- timepassed = world.time
+ tick_time = world.time
progbar?.update(TIMELEFT)
if(QDELETED(user) || QDELETED(target) || (user.loc == null) || (target.loc == null))
. = FALSE
diff --git a/code/controllers/subsystem/acid.dm b/code/controllers/subsystem/acid.dm
deleted file mode 100644
index 25d080a1b1..0000000000
--- a/code/controllers/subsystem/acid.dm
+++ /dev/null
@@ -1,37 +0,0 @@
-SUBSYSTEM_DEF(acid)
- name = "Acid"
- priority = FIRE_PRIORITY_ACID
- flags = SS_NO_INIT|SS_BACKGROUND
- runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
-
- var/list/currentrun = list()
- var/list/processing = list()
-
-/datum/controller/subsystem/acid/stat_entry(msg)
- msg = "P:[length(processing)]"
- return ..()
-
-
-/datum/controller/subsystem/acid/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/obj/O = currentrun[currentrun.len]
- currentrun.len--
- if (!O || QDELETED(O))
- processing -= O
- if (MC_TICK_CHECK)
- return
- continue
-
- if(O.acid_level && O.acid_processing())
- else
- O.update_icon()
- processing -= O
-
- if (MC_TICK_CHECK)
- return
diff --git a/code/controllers/subsystem/fluid.dm b/code/controllers/subsystem/fluid.dm
index c4fa13d693..70903e0088 100644
--- a/code/controllers/subsystem/fluid.dm
+++ b/code/controllers/subsystem/fluid.dm
@@ -1,5 +1,5 @@
PROCESSING_SUBSYSTEM_DEF(fluids)
name = "Fluids"
- wait = 20
+ wait = 10
stat_tag = "FD" //its actually Fluid Ducts
- flags = SS_NO_INIT | SS_TICKER
+ flags = SS_NO_INIT
diff --git a/code/controllers/subsystem/nightshift.dm b/code/controllers/subsystem/nightshift.dm
index 78b2e63cf2..c45bd64702 100644
--- a/code/controllers/subsystem/nightshift.dm
+++ b/code/controllers/subsystem/nightshift.dm
@@ -42,6 +42,7 @@ SUBSYSTEM_DEF(nightshift)
update_nightshift(night_time, announcing)
/datum/controller/subsystem/nightshift/proc/update_nightshift(active, announce = TRUE, max_level_override)
+ set waitfor = FALSE
nightshift_active = active
if(announce)
if (active)
diff --git a/code/controllers/subsystem/processing/processing.dm b/code/controllers/subsystem/processing/processing.dm
index f5a423b353..661eafc2a5 100644
--- a/code/controllers/subsystem/processing/processing.dm
+++ b/code/controllers/subsystem/processing/processing.dm
@@ -47,5 +47,5 @@ SUBSYSTEM_DEF(processing)
* If you override this do not call parent, as it will return PROCESS_KILL. This is done to prevent objects that dont override process() from staying in the processing list
*/
/datum/proc/process(delta_time)
- // SHOULD_NOT_SLEEP(TRUE)
+ SHOULD_NOT_SLEEP(TRUE)
return PROCESS_KILL
diff --git a/code/datums/components/acid.dm b/code/datums/components/acid.dm
new file mode 100644
index 0000000000..2e3784dc97
--- /dev/null
+++ b/code/datums/components/acid.dm
@@ -0,0 +1,65 @@
+/datum/component/acid
+ dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
+ var/level = 0
+
+/datum/component/acid/Initialize(acidpwr, acid_volume)
+ if(!isobj(parent))
+ return COMPONENT_INCOMPATIBLE
+ var/obj/O = parent
+ var/acid_cap = acidpwr * 300
+ level = min(acidpwr * acid_volume, acid_cap)
+ START_PROCESSING(SSprocessing, src)
+ RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, .proc/add_acid_overlay)
+ if(isitem(parent))
+ RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, .proc/on_attack_hand)
+ O.update_icon()
+
+/datum/component/acid/proc/on_attack_hand(datum/source, mob/user)
+ var/obj/item/I = parent
+ if(istype(I) && level > 20 && !ismob(I.loc))// so we can still remove the clothes on us that have acid.
+ var/mob/living/carbon/C = user
+ if(istype(C))
+ if(!C.gloves || (!(C.gloves.resistance_flags & (UNACIDABLE|ACID_PROOF))))
+ to_chat(user, "The acid on [I] burns your hand!")
+ var/obj/item/bodypart/affecting = C.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm")
+ if(affecting && affecting.receive_damage( 0, 5 )) // 5 burn damage
+ C.update_damage_overlays()
+
+/datum/component/acid/InheritComponent(datum/component/C, i_am_original, acidpwr, acid_volume)
+ if(!i_am_original)
+ return
+ var/acid_cap = acidpwr * 300
+ if(level < acid_cap)
+ if(C)
+ var/datum/component/acid/other = C
+ level = min(level + other.level, acid_cap)
+ else
+ level = min(level + acidpwr * acid_volume, acid_cap)
+
+/datum/component/acid/Destroy()
+ STOP_PROCESSING(SSprocessing, src)
+ var/obj/O = parent
+ level = 0
+ O.update_overlays()
+ return ..()
+
+/datum/component/acid/process()
+ var/obj/O = parent
+ if(!istype(O))
+ qdel(src)
+ return PROCESS_KILL
+ if(!(O.resistance_flags & ACID_PROOF))
+ if(prob(33))
+ playsound(O.loc, 'sound/items/welder.ogg', 150, 1)
+ O.take_damage(min(1 + round(sqrt(level)*0.3), 300), BURN, "acid", 0)
+
+ level = max(level - (5 + 3*round(sqrt(level))), 0)
+ if(level <= 0)
+ qdel(src)
+ return PROCESS_KILL
+ else
+ O.update_icon()
+ return TRUE
+
+/datum/component/acid/proc/add_acid_overlay(atom/source, list/overlay_list)
+ overlay_list += GLOB.acid_overlay
diff --git a/code/datums/components/activity.dm b/code/datums/components/activity.dm
index ae18ca01a2..7c4c758d49 100644
--- a/code/datums/components/activity.dm
+++ b/code/datums/components/activity.dm
@@ -16,7 +16,7 @@
RegisterSignal(L, list(COMSIG_MOB_ITEM_ATTACK, COMSIG_MOB_ATTACK_RANGED, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, COMSIG_MOB_ATTACK_HAND, COMSIG_MOB_THROW, COMSIG_MOVABLE_TELEPORTED, COMSIG_LIVING_GUN_PROCESS_FIRE, COMSIG_MOB_APPLY_DAMAGE), .proc/minor_activity)
/datum/component/activity/proc/log_activity()
- historical_activity_levels[world.time] = activity_level
+ historical_activity_levels["[world.time]"] = activity_level
/datum/component/activity/proc/minor_activity(datum/source)
activity_level += 1
diff --git a/code/datums/components/crafting/recipes/recipes_misc.dm b/code/datums/components/crafting/recipes/recipes_misc.dm
index 032dd0ea90..625e850212 100644
--- a/code/datums/components/crafting/recipes/recipes_misc.dm
+++ b/code/datums/components/crafting/recipes/recipes_misc.dm
@@ -374,6 +374,20 @@
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
+/datum/crafting_recipe/motorized_wheelchair
+ name = "Hoverchair"
+ result = /obj/vehicle/ridden/wheelchair/motorized
+ reqs = list(/obj/item/stack/sheet/plasteel = 10,
+ /obj/item/stack/rods = 8,
+ /obj/item/stock_parts/manipulator = 2,
+ /obj/item/stock_parts/capacitor = 1)
+ parts = list(/obj/item/stock_parts/manipulator = 2,
+ /obj/item/stock_parts/capacitor = 1)
+ tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WRENCH)
+ time = 200
+ subcategory = CAT_MISCELLANEOUS
+ category = CAT_MISC
+
/datum/crafting_recipe/skateboard
name = "Skateboard"
result = /obj/vehicle/ridden/scooter/skateboard
diff --git a/code/datums/components/embedded.dm b/code/datums/components/embedded.dm
index ec5ec19a6b..eca38fee34 100644
--- a/code/datums/components/embedded.dm
+++ b/code/datums/components/embedded.dm
@@ -265,6 +265,7 @@
/// Items embedded/stuck to carbons both check whether they randomly fall out (if applicable), as well as if the target mob and limb still exists.
/// Items harmfully embedded in carbons have an additional check for random pain (if applicable)
/datum/component/embedded/proc/processCarbon()
+ set waitfor = FALSE
var/mob/living/carbon/victim = parent
if(!victim || !limb) // in case the victim and/or their limbs exploded (say, due to a sticky bomb)
diff --git a/code/datums/components/lockon_aiming.dm b/code/datums/components/lockon_aiming.dm
index 2f4401862d..4acdece7e5 100644
--- a/code/datums/components/lockon_aiming.dm
+++ b/code/datums/components/lockon_aiming.dm
@@ -158,6 +158,7 @@
autolock()
/datum/component/lockon_aiming/proc/autolock()
+ set waitfor = FALSE
var/mob/M = parent
if(!M.client)
return FALSE
diff --git a/code/datums/dna.dm b/code/datums/dna.dm
index 248b669ab1..a2982a3caf 100644
--- a/code/datums/dna.dm
+++ b/code/datums/dna.dm
@@ -405,7 +405,7 @@
/mob/living/carbon/human/proc/hardset_dna(ui, list/mutation_index, newreal_name, newblood_type, datum/species/mrace, newfeatures, list/default_mutation_genes)
-
+ set waitfor = FALSE
if(newreal_name)
real_name = newreal_name
dna.generate_unique_enzymes()
diff --git a/code/datums/elements/earhealing.dm b/code/datums/elements/earhealing.dm
index 91c2120fc2..1c74777845 100644
--- a/code/datums/elements/earhealing.dm
+++ b/code/datums/elements/earhealing.dm
@@ -24,7 +24,8 @@
else
user_by_item -= source
-/datum/element/earhealing/process()
+/datum/element/earhealing/proc/do_process()
+ set waitfor = FALSE
for(var/i in user_by_item)
var/mob/living/carbon/user = user_by_item[i]
if(HAS_TRAIT(user, TRAIT_DEAF))
@@ -35,3 +36,6 @@
ears.deaf = max(ears.deaf - 0.25, (ears.damage < ears.maxHealth ? 0 : 1)) // Do not clear deafness if our ears are too damaged
ears.damage = max(ears.damage - 0.025, 0)
CHECK_TICK
+
+/datum/element/earhealing/process()
+ do_process()
diff --git a/code/datums/wires/_wires.dm b/code/datums/wires/_wires.dm
index 1c9c14ee3e..81f99cfa69 100644
--- a/code/datums/wires/_wires.dm
+++ b/code/datums/wires/_wires.dm
@@ -166,6 +166,7 @@
on_pulse(wire, user)
/datum/wires/proc/pulse_color(color, mob/living/user)
+ set waitfor = FALSE
LAZYINITLIST(current_users)
if(current_users[user])
return FALSE
diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm
index 55f91ba3d3..c7fee7df96 100644
--- a/code/game/gamemodes/dynamic/dynamic.dm
+++ b/code/game/gamemodes/dynamic/dynamic.dm
@@ -711,10 +711,15 @@ GLOBAL_VAR_INIT(dynamic_forced_storyteller, null)
update_playercounts()
if (storyteller.should_inject_antag())
SSblackbox.record_feedback("tally","dynamic",1,"Attempted midround injections")
- var/list/drafted_rules = storyteller.midround_draft()
- if (drafted_rules.len > 0)
- SSblackbox.record_feedback("tally","dynamic",1,"Successful midround injections")
- picking_midround_latejoin_rule(drafted_rules)
+ do_midround_injection()
+
+/datum/game_mode/dynamic/proc/do_midround_injection()
+ set waitfor = FALSE
+ var/list/drafted_rules = storyteller.midround_draft()
+ if (drafted_rules.len > 0)
+ SSblackbox.record_feedback("tally","dynamic",1,"Successful midround injections")
+ picking_midround_latejoin_rule(drafted_rules)
+
/// Updates current_players.
/datum/game_mode/dynamic/proc/update_playercounts()
diff --git a/code/game/gamemodes/gangs/dominator.dm b/code/game/gamemodes/gangs/dominator.dm
index ed17d830ba..a253aa906c 100644
--- a/code/game/gamemodes/gangs/dominator.dm
+++ b/code/game/gamemodes/gangs/dominator.dm
@@ -105,14 +105,18 @@
if(tempgang != gang)
tempgang.message_gangtools("WARNING: [gang.name] Gang takeover imminent. Their dominator at [domloc.map_name] must be destroyed!",1,1)
else
- Cinematic(CINEMATIC_MALF,world) //Here is the gang victory trigger on the dominator ending.
- gang.winner = TRUE
- SSticker.news_report = GANG_VICTORY
- SSticker.force_ending = TRUE
+ endgame()
if(!.)
STOP_PROCESSING(SSmachines, src)
+/obj/machinery/dominator/proc/endgame()
+ set waitfor = FALSE
+ Cinematic(CINEMATIC_MALF,world) //Here is the gang victory trigger on the dominator ending.
+ gang.winner = TRUE
+ SSticker.news_report = GANG_VICTORY
+ SSticker.force_ending = TRUE
+
/obj/machinery/dominator/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BRUTE)
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index e95543cffb..a3bdfe4243 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -173,10 +173,7 @@
clonemind.transfer_to(H)
else if(get_clone_mind == CLONEPOD_POLL_MIND)
- var/list/candidates = pollCandidatesForMob("Do you want to play as [clonename]'s defective clone? (Don't ERP without permission from the original)", null, null, null, 100, H, POLL_IGNORE_CLONE)
- if(LAZYLEN(candidates))
- var/mob/C = pick(candidates)
- H.key = C.key
+ poll_for_mind(H, clonename)
if(grab_ghost_when == CLONER_FRESH_CLONE)
H.grab_ghost()
@@ -206,6 +203,13 @@
attempting = FALSE
return TRUE
+/obj/machinery/clonepod/proc/poll_for_mind(mob/living/carbon/human/H, clonename)
+ set waitfor = FALSE
+ var/list/candidates = pollCandidatesForMob("Do you want to play as [clonename]'s defective clone? (Don't ERP without permission from the original)", null, null, null, 100, H, POLL_IGNORE_CLONE)
+ if(LAZYLEN(candidates))
+ var/mob/C = pick(candidates)
+ H.key = C.key
+
//Grow clones to maturity then kick them out. FREELOADERS
/obj/machinery/clonepod/process()
var/mob/living/mob_occupant = occupant
diff --git a/code/game/machinery/computer/pod.dm b/code/game/machinery/computer/pod.dm
index 97e2d4ea0a..f1cf187ff9 100644
--- a/code/game/machinery/computer/pod.dm
+++ b/code/game/machinery/computer/pod.dm
@@ -34,6 +34,7 @@
* Initiates launching sequence by checking if all components are functional, opening poddoors, firing mass drivers and then closing poddoors
*/
/obj/machinery/computer/pod/proc/alarm()
+ set waitfor = FALSE
if(stat & (NOPOWER|BROKEN))
return
diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm
index aad64df6d9..231075a27d 100644
--- a/code/game/machinery/porta_turret/portable_turret.dm
+++ b/code/game/machinery/porta_turret/portable_turret.dm
@@ -459,11 +459,11 @@
else if(iscarbon(A))
var/mob/living/carbon/C = A
- //If not emagged, only target carbons that can use items
- if(mode != TURRET_LETHAL && (C.stat || C.handcuffed || !(C.mobility_flags & MOBILITY_USE)))
+ //If not on lethal, only target carbons that aren't cuffed nor stamcrit or just plain crit.
+ if(mode != TURRET_LETHAL && (C.stat || C.handcuffed || IS_STAMCRIT(C)))
continue
- //If emagged, target all but dead carbons
+ //If on lethal, target all but dead carbons
if(mode == TURRET_LETHAL && C.stat == DEAD)
continue
@@ -503,6 +503,7 @@
return 1
/obj/machinery/porta_turret/proc/popUp() //pops the turret up
+ set waitfor = FALSE
if(!anchored)
return
if(raising || raised)
@@ -521,6 +522,7 @@
layer = MOB_LAYER
/obj/machinery/porta_turret/proc/popDown() //pops the turret down
+ set waitfor = FALSE
if(raising || !raised)
return
if(stat & BROKEN)
diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm
index 561daf433d..4009b1b56b 100644
--- a/code/game/machinery/syndicatebomb.dm
+++ b/code/game/machinery/syndicatebomb.dm
@@ -288,6 +288,7 @@
qdel(src)
/obj/item/bombcore/proc/defuse()
+ set waitfor = FALSE
//Note: Because of how var/defused is used you shouldn't override this UNLESS you intend to set the var to 0 or
// otherwise remove the core/reset the wires before the end of defuse(). It will repeatedly be called otherwise.
diff --git a/code/game/mecha/combat/neovgre.dm b/code/game/mecha/combat/neovgre.dm
index 584a2d007e..75470abe88 100644
--- a/code/game/mecha/combat/neovgre.dm
+++ b/code/game/mecha/combat/neovgre.dm
@@ -70,7 +70,6 @@
cell.charge = INFINITY
max_integrity = INFINITY
obj_integrity = max_integrity
- CHECK_TICK //Just to be on the safe side lag wise
else
if(cell.charge < cell.maxcharge)
for(var/obj/effect/clockwork/sigil/transmission/T in range(SIGIL_ACCESS_RANGE, src))
@@ -80,7 +79,6 @@
adjust_clockwork_power(-delta)
if(obj_integrity < max_integrity && istype(loc, /turf/open/floor/clockwork))
obj_integrity += min(max_integrity - obj_integrity, max_integrity / 200)
- CHECK_TICK
/obj/mecha/combat/neovgre/Initialize()
.=..()
diff --git a/code/game/objects/effects/alien_acid.dm b/code/game/objects/effects/alien_acid.dm
index 6496b392c3..40d950332c 100644
--- a/code/game/objects/effects/alien_acid.dm
+++ b/code/game/objects/effects/alien_acid.dm
@@ -9,6 +9,7 @@
resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF
layer = ABOVE_NORMAL_TURF_LAYER
var/turf/target
+ var/acid_level = 0 // Removed from obj, so it goes here now
/obj/effect/acid/Initialize(mapload, acid_pwr, acid_amt)
@@ -42,7 +43,7 @@
for(var/obj/O in target)
if(prob(20) && !(resistance_flags & UNACIDABLE))
- if(O.acid_level < acid_level*0.3)
+ if(O.acid_level() < acid_level*0.3)
var/acid_used = min(acid_level*0.05, 20)
O.acid_act(10, acid_used)
acid_level = max(0, acid_level - acid_used*10)
diff --git a/code/game/objects/effects/decals/misc.dm b/code/game/objects/effects/decals/misc.dm
index 6b90cfd62c..752a5dff2c 100644
--- a/code/game/objects/effects/decals/misc.dm
+++ b/code/game/objects/effects/decals/misc.dm
@@ -24,55 +24,86 @@
var/range = 3
var/hits_left = 3
var/range_left = 3
+ var/firstmove = TRUE
+ var/list/hit
/obj/effect/decal/chempuff/blob_act(obj/structure/blob/B)
return
-/obj/effect/decal/chempuff/Initialize(mapload, stream_mode, speed, range, hits_left)
+/obj/effect/decal/chempuff/Initialize(mapload, stream_mode, speed, range, hits_left, size)
. = ..()
+ create_reagents(size, NONE, NO_REAGENTS_VALUE)
stream = stream_mode
src.speed = speed
src.range = src.range_left = range
src.hits_left = hits_left
+ hit = list()
-/obj/effect/decal/chempuff/proc/hit_thing(atom/A)
+/obj/effect/decal/chempuff/Destroy()
+ hit = null
+ return ..()
+
+/// proc called to handle us hitting something
+/obj/effect/decal/chempuff/proc/hit_thing(atom/A, bump_hit)
+ // if the thing is invisible it usually is abstract/underfloor. also, don't hit ourselves.
if(A == src || A.invisibility)
return
- if(!hits_left)
+ // don't hit anything on the first move unless overridden (see: we're colliding a wall blocking our move out of the first tile)
+ if(firstmove && !bump_hit)
return
- if(stream)
- if(ismob(A))
- var/mob/M = A
- if(!M.lying || !range_left)
- reagents.reaction(M, VAPOR)
- hits_left--
- else
- if(!range_left)
- reagents.reaction(A, VAPOR)
- else
- reagents.reaction(A)
- if(ismob(A))
- hits_left--
+ // we're out of hits or we already hit it
+ if(!hits_left || hit[A])
+ return
+ var/living = isliving(A)
+ // if it's not dense and we're a stream instead of a mist, and we're not out of range
+ if(!A.density && stream && range_left && !bump_hit)
+ return
+ // non living mobs are effectively abstract
+ if(ismob(A) && !living)
+ return
+ hit[A] = TRUE
+ reagents.reaction(A, VAPOR)
+ // mobs absorb enough to decrement hits_left, as well as stuff blocking us.
+ if(ismob(A) || bump_hit)
+ hits_left--
/obj/effect/decal/chempuff/Crossed(atom/movable/AM, oldloc)
. = ..()
+ // bump things moving into us as long as we're not on our first move/moving out of origin tile
hit_thing(AM)
+/obj/effect/decal/chempuff/Bump(atom/A)
+ . = ..()
+ // if we hit something blocking our movement, collide it regardless even if we're still on our origin tile
+ hit_thing(A, TRUE)
+
/obj/effect/decal/chempuff/proc/run_puff(atom/target)
- set waitfor = FALSE
- for(var/i in 1 to range)
+ var/safety = 255
+ while(range_left)
+ if(!safety--)
+ CRASH("Spray ran out of safety.")
+ // move towards new turf
+ step_towards(src, target)
+ if(firstmove)
+ // mark first movement so future Cross()es result in collisions
+ firstmove = FALSE
+ // decrement range
range_left--
+ // if we got nullspaced, exit
if(!isturf(loc))
break
+ // hit everything in it
for(var/atom/T in loc)
hit_thing(T)
+ // if we got deleted or ran out of hits, stop
if(!hits_left || !isturf(loc))
break
- if(hits_left && isturf(loc) && (!stream || !range_left))
- reagents.reaction(loc, VAPOR)
- hits_left--
- if(!hits_left)
+ if(!hits_left || !isturf(loc))
+ // yeah yeah sue me it's copypasted code but I don't want to declare a var.
break
+ // hit the turf
+ hit_thing(loc)
+ sleep(speed)
qdel(src)
/obj/effect/decal/fakelattice
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index cbfd5ef5a0..cd486ccf6b 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -352,15 +352,6 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
C.update_damage_overlays()
return
- if(acid_level > 20 && ismob(loc))// so we can still remove the clothes on us that have acid.
- var/mob/living/carbon/C = user
- if(istype(C))
- if(!C.gloves || (!(C.gloves.resistance_flags & (UNACIDABLE|ACID_PROOF))))
- to_chat(user, "The acid on [src] burns your hand!")
- var/obj/item/bodypart/affecting = C.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm")
- if(affecting && affecting.receive_damage( 0, 5 )) // 5 burn damage
- C.update_damage_overlays()
-
if(!(interaction_flags_item & INTERACT_ITEM_ATTACK_HAND_PICKUP)) //See if we're supposed to auto pickup.
return
diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm
index 9ae8fb80db..60538b479b 100644
--- a/code/game/objects/items/handcuffs.dm
+++ b/code/game/objects/items/handcuffs.dm
@@ -1,6 +1,8 @@
/obj/item/restraints
breakouttime = 600
var/demoralize_criminals = TRUE // checked on carbon/carbon.dm to decide wheter to apply the handcuffed negative moodlet or not.
+ /// allow movement at all during breakout
+ var/allow_breakout_movement = FALSE
/obj/item/restraints/suicide_act(mob/living/carbon/user)
user.visible_message("[user] is strangling [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!")
@@ -243,6 +245,7 @@
throwforce = 0
w_class = WEIGHT_CLASS_NORMAL
slowdown = 7
+ allow_breakout_movement = TRUE
breakouttime = 300 //Deciseconds = 30s = 0.5 minute
/obj/item/restraints/legcuffs/proc/on_removed()
@@ -312,7 +315,7 @@
trap_damage = 0
item_flags = DROPDEL
flags_1 = NONE
- breakouttime = 25
+ breakouttime = 50
/obj/item/restraints/legcuffs/beartrap/energy/New()
..()
@@ -328,7 +331,7 @@
. = ..()
/obj/item/restraints/legcuffs/beartrap/energy/cyborg
- breakouttime = 20 // Cyborgs shouldn't have a strong restraint
+ breakouttime = 40 // Cyborgs shouldn't have a strong restraint
/obj/item/restraints/legcuffs/bola
name = "bola"
@@ -379,7 +382,7 @@
icon_state = "ebola"
hitsound = 'sound/weapons/taserhit.ogg'
w_class = WEIGHT_CLASS_SMALL
- breakouttime = 25
+ breakouttime = 50
/obj/item/restraints/legcuffs/bola/energy/on_removed()
do_sparks(1, TRUE, src)
diff --git a/code/game/objects/items/pneumaticCannon.dm b/code/game/objects/items/pneumaticCannon.dm
index e62208f848..42e345b502 100644
--- a/code/game/objects/items/pneumaticCannon.dm
+++ b/code/game/objects/items/pneumaticCannon.dm
@@ -266,6 +266,7 @@
. += tank.icon_state
/obj/item/pneumatic_cannon/proc/fill_with_type(type, amount)
+ set waitfor = FALSE
if(!ispath(type, /obj) && !ispath(type, /mob))
return FALSE
var/loaded = 0
diff --git a/code/game/objects/items/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm
index f0fd29adbc..f481cab91f 100644
--- a/code/game/objects/items/tools/crowbar.dm
+++ b/code/game/objects/items/tools/crowbar.dm
@@ -67,6 +67,12 @@
item_state = "crowbar"
toolspeed = 0.5
+/obj/item/crowbar/large/heavy
+ name = "heavy crowbar"
+ desc = "It's a big crowbar. It doesn't fit in your pockets, because it's big. It feels oddly heavy.."
+ force = 20
+ icon_state = "crowbar_powergame"
+
/obj/item/crowbar/cyborg
name = "hydraulic crowbar"
desc = "A hydraulic prying tool, compact but powerful. Designed to replace crowbar in construction cyborgs."
diff --git a/code/game/objects/items/tools/wirecutters.dm b/code/game/objects/items/tools/wirecutters.dm
index ee72c7fed2..51bb046290 100644
--- a/code/game/objects/items/tools/wirecutters.dm
+++ b/code/game/objects/items/tools/wirecutters.dm
@@ -23,13 +23,13 @@
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30)
var/random_color = TRUE
var/static/list/wirecutter_colors = list(
- "blue" = "#1861d5",
- "red" = "#951710",
- "pink" = "#d5188d",
- "brown" = "#a05212",
- "green" = "#0e7f1b",
- "cyan" = "#18a2d5",
- "yellow" = "#d58c18"
+ "blue" = rgb(24, 97, 213),
+ "red" = rgb(255, 0, 0),
+ "pink" = rgb(213, 24, 141),
+ "brown" = rgb(160, 82, 18),
+ "green" = rgb(14, 127, 27),
+ "cyan" = rgb(24, 162, 213),
+ "yellow" = rgb(255, 165, 0)
)
@@ -49,6 +49,23 @@
base_overlay.appearance_flags = RESET_COLOR
. += base_overlay
+/obj/item/wirecutters/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
+ . = ..()
+ if(isinhands && random_color)
+ var/mutable_appearance/M = mutable_appearance(icon_file, "cutters_cutty_thingy")
+ M.appearance_flags = RESET_COLOR
+ . += M
+
+/obj/item/wirecutters/get_belt_overlay()
+ if(random_color)
+ var/mutable_appearance/body = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "cutters")
+ var/mutable_appearance/head = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "cutters_cutty_thingy")
+ body.color = color
+ head.add_overlay(body)
+ return head
+ else
+ return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', icon_state)
+
/obj/item/wirecutters/attack(mob/living/carbon/C, mob/user)
if(istype(C) && C.handcuffed && istype(C.handcuffed, /obj/item/restraints/handcuffs/cable))
user.visible_message("[user] cuts [C]'s restraints with [src]!")
diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm
index 02f2009667..cc2e6412eb 100644
--- a/code/game/objects/obj_defense.dm
+++ b/code/game/objects/obj_defense.dm
@@ -204,32 +204,23 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
//the obj's reaction when touched by acid
/obj/acid_act(acidpwr, acid_volume)
if(!(resistance_flags & UNACIDABLE) && acid_volume)
-
- if(!acid_level)
- SSacid.processing[src] = src
- update_icon()
- var/acid_cap = acidpwr * 300 //so we cannot use huge amounts of weak acids to do as well as strong acids.
- if(acid_level < acid_cap)
- acid_level = min(acid_level + acidpwr * acid_volume, acid_cap)
+ AddComponent(/datum/component/acid, acidpwr, acid_volume)
return 1
-//the proc called by the acid subsystem to process the acid that's on the obj
-/obj/proc/acid_processing()
- . = 1
- if(!(resistance_flags & ACID_PROOF))
- if(prob(33))
- playsound(loc, 'sound/items/welder.ogg', 150, 1)
- take_damage(min(1 + round(sqrt(acid_level)*0.3), 300), BURN, "acid", 0)
-
- acid_level = max(acid_level - (5 + 3*round(sqrt(acid_level))), 0)
- if(!acid_level)
- return 0
-
//called when the obj is destroyed by acid.
/obj/proc/acid_melt()
- SSacid.processing -= src
+ var/datum/component/acid/acid = GetComponent(/datum/component/acid)
+ if(acid)
+ acid.RemoveComponent()
deconstruct(FALSE)
+/obj/proc/acid_level()
+ var/datum/component/acid/acid = GetComponent(/datum/component/acid)
+ if(acid)
+ return acid.level
+ else
+ return 0
+
//// FIRE
/obj/fire_act(exposed_temperature, exposed_volume)
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index a9a891464b..ca4428db57 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -22,8 +22,6 @@
var/resistance_flags = NONE // INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ON_FIRE | UNACIDABLE | ACID_PROOF
- var/acid_level = 0 //how much acid is on that obj
-
var/persistence_replacement //have something WAY too amazing to live to the next round? Set a new path here. Overuse of this var will make me upset.
var/current_skin //the item reskin
var/list/unique_reskin //List of options to reskin.
@@ -369,8 +367,6 @@
/obj/update_overlays()
. = ..()
- if(acid_level)
- . += GLOB.acid_overlay
if(resistance_flags & ON_FIRE)
. += GLOB.fire_overlay
diff --git a/code/game/objects/structures/transit_tubes/station.dm b/code/game/objects/structures/transit_tubes/station.dm
index 119026a66e..376725b262 100644
--- a/code/game/objects/structures/transit_tubes/station.dm
+++ b/code/game/objects/structures/transit_tubes/station.dm
@@ -121,6 +121,7 @@
/obj/structure/transit_tube/station/proc/launch_pod()
+ set waitfor = FALSE
if(launch_cooldown >= world.time)
return
for(var/obj/structure/transit_tube_pod/pod in loc)
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index 01c62a7901..9a2b4aab1a 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -354,10 +354,10 @@
. = SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
. = O.clean_blood()
O.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
- if(isitem(O))
- var/obj/item/I = O
- I.acid_level = 0
- I.extinguish()
+ var/datum/component/acid/acid = O.GetComponent(/datum/component/acid)
+ if(acid)
+ acid.level = 0
+ O.extinguish()
/obj/machinery/shower/proc/wash_turf()
if(isturf(loc))
@@ -601,7 +601,9 @@
busy = FALSE
SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
O.clean_blood()
- O.acid_level = 0
+ var/datum/component/acid/acid = O.GetComponent(/datum/component/acid)
+ if(acid)
+ acid.level = 0
create_reagents(5)
reagents.add_reagent(dispensedreagent, 5)
reagents.reaction(O, TOUCH)
diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm
index b92b659183..4082a48e71 100644
--- a/code/modules/antagonists/_common/antag_datum.dm
+++ b/code/modules/antagonists/_common/antag_datum.dm
@@ -96,6 +96,7 @@ GLOBAL_LIST_EMPTY(antagonists)
//Proc called when the datum is given to a mind.
/datum/antagonist/proc/on_gain()
+ set waitfor = FALSE
if(!(owner?.current))
return
if(!silent)
diff --git a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm
index 34370faa0a..4b88d203d6 100644
--- a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm
+++ b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm
@@ -225,18 +225,22 @@
return ..()
/obj/effect/clockwork/sigil/transmission/process()
- var/power_drained = 0
- var/power_mod = 0.005
- for(var/t in spiral_range_turfs(SIGIL_ACCESS_RANGE, src))
- var/turf/T = t
- for(var/M in T)
- var/atom/movable/A = M
- power_drained += A.power_drain(TRUE)
+ do_process()
- CHECK_TICK
+/obj/effect/clockwork/sigil/transmission/proc/do_process()
+ set waitfor = FALSE
+ var/power_drained = 0
+ var/power_mod = 0.005
+ for(var/t in spiral_range_turfs(SIGIL_ACCESS_RANGE, src))
+ var/turf/T = t
+ for(var/M in T)
+ var/atom/movable/A = M
+ power_drained += A.power_drain(TRUE)
- adjust_clockwork_power(power_drained * power_mod * 15)
- new /obj/effect/temp_visual/ratvar/sigil/transmission(loc, 1 + (power_drained * 0.0035))
+ CHECK_TICK
+
+ adjust_clockwork_power(power_drained * power_mod * 15)
+ new /obj/effect/temp_visual/ratvar/sigil/transmission(loc, 1 + (power_drained * 0.0035))
/obj/effect/clockwork/sigil/transmission/proc/charge_cyborg(mob/living/silicon/robot/cyborg)
if(!cyborg_checks(cyborg))
diff --git a/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm b/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm
index 5fc2a0ab63..8fcc36a456 100644
--- a/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm
@@ -246,6 +246,36 @@
if(GATEWAY_RATVAR_COMING to INFINITY)
. += "The anomaly is stable! Something is coming through!"
+/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/fulfill_purpose()
+ set waitfor = FALSE
+ countdown.stop()
+ resistance_flags |= INDESTRUCTIBLE
+ purpose_fulfilled = TRUE
+ make_glow()
+ animate(glow, transform = matrix() * 1.5, alpha = 255, time = 125)
+ sound_to_playing_players(volume = 100, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/ratvar_rises.ogg')) //End the sounds
+ sleep(125)
+ make_glow()
+ animate(glow, transform = matrix() * 3, alpha = 0, time = 5)
+ QDEL_IN(src, 3)
+ sleep(3)
+ GLOB.clockwork_gateway_activated = TRUE
+ var/turf/T = SSmapping.get_station_center()
+ new /obj/structure/destructible/clockwork/massive/ratvar(T)
+ var/x0 = T.x
+ var/y0 = T.y
+ for(var/I in spiral_range_turfs(255, T, tick_checked = TRUE))
+ var/turf/T2 = I
+ if(!T2)
+ continue
+ var/dist = cheap_hypotenuse(T2.x, T2.y, x0, y0)
+ if(dist < 100)
+ dist = TRUE
+ else
+ dist = FALSE
+ T.ratvar_act(dist)
+ CHECK_TICK
+
/obj/structure/destructible/clockwork/massive/celestial_gateway/process()
adjust_clockwork_power(2.5) //Provides weak power generation on its own
if(seconds_until_activation)
@@ -306,33 +336,7 @@
glow.icon_state = "clockwork_gateway_closing"
if(GATEWAY_RATVAR_ARRIVAL to INFINITY)
if(!purpose_fulfilled)
- countdown.stop()
- resistance_flags |= INDESTRUCTIBLE
- purpose_fulfilled = TRUE
- make_glow()
- animate(glow, transform = matrix() * 1.5, alpha = 255, time = 125)
- sound_to_playing_players(volume = 100, channel = CHANNEL_JUSTICAR_ARK, S = sound('sound/effects/ratvar_rises.ogg')) //End the sounds
- sleep(125)
- make_glow()
- animate(glow, transform = matrix() * 3, alpha = 0, time = 5)
- QDEL_IN(src, 3)
- sleep(3)
- GLOB.clockwork_gateway_activated = TRUE
- var/turf/T = SSmapping.get_station_center()
- new /obj/structure/destructible/clockwork/massive/ratvar(T)
- var/x0 = T.x
- var/y0 = T.y
- for(var/I in spiral_range_turfs(255, T, tick_checked = TRUE))
- var/turf/T2 = I
- if(!T2)
- continue
- var/dist = cheap_hypotenuse(T2.x, T2.y, x0, y0)
- if(dist < 100)
- dist = TRUE
- else
- dist = FALSE
- T.ratvar_act(dist)
- CHECK_TICK
+ fulfill_purpose()
//Converts nearby turfs into their clockwork equivalent, with ever-increasing range the closer the ark is to summoning Ratvar
/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/conversion_pulse()
diff --git a/code/modules/antagonists/clockcult/clock_structures/prolonging_prism.dm b/code/modules/antagonists/clockcult/clock_structures/prolonging_prism.dm
index 73488d736a..ededd0174c 100644
--- a/code/modules/antagonists/clockcult/clock_structures/prolonging_prism.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/prolonging_prism.dm
@@ -60,12 +60,8 @@
delay_remaining += PRISM_DELAY_DURATION
toggle(0, user)
-/obj/structure/destructible/clockwork/powered/prolonging_prism/process()
- var/turf/own_turf = get_turf(src)
- if(SSshuttle.emergency.mode != SHUTTLE_CALL || delay_remaining <= 0 || !own_turf || !is_station_level(own_turf.z))
- forced_disable(FALSE)
- return
- . = ..()
+/obj/structure/destructible/clockwork/powered/prolonging_prism/proc/do_process()
+ set waitfor = FALSE
var/delay_amount = 40
delay_remaining -= delay_amount
var/efficiency = get_efficiency_mod()
@@ -114,6 +110,14 @@
new /obj/effect/temp_visual/ratvar/prolonging_prism(T)
CHECK_TICK //we may be going over a hell of a lot of turfs
+/obj/structure/destructible/clockwork/powered/prolonging_prism/process()
+ var/turf/own_turf = get_turf(src)
+ if(SSshuttle.emergency.mode != SHUTTLE_CALL || delay_remaining <= 0 || !own_turf || !is_station_level(own_turf.z))
+ forced_disable(FALSE)
+ return
+ . = ..()
+ do_process()
+
/obj/structure/destructible/clockwork/powered/prolonging_prism/proc/get_delay_cost()
return FLOOR(delay_cost, MIN_CLOCKCULT_POWER)
diff --git a/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm b/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm
index 24ad1af88a..51f8dc7101 100644
--- a/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm
@@ -110,6 +110,7 @@
//Put me in Reebe, will you? Ratvar has found and is going to do a hecking murder on Nar'Sie
/obj/structure/destructible/clockwork/massive/ratvar/proc/clash_of_the_titans(obj/singularity/narsie/narsie)
+ set waitfor = FALSE
var/winner = "Undeclared"
var/base_victory_chance = 1
while(src && narsie)
diff --git a/code/modules/antagonists/cult/cult_structures.dm b/code/modules/antagonists/cult/cult_structures.dm
index 25fd446b06..a0093e4da1 100644
--- a/code/modules/antagonists/cult/cult_structures.dm
+++ b/code/modules/antagonists/cult/cult_structures.dm
@@ -204,26 +204,31 @@
STOP_PROCESSING(SSfastprocess, src)
return ..()
+/obj/structure/destructible/cult/pylon/proc/heal_friends()
+ set waitfor = FALSE
+ for(var/mob/living/L in range(5, src))
+ if(iscultist(L) || isshade(L) || isconstruct(L))
+ if(L.health != L.maxHealth)
+ new /obj/effect/temp_visual/heal(get_turf(src), "#960000")
+ if(ishuman(L))
+ L.adjustBruteLoss(-1, 0, only_organic = FALSE)
+ L.adjustFireLoss(-1, 0, only_organic = FALSE)
+ L.updatehealth()
+ if(isshade(L) || isconstruct(L))
+ var/mob/living/simple_animal/M = L
+ if(M.health < M.maxHealth)
+ M.adjustHealth(-3)
+ if(ishuman(L) && L.blood_volume < (BLOOD_VOLUME_NORMAL * L.blood_ratio))
+ L.blood_volume += 1.0
+ CHECK_TICK
+
+
/obj/structure/destructible/cult/pylon/process()
if(!anchored)
return
if(last_heal <= world.time)
last_heal = world.time + heal_delay
- for(var/mob/living/L in range(5, src))
- if(iscultist(L) || isshade(L) || isconstruct(L))
- if(L.health != L.maxHealth)
- new /obj/effect/temp_visual/heal(get_turf(src), "#960000")
- if(ishuman(L))
- L.adjustBruteLoss(-1, 0, only_organic = FALSE)
- L.adjustFireLoss(-1, 0, only_organic = FALSE)
- L.updatehealth()
- if(isshade(L) || isconstruct(L))
- var/mob/living/simple_animal/M = L
- if(M.health < M.maxHealth)
- M.adjustHealth(-3)
- if(ishuman(L) && L.blood_volume < (BLOOD_VOLUME_NORMAL * L.blood_ratio))
- L.blood_volume += 1.0
- CHECK_TICK
+ heal_friends()
if(last_corrupt <= world.time)
var/list/validturfs = list()
var/list/cultturfs = list()
diff --git a/code/modules/antagonists/devil/devil.dm b/code/modules/antagonists/devil/devil.dm
index 3b6dc68986..65ce89d33f 100644
--- a/code/modules/antagonists/devil/devil.dm
+++ b/code/modules/antagonists/devil/devil.dm
@@ -515,7 +515,6 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
var/mob/living/silicon/robot_devil = owner.current
var/laws = list("You may not use violence to coerce someone into selling their soul.", "You may not directly and knowingly physically harm a devil, other than yourself.", GLOB.lawlorify[LAW][ban], GLOB.lawlorify[LAW][obligation], "Accomplish your objectives at all costs.")
robot_devil.set_law_sixsixsix(laws)
- sleep(10)
if(owner.assigned_role == "Clown" && ishuman(owner.current))
var/mob/living/carbon/human/S = owner.current
to_chat(S, "Your infernal nature has allowed you to overcome your clownishness.")
diff --git a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm
index 0659655da5..fcc8bcade8 100644
--- a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm
+++ b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm
@@ -401,6 +401,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
next_announce += DOOMSDAY_ANNOUNCE_INTERVAL
/obj/machinery/doomsday_device/proc/detonate()
+ set waitfor = FALSE
sound_to_playing_players('sound/machines/alarm.ogg')
sleep(100)
for(var/i in GLOB.mob_living_list)
diff --git a/code/modules/arousal/arousal.dm b/code/modules/arousal/arousal.dm
index bd8b5dbf7a..36da6c73ba 100644
--- a/code/modules/arousal/arousal.dm
+++ b/code/modules/arousal/arousal.dm
@@ -197,6 +197,7 @@
//Here's the main proc itself
/mob/living/carbon/human/proc/mob_climax(forced_climax=FALSE,cause = "") //Forced is instead of the other proc, makes you cum if you have the tools for it, ignoring restraints
+ set waitfor = FALSE
if(mb_cd_timer > world.time)
if(!forced_climax) //Don't spam the message to the victim if forced to come too fast
to_chat(src, "You need to wait [DisplayTimeText((mb_cd_timer - world.time), TRUE)] before you can do that again!")
diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm
index 899eb12511..d0ed0f2436 100644
--- a/code/modules/assembly/infrared.dm
+++ b/code/modules/assembly/infrared.dm
@@ -81,6 +81,7 @@
return
/obj/item/assembly/infra/proc/refreshBeam()
+ set waitfor = FALSE
QDEL_LIST(beams)
if(throwing || !on || !secured)
return
diff --git a/code/modules/atmospherics/environmental/LINDA_fire.dm b/code/modules/atmospherics/environmental/LINDA_fire.dm
index c25e74fc5c..cfa3e7eb14 100644
--- a/code/modules/atmospherics/environmental/LINDA_fire.dm
+++ b/code/modules/atmospherics/environmental/LINDA_fire.dm
@@ -13,7 +13,7 @@
if(!air)
return
- if (air.get_oxidation_power(exposed_temperature) < 0.5)
+ if (air.get_oxidation_power(exposed_temperature) < 0.5 || air.get_moles(GAS_HYPERNOB) > 5)
return
var/has_fuel = air.get_moles(GAS_PLASMA) > 0.5 || air.get_moles(GAS_TRITIUM) > 0.5 || air.get_fuel_amount(exposed_temperature) > 0.5
if(active_hotspot)
@@ -152,7 +152,7 @@
if((temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) || (volume <= 1))
qdel(src)
return
- if(!location.air || location.air.get_oxidation_power() < 0.5 || (INSUFFICIENT(GAS_PLASMA) && INSUFFICIENT(GAS_TRITIUM) && location.air.get_fuel_amount() < 0.5))
+ if(!location.air || location.air.get_moles(GAS_HYPERNOB) > 5 || location.air.get_oxidation_power() < 0.5 || (INSUFFICIENT(GAS_PLASMA) && INSUFFICIENT(GAS_TRITIUM) && location.air.get_fuel_amount() < 0.5))
qdel(src)
return
diff --git a/code/modules/events/portal_storm.dm b/code/modules/events/portal_storm.dm
index 5ef30d0030..59bb22e9af 100644
--- a/code/modules/events/portal_storm.dm
+++ b/code/modules/events/portal_storm.dm
@@ -56,7 +56,10 @@
next_boss_spawn = startWhen + CEILING(2 * number_of_hostiles / number_of_bosses, 1)
/datum/round_event/portal_storm/announce(fake)
- set waitfor = 0
+ do_announce()
+
+/datum/round_event/portal_storm/proc/do_announce()
+ set waitfor = FALSE
sound_to_playing_players('sound/magic/lightning_chargeup.ogg')
sleep(80)
priority_announce("Massive bluespace anomaly detected en route to [station_name()]. Brace for impact.")
diff --git a/code/modules/events/wizard/fakeexplosion.dm b/code/modules/events/wizard/fakeexplosion.dm
index 5858064819..3ba20f4768 100644
--- a/code/modules/events/wizard/fakeexplosion.dm
+++ b/code/modules/events/wizard/fakeexplosion.dm
@@ -7,5 +7,4 @@
/datum/round_event/wizard/fake_explosion/start()
sound_to_playing_players('sound/machines/alarm.ogg')
- sleep(100)
- Cinematic(CINEMATIC_NUKE_FAKE,world)
+ addtimer(CALLBACK(GLOBAL_PROC,.proc/Cinematic, CINEMATIC_NUKE_FAKE, world), 100)
diff --git a/code/modules/fields/fields.dm b/code/modules/fields/fields.dm
index cb8d3e8dcf..8c7b414996 100644
--- a/code/modules/fields/fields.dm
+++ b/code/modules/fields/fields.dm
@@ -64,7 +64,8 @@
pass = FALSE
return pass
-/datum/proximity_monitor/advanced/process()
+/datum/proximity_monitor/advanced/proc/lag_checked_process()
+ set waitfor = FALSE
if(process_inner_turfs)
for(var/turf/T in field_turfs)
process_inner_turf(T)
@@ -72,7 +73,10 @@
if(process_edge_turfs)
for(var/turf/T in edge_turfs)
process_edge_turf(T)
- CHECK_TICK //Same here.
+ CHECK_TICK //Same here.
+
+/datum/proximity_monitor/advanced/process()
+ lag_checked_process()
/datum/proximity_monitor/advanced/proc/process_inner_turf(turf/T)
diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm
index aca727ad8d..fa7decc437 100644
--- a/code/modules/hydroponics/hydroponics.dm
+++ b/code/modules/hydroponics/hydroponics.dm
@@ -391,6 +391,7 @@
mutate(4, 10, 2, 4, 50, 4, 10, 3)
/obj/machinery/hydroponics/proc/mutatespecie() // Mutagent produced a new plant!
+ set waitfor = FALSE
if(!myseed || dead)
return
diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm
index 6cba540ca0..1adc951447 100644
--- a/code/modules/mining/machine_redemption.dm
+++ b/code/modules/mining/machine_redemption.dm
@@ -145,8 +145,11 @@
D.createmessage("Ore Redemption Machine", "New minerals available!", msg, 1, 0)
/obj/machinery/mineral/ore_redemption/process()
- if(!materials.mat_container || panel_open || !powered())
- return
+ if(materials.mat_container && !panel_open && powered())
+ process_all_ores()
+
+/obj/machinery/mineral/ore_redemption/proc/process_all_ores()
+ set waitfor = FALSE
var/atom/input = get_step(src, input_dir)
var/obj/structure/ore_box/OB = locate() in input
if(OB)
@@ -165,6 +168,7 @@
else if(!message_sent)
send_console_message()
+
/obj/machinery/mineral/ore_redemption/attackby(obj/item/W, mob/user, params)
if(default_unfasten_wrench(user, W))
return
diff --git a/code/modules/mining/machine_unloading.dm b/code/modules/mining/machine_unloading.dm
index dc7caa12c8..b39b0df6ab 100644
--- a/code/modules/mining/machine_unloading.dm
+++ b/code/modules/mining/machine_unloading.dm
@@ -10,22 +10,25 @@
output_dir = EAST
speed_process = TRUE
-/obj/machinery/mineral/unloading_machine/process()
- var/turf/T = get_step(src,input_dir)
- if(T)
- var/limit
- for(var/obj/structure/ore_box/B in T)
- for (var/obj/item/stack/ore/O in B)
- B.contents -= O
- unload_mineral(O)
- limit++
- if (limit>=10)
- return
- CHECK_TICK
- CHECK_TICK
- for(var/obj/item/I in T)
- unload_mineral(I)
+/obj/machinery/mineral/unloading_machine/proc/horrible_quadratic_monster(var/turf/T)
+ set waitfor = FALSE
+ var/limit = 0
+ for(var/obj/structure/ore_box/B in T)
+ for (var/obj/item/stack/ore/O in B)
+ B.contents -= O
+ unload_mineral(O)
limit++
if (limit>=10)
return
CHECK_TICK
+ for(var/obj/item/I in T)
+ unload_mineral(I)
+ limit++
+ if (limit>=10)
+ return
+ CHECK_TICK
+
+/obj/machinery/mineral/unloading_machine/process()
+ var/turf/T = get_step(src,input_dir)
+ if(T)
+ horrible_quadratic_monster(T)
diff --git a/code/modules/mining/mint.dm b/code/modules/mining/mint.dm
index 2a8e0f2516..f8a4ba4a72 100644
--- a/code/modules/mining/mint.dm
+++ b/code/modules/mining/mint.dm
@@ -64,8 +64,6 @@
if(materials.use_amount_mat(coin_mat, chosen))
for(var/coin_to_make in 1 to 5)
create_coins()
- produced_coins++
- CHECK_TICK
else
var/found_new = FALSE
for(var/datum/material/inserted_material in materials.materials)
@@ -131,6 +129,7 @@
return TRUE
/obj/machinery/mineral/mint/proc/create_coins()
+ set waitfor = FALSE
var/turf/T = get_step(src,output_dir)
var/temp_list = list()
temp_list[chosen] = 400
@@ -143,3 +142,5 @@
O.forceMove(bag_to_use) //don't bother sending the signal, the new bag is empty and all that.
SSblackbox.record_feedback("amount", "coins_minted", 1)
+ produced_coins++
+ CHECK_TICK
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index e4d6f5253e..44379660b6 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -358,7 +358,7 @@
return
I.item_flags |= BEING_REMOVED
breakouttime = I.breakouttime
- var/datum/cuffbreak_checker/cuffbreak_checker = new(get_turf(src))
+ var/datum/cuffbreak_checker/cuffbreak_checker = new(get_turf(src), istype(I, /obj/item/restraints)? I : null)
if(!cuff_break)
visible_message("[src] attempts to remove [I]!")
to_chat(src, "You attempt to remove [I]... (This will take around [DisplayTimeText(breakouttime)] and you need to stand still.)")
@@ -384,16 +384,22 @@
/datum/cuffbreak_checker
var/turf/last
+ var/obj/item/restraints/cuffs
-/datum/cuffbreak_checker/New(turf/initial_turf)
+/datum/cuffbreak_checker/New(turf/initial_turf, obj/item/restraints/R)
last = initial_turf
+ if(R)
+ cuffs = R
/datum/cuffbreak_checker/proc/check_movement(atom/user, delay, atom/target, time_left, do_after_flags, required_mobility_flags, required_combat_flags, mob_redirect, stage, initially_held_item, tool, list/passed_in)
if(get_turf(user) != last)
last = get_turf(user)
passed_in[1] = 0.5
+ if(cuffs && !cuffs.allow_breakout_movement)
+ return DO_AFTER_STOP
else
passed_in[1] = 1
+ return DO_AFTER_CONTINUE
/mob/living/carbon/proc/uncuff()
if (handcuffed)
@@ -961,7 +967,9 @@
/mob/living/carbon/ExtinguishMob()
for(var/X in get_equipped_items())
var/obj/item/I = X
- I.acid_level = 0 //washes off the acid on our clothes
+ var/datum/component/acid/acid = I.GetComponent(/datum/component/acid)
+ if(acid)
+ acid.level = 0
I.extinguish() //extinguishes our clothes
..()
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index a0088ead04..65bcddf0ad 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1101,9 +1101,9 @@
if(HAS_TRAIT(src, TRAIT_TOXINLOVER))
return ""
if(isplasmaman(src))
- return ""
if(isgolem(src))
- return ""
return ""
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 6f1fe57df3..ac456ead3f 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -15,7 +15,6 @@
block_parry_data = /datum/block_parry_data/unarmed/human
default_block_parry_data = /datum/block_parry_data/unarmed/human
- causes_dirt_buildup_on_floor = TRUE
//Hair colour and style
var/hair_color = "000"
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index 1619d0f6de..54d6771c6c 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -90,13 +90,31 @@
//End bloody footprints
S.step_action()
+ if(movement_type & GROUND)
+ dirt_buildup()
/mob/living/carbon/human/Process_Spacemove(movement_dir = 0) //Temporary laziness thing. Will change to handles by species reee.
if(dna.species.space_move(src))
return TRUE
return ..()
-/mob/living/carbon/human/dirt_buildup(strength)
+/mob/living/carbon/human/proc/dirt_buildup(strength = 1)
if(!shoes || !(shoes.body_parts_covered & FEET))
return // barefoot advantage
- return ..()
+ var/turf/open/T = loc
+ if(!istype(T) || !T.dirt_buildup_allowed)
+ return
+ var/area/A = T.loc
+ if(!A.dirt_buildup_allowed)
+ return
+ var/multiplier = CONFIG_GET(number/turf_dirty_multiplier)
+ strength *= multiplier
+ var/obj/effect/decal/cleanable/dirt/D = locate() in T
+ if(D)
+ D.dirty(strength)
+ else
+ T.dirtyness += strength
+ if(T.dirtyness >= (isnull(T.dirt_spawn_threshold)? CONFIG_GET(number/turf_dirt_threshold) : T.dirt_spawn_threshold))
+ D = new /obj/effect/decal/cleanable/dirt(T)
+ D.dirty(T.dirt_spawn_threshold - T.dirtyness)
+ T.dirtyness = 0 // reset.
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index 3b53eec64f..a76fbe4c4e 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -67,8 +67,6 @@
//Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects.
var/incorporeal_move = FALSE //FALSE is off, INCORPOREAL_MOVE_BASIC is normal, INCORPOREAL_MOVE_SHADOW is for ninjas
//and INCORPOREAL_MOVE_JAUNT is blocked by holy water/salt
- /// Do we make floors dirty as we move?
- var/causes_dirt_buildup_on_floor = FALSE
var/list/roundstart_quirks = list()
diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm
index bafa38ec5e..07b40b3ab1 100644
--- a/code/modules/mob/living/living_movement.dm
+++ b/code/modules/mob/living/living_movement.dm
@@ -102,31 +102,6 @@
if(lying && !buckled && prob(getBruteLoss()*200/maxHealth))
makeTrail(newloc, T, old_direction)
- if(causes_dirt_buildup_on_floor && (movement_type & GROUND))
- dirt_buildup()
-
-/**
- * Attempts to make the floor dirty.
- */
-/mob/living/proc/dirt_buildup(strength = 1)
- var/turf/open/T = loc
- if(!istype(T) || !T.dirt_buildup_allowed)
- return
- var/area/A = T.loc
- if(!A.dirt_buildup_allowed)
- return
- var/multiplier = CONFIG_GET(number/turf_dirty_multiplier)
- strength *= multiplier
- var/obj/effect/decal/cleanable/dirt/D = locate() in T
- if(D)
- D.dirty(strength)
- else
- T.dirtyness += strength
- if(T.dirtyness >= (isnull(T.dirt_spawn_threshold)? CONFIG_GET(number/turf_dirt_threshold) : T.dirt_spawn_threshold))
- D = new /obj/effect/decal/cleanable/dirt(T)
- D.dirty(T.dirt_spawn_threshold - T.dirtyness)
- T.dirtyness = 0 // reset.
-
/mob/living/Move_Pulled(atom/A)
. = ..()
if(!. || !isliving(A))
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index ce6a5dcda1..1f582b68bf 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -182,6 +182,7 @@
. = ..()
/mob/living/silicon/ai/proc/set_core_display_icon(input, client/C)
+ set waitfor = FALSE
if(client && !C)
C = client
if(!input && !C?.prefs?.preferred_ai_core_display)
diff --git a/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm b/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm
index 98700ffaf0..1b0d210d9c 100644
--- a/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm
@@ -133,6 +133,10 @@
chance_to_hold_onto_points = highest_cost*0.5
if(points != max_points && prob(chance_to_hold_onto_points))
return //Let's save our points for a better ability (unless we're at max points, in which case we can't save anymore!)
+ do_ability()
+
+/datum/boss_active_timed_battle/proc/do_ability()
+ set waitfor = FALSE
if(!boss.client)
abilities = shuffle(abilities)
for(var/ab in abilities)
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 f2ece50af2..24e595ef7e 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
@@ -102,23 +102,13 @@
consume_bait()
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/proc/consume_bait()
- var/list/L = list()
- for(var/obj/O in view(src, 9))
- L += O
- var/obj/item/stack/ore/diamond/diamonds = locate(/obj/item/stack/ore/diamond) in L
- if(diamonds)
- var/distanced = 0
- distanced = get_dist(loc,diamonds.loc)
- if(distanced <= 1 && diamonds)
- qdel(diamonds)
- src.visible_message("[src] consumes [diamonds], and it disappears! ...At least, you think.")
- var/obj/item/pen/survival/bait = locate(/obj/item/pen/survival) in L
- if(bait)
- var/distanceb = 0
- distanceb = get_dist(loc,bait.loc)
- if(distanceb <= 1 && bait)
- qdel(bait)
- visible_message("[src] examines [bait] closer, and telekinetically shatters the pen.")
+ for(var/obj/O in view(1, src))
+ if(istype(O, /obj/item/stack/ore/diamond))
+ qdel(O)
+ src.visible_message("[src] consumes [O], and it disappears! ...At least, you think.")
+ else if(istype(O, /obj/item/pen/survival))
+ qdel(O)
+ src.visible_message("[src] examines [O] closer, and telekinetically shatters the pen.")
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/random/Initialize()
. = ..()
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 2af68eab46..f7d8a810ce 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -95,7 +95,7 @@
. = ..()
if((direction & (direction - 1)) && mob.loc == n) //moved diagonally successfully
- add_delay *= 2
+ add_delay *= SQRT_2
mob.set_glide_size(DELAY_TO_GLIDE_SIZE(add_delay), FALSE)
move_delay += add_delay
if(.) // If mob is null here, we deserve the runtime
diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm
index 131a098258..64c99e01bf 100644
--- a/code/modules/modular_computers/computers/item/computer.dm
+++ b/code/modules/modular_computers/computers/item/computer.dm
@@ -349,6 +349,7 @@
// Relays kill program request to currently active program. Use this to quit current program.
/obj/item/modular_computer/proc/kill_program(forced = FALSE)
+ set waitfor = FALSE
if(active_program)
active_program.kill_program(forced)
active_program = null
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index 593d77f959..0c70f47c53 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -287,7 +287,9 @@
/datum/reagent/water/reaction_obj(obj/O, reac_volume)
O.extinguish()
- O.acid_level = 0
+ var/datum/component/acid/acid = O.GetComponent(/datum/component/acid)
+ if(acid)
+ acid.level = 0
// cubes
if(istype(O, /obj/item/reagent_containers/food/snacks/cube))
var/obj/item/reagent_containers/food/snacks/cube/cube = O
diff --git a/code/modules/reagents/chemistry/recipes.dm b/code/modules/reagents/chemistry/recipes.dm
index 7df061c8aa..41c0ed717e 100644
--- a/code/modules/reagents/chemistry/recipes.dm
+++ b/code/modules/reagents/chemistry/recipes.dm
@@ -40,6 +40,7 @@
/datum/chemical_reaction/proc/on_reaction(datum/reagents/holder, multiplier, specialreact)
+ set waitfor = FALSE
return
//I recommend you set the result amount to the total volume of all components.
diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm
index b90815d543..02c8a9802c 100644
--- a/code/modules/reagents/reagent_containers/spray.dm
+++ b/code/modules/reagents/reagent_containers/spray.dm
@@ -16,7 +16,7 @@
var/stream_mode = 0 //whether we use the more focused mode
var/current_range = 3 //the range of tiles the sprayer will reach.
var/spray_range = 3 //the range of tiles the sprayer will reach when in spray mode.
- var/stream_range = 1 //the range of tiles the sprayer will reach when in stream mode.
+ var/stream_range = 3 //the range of tiles the sprayer will reach when in stream mode.
var/stream_amount = 10 //the amount of reagents transfered when in stream mode.
/// Amount of time it takes for a spray to completely travel.
var/spray_delay = 8
@@ -74,19 +74,18 @@
return
var/range = clamp(get_dist(src, A), 1, current_range)
var/wait_step = CEILING(spray_delay * INVERSE(range), world.tick_lag)
- var/obj/effect/decal/chempuff/D = new /obj/effect/decal/chempuff(get_turf(src), stream_mode, wait_step, range, stream_mode? 1 : range)
+ var/obj/effect/decal/chempuff/D = new /obj/effect/decal/chempuff(get_turf(src), stream_mode, wait_step, range, stream_mode? 1 : range, amount_per_transfer_from_this)
var/turf/T = get_turf(src)
if(!T)
return
log_reagent("SPRAY: [key_name(usr)] fired [src] ([REF(src)]) [COORD(T)] at [A] ([REF(A)]) [COORD(A)] (chempuff: [D.reagents.log_list()])")
- D.create_reagents(amount_per_transfer_from_this, NONE, NO_REAGENTS_VALUE)
if(stream_mode)
reagents.trans_to(D, amount_per_transfer_from_this)
else
reagents.trans_to(D, amount_per_transfer_from_this, 1/range)
- D.color = mix_color_from_reagents(D.reagents.reagent_list)
+ D.add_atom_colour(mix_color_from_reagents(D.reagents.reagent_list), TEMPORARY_COLOUR_PRIORITY)
last_spray = world.time
- D.run_puff(A)
+ INVOKE_ASYNC(D, /obj/effect/decal/chempuff/proc/run_puff, A)
/obj/item/reagent_containers/spray/attack_self(mob/user)
stream_mode = !stream_mode
diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm
index aefb670dd3..e9c17ecc28 100644
--- a/code/modules/recycling/conveyor2.dm
+++ b/code/modules/recycling/conveyor2.dm
@@ -268,16 +268,19 @@ GLOBAL_LIST_EMPTY(conveyors_by_id)
// timed process
// if the switch changed, update the linked conveyors
-/obj/machinery/conveyor_switch/process()
- if(!operated)
- return
- operated = 0
-
+/obj/machinery/conveyor_switch/proc/do_process()
+ set waitfor = FALSE
for(var/obj/machinery/conveyor/C in GLOB.conveyors_by_id[id])
C.operating = position
C.update_move_direction()
CHECK_TICK
+/obj/machinery/conveyor_switch/process()
+ if(!operated)
+ return
+ operated = 0
+ do_process()
+
// attack with hand, switch position
/obj/machinery/conveyor_switch/interact(mob/user)
add_fingerprint(user)
diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
index f3e14993ed..62e68e5b0e 100644
--- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
+++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
@@ -622,7 +622,9 @@
var/obj/O = owner.get_active_held_item()
if(O)
O.extinguish() //All shamelessly copied from water's reaction_obj, since I didn't seem to be able to get it here for some reason.
- O.acid_level = 0
+ var/datum/component/acid/acid = O.GetComponent(/datum/component/acid)
+ if(acid)
+ acid.level = 0
// Monkey cube
if(istype(O, /obj/item/reagent_containers/food/snacks/cube))
to_chat(owner, "[linked_extract] kept your hands wet! It makes [O] expand!")
diff --git a/code/modules/ruins/spaceruin_code/caravanambush.dm b/code/modules/ruins/spaceruin_code/caravanambush.dm
index 740850524c..ab38ed8e4d 100644
--- a/code/modules/ruins/spaceruin_code/caravanambush.dm
+++ b/code/modules/ruins/spaceruin_code/caravanambush.dm
@@ -1,27 +1,27 @@
//caravan ambush
/obj/item/wrench/caravan
- color = "#ff0000"
+ icon_state = "wrench_caravan"
desc = "A prototype of a new wrench design, allegedly the red color scheme makes it go faster."
name = "experimental wrench"
toolspeed = 0.3
/obj/item/screwdriver/caravan
- color = "#ff0000"
+ icon_state = "screwdriver_caravan"
desc = "A prototype of a new screwdriver design, allegedly the red color scheme makes it go faster."
name = "experimental screwdriver"
toolspeed = 0.3
random_color = FALSE
/obj/item/wirecutters/caravan
- color = "#ff0000"
+ icon_state = "cutters_caravan"
desc = "A prototype of a new wirecutter design, allegedly the red color scheme makes it go faster."
name = "experimental wirecutters"
toolspeed = 0.3
random_color = FALSE
/obj/item/crowbar/red/caravan
- color = "#ff0000"
+ icon_state = "crowbar_caravan"
desc = "A prototype of a new crowbar design, allegedly the red color scheme makes it go faster."
name = "experimental crowbar"
toolspeed = 0.3
diff --git a/code/modules/vehicles/motorized_wheelchair.dm b/code/modules/vehicles/motorized_wheelchair.dm
new file mode 100644
index 0000000000..8e2d838066
--- /dev/null
+++ b/code/modules/vehicles/motorized_wheelchair.dm
@@ -0,0 +1,155 @@
+/obj/vehicle/ridden/wheelchair/motorized
+ name = "Hoverchair"
+ desc = "A chair with thrusters. It seems to have a motor in it."
+ icon = 'icons/obj/vehicles.dmi'
+ icon_state = "wheelchair_motorized"
+ max_integrity = 150
+ var/speed = 2
+ var/power_efficiency = 1
+ var/power_usage = 25
+ var/panel_open = FALSE
+ var/list/required_parts = list(/obj/item/stock_parts/manipulator,
+ /obj/item/stock_parts/manipulator,
+ /obj/item/stock_parts/capacitor)
+ var/obj/item/stock_parts/cell/power_cell
+
+/obj/vehicle/ridden/wheelchair/motorized/CheckParts(list/parts_list)
+ ..()
+ refresh_parts()
+
+/obj/vehicle/ridden/wheelchair/motorized/proc/refresh_parts()
+ speed = 1 // Should never be under 1
+ for(var/obj/item/stock_parts/manipulator/M in contents)
+ speed += M.rating
+ for(var/obj/item/stock_parts/capacitor/C in contents)
+ power_efficiency = C.rating
+ var/datum/component/riding/D = GetComponent(/datum/component/riding)
+ D.vehicle_move_delay = round((CONFIG_GET(number/movedelay/run_delay) * 2) / speed, world.tick_lag)
+
+/obj/vehicle/ridden/wheelchair/motorized/obj_destruction(damage_flag)
+ var/turf/T = get_turf(src)
+ for(var/atom/movable/A in contents)
+ A.forceMove(T)
+ if(isliving(A))
+ var/mob/living/L = A
+ L.update_mobility()
+ ..()
+
+/obj/vehicle/ridden/wheelchair/motorized/driver_move(mob/living/user, direction)
+ if(istype(user))
+ if(!canmove)
+ return FALSE
+ if(!power_cell)
+ to_chat(user, "There seems to be no cell installed in [src].")
+ canmove = FALSE
+ addtimer(VARSET_CALLBACK(src, canmove, TRUE), 20)
+ return FALSE
+ if(power_cell.charge < power_usage / max(power_efficiency, 1))
+ to_chat(user, "The display on [src] blinks 'Out of Power'.")
+ canmove = FALSE
+ addtimer(VARSET_CALLBACK(src, canmove, TRUE), 20)
+ return FALSE
+ if(user.get_num_arms() < arms_required)
+ to_chat(user, "You don't have enough arms to operate the motor controller!")
+ canmove = FALSE
+ addtimer(VARSET_CALLBACK(src, canmove, TRUE), 20)
+ return FALSE
+ power_cell.use(power_usage / max(power_efficiency, 1))
+ return ..()
+
+/obj/vehicle/ridden/wheelchair/motorized/post_buckle_mob(mob/living/user)
+ . = ..()
+ density = TRUE
+
+/obj/vehicle/ridden/wheelchair/motorized/post_unbuckle_mob()
+ . = ..()
+ density = FALSE
+
+/obj/vehicle/ridden/wheelchair/motorized/attack_hand(mob/living/user)
+ if(power_cell && panel_open)
+ power_cell.update_icon()
+ user.put_in_hands(power_cell)
+ power_cell = null
+ to_chat(user, "You remove the power cell from [src].")
+ return
+ return ..()
+
+/obj/vehicle/ridden/wheelchair/motorized/attackby(obj/item/I, mob/user, params)
+ if(I.tool_behaviour == TOOL_SCREWDRIVER)
+ I.play_tool_sound(src)
+ panel_open = !panel_open
+ user.visible_message("[user] [panel_open ? "opens" : "closes"] the maintenance panel on [src].", "You [panel_open ? "open" : "close"] the maintenance panel.")
+ return
+ if(panel_open)
+ if(istype(I, /obj/item/stock_parts/cell))
+ if(power_cell)
+ to_chat(user, "There is a power cell already installed.")
+ else
+ I.forceMove(src)
+ power_cell = I
+ to_chat(user, "You install the [I].")
+ refresh_parts()
+ return
+ if(istype(I, /obj/item/stock_parts))
+ var/obj/item/stock_parts/B = I
+ var/P
+ for(var/obj/item/stock_parts/A in contents)
+ for(var/D in required_parts)
+ if(ispath(A.type, D))
+ P = D
+ break
+ if(istype(B, P) && istype(A, P))
+ if(B.get_part_rating() > A.get_part_rating())
+ B.forceMove(src)
+ user.put_in_hands(A)
+ user.visible_message("[user] replaces [A] with [B] in [src].", "You replace [A] with [B].")
+ break
+ refresh_parts()
+ return
+ return ..()
+
+/obj/vehicle/ridden/wheelchair/motorized/wrench_act(mob/living/user, obj/item/I)
+ to_chat(user, "You begin to detach the thrusters...")
+ if(I.use_tool(src, user, 40, volume=50))
+ to_chat(user, "You detach the thrusters and deconstruct the chair.")
+ new /obj/item/stack/rods(drop_location(), 8)
+ new /obj/item/stack/sheet/plasteel(drop_location(), 10)
+ var/turf/T = get_turf(src)
+ for(var/atom/movable/A in contents)
+ A.forceMove(T)
+ if(isliving(A))
+ var/mob/living/L = A
+ L.update_mobility()
+ qdel(src)
+ return TRUE
+
+/obj/vehicle/ridden/wheelchair/motorized/examine(mob/user)
+ . = ..()
+ if(panel_open)
+ . += "There is a small screen on it, [(in_range(user, src) || isobserver(user)) ? "[power_cell ? "it reads:" : "but it is dark."]" : "but you can't see it from here."]"
+ if(!power_cell || (!in_range(user, src) && !isobserver(user)))
+ return
+ . += "Speed: [speed]"
+ . += "Energy efficiency: [power_efficiency]"
+ . += "Power: [power_cell.charge] out of [power_cell.maxcharge]"
+
+/obj/vehicle/ridden/wheelchair/motorized/Bump(atom/movable/M)
+ . = ..()
+ // If the speed is higher than delay_multiplier throw the person on the wheelchair away
+ if(M.density && speed > 2 && has_buckled_mobs())
+ var/mob/living/H = buckled_mobs[1]
+ var/atom/throw_target = get_edge_target_turf(H, pick(GLOB.cardinals))
+ unbuckle_mob(H)
+ H.throw_at(throw_target, 2, 3)
+ H.Knockdown(100)
+ H.adjustStaminaLoss(40)
+ if(isliving(M))
+ var/mob/living/D = M
+ throw_target = get_edge_target_turf(D, pick(GLOB.cardinals))
+ D.throw_at(throw_target, 2, 3)
+ D.Knockdown(80)
+ D.adjustStaminaLoss(35)
+ visible_message("[src] crashes into [M], sending [H] and [D] flying!")
+ else
+ visible_message("[src] crashes into [M], sending [H] flying!")
+ playsound(src, 'sound/effects/bang.ogg', 50, 1)
diff --git a/code/modules/vehicles/wheelchair.dm b/code/modules/vehicles/wheelchair.dm
index a81dff37ad..28145ba8e1 100644
--- a/code/modules/vehicles/wheelchair.dm
+++ b/code/modules/vehicles/wheelchair.dm
@@ -26,8 +26,8 @@
AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE, CALLBACK(src, .proc/can_user_rotate),CALLBACK(src, .proc/can_be_rotated),null)
/obj/vehicle/ridden/wheelchair/obj_destruction(damage_flag)
- new /obj/item/stack/rods(drop_location(), 1)
- new /obj/item/stack/sheet/metal(drop_location(), 1)
+ new /obj/item/stack/rods(drop_location(), 8)
+ new /obj/item/stack/sheet/metal(drop_location(), 2)
..()
/obj/vehicle/ridden/wheelchair/Destroy()
@@ -53,7 +53,10 @@
/obj/vehicle/ridden/wheelchair/Moved()
. = ..()
cut_overlays()
- playsound(src, 'sound/effects/roll.ogg', 75, 1)
+ if(istype(src, /obj/vehicle/ridden/wheelchair/motorized))
+ playsound(src, 'sound/effects/chairwhoosh.ogg', 75, 1)
+ else
+ playsound(src, 'sound/effects/roll.ogg', 75, 1)
if(has_buckled_mobs())
handle_rotation_overlayed()
@@ -88,8 +91,12 @@
/obj/vehicle/ridden/wheelchair/proc/handle_rotation_overlayed()
cut_overlays()
- var/image/V = image(icon = icon, icon_state = "wheelchair_overlay", layer = FLY_LAYER, dir = src.dir)
- add_overlay(V)
+ if(istype(src, /obj/vehicle/ridden/wheelchair/motorized))
+ var/image/V = image(icon = icon, icon_state = "wheelchair_noverlay", layer = FLY_LAYER, dir = src.dir)
+ add_overlay(V)
+ else
+ var/image/V = image(icon = icon, icon_state = "wheelchair_overlay", layer = FLY_LAYER, dir = src.dir)
+ add_overlay(V)
diff --git a/code/modules/vore/eating/living.dm b/code/modules/vore/eating/living.dm
index 41d7da16a1..ca5ee0f476 100644
--- a/code/modules/vore/eating/living.dm
+++ b/code/modules/vore/eating/living.dm
@@ -59,13 +59,14 @@
// Critical adjustments due to TG grab changes - Poojawa
/mob/living/proc/vore_attack(var/mob/living/user, var/mob/living/prey, var/mob/living/pred)
- lazy_init_belly()
+ set waitfor = FALSE
if(!user || !prey || !pred)
return
if(!isliving(pred)) //no badmin, you can't feed people to ghosts or objects.
return
+ lazy_init_belly()
if(pred == prey) //you click your target
if(!CHECK_BITFIELD(pred.vore_flags,FEEDING))
to_chat(user, "They aren't able to be fed.")
diff --git a/code/modules/zombie/organs.dm b/code/modules/zombie/organs.dm
index 2681f781a9..a724d26314 100644
--- a/code/modules/zombie/organs.dm
+++ b/code/modules/zombie/organs.dm
@@ -45,7 +45,7 @@
if(!owner)
return
if(!(src in owner.internal_organs))
- Remove(owner)
+ INVOKE_ASYNC(src,.proc/Remove,owner)
if(owner.mob_biotypes & MOB_MINERAL)//does not process in inorganic things
return
if (causes_damage && !iszombie(owner) && owner.stat != DEAD)
diff --git a/dependencies.sh b/dependencies.sh
index 0fbad2153c..a86c58a5a2 100644
--- a/dependencies.sh
+++ b/dependencies.sh
@@ -8,7 +8,10 @@ export BYOND_MAJOR=513
export BYOND_MINOR=1536
#rust_g git tag
-export RUST_G_VERSION=0.4.7
+export RUST_G_VERSION=0.4.8
+
+#auxmos git tag
+export AUXMOS_VERSION=v0.2.0
#node version
export NODE_VERSION=12
diff --git a/html/changelog.html b/html/changelog.html
index 5e00eea3ab..d7d439a7c8 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -50,6 +50,94 @@
-->
+
14 July 2021
+
Putnam3145 updated:
+
+ - Acid is now a component
+
+
+
13 July 2021
+
MrJWhit updated:
+
+ - Adds a mirror above the sink in the captains bedroom in pubby
+
+
+
12 July 2021
+
Putnam3145 updated:
+
+ - causes_dirt_buildup_on_floor is now just a thing humans do instead of a weird var only true for humans
+
+
+
11 July 2021
+
shellspeed1 updated:
+
+ - replaces the seed machine with a biogen in the survival pod.
+ - corrected an issue regarding wrong pair of gloves in the pod for DYI wiring .
+
+
+
10 July 2021
+
WanderingFox95 updated:
+
+ - Returns the wheelchair sprites to having, you know, wheels?
+ - A motorized wheelchair addsound: Chairwhoosh.
+
+
+
09 July 2021
+
MrJWhit updated:
+
+ - Made a light not exist on the same tile as a door on pubby.
+ - Makes the RD APC automatically connect to the powernet with the correct wire on pubby.
+ - Added another wall for the AM engine so it doesn't space the airlock roundstart.
+
+
+
07 July 2021
+
DeltaFire15 updated:
+
+ - Golem / Plasmaman species color should work again.
+
+
+
05 July 2021
+
Putnam3145 updated:
+
+ - Watchers no longer search 9 tiles away for stuff then throw the result away if it's more than 1 tile away
+ - Auxmos pull now uses a tag instead of pulling straight from the main branch
+
+
WanderingFox95 updated:
+
+ - Moved a sprite one pixel to the left.
+
+
zeroisthebiggay updated:
+
+ - tg based tool resprites
+ - wirecutters have proper overlays
+
+
+
04 July 2021
+
cadyn updated:
+
+ - Updated server scripts for proper linux support
+
+
+
03 July 2021
+
DeltaFire15 updated:
+
+ - Turrets on nonlethal mode now once again shoot till the target is stamcrit as opposed to unable to use items, resolving some issues.
+
+
Putnam3145 updated:
+
+ - A bunch of sleeping process() calls now either don't sleep or make sure to call a proc with waitfor set to FALSE
+
+
WanderingFox95 updated:
+
+ - The axolotl ears in the .dmi file actually exist to the game now.
+
+
+
02 July 2021
+
silicons updated:
+
+ - spray bottles work again.
+
+
30 June 2021
WanderingFox95 updated:
@@ -508,151 +596,6 @@
-
- 12 May 2021
- DeltaFire15 updated:
-
- - find_safe_turf no longer always fails on safe oxygen levels(??)
- - Heretic bladeshatters now actually take the heretic's z into account as intended, instead of always being station z tweak: Message for failing the bladeshatter despite succeeding the do_after tweak: Improves bladeshatter a bit by making it safer codewise
-
-
- 11 May 2021
- LetterN updated:
-
- - fixes emagging console shuttle purchases
- - syndie melee simplemobs has no more bullshit shield
-
- bunny232 updated:
-
- - Delta station xenobiology department has received enhanced scrubbing and ventilation capabilities similar to box and meta
-
-
- 09 May 2021
- Putnam3145 updated:
-
- - Priority announcement admeme verb
-
- SandPoot updated:
-
- - Fixed Cyborg examines adding an extra weird line.
- - Everything can be set to have tooltips, and even coded to have neat tooltips.
- - Makes it so humans and borgs already have tooltips.
-
- TheObserver-sys updated:
-
- - Fixes most of the weird handling bugs and improves cigarette case handling in general.
- - The Gorlex Marauders have seen fit to allow you to purchase the .45-70 GOVT rare ammo, at a premium cost. Don't waste it.
-
- WanderingFox95 updated:
-
- - added the unrolling pin, an innovative solution to dough-based mishaps.
- - added visuals for the unrolling pin
-
- dzahlus updated:
-
- - added new malf AI spawn and doomsday sound
- - removed old malf AI spawn and doomsday sound
-
- zeroisthebiggay updated:
-
- - pirates now have a medbay and several other things qualifying as a buff
- - pirates lost their toilet
-
-
- 08 May 2021
- Arturlang updated:
-
- - Synthblood bottles now have the proper color and probably won't poison you anymore
-
- timothyteakettle updated:
-
- - lets humans have digi legs (and avian legs)
-
-
- 05 May 2021
- The0bserver, with a great amount of advice from TripleZeta/TetraZeta updated:
-
- - Adds a new crate type, for use with any manner of cheeky breeki shenanigans, as well as with existing Russian contraband.
-
- bunny232 updated:
-
- - There's some new vents and scrubbers in the meta station xenobiology department. Welders and wrenches not included*
-
- keronshb updated:
-
- - Nightmare Shadow Jaunt threshold up to 0.4
- - Vendor and Engraved message light down to 0.3
-
-
- 03 May 2021
- TripleShades updated:
-
- - Added two air alarms to Pubby Security, one in the evidence locker room and one in the main equipment back room
- - pAI Card back to outside Research in Meta Station
- - Pubby Disposals now shunts to space
- - Maintinence Areas being not applied to certain airlocks as well as stealing minor walls
- - Box Surgery Storage camera is now renamed to be on the network
- - Box Paramedic Station camera is now renamed to be on the network, and no longer steals the Morgue's cam tweak: Box Surgery Storage is now it's own proper room
-
-
- 01 May 2021
- qweq12yt updated:
-
- - Restores the sprite for the Riot Suit.
-
-
- 30 April 2021
- DrPainis updated:
-
- - Bubblegum's hallucinations are capitalized.
-
- Melbert, SandPoot updated:
-
- - TGUI Limbgrower
- - Refactored the limbgrower to modernize the code and allow for more types of designs.
- - The limbgrower now supports plumbing ducts.
- - Fixes genitals not actually getting data from disks.
- - Adds two special helpers.
-
- SandPoot updated:
-
- - The decal painter now has visible previews for your tile painting funs.
- - Fixes decal painter painting in the opposite direction.
-
- TheObserver-sys updated:
-
- - Restores the access lock on crates that should have them, given the goods inside.
- - Makes the 10MM Surplus Rifle a less awful thing to use.
- - replaces unarmored things with their armored versions.
- - Illegal Tech Ammo actually is fucking reasonable, now.
- - Expensive Illegal Tech Ammo Boxes are now constructible, with actually justifiable prices.
-
- WanderingFox95 updated:
-
- - There's finally a reason for the reagent dart gun to exist and be used!
-
- akada updated:
-
- - Changes the space adaptation sprite to something less intrusive and more subtle.
-
- necromanceranne updated:
-
- - Basic cybernetic organs: they're worse than organic! Basic stomachs, hearts, lungs and livers! For when you hate someone enough to not bother harvesting organs from a monkeyhuman!
- - Cybernetic organs have been adjusted into three tiers: 1 (basic), 2 (standard, better than organic) and 3 (absolutely better than organic but expensive to print)
- - Cybernetic organs that are emp'd instead suffer different effects based on the severity of the emp. The bigger the emp, the worse the effect is.
- - Rather than outright bricking, severely emp'd cyberorgans degrade over time very quickly, requiring replacement in the near future.
- - Fake blindfolds in the loadout. They don't obscure vision, for better or worse.
-
-
- 29 April 2021
- Putnam3145 updated:
-
- - Fixed a couple runtimes in activity (threat) tracking
-
- keronshb updated:
-
- - Removes the Reinforcement Chromosome from Genetics.
-
GoonStation 13 Development Team
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index 82e2f373c8..ba0af9c448 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -29606,3 +29606,56 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
Make sure to try and recover it.
- rscadd: Adds an extremely expensive survival pod to mining for people to work
towards. Get to work cracking rocks today.
+2021-07-02:
+ silicons:
+ - bugfix: spray bottles work again.
+2021-07-03:
+ DeltaFire15:
+ - bugfix: Turrets on nonlethal mode now once again shoot till the target is stamcrit
+ as opposed to unable to use items, resolving some issues.
+ Putnam3145:
+ - bugfix: A bunch of sleeping process() calls now either don't sleep or make sure
+ to call a proc with waitfor set to FALSE
+ WanderingFox95:
+ - bugfix: The axolotl ears in the .dmi file actually exist to the game now.
+2021-07-04:
+ cadyn:
+ - server: Updated server scripts for proper linux support
+2021-07-05:
+ Putnam3145:
+ - bugfix: Watchers no longer search 9 tiles away for stuff then throw the result
+ away if it's more than 1 tile away
+ - server: Auxmos pull now uses a tag instead of pulling straight from the main branch
+ WanderingFox95:
+ - bugfix: Moved a sprite one pixel to the left.
+ zeroisthebiggay:
+ - imageadd: tg based tool resprites
+ - bugfix: wirecutters have proper overlays
+2021-07-07:
+ DeltaFire15:
+ - bugfix: Golem / Plasmaman species color should work again.
+2021-07-09:
+ MrJWhit:
+ - bugfix: Made a light not exist on the same tile as a door on pubby.
+ - bugfix: Makes the RD APC automatically connect to the powernet with the correct
+ wire on pubby.
+ - rscadd: Added another wall for the AM engine so it doesn't space the airlock roundstart.
+2021-07-10:
+ WanderingFox95:
+ - imageadd: Returns the wheelchair sprites to having, you know, wheels?
+ - rscadd: 'A motorized wheelchair addsound: Chairwhoosh.'
+2021-07-11:
+ shellspeed1:
+ - balance: replaces the seed machine with a biogen in the survival pod.
+ - bugfix: corrected an issue regarding wrong pair of gloves in the pod for DYI wiring
+ .
+2021-07-12:
+ Putnam3145:
+ - refactor: causes_dirt_buildup_on_floor is now just a thing humans do instead of
+ a weird var only true for humans
+2021-07-13:
+ MrJWhit:
+ - rscadd: Adds a mirror above the sink in the captains bedroom in pubby
+2021-07-14:
+ Putnam3145:
+ - refactor: Acid is now a component
diff --git a/icons/mob/inhands/equipment/tools_lefthand.dmi b/icons/mob/inhands/equipment/tools_lefthand.dmi
index c25ea837da..27aaef50b1 100644
Binary files a/icons/mob/inhands/equipment/tools_lefthand.dmi and b/icons/mob/inhands/equipment/tools_lefthand.dmi differ
diff --git a/icons/mob/inhands/equipment/tools_righthand.dmi b/icons/mob/inhands/equipment/tools_righthand.dmi
index 65f1145278..54f8f6560d 100644
Binary files a/icons/mob/inhands/equipment/tools_righthand.dmi and b/icons/mob/inhands/equipment/tools_righthand.dmi differ
diff --git a/icons/obj/clothing/belt_overlays.dmi b/icons/obj/clothing/belt_overlays.dmi
index 5f31a65ffa..0799920a6c 100644
Binary files a/icons/obj/clothing/belt_overlays.dmi and b/icons/obj/clothing/belt_overlays.dmi differ
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index 34f9867ee9..b507b3bcdd 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ
diff --git a/icons/obj/nuke_tools.dmi b/icons/obj/nuke_tools.dmi
index 799c4baabb..7f5c730fe5 100644
Binary files a/icons/obj/nuke_tools.dmi and b/icons/obj/nuke_tools.dmi differ
diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi
index 8414c8b95c..a720aff62c 100644
Binary files a/icons/obj/tools.dmi and b/icons/obj/tools.dmi differ
diff --git a/icons/obj/vehicles.dmi b/icons/obj/vehicles.dmi
index d12851f572..14b19caef8 100644
Binary files a/icons/obj/vehicles.dmi and b/icons/obj/vehicles.dmi differ
diff --git a/libauxmos.so b/libauxmos.so
deleted file mode 100644
index d7566ab1e4..0000000000
Binary files a/libauxmos.so and /dev/null differ
diff --git a/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm b/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm
index ab39e6f4a7..edaaeb19b2 100644
--- a/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm
+++ b/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm
@@ -28,6 +28,7 @@
//Called when temperature is above a certain threshold, or if purity is too low.
/datum/chemical_reaction/proc/FermiExplode(datum/reagents/R0, var/atom/my_atom, volume, temp, pH, Exploding = FALSE)
+ set waitfor = FALSE
if (Exploding == TRUE)
return
diff --git a/modular_citadel/icons/mob/mam_ears.dmi b/modular_citadel/icons/mob/mam_ears.dmi
index 51541619d4..dd3ea5f82b 100644
Binary files a/modular_citadel/icons/mob/mam_ears.dmi and b/modular_citadel/icons/mob/mam_ears.dmi differ
diff --git a/sound/effects/chairwhoosh.ogg b/sound/effects/chairwhoosh.ogg
new file mode 100644
index 0000000000..907659f7cb
Binary files /dev/null and b/sound/effects/chairwhoosh.ogg differ
diff --git a/tgstation.dme b/tgstation.dme
index ed85c32cc4..a9b83f27b6 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -306,7 +306,6 @@
#include "code\controllers\configuration\entries\respawns.dm"
#include "code\controllers\configuration\entries\stamina_combat.dm"
#include "code\controllers\subsystem\achievements.dm"
-#include "code\controllers\subsystem\acid.dm"
#include "code\controllers\subsystem\activity.dm"
#include "code\controllers\subsystem\adjacent_air.dm"
#include "code\controllers\subsystem\air.dm"
@@ -459,6 +458,7 @@
#include "code\datums\brain_damage\special.dm"
#include "code\datums\brain_damage\split_personality.dm"
#include "code\datums\components\_component.dm"
+#include "code\datums\components\acid.dm"
#include "code\datums\components\activity.dm"
#include "code\datums\components\anti_magic.dm"
#include "code\datums\components\armor_plate.dm"
@@ -3630,6 +3630,7 @@
#include "code\modules\vehicles\wheelchair.dm"
#include "code\modules\vehicles\cars\car.dm"
#include "code\modules\vehicles\cars\clowncar.dm"
+#include "code\modules\vehicles\motorized_wheelchair.dm"
#include "code\modules\vending\_vending.dm"
#include "code\modules\vending\assist.dm"
#include "code\modules\vending\autodrobe.dm"
diff --git a/tools/build/binaries/README.md b/tools/build/binaries/README.md
new file mode 100644
index 0000000000..625f337d98
--- /dev/null
+++ b/tools/build/binaries/README.md
@@ -0,0 +1 @@
+This directory is used to store temporary files to create binaries on linux
\ No newline at end of file
diff --git a/tools/build/build b/tools/build/build
index 0e202e1bba..cd4d804e8f 100755
--- a/tools/build/build
+++ b/tools/build/build
@@ -1,4 +1,6 @@
#!/bin/sh
+
+#Build TGUI
set -e
cd "$(dirname "$0")"
exec ../bootstrap/node build.js "$@"
diff --git a/tools/build/build.sh b/tools/build/build.sh
new file mode 100755
index 0000000000..5d050764d1
--- /dev/null
+++ b/tools/build/build.sh
@@ -0,0 +1,75 @@
+#!/bin/sh
+
+#Detect OS and use corresponding package manager for dependencies. Currently only works for arch, debian/ubuntu, and RHEL/fedora/CentOS
+if [[ -f '/etc/arch-release' ]]; then
+ echo -ne '\n y' | sudo pacman --needed -Sy base-devel git curl nodejs unzip
+fi
+if [[ -f '/etc/debian version' ]]; then
+ sudo dpkg --add-architecture i386
+ sudo apt-get update
+ sudo apt-get install -y build-essential git curl lib32z1 pkg-config libssl-dev:i386 libssl-dev nodejs unzip g++-multilib libc6-i386 libstdc++6:i386
+fi
+if [[ -f '/etc/centos-release' ]] || [[ -f '/etc/fedora-release' ]]; then #DNF should work for both of these
+ sudo dnf --refresh install make automake gcc gcc-c++ kernel-devel git curl unzip glibc-devel.i686 openssl-devel.i686 libgcc.i686 libstdc++-devel.i686
+fi
+
+cd binaries
+
+#Install rust if not present
+if ! [ -x "$has_cargo" ]; then
+ echo "Installing rust..."
+ curl https://sh.rustup.rs -sSf | sh -s -- -y
+ . ~/.profile
+fi
+
+#Download/update rust-g repo
+if [ ! -d "rust-g" ]; then
+ echo "Cloning rust-g..."
+ git clone https://github.com/tgstation/rust-g
+ cd rust-g
+ ~/.cargo/bin/rustup target add i686-unknown-linux-gnu
+else
+ echo "Fetching rust-g..."
+ cd rust-g
+ git fetch
+ ~/.cargo/bin/rustup target add i686-unknown-linux-gnu
+fi
+
+#Compile and move rust-g binary to repo root
+echo "Deploying rust-g..."
+git checkout "$RUST_G_VERSION"
+env PKG_CONFIG_ALLOW_CROSS=1 ~/.cargo/bin/cargo build --release --target=i686-unknown-linux-gnu
+mv target/i686-unknown-linux-gnu/release/librust_g.so ../../../../librust_g.so
+cd ..
+
+#Download/update auxmos repo
+if [ ! -d "auxmos" ]; then
+ echo "Cloning auxmos..."
+ git clone https://github.com/Putnam3145/auxmos
+ cd auxmos
+ ~/.cargo/bin/rustup target add i686-unknown-linux-gnu
+else
+ echo "Fetching auxmos..."
+ cd auxmos
+ git fetch
+ ~/.cargo/bin/rustup target add i686-unknown-linux-gnu
+fi
+
+#Compile and move auxmos binary to repo root
+echo "Deploying auxmos..."
+git checkout "$AUXMOS_VERSION"
+env PKG_CONFIG_ALLOW_CROSS=1 ~/.cargo/bin/cargo rustc --release --target=i686-unknown-linux-gnu --features "all_reaction_hooks" -- -C target-cpu=native
+mv target/i686-unknown-linux-gnu/release/libauxmos.so ../../../../libauxmos.so
+cd ../..
+
+#Install BYOND
+cd ../..
+./tools/ci/install_byond.sh
+source $HOME/BYOND/byond/bin/byondsetup
+
+cd tools/build
+
+#Build TGUI
+set -e
+cd "$(dirname "$0")"
+exec ../bootstrap/node build.js "$@"
diff --git a/tools/tgs4_scripts/PreCompile.sh b/tools/tgs4_scripts/PreCompile.sh
index f21036ab19..7018b8f2e9 100755
--- a/tools/tgs4_scripts/PreCompile.sh
+++ b/tools/tgs4_scripts/PreCompile.sh
@@ -66,31 +66,27 @@ env PKG_CONFIG_ALLOW_CROSS=1 ~/.cargo/bin/cargo build --release --target=i686-un
mv target/i686-unknown-linux-gnu/release/librust_g.so "$1/librust_g.so"
cd ..
-# get dependencies for extools
-apt-get install -y cmake build-essential gcc-multilib g++-multilib cmake wget
+# Auxtools dependencies
+apt-get install build-essential g++-multilib libc6-i386 libstdc++6:i386
-# update extools
-if [ ! -d "extools" ]; then
- echo "Cloning extools..."
- git clone https://github.com/MCHSL/extools
- cd extools/byond-extools
+# Update auxmos
+if [ ! -d "auxmos" ]; then
+ echo "Cloning auxmos..."
+ git clone https://github.com/Putnam3145/auxmos
+ cd auxmos
+ ~/.cargo/bin/rustup target add i686-unknown-linux-gnu
else
- echo "Fetching extools..."
- cd extools/byond-extools
+ echo "Fetching auxmos..."
+ cd auxmos
git fetch
+ ~/.cargo/bin/rustup target add i686-unknown-linux-gnu
fi
-echo "Deploying extools..."
-git checkout "$EXTOOLS_VERSION"
-if [ -d "build" ]; then
- rm -R build
-fi
-mkdir build
-cd build
-cmake ..
-make
-mv libbyond-extools.so "$1/libbyond-extools.so"
-cd ../../..
+echo "Deploying auxmos..."
+git checkout "$AUXMOS_VERSION"
+env PKG_CONFIG_ALLOW_CROSS=1 ~/.cargo/bin/cargo rustc --release --target=i686-unknown-linux-gnu --features "all_reaction_hooks" -- -C target-cpu=native
+mv -f target/i686-unknown-linux-gnu/release/libauxmos.so "$1/libauxmos.so"
+cd ..
# install or update youtube-dl when not present, or if it is present with pip3,
# which we assume was used to install it