diff --git a/_maps/RandomRuins/SpaceRuins/spacehermit.dmm b/_maps/RandomRuins/SpaceRuins/spacehermit.dmm
index 8113c586ff..dd7e700146 100644
--- a/_maps/RandomRuins/SpaceRuins/spacehermit.dmm
+++ b/_maps/RandomRuins/SpaceRuins/spacehermit.dmm
@@ -145,9 +145,6 @@
"aE" = (
/turf/open/floor/plating/asteroid/airless,
/area/ruin/powered)
-"aF" = (
-/turf/open/floor/plating/asteroid,
-/area/ruin/powered)
"aG" = (
/obj/structure/sink/puddle,
/turf/open/floor/plating/asteroid,
@@ -241,7 +238,7 @@
/turf/closed/mineral/random/low_chance/earth_like,
/area/ruin/powered)
"bb" = (
-/turf/closed/mineral/random/earth_like,
+/turf/closed/mineral/random/no_caves/earth_like,
/area/ruin/powered)
"bc" = (
/obj/item/circuitboard/machine/circuit_imprinter,
@@ -1137,7 +1134,7 @@ ao
ao
ak
af
-aF
+am
bb
bb
bb
@@ -1189,7 +1186,7 @@ an
an
ae
ae
-aF
+am
bb
bb
bb
@@ -1223,8 +1220,8 @@ bb
bb
bb
ba
-aF
-aF
+am
+am
ba
ba
ba
@@ -1241,7 +1238,7 @@ ar
af
at
at
-aF
+am
bb
fp
bb
@@ -1275,10 +1272,10 @@ bb
bb
bb
ad
-aF
-aF
-aF
-aF
+am
+am
+am
+am
ba
aH
aJ
@@ -1286,13 +1283,13 @@ aL
bb
bb
aT
-aF
-aF
-aF
-aF
-aF
-aF
-aF
+am
+am
+am
+am
+am
+am
+am
aR
bb
bb
@@ -1328,23 +1325,23 @@ bb
bb
ad
au
-aF
+am
aB
-aF
-aF
-aF
-aF
-aF
+am
+am
+am
+am
+am
ba
bb
-aF
-aF
-aF
-aF
-aF
-aF
-aF
-aF
+am
+am
+am
+am
+am
+am
+am
+am
bg
bb
fp
@@ -1384,19 +1381,19 @@ bs
aC
bC
WH
-aF
-aF
-aF
+am
+am
+am
ba
bb
bb
-aF
-aF
-aF
-aF
-aF
-aF
-aF
+am
+am
+am
+am
+am
+am
+am
bb
bb
bb
@@ -1432,23 +1429,23 @@ bb
bb
ad
ax
-aF
+am
aD
-aF
-aF
-aF
-aF
+am
+am
+am
+am
bb
bb
bb
aU
bd
-aF
-aF
+am
+am
bl
bm
-aF
-aF
+am
+am
bb
bb
bb
@@ -1484,20 +1481,20 @@ bb
bb
ad
ay
-aF
-aF
-aF
+am
+am
+am
aG
-aF
-aF
+am
+am
bb
bb
ba
av
be
-aF
-aF
-aF
+am
+am
+am
bn
bo
bo
@@ -1535,24 +1532,24 @@ bb
bb
bb
ba
-aF
-aF
-aF
-aF
-aF
-aF
-aF
+am
+am
+am
+am
+am
+am
+am
bb
bb
bb
bc
bf
-aF
-aF
-aF
-aF
-aF
-aF
+am
+am
+am
+am
+am
+am
br
bb
bb
@@ -1590,22 +1587,22 @@ bb
bb
bb
bb
-aF
-aF
-aF
-aF
-aF
+am
+am
+am
+am
+am
bb
bb
-aF
-aF
-aF
-aF
-aF
-aF
-aF
-aF
-aF
+am
+am
+am
+am
+am
+am
+am
+am
+am
bb
bb
bb
@@ -1642,21 +1639,21 @@ bb
bb
bb
bb
-aF
-aF
-aF
-aF
-aF
+am
+am
+am
+am
+am
aN
-aF
-aF
-aF
-aF
+am
+am
+am
+am
aR
-aF
-aF
-aF
-aF
+am
+am
+am
+am
bb
bb
fp
@@ -1695,22 +1692,22 @@ bb
bb
bb
ba
-aF
-aF
-aF
+am
+am
+am
ba
ba
-aF
-aF
-aF
-aF
-aF
-aF
-aF
-aF
-aF
-aF
-aF
+am
+am
+am
+am
+am
+am
+am
+am
+am
+am
+am
ba
ba
ba
@@ -1752,16 +1749,16 @@ ba
aK
ba
ba
-aF
-aF
-aF
-aF
-aF
-aF
-aF
+am
+am
+am
+am
+am
+am
+am
bp
-aF
-aF
+am
+am
aR
ba
ba
@@ -1805,15 +1802,15 @@ ba
fp
ba
aP
-aF
-aF
-aF
-aF
-aF
-aF
-aF
-aF
-aF
+am
+am
+am
+am
+am
+am
+am
+am
+am
aR
ba
ba
@@ -1858,15 +1855,15 @@ ba
ba
aQ
aP
-aF
-aF
+am
+am
aR
-aF
-aF
-aF
-aF
+am
+am
+am
+am
bb
-aF
+am
ba
ba
aZ
@@ -1910,12 +1907,12 @@ ba
ba
ba
ba
-aF
-aF
-aF
-aF
+am
+am
+am
+am
aP
-aF
+am
bg
bb
bb
@@ -1962,12 +1959,12 @@ bb
bb
ba
ba
-aF
-aF
-aF
-aF
-aF
-aF
+am
+am
+am
+am
+am
+am
aS
bb
fp
@@ -2015,11 +2012,11 @@ bb
bb
ba
bg
-aF
-aF
-aF
-aF
-aF
+am
+am
+am
+am
+am
aS
bb
fp
@@ -2066,12 +2063,12 @@ bb
bb
fp
ba
-aF
-aF
+am
+am
bj
-aF
-aF
-aF
+am
+am
+am
aS
fp
bb
@@ -2120,9 +2117,9 @@ ba
ba
aS
bi
-aF
-aF
-aF
+am
+am
+am
aS
aS
bb
@@ -2171,10 +2168,10 @@ ba
aZ
ba
aS
-aF
-aF
-aF
-aF
+am
+am
+am
+am
aS
aS
ba
diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index 03b89159b3..b16002e35b 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -179,7 +179,7 @@
// #define SPEECH_FORCED 7
#define COMSIG_MOB_ANTAG_ON_GAIN "mob_antag_on_gain" //from base of /datum/antagonist/on_gain(): (antag_datum)
-#define COMSIG_MOB_SPELL_CAST_CHECK "mob_spell_cast_check" //called from base of /obj/effect/proc_holder/spell/cast_check(): (spell)
+#define COMSIG_MOB_SPELL_CAN_CAST "mob_spell_can_cast" //called from base of /obj/effect/proc_holder/spell/can_cast(): (spell)
// /mob/living signals
#define COMSIG_LIVING_REGENERATE_LIMBS "living_regenerate_limbs" //from base of /mob/living/regenerate_limbs(): (noheal, excluded_limbs)
diff --git a/code/__DEFINES/movespeed_modification.dm b/code/__DEFINES/movespeed_modification.dm
index 76c326cec0..bc1e6f7d5f 100644
--- a/code/__DEFINES/movespeed_modification.dm
+++ b/code/__DEFINES/movespeed_modification.dm
@@ -78,4 +78,6 @@
#define MOVESPEED_ID_COLD "COLD"
#define MOVESPEED_ID_HUNGRY "HUNGRY"
#define MOVESPEED_ID_DAMAGE_SLOWDOWN "DAMAGE"
-#define MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING "FLYING"
\ No newline at end of file
+#define MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING "FLYING"
+
+#define MOVESPEED_ID_CIRRHOSIS "CIRRHOSIS"
\ No newline at end of file
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
index 38e25b04c5..0c45a746d8 100644
--- a/code/__HELPERS/global_lists.dm
+++ b/code/__HELPERS/global_lists.dm
@@ -89,6 +89,14 @@
INVOKE_ASYNC(GLOBAL_PROC, /proc/init_ref_coin_values) //so the current procedure doesn't sleep because of UNTIL()
+ for(var/path in subtypesof(/area/holodeck))
+ var/area/holodeck/A = path
+ var/list/compatibles = initial(A.compatible_holodeck_comps)
+ if(!compatibles || initial(A.abstract_type) == path)
+ continue
+ for(var/comp in compatibles)
+ LAZYADD(GLOB.holodeck_areas_prototypes[comp], A)
+
//creates every subtype of prototype (excluding prototype) and adds it to list L.
//if no list/L is provided, one is created.
/proc/init_subtypes(prototype, list/L)
diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm
index e416396991..7cbfbd040a 100644
--- a/code/__HELPERS/roundend.dm
+++ b/code/__HELPERS/roundend.dm
@@ -513,7 +513,7 @@
if(owner && GLOB.common_report && SSticker.current_state == GAME_STATE_FINISHED)
SSticker.show_roundend_report(owner.client, FALSE)
-/datum/action/report/IsAvailable()
+/datum/action/report/IsAvailable(silent = FALSE)
return 1
/datum/action/report/Topic(href,href_list)
diff --git a/code/_globalvars/lists/mapping.dm b/code/_globalvars/lists/mapping.dm
index fb8863ebe7..bcf35859c3 100644
--- a/code/_globalvars/lists/mapping.dm
+++ b/code/_globalvars/lists/mapping.dm
@@ -50,3 +50,5 @@ GLOBAL_LIST_EMPTY_TYPED(areas_by_type, /area)
GLOBAL_LIST_EMPTY(all_abstract_markers)
GLOBAL_LIST_EMPTY(stationroom_landmarks) //List of all spawns for stationrooms
+
+GLOBAL_LIST_EMPTY(holodeck_areas_prototypes) //List of holodeck area prototypes per holodeck computer type
\ No newline at end of file
diff --git a/code/controllers/subsystem/persistence.dm b/code/controllers/subsystem/persistence.dm
index 5b350a7917..0a60c6e5d3 100644
--- a/code/controllers/subsystem/persistence.dm
+++ b/code/controllers/subsystem/persistence.dm
@@ -192,7 +192,8 @@ SUBSYSTEM_DEF(persistence)
if(!json)
return
saved_storytellers = json["data"]
- average_dynamic_threat = saved_storytellers[4]
+ if(saved_storytellers.len > 3)
+ average_dynamic_threat = saved_storytellers[4]
saved_storytellers.len = 3
/datum/controller/subsystem/persistence/proc/LoadRecentMaps()
diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm
index 7d72951278..a202afd905 100644
--- a/code/controllers/subsystem/vote.dm
+++ b/code/controllers/subsystem/vote.dm
@@ -763,7 +763,7 @@ SUBSYSTEM_DEF(vote)
remove_from_client()
Remove(owner)
-/datum/action/vote/IsAvailable()
+/datum/action/vote/IsAvailable(silent = FALSE)
return 1
/datum/action/vote/proc/remove_from_client()
diff --git a/code/datums/action.dm b/code/datums/action.dm
index 22cd6da169..e94e6a182d 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -97,7 +97,7 @@
/datum/action/proc/Process()
return
-/datum/action/proc/IsAvailable()
+/datum/action/proc/IsAvailable(silent = FALSE)
if(!owner)
return FALSE
var/mob/living/L = owner
@@ -149,7 +149,7 @@
button.add_overlay(M)
button.appearance_cache = target.appearance
- if(!IsAvailable())
+ if(!IsAvailable(TRUE))
button.color = transparent_when_unavailable ? rgb(128,0,0,128) : rgb(128,0,0)
else
button.color = rgb(255,255,255,255)
@@ -307,7 +307,7 @@
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "vortex_recall"
-/datum/action/item_action/vortex_recall/IsAvailable()
+/datum/action/item_action/vortex_recall/IsAvailable(silent = FALSE)
if(istype(target, /obj/item/hierophant_club))
var/obj/item/hierophant_club/H = target
if(H.teleporting)
@@ -319,7 +319,7 @@
background_icon_state = "bg_clock"
buttontooltipstyle = "clockcult"
-/datum/action/item_action/clock/IsAvailable()
+/datum/action/item_action/clock/IsAvailable(silent = FALSE)
if(!is_servant_of_ratvar(owner))
return 0
return ..()
@@ -328,7 +328,7 @@
name = "Create Judicial Marker"
desc = "Allows you to create a stunning Judicial Marker at any location in view. Click again to disable."
-/datum/action/item_action/clock/toggle_visor/IsAvailable()
+/datum/action/item_action/clock/toggle_visor/IsAvailable(silent = FALSE)
if(!is_servant_of_ratvar(owner))
return 0
if(istype(target, /obj/item/clothing/glasses/judicial_visor))
@@ -407,7 +407,7 @@
/datum/action/item_action/jetpack_stabilization
name = "Toggle Jetpack Stabilization"
-/datum/action/item_action/jetpack_stabilization/IsAvailable()
+/datum/action/item_action/jetpack_stabilization/IsAvailable(silent = FALSE)
var/obj/item/tank/jetpack/J = target
if(!istype(J) || !J.on)
return 0
@@ -464,7 +464,7 @@
/datum/action/item_action/organ_action
check_flags = AB_CHECK_CONSCIOUS
-/datum/action/item_action/organ_action/IsAvailable()
+/datum/action/item_action/organ_action/IsAvailable(silent = FALSE)
var/obj/item/organ/I = target
if(!I.owner)
return 0
@@ -633,32 +633,32 @@
return FALSE
if(target)
var/obj/effect/proc_holder/S = target
- S.Click()
+ S.Trigger(usr)
return TRUE
-/datum/action/spell_action/IsAvailable()
+/datum/action/spell_action/IsAvailable(silent = FALSE)
if(!target)
return FALSE
return TRUE
/datum/action/spell_action/spell
-/datum/action/spell_action/spell/IsAvailable()
+/datum/action/spell_action/spell/IsAvailable(silent = FALSE)
if(!target)
return FALSE
var/obj/effect/proc_holder/spell/S = target
if(owner)
- return S.can_cast(owner, FALSE, TRUE)
+ return S.can_cast(owner, FALSE, silent)
return FALSE
/datum/action/spell_action/alien
-/datum/action/spell_action/alien/IsAvailable()
+/datum/action/spell_action/alien/IsAvailable(silent = FALSE)
if(!target)
return FALSE
var/obj/effect/proc_holder/alien/ab = target
if(owner)
- return ab.cost_check(ab.check_turf,owner,1)
+ return ab.cost_check(ab.check_turf,owner,silent)
return FALSE
@@ -700,7 +700,7 @@
button.maptext_width = 24
button.maptext_height = 12
-/datum/action/cooldown/IsAvailable()
+/datum/action/cooldown/IsAvailable(silent = FALSE)
return next_use_time <= world.time
/datum/action/cooldown/proc/StartCooldown()
diff --git a/code/datums/dash_weapon.dm b/code/datums/dash_weapon.dm
index 8eda936bb7..c31139dcd7 100644
--- a/code/datums/dash_weapon.dm
+++ b/code/datums/dash_weapon.dm
@@ -19,7 +19,7 @@
dashing_item = dasher
holder = user
-/datum/action/innate/dash/IsAvailable()
+/datum/action/innate/dash/IsAvailable(silent = FALSE)
if(current_charges > 0)
return TRUE
else
diff --git a/code/datums/elements/spellcasting.dm b/code/datums/elements/spellcasting.dm
index a917108bf1..69d628d9d2 100644
--- a/code/datums/elements/spellcasting.dm
+++ b/code/datums/elements/spellcasting.dm
@@ -12,7 +12,7 @@
RegisterSignal(target, COMSIG_ITEM_EQUIPPED, .proc/on_equip)
RegisterSignal(target, COMSIG_ITEM_DROPPED, .proc/on_drop)
else if(ismob(target))
- RegisterSignal(target, COMSIG_MOB_SPELL_CAST_CHECK, .proc/on_cast)
+ RegisterSignal(target, COMSIG_MOB_SPELL_CAN_CAST, .proc/on_cast)
stacked_spellcasting_by_user[target]++
else
return ELEMENT_INCOMPATIBLE
@@ -21,24 +21,24 @@
/datum/element/spellcasting/Detach(datum/target)
. = ..()
- UnregisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED, COMSIG_MOB_SPELL_CAST_CHECK))
+ UnregisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED, COMSIG_MOB_SPELL_CAN_CAST))
if(users_by_item[target])
var/mob/user = users_by_item[target]
stacked_spellcasting_by_user[user]--
if(!stacked_spellcasting_by_user[user])
stacked_spellcasting_by_user -= user
- UnregisterSignal(user, COMSIG_MOB_SPELL_CAST_CHECK)
+ UnregisterSignal(user, COMSIG_MOB_SPELL_CAN_CAST)
else if(ismob(target))
stacked_spellcasting_by_user[target]--
if(!stacked_spellcasting_by_user[target])
stacked_spellcasting_by_user -= target
/datum/element/spellcasting/proc/on_equip(datum/source, mob/equipper, slot)
- if(!(slot in cast_slots))
+ if(!(slot & cast_slots))
return
users_by_item[source] = equipper
if(!stacked_spellcasting_by_user[equipper])
- RegisterSignal(equipper, COMSIG_MOB_SPELL_CAST_CHECK, .proc/on_cast)
+ RegisterSignal(equipper, COMSIG_MOB_SPELL_CAN_CAST, .proc/on_cast)
stacked_spellcasting_by_user[equipper]++
/datum/element/spellcasting/proc/on_drop(datum/source, mob/user)
@@ -48,7 +48,7 @@
stacked_spellcasting_by_user[user]--
if(!stacked_spellcasting_by_user[user])
stacked_spellcasting_by_user -= user
- UnregisterSignal(user, COMSIG_MOB_SPELL_CAST_CHECK)
+ UnregisterSignal(user, COMSIG_MOB_SPELL_CAN_CAST)
/datum/element/spellcasting/proc/on_cast(mob/caster, obj/effect/proc_holder/spell)
return cast_flags
diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm
index 6b0981665d..c46a03a986 100644
--- a/code/datums/helper_datums/teleport.dm
+++ b/code/datums/helper_datums/teleport.dm
@@ -128,7 +128,7 @@
// Can most things breathe?
if(trace_gases)
continue
- if(A_gases[/datum/gas/oxygen] >= 16)
+ if(A_gases[/datum/gas/oxygen] <= 16)
continue
if(A_gases[/datum/gas/plasma])
continue
diff --git a/code/datums/mutations/combined.dm b/code/datums/mutations/combined.dm
index d3cc83f9c0..465706c897 100644
--- a/code/datums/mutations/combined.dm
+++ b/code/datums/mutations/combined.dm
@@ -26,3 +26,7 @@
/datum/generecipe/tonguechem
required = "/datum/mutation/human/tongue_spike; /datum/mutation/human/stimmed"
result = TONGUESPIKECHEM
+
+/datum/generecipe/hulk
+ required = "/datum/mutation/human/strong; /datum/mutation/human/radioactive"
+ result = HULK
diff --git a/code/game/area/areas/holodeck.dm b/code/game/area/areas/holodeck.dm
index d32091f98b..75ed2b656c 100644
--- a/code/game/area/areas/holodeck.dm
+++ b/code/game/area/areas/holodeck.dm
@@ -6,6 +6,8 @@
hidden = TRUE
var/obj/machinery/computer/holodeck/linked
+ var/list/compatible_holodeck_comps
+ var/abstract_type = /area/holodeck
var/restricted = 0 // if true, program goes on emag list
/*
@@ -53,6 +55,8 @@
*/
/area/holodeck/rec_center
name = "\improper Recreational Holodeck"
+ compatible_holodeck_comps = list(/obj/machinery/computer/holodeck)
+ abstract_type = /area/holodeck/rec_center
/area/holodeck/rec_center/offline
name = "Holodeck - Offline"
diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm
index b869235c69..d548f373db 100644
--- a/code/game/gamemodes/dynamic/dynamic.dm
+++ b/code/game/gamemodes/dynamic/dynamic.dm
@@ -205,7 +205,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
if(threatadd > 0)
create_threat(threatadd)
else
- spend_threat(-threatadd)
+ remove_threat(threatadd)
else if (href_list["injectlate"])
latejoin_injection_cooldown = 0
forced_injection = TRUE
@@ -247,6 +247,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
. += "Peaceful Waypoint
"
. += "Your station orbits deep within controlled, core-sector systems and serves as a waypoint for routine traffic through Nanotrasen's trade empire. Due to the combination of high security, interstellar traffic, and low strategic value, it makes any direct threat of violence unlikely. Your primary enemies will be incompetence and bored crewmen: try to organize team-building events to keep staffers interested and productive. However, even deep in our territory there may be subversive elements, especially for such a high-value target as your station. Keep an eye out, but don't expect much trouble."
set_security_level(SEC_LEVEL_GREEN)
+ station_goals.len = 0
for(var/T in subtypesof(/datum/station_goal))
var/datum/station_goal/G = new T
if(!(G in station_goals))
@@ -257,6 +258,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
. += "Core Territory
"
. += "Your station orbits within reliably mundane, secure space. Although Nanotrasen has a firm grip on security in your region, the valuable resources and strategic position aboard your station make it a potential target for infiltrations. Monitor crew for non-loyal behavior, but expect a relatively tame shift free of large-scale destruction. We expect great things from your station."
set_security_level(SEC_LEVEL_GREEN)
+ station_goals.len = 0
for(var/T in subtypesof(/datum/station_goal))
var/datum/station_goal/G = new T
if(!(G in station_goals))
@@ -496,7 +498,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
starting_rule = pickweight(drafted_rules)
// Check if the ruleset is highlander and if a highlander ruleset has been executed
else if(starting_rule.flags & HIGHLANDER_RULESET) // Should already be filtered out, but making sure. Check filtering at end of proc if reported.
- if(threat_level > GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking)
+ if(threat_level <= GLOB.dynamic_stacking_limit && GLOB.dynamic_no_stacking)
if(highlander_executed)
drafted_rules -= starting_rule
if(drafted_rules.len <= 0)
@@ -723,7 +725,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic)
threat = storyteller.calculate_threat() + added_threat
if(threat_average_weight)
var/cur_sample_weight = world.time - last_threat_sample_time
- threat_average = ((threat_average * threat_average_weight) + threat) / (threat_average_weight + cur_sample_weight)
+ threat_average = ((threat_average * threat_average_weight) + (threat * cur_sample_weight)) / (threat_average_weight + cur_sample_weight)
threat_average_weight += cur_sample_weight
last_threat_sample_time = world.time
else
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm
index cec6f31e99..da33da5f43 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm
@@ -222,6 +222,26 @@
message_admins("[M.name] was made into a bloodsucker by dynamic.")
return TRUE
+//////////////////////////////////////////////
+// //
+// CHANGELINGS //
+// //
+//////////////////////////////////////////////
+
+/datum/dynamic_ruleset/latejoin/changeling
+ name = "Changeling Infiltrator"
+ config_tag = "latejoin_changeling"
+ antag_flag = ROLE_CHANGELING
+ antag_datum = /datum/antagonist/changeling
+ restricted_roles = list("AI", "Cyborg")
+ protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
+ required_candidates = 1
+ weight = 3
+ cost = 15
+ requirements = list(101,101,101,101,101,101,101,101,101,101)
+ property_weights = list("trust" = -2, "valid" = 2)
+ high_population_requirement = 101
+
//////////////////////////////////////////////
// //
// COLLECTOR //
diff --git a/code/game/machinery/launch_pad.dm b/code/game/machinery/launch_pad.dm
index 0f5e51215d..d01f7e3e40 100644
--- a/code/game/machinery/launch_pad.dm
+++ b/code/game/machinery/launch_pad.dm
@@ -57,7 +57,7 @@
var/turf/target = locate(target_x, target_y, z)
ghost.forceMove(target)
-/obj/machinery/launchpad/proc/isAvailable()
+/obj/machinery/launchpad/proc/isAvailable(silent = FALSE)
if(stat & NOPOWER)
return FALSE
if(panel_open)
@@ -198,7 +198,7 @@
QDEL_NULL(briefcase)
return ..()
-/obj/machinery/launchpad/briefcase/isAvailable()
+/obj/machinery/launchpad/briefcase/isAvailable(silent = FALSE)
if(closed)
return FALSE
return ..()
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 634ca4d637..b6cab8b438 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -275,10 +275,8 @@ SLIME SCANNER
//LIVER
else if(istype(O, /obj/item/organ/liver))
var/obj/item/organ/liver/L = O
- if(H.undergoing_liver_failure() && H.stat != DEAD) //might be depreciated
+ if(L.organ_flags & ORGAN_FAILING && H.stat != DEAD) //might be depreciated
temp_message += "Subject is suffering from liver failure: Apply Corazone and begin a liver transplant immediately!"
- if(L.swelling > 20)
- temp_message += " Subject is suffering from an enlarged liver." //i.e. shrink their liver or give them a transplant.
//HEART
else if(ishuman(M) && (istype(O, /obj/item/organ/heart)))
diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm
index b137c5c0f3..08ce73109c 100644
--- a/code/game/objects/items/robot/robot_upgrades.dm
+++ b/code/game/objects/items/robot/robot_upgrades.dm
@@ -663,21 +663,19 @@
var/maxReduction = 1
-/obj/effect/proc_holder/silicon/cyborg/vtecControl/Click(mob/living/silicon/robot/user)
- var/mob/living/silicon/robot/self = usr
-
+/obj/effect/proc_holder/silicon/cyborg/vtecControl/Trigger(mob/living/silicon/robot/user)
currentState = (currentState + 1) % 3
- if(istype(self))
+ if(istype(user))
switch(currentState)
if (0)
- self.speed = initial(self.speed)
+ user.speed = initial(user.speed)
if (1)
- self.speed = initial(self.speed) - maxReduction * 0.5
+ user.speed = initial(user.speed) - maxReduction * 0.5
if (2)
- self.speed = initial(self.speed) - maxReduction * 1
+ user.speed = initial(user.speed) - maxReduction * 1
action.button_icon_state = "Chevron_State_[currentState]"
action.UpdateButtonIcon()
- return
+ return TRUE
diff --git a/code/game/turfs/simulated/minerals.dm b/code/game/turfs/simulated/minerals.dm
index c61ac8972c..7e1b39cb39 100644
--- a/code/game/turfs/simulated/minerals.dm
+++ b/code/game/turfs/simulated/minerals.dm
@@ -173,6 +173,16 @@
/turf/closed/mineral/silver = 12, /turf/closed/mineral/plasma = 20, /turf/closed/mineral/iron = 40, /turf/closed/mineral/titanium = 11,
/turf/closed/mineral/gibtonite = 4, /turf/closed/mineral/bscrystal = 1)
+/turf/closed/mineral/random/no_caves/earth_like
+ icon_state = "rock_oxy"
+ turf_type = /turf/open/floor/plating/asteroid
+ baseturfs = /turf/open/floor/plating/asteroid
+ mineralSpawnChanceList = list(/turf/closed/mineral/uranium/earth_like = 5, /turf/closed/mineral/diamond/earth_like = 1, /turf/closed/mineral/gold/earth_like = 10,
+ /turf/closed/mineral/silver/earth_like = 12, /turf/closed/mineral/plasma/earth_like = 20, /turf/closed/mineral/iron/earth_like = 40,
+ /turf/closed/mineral/titanium/earth_like = 11, /turf/closed/mineral/gibtonite/earth_like = 4, /turf/closed/mineral/bscrystal/earth_like = 1)
+ initial_gas_mix = OPENTURF_DEFAULT_ATMOS
+ defer_change = TRUE
+
/turf/closed/mineral/random/high_chance
icon_state = "rock_highchance"
mineralChance = 25
@@ -194,6 +204,10 @@
icon_state = "rock_highchance_oxy"
turf_type = /turf/open/floor/plating/asteroid
baseturfs = /turf/open/floor/plating/asteroid
+ mineralSpawnChanceList = list(
+ /turf/closed/mineral/uranium/earth_like = 35, /turf/closed/mineral/diamond/earth_like = 30, /turf/closed/mineral/gold/earth_like = 45,
+ /turf/closed/mineral/titanium/earth_like = 45, /turf/closed/mineral/silver/earth_like = 50, /turf/closed/mineral/plasma/earth_like = 50,
+ /turf/closed/mineral/bscrystal/earth_like = 20)
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
defer_change = TRUE
@@ -211,6 +225,10 @@
turf_type = /turf/open/floor/plating/asteroid
baseturfs = /turf/open/floor/plating/asteroid
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
+ mineralSpawnChanceList = list(
+ /turf/closed/mineral/uranium/earth_like = 2, /turf/closed/mineral/diamond/earth_like = 1, /turf/closed/mineral/gold/earth_like = 4,
+ /turf/closed/mineral/titanium/earth_like = 4, /turf/closed/mineral/silver/earth_like = 6, /turf/closed/mineral/plasma/earth_like = 15,
+ /turf/closed/mineral/iron/earth_like = 40, /turf/closed/mineral/gibtonite/earth_like = 2, /turf/closed/mineral/bscrystal/earth_like = 1)
defer_change = TRUE
/turf/closed/mineral/random/volcanic
@@ -246,13 +264,6 @@
/turf/closed/mineral/silver/volcanic = 20, /turf/closed/mineral/plasma/volcanic = 30, /turf/closed/mineral/bscrystal/volcanic = 1, /turf/closed/mineral/gibtonite/volcanic = 2,
/turf/closed/mineral/iron/volcanic = 95)
-/turf/closed/mineral/random/earth_like
- icon_state = "rock_oxy"
- turf_type = /turf/open/floor/plating/asteroid
- baseturfs = /turf/open/floor/plating/asteroid
- initial_gas_mix = OPENTURF_DEFAULT_ATMOS
- defer_change = TRUE
-
/turf/closed/mineral/iron
mineralType = /obj/item/stack/ore/iron
@@ -624,3 +635,10 @@
baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
defer_change = 1
+
+/turf/closed/mineral/gibtonite/earth_like
+ icon_state = "rock_oxy"
+ turf_type = /turf/open/floor/plating/asteroid
+ baseturfs = /turf/open/floor/plating/asteroid
+ initial_gas_mix = OPENTURF_DEFAULT_ATMOS
+ defer_change = TRUE
diff --git a/code/modules/antagonists/bloodsucker/powers/haste.dm b/code/modules/antagonists/bloodsucker/powers/haste.dm
index 143950b32f..05e2cd0330 100644
--- a/code/modules/antagonists/bloodsucker/powers/haste.dm
+++ b/code/modules/antagonists/bloodsucker/powers/haste.dm
@@ -8,7 +8,7 @@
desc = "Dash somewhere with supernatural speed. Those nearby may be knocked away, stunned, or left empty-handed."
button_icon_state = "power_speed"
bloodcost = 6
- cooldown = 50
+ cooldown = 120
target_range = 15
power_activates_immediately = TRUE
message_Trigger = ""//"Whom will you subvert to your will?"
diff --git a/code/modules/antagonists/changeling/changeling_power.dm b/code/modules/antagonists/changeling/changeling_power.dm
index 574edf225a..aa45c56892 100644
--- a/code/modules/antagonists/changeling/changeling_power.dm
+++ b/code/modules/antagonists/changeling/changeling_power.dm
@@ -28,8 +28,7 @@
action.Remove(user)
return
-/obj/effect/proc_holder/changeling/Click()
- var/mob/user = usr
+/obj/effect/proc_holder/changeling/Trigger(mob/user)
if(!user || !user.mind || !user.mind.has_antag_datum(/datum/antagonist/changeling))
return
try_to_sting(user)
diff --git a/code/modules/antagonists/changeling/powers/tiny_prick.dm b/code/modules/antagonists/changeling/powers/tiny_prick.dm
index 3e19ce74fe..a8fe56aae7 100644
--- a/code/modules/antagonists/changeling/powers/tiny_prick.dm
+++ b/code/modules/antagonists/changeling/powers/tiny_prick.dm
@@ -3,8 +3,7 @@
desc = "Stabby stabby."
var/sting_icon = null
-/obj/effect/proc_holder/changeling/sting/Click()
- var/mob/user = usr
+/obj/effect/proc_holder/changeling/sting/Trigger(mob/user)
if(!user || !user.mind)
return
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
@@ -74,8 +73,7 @@
action_icon_state = "ling_sting_transform"
action_background_icon_state = "bg_ling"
-/obj/effect/proc_holder/changeling/sting/transformation/Click()
- var/mob/user = usr
+/obj/effect/proc_holder/changeling/sting/transformation/Trigger(mob/user)
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
if(changeling.chosen_sting)
unset_sting(user)
diff --git a/code/modules/antagonists/clockcult/clock_helpers/hierophant_network.dm b/code/modules/antagonists/clockcult/clock_helpers/hierophant_network.dm
index 37f6f0b2d7..0c01dc0963 100644
--- a/code/modules/antagonists/clockcult/clock_helpers/hierophant_network.dm
+++ b/code/modules/antagonists/clockcult/clock_helpers/hierophant_network.dm
@@ -35,7 +35,7 @@
var/span_for_name = "heavy_brass"
var/span_for_message = "brass"
-/datum/action/innate/hierophant/IsAvailable()
+/datum/action/innate/hierophant/IsAvailable(silent = FALSE)
if(!is_servant_of_ratvar(owner))
return FALSE
return ..()
diff --git a/code/modules/antagonists/clockcult/clock_items/clock_weapons/_call_weapon.dm b/code/modules/antagonists/clockcult/clock_items/clock_weapons/_call_weapon.dm
index a87767c05e..40aca961fc 100644
--- a/code/modules/antagonists/clockcult/clock_items/clock_weapons/_call_weapon.dm
+++ b/code/modules/antagonists/clockcult/clock_items/clock_weapons/_call_weapon.dm
@@ -12,7 +12,7 @@
var/obj/item/clockwork/weapon/weapon_type //The type of weapon to create
var/obj/item/clockwork/weapon/weapon
-/datum/action/innate/call_weapon/IsAvailable()
+/datum/action/innate/call_weapon/IsAvailable(silent = FALSE)
if(!is_servant_of_ratvar(owner))
qdel(src)
return
diff --git a/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm b/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm
index e4722dbcb0..faa5e025ca 100644
--- a/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm
+++ b/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm
@@ -232,7 +232,7 @@
background_icon_state = "bg_clock"
buttontooltipstyle = "clockcult"
-/datum/action/innate/eminence/IsAvailable()
+/datum/action/innate/eminence/IsAvailable(silent = FALSE)
if(!iseminence(owner))
qdel(src)
return
@@ -283,7 +283,7 @@
desc = "Initiates a mass recall, warping all servants to the Ark after a short delay. This can only be used once."
button_icon_state = "Spatial Gateway"
-/datum/action/innate/eminence/mass_recall/IsAvailable()
+/datum/action/innate/eminence/mass_recall/IsAvailable(silent = FALSE)
. = ..()
if(.)
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar
diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm
index d6296aeaa0..130fc24583 100644
--- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm
+++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm
@@ -153,7 +153,7 @@
/obj/item/clothing/head/helmet/space,
/obj/item/clothing/shoes/magboots)) //replace this only if ratvar is up
-/datum/action/innate/clockwork_armaments/IsAvailable()
+/datum/action/innate/clockwork_armaments/IsAvailable(silent = FALSE)
if(!is_servant_of_ratvar(owner))
qdel(src)
return
diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm
index bea86d8bb4..d64e99d206 100644
--- a/code/modules/antagonists/cult/blood_magic.dm
+++ b/code/modules/antagonists/cult/blood_magic.dm
@@ -17,7 +17,7 @@
qdel(X)
..()
-/datum/action/innate/cult/blood_magic/IsAvailable()
+/datum/action/innate/cult/blood_magic/IsAvailable(silent = FALSE)
if(!iscultist(owner))
return FALSE
return ..()
@@ -118,7 +118,7 @@
hand_magic = null
..()
-/datum/action/innate/cult/blood_spell/IsAvailable()
+/datum/action/innate/cult/blood_spell/IsAvailable(silent = FALSE)
if(!iscultist(owner) || owner.incapacitated() || !charges)
return FALSE
return ..()
diff --git a/code/modules/antagonists/cult/cult_comms.dm b/code/modules/antagonists/cult/cult_comms.dm
index 8021443217..77893225fa 100644
--- a/code/modules/antagonists/cult/cult_comms.dm
+++ b/code/modules/antagonists/cult/cult_comms.dm
@@ -6,7 +6,7 @@
buttontooltipstyle = "cult"
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_CONSCIOUS
-/datum/action/innate/cult/IsAvailable()
+/datum/action/innate/cult/IsAvailable(silent = FALSE)
if(!iscultist(owner))
return FALSE
return ..()
@@ -51,7 +51,7 @@
name = "Spiritual Communion"
desc = "Conveys a message from the spirit realm that all cultists can hear."
-/datum/action/innate/cult/comm/spirit/IsAvailable()
+/datum/action/innate/cult/comm/spirit/IsAvailable(silent = FALSE)
if(iscultist(owner.mind.current))
return TRUE
@@ -72,7 +72,7 @@
name = "Assert Leadership"
button_icon_state = "cultvote"
-/datum/action/innate/cult/mastervote/IsAvailable()
+/datum/action/innate/cult/mastervote/IsAvailable(silent = FALSE)
var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
if(!C?.cult_team || C.cult_team.cult_vote_called || !ishuman(owner))
return FALSE
@@ -140,7 +140,7 @@
to_chat(B.current,"[Nominee] has won the cult's support and is now their master. Follow [Nominee.p_their()] orders to the best of your ability!")
return TRUE
-/datum/action/innate/cult/master/IsAvailable()
+/datum/action/innate/cult/master/IsAvailable(silent = FALSE)
if(!owner.mind || !owner.mind.has_antag_datum(/datum/antagonist/cult/master) || GLOB.cult_narsie)
return 0
return ..()
@@ -226,9 +226,9 @@
CM.attached_action = src
..()
-/datum/action/innate/cult/master/cultmark/IsAvailable()
+/datum/action/innate/cult/master/cultmark/IsAvailable(silent = FALSE)
if(cooldown > world.time)
- if(!CM.active)
+ if(!CM.active && !silent)
to_chat(owner, "You need to wait [DisplayTimeText(cooldown - world.time)] before you can mark another target!")
return FALSE
return ..()
@@ -308,7 +308,7 @@
name = "Mark a Blood Target for the Cult"
desc = "Marks a target for the entire cult to track."
-/datum/action/innate/cult/master/cultmark/ghost/IsAvailable()
+/datum/action/innate/cult/master/cultmark/ghost/IsAvailable(silent = FALSE)
if(istype(owner, /mob/dead/observer) && iscultist(owner.mind.current))
return TRUE
else
@@ -322,7 +322,7 @@
var/cooldown = 0
var/base_cooldown = 600
-/datum/action/innate/cult/ghostmark/IsAvailable()
+/datum/action/innate/cult/ghostmark/IsAvailable(silent = FALSE)
if(istype(owner, /mob/dead/observer) && iscultist(owner.mind.current))
return TRUE
else
@@ -401,11 +401,11 @@
PM.attached_action = src
..()
-/datum/action/innate/cult/master/pulse/IsAvailable()
+/datum/action/innate/cult/master/pulse/IsAvailable(silent = FALSE)
if(!owner.mind || !owner.mind.has_antag_datum(/datum/antagonist/cult/master))
return FALSE
if(cooldown > world.time)
- if(!PM.active)
+ if(!PM.active && !silent)
to_chat(owner, "You need to wait [DisplayTimeText(cooldown - world.time)] before you can pulse again!")
return FALSE
return ..()
diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm
index 757aeb8695..ea6bfa9b92 100644
--- a/code/modules/antagonists/cult/cult_items.dm
+++ b/code/modules/antagonists/cult/cult_items.dm
@@ -222,7 +222,7 @@
phasein = /obj/effect/temp_visual/dir_setting/cult/phase
phaseout = /obj/effect/temp_visual/dir_setting/cult/phase/out
-/datum/action/innate/dash/cult/IsAvailable()
+/datum/action/innate/dash/cult/IsAvailable(silent = FALSE)
if(iscultist(holder) && current_charges)
return TRUE
else
@@ -242,7 +242,7 @@
sword = bastard
holder = user
-/datum/action/innate/cult/spin2win/IsAvailable()
+/datum/action/innate/cult/spin2win/IsAvailable(silent = FALSE)
if(iscultist(holder) && cooldown <= world.time)
return TRUE
else
diff --git a/code/modules/antagonists/cult/rune_spawn_action.dm b/code/modules/antagonists/cult/rune_spawn_action.dm
index 60a8527860..b164246060 100644
--- a/code/modules/antagonists/cult/rune_spawn_action.dm
+++ b/code/modules/antagonists/cult/rune_spawn_action.dm
@@ -14,7 +14,7 @@
var/obj/effect/temp_visual/cult/rune_spawn/rune_center_type
var/rune_color
-/datum/action/innate/cult/create_rune/IsAvailable()
+/datum/action/innate/cult/create_rune/IsAvailable(silent = FALSE)
if(!rune_type || cooldown > world.time)
return FALSE
return ..()
diff --git a/code/modules/antagonists/swarmer/swarmer.dm b/code/modules/antagonists/swarmer/swarmer.dm
index 724c4e6f76..c1f493ac52 100644
--- a/code/modules/antagonists/swarmer/swarmer.dm
+++ b/code/modules/antagonists/swarmer/swarmer.dm
@@ -179,8 +179,8 @@
/obj/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
if(resistance_flags & INDESTRUCTIBLE)
return FALSE
- for(var/mob/living/L in contents)
- if(!issilicon(L) && !isbrain(L))
+ for(var/mob/living/L in GetAllContents())
+ if(!ispAI(L) && !isbrain(L))
to_chat(S, "An organism has been detected inside this object. Aborting.")
return FALSE
return ..()
@@ -416,6 +416,57 @@
to_chat(S, "Destroying this object would cause a catastrophic chain reaction. Aborting.")
return FALSE
+/obj/machinery/ore_silo/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
+ to_chat(S, "Destroying this object, however tempting it's, will disrupt the research development that may serve for our masters in the future. Aborting.")
+ return FALSE
+
+/obj/machinery/rnd/server/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
+ to_chat(S, "Destroying this object, will disrupt the research development that may serve for our masters in the future. Aborting.")
+ return FALSE
+
+/obj/machinery/pool/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) //pool's closed, but not.
+ to_chat(S, "The pool must not be closed, it will provide healthy fun for our masters in the future. Aborting.")
+ return FALSE
+
+/obj/structure/pool/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
+ to_chat(S, "The pool must not be closed, it will provide healthy fun for our masters in the future. Aborting.")
+ return FALSE
+
+/obj/structure/holosign/barrier/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
+ var/static/list/lazy_typecache = typecacheof(list(/obj/structure/holosign/barrier/engineering, /obj/structure/holosign/barrier/firelock, /obj/structure/holosign/barrier/atmos, /obj/structure/holosign/barrier/combifan))
+ if(lazy_typecache[type])
+ to_chat(S, "Destroying this holographic barrier may not benefit us. Aborting.")
+ return FALSE
+ return ..()
+
+/obj/machinery/dominator/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
+ to_chat(S, "This advanced piece of technology may be of use for our masters in the future. Aborting.")
+ return FALSE
+
+/obj/machinery/computer/bsa_control/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
+ to_chat(S, "This advanced piece of technology may be of use for our masters in the future. Aborting.")
+ return FALSE
+
+/obj/machinery/bsa/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
+ to_chat(S, "This advanced piece of technology may be of use for our masters in the future. Aborting.")
+ return FALSE
+
+/obj/machinery/dna_vault/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
+ to_chat(S, "This advanced piece of technology may be of use for our masters in the future. Aborting.")
+ return FALSE
+
+/obj/structure/filler/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
+ to_chat(S, "This advanced piece of technology may be of use for our masters in the future. Aborting.")
+ return FALSE
+
+/obj/machinery/computer/sat_control/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
+ to_chat(S, "Destroying this object will lower the station shielding against space debris. Aborting.")
+ return FALSE
+
+/obj/machinery/satellite/meteor_shield/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
+ to_chat(S, "Destroying this object will lower the station shielding against space debris. Aborting.")
+ return FALSE
+
////END CTRL CLICK FOR SWARMERS////
/mob/living/simple_animal/hostile/swarmer/proc/Fabricate(atom/fabrication_object,fabrication_cost = 0)
@@ -429,6 +480,14 @@
return new fabrication_object(loc)
/mob/living/simple_animal/hostile/swarmer/proc/Integrate(atom/movable/target)
+ if(isobj(target))
+ var/obj/O = target
+ if(O.resistance_flags & INDESTRUCTIBLE)
+ return FALSE
+ for(var/mob/living/L in GetAllContents())
+ if(!ispAI(L) && !isbrain(L))
+ to_chat(src, "An organism has been detected inside this object. Aborting.")
+ return FALSE
var/resource_gain = target.IntegrateAmount()
if(resources + resource_gain > max_resources)
to_chat(src, "We cannot hold more materials!")
diff --git a/code/modules/antagonists/swarmer/swarmer_event.dm b/code/modules/antagonists/swarmer/swarmer_event.dm
index 6ef35fdbaa..c626799a53 100644
--- a/code/modules/antagonists/swarmer/swarmer_event.dm
+++ b/code/modules/antagonists/swarmer/swarmer_event.dm
@@ -1,10 +1,10 @@
/datum/round_event_control/spawn_swarmer
name = "Spawn Swarmer Shell"
typepath = /datum/round_event/spawn_swarmer
- weight = 0
- max_occurrences = 0
+ weight = 7
+ max_occurrences = 1 //Only once okay fam
earliest_start = 30 MINUTES
- min_players = 15
+ min_players = 35
gamemode_blacklist = list("dynamic")
diff --git a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm
index e6ca95472e..6616eea006 100644
--- a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm
+++ b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm
@@ -43,7 +43,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
else
owner_AI = owner
-/datum/action/innate/ai/IsAvailable()
+/datum/action/innate/ai/IsAvailable(silent = FALSE)
. = ..()
if(owner_AI && owner_AI.malf_cooldown > world.time)
return FALSE
diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm
index 1f868dad6d..7a3ed902ea 100644
--- a/code/modules/clothing/shoes/miscellaneous.dm
+++ b/code/modules/clothing/shoes/miscellaneous.dm
@@ -377,3 +377,99 @@
name = "black cowboy boots"
desc = "A pair of black cowboy boots, pretty easy to scuff up."
icon_state = "cowboyboots_black"
+
+/obj/item/clothing/shoes/wallwalkers
+ name = "wall walking boots"
+ desc = "Contrary to popular belief, these do not allow you to walk on walls. Through bluespace magic stolen from an organisation that hoards technology, they simply allow you to slip through the atoms that make up anything, but only while walking, for safety reasons. As well as this, they unfortunately cause minor breath loss as the majority of atoms in your lungs are sucked out into any solid object you walk through. Make sure not to overuse them."
+ icon_state = "walkboots"
+ var/walkcool = 0
+ var/wallcharges = 4
+ var/newlocobject = null
+
+/obj/item/clothing/shoes/wallwalkers/equipped(mob/user,slot)
+ . = ..()
+ if(slot == SLOT_SHOES)
+ RegisterSignal(user, COMSIG_MOB_CLIENT_MOVE,.proc/intercept_user_move)
+
+/obj/item/clothing/shoes/wallwalkers/dropped(mob/user)
+ . = ..()
+ UnregisterSignal(user, COMSIG_MOB_CLIENT_MOVE)
+
+/obj/item/clothing/shoes/wallwalkers/attackby(obj/item/W, mob/user, params)
+ . = ..()
+ if(!istype(W, /obj/item/bluespacerecharge))
+ return
+ var/obj/item/bluespacerecharge/ER = W
+ if(ER.uses)
+ wallcharges += ER.uses
+ to_chat(user, "You charged the bluespace crystal in the [src]. It now has [wallcharges] charges left.")
+ ER.uses = 0
+ ER.icon_state = "[initial(ER.icon_state)]0"
+ else
+ to_chat(user, "[ER] has no crystal on it.")
+
+/obj/item/clothing/shoes/wallwalkers/examine(mob/user)
+ . = ..()
+ . += "It has [wallcharges] charges left."
+
+/obj/item/clothing/shoes/wallwalkers/proc/intercept_user_move(mob/living/m, client/client, dir, newloc, oldloc)
+ if (walkcool >= world.time || m.m_intent != MOVE_INTENT_WALK || wallcharges <= 0)
+ return
+ walkcool = world.time + m.movement_delay()
+ var/issolid = FALSE
+ var/turf/K = newloc
+ if (istype(K))
+ if (K.density)
+ issolid = TRUE
+ if (!issolid)
+ for (var/atom/T in newloc) //stuff on the new turf
+ if (!T.CanPass(m,newloc) && T != m)
+ issolid = TRUE
+ newlocobject = T
+ break
+ if (!issolid)
+ for (var/atom/T in oldloc) //directional shit on the old turf
+ if (!T.CanPass(m,newloc) && T != m && T != newlocobject)
+ issolid = TRUE
+ break
+ newlocobject = null //stopping structures from using two charges because of how shitty the canpass code is
+ m.forceMove(newloc)
+ if (!issolid)
+ return
+ m.adjustOxyLoss(rand(5,13))
+ if (prob(15))
+ m.adjustBruteLoss(rand(4,7))
+ to_chat(m,"You feel as if travelling through the solid object left something behind and it hurts!")
+ var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
+ s.set_up(5, 1, oldloc)
+ s.start()
+ flash_lighting_fx(3, 3, LIGHT_COLOR_ORANGE)
+ wallcharges--
+
+/obj/item/bluespacerecharge
+ name = "bluespace crystal recharging device"
+ desc = "A small cell with two prongs lazily jabbed into it. It looks like it's made for replacing the crystals in bluespace devices."
+ icon = 'icons/obj/module.dmi'
+ icon_state = "bluespace_charge"
+ item_flags = NOBLUDGEON
+ w_class = WEIGHT_CLASS_TINY
+ var/uses = 6
+
+/obj/item/bluespacerecharge/examine(mob/user)
+ . = ..()
+ if(uses)
+ . += "It can add up to [uses] charges to compatible devices."
+ else
+ . += "The crystal is gone."
+
+/obj/item/bluespacerecharge/attackby(obj/item/I, mob/user, params)
+ ..()
+ if(!istype(I, /obj/item/stack/ore/bluespace_crystal) || uses)
+ return
+ var/obj/item/stack/ore/bluespace_crystal/B = I
+ if (B.amount < 10)
+ return
+ uses += 3
+ to_chat(user, "You insert [I] into [src].")
+ B.use(10)
+ icon_state = initial(icon_state)
diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm
index 4311aa5166..94ccdf94c6 100644
--- a/code/modules/clothing/spacesuits/chronosuit.dm
+++ b/code/modules/clothing/spacesuits/chronosuit.dm
@@ -321,7 +321,7 @@
check_flags = AB_CHECK_CONSCIOUS //|AB_CHECK_INSIDE
var/obj/item/clothing/suit/space/chronos/chronosuit = null
-/datum/action/innate/chrono_teleport/IsAvailable()
+/datum/action/innate/chrono_teleport/IsAvailable(silent = FALSE)
return (chronosuit && chronosuit.activated && chronosuit.camera && !chronosuit.teleporting)
/datum/action/innate/chrono_teleport/Activate()
diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm
index ac74f91743..93b34f4522 100644
--- a/code/modules/clothing/spacesuits/hardsuit.dm
+++ b/code/modules/clothing/spacesuits/hardsuit.dm
@@ -30,16 +30,14 @@
/obj/item/clothing/head/helmet/space/hardsuit/attack_self(mob/user)
on = !on
- icon_state = "[basestate][on]-[hardsuit_type]"
user.update_inv_head() //so our mob-overlays update
-
if(on)
set_light(brightness_on)
else
set_light(0)
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
+
+/obj/item/clothing/head/helmet/space/hardsuit/update_icon_state()
+ icon_state = "[basestate][on]-[hardsuit_type]"
/obj/item/clothing/head/helmet/space/hardsuit/dropped(mob/user)
..()
diff --git a/code/modules/holodeck/area_copy.dm b/code/modules/holodeck/area_copy.dm
index 9fb97c08a7..316bdb8289 100644
--- a/code/modules/holodeck/area_copy.dm
+++ b/code/modules/holodeck/area_copy.dm
@@ -63,23 +63,34 @@ GLOBAL_LIST_INIT(duplicate_forbidden_vars_by_type, typecacheof_assoc_list(list(
var/src_min_x = 99999
var/src_min_y = 99999
+ var/src_max_x = 0
+ var/src_max_y = 0
var/list/refined_src = new/list()
for (var/turf/T in turfs_src)
src_min_x = min(src_min_x,T.x)
src_min_y = min(src_min_y,T.y)
+ src_max_x = max(src_max_x,T.y)
+ src_max_y = max(src_max_y,T.y)
for (var/turf/T in turfs_src)
refined_src[T] = "[T.x - src_min_x].[T.y - src_min_y]"
var/trg_min_x = 99999
var/trg_min_y = 99999
+ var/trg_max_x = 0
+ var/trg_max_y = 0
var/list/refined_trg = new/list()
for (var/turf/T in turfs_trg)
trg_min_x = min(trg_min_x,T.x)
trg_min_y = min(trg_min_y,T.y)
+ trg_max_x = max(trg_max_x,T.y)
+ trg_max_y = max(trg_max_y,T.y)
+
+ var/diff_x = round(((src_max_x - src_min_x) - (trg_max_x - trg_min_x))/2)
+ var/diff_y = round(((src_max_y - src_min_y) - (trg_max_y - trg_min_y))/2)
for (var/turf/T in turfs_trg)
- refined_trg["[T.x - trg_min_x].[T.y - trg_min_y]"] = T
+ refined_trg["[T.x - trg_min_x + diff_x].[T.y - trg_min_y + diff_y]"] = T
var/list/toupdate = new/list()
diff --git a/code/modules/holodeck/computer.dm b/code/modules/holodeck/computer.dm
index b5cbed8b79..3c87082393 100644
--- a/code/modules/holodeck/computer.dm
+++ b/code/modules/holodeck/computer.dm
@@ -2,7 +2,10 @@
Holodeck Update
The on-station holodeck area is of type [holodeck_type].
- All subtypes of [program_type] are loaded into the program cache or emag programs list.
+ All types found in GLOB.holodeck_areas_per_comp_type[src.type], generated on make_datum_references_lists(),
+ are loaded into the program cache or emag programs list.
+ Paths with their abstract_type variable equal to themselves will be skipped.
+
If init_program is null, a random program will be loaded on startup.
If you don't wish this, set it to the offline program or another of your choosing.
@@ -12,7 +15,6 @@
3) Create a new control console that uses those areas
Non-mapped areas should be skipped but you should probably comment them out anyway.
- The base of program_type will always be ignored; only subtypes will be loaded.
*/
#define HOLODECK_CD 25
@@ -35,7 +37,6 @@
// Splitting this up allows two holodecks of the same size
// to use the same source patterns. Y'know, if you want to.
var/holodeck_type = /area/holodeck/rec_center // locate(this) to get the target holodeck
- var/program_type = /area/holodeck/rec_center // subtypes of this (but not this itself) are loadable programs
var/active = FALSE
var/damaged = FALSE
@@ -181,7 +182,7 @@
return ..()
/obj/machinery/computer/holodeck/proc/generate_program_list()
- for(var/typekey in subtypesof(program_type))
+ for(var/typekey in GLOB.holodeck_areas_prototypes[type])
var/area/holodeck/A = GLOB.areas_by_type[typekey]
if(!A || !A.contents.len)
continue
diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
index ef6a372f9e..42b2c4433b 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
@@ -21,14 +21,13 @@ Doesn't work on other aliens/AI.*/
. = ..()
action = new(src)
-/obj/effect/proc_holder/alien/Click()
- if(!iscarbon(usr))
- return 1
- var/mob/living/carbon/user = usr
- if(cost_check(check_turf,user))
+/obj/effect/proc_holder/alien/Trigger(mob/living/carbon/user, skip_cost_check)
+ if(!istype(user))
+ return TRUE
+ if(!skip_cost_check || cost_check(check_turf,user))
if(fire(user) && user) // Second check to prevent runtimes when evolving
user.adjustPlasma(-plasma_cost)
- return 1
+ return TRUE
/obj/effect/proc_holder/alien/on_gain(mob/living/carbon/user)
return
diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm
index 4ee069afe8..abc2288e9b 100644
--- a/code/modules/mob/living/carbon/human/species_types/golems.dm
+++ b/code/modules/mob/living/carbon/human/species_types/golems.dm
@@ -469,7 +469,7 @@
var/cooldown = 150
var/last_teleport = 0
-/datum/action/innate/unstable_teleport/IsAvailable()
+/datum/action/innate/unstable_teleport/IsAvailable(silent = FALSE)
if(..())
if(world.time > last_teleport + cooldown)
return 1
diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
index 9937b52002..c04167a61f 100644
--- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
@@ -84,7 +84,7 @@
background_icon_state = "bg_alien"
required_mobility_flags = NONE
-/datum/action/innate/regenerate_limbs/IsAvailable()
+/datum/action/innate/regenerate_limbs/IsAvailable(silent = FALSE)
if(..())
var/mob/living/carbon/human/H = owner
var/list/limbs_to_heal = H.get_missing_limbs()
@@ -223,7 +223,7 @@
icon_icon = 'icons/mob/actions/actions_slime.dmi'
background_icon_state = "bg_alien"
-/datum/action/innate/split_body/IsAvailable()
+/datum/action/innate/split_body/IsAvailable(silent = FALSE)
if(..())
var/mob/living/carbon/human/H = owner
if(H.blood_volume >= BLOOD_VOLUME_SLIME_SPLIT)
@@ -776,7 +776,7 @@
..()
species = _species
-/datum/action/innate/use_extract/IsAvailable()
+/datum/action/innate/use_extract/IsAvailable(silent = FALSE)
if(..())
if(species && species.current_extract && (world.time > species.extract_cooldown))
return TRUE
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index b3d020424f..63e772e07c 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -321,12 +321,16 @@ There are several things that need to be remembered:
if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
return
- if(client && hud_used && hud_used.inv_slots[SLOT_BACK])
+ if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_HEAD]
inv.update_icon()
- update_mutant_bodyparts()
if(head)
+ head.screen_loc = ui_head
+ if(client && hud_used && hud_used.hud_shown)
+ if(hud_used.inventory_shown)
+ client.screen += head
+ update_observer_view(head,1)
remove_overlay(HEAD_LAYER)
var/obj/item/clothing/head/H = head
var/alt_icon = H.mob_overlay_icon || 'icons/mob/clothing/head.dmi'
@@ -348,6 +352,7 @@ There are several things that need to be remembered:
head_overlay.pixel_y += dna.species.offset_features[OFFSET_HEAD][2]
overlays_standing[HEAD_LAYER] = head_overlay
apply_overlay(HEAD_LAYER)
+ update_mutant_bodyparts()
/mob/living/carbon/human/update_inv_belt()
remove_overlay(BELT_LAYER)
@@ -457,11 +462,16 @@ There are several things that need to be remembered:
if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
return
- if(client && hud_used && hud_used.inv_slots[SLOT_WEAR_MASK])
+ if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_MASK]
inv.update_icon()
if(wear_mask)
+ wear_mask.screen_loc = ui_mask
+ if(client && hud_used && hud_used.hud_shown)
+ if(hud_used.inventory_shown)
+ client.screen += wear_mask
+ update_observer_view(wear_mask,1)
var/obj/item/clothing/mask/M = wear_mask
remove_overlay(FACEMASK_LAYER)
var/alt_icon = M.mob_overlay_icon || 'icons/mob/clothing/mask.dmi'
@@ -515,22 +525,6 @@ There are several things that need to be remembered:
//human HUD updates for items in our inventory
-//update whether our head item appears on our hud.
-/mob/living/carbon/human/update_hud_head(obj/item/I)
- I.screen_loc = ui_head
- if(client && hud_used && hud_used.hud_shown)
- if(hud_used.inventory_shown)
- client.screen += I
- update_observer_view(I,1)
-
-//update whether our mask item appears on our hud.
-/mob/living/carbon/human/update_hud_wear_mask(obj/item/I)
- I.screen_loc = ui_mask
- if(client && hud_used && hud_used.hud_shown)
- if(hud_used.inventory_shown)
- client.screen += I
- update_observer_view(I,1)
-
//update whether our neck item appears on our hud.
/mob/living/carbon/human/update_hud_neck(obj/item/I)
I.screen_loc = ui_neck
@@ -579,13 +573,7 @@ use_mob_overlay_icon: if FALSE, it will always use the default_icon_file even if
/obj/item/proc/build_worn_icon(default_layer = 0, default_icon_file = null, isinhands = FALSE, femaleuniform = NO_FEMALE_UNIFORM, override_state, style_flags = NONE, use_mob_overlay_icon = TRUE)
var/t_state
- if(override_state)
- t_state = override_state
- else
- if(isinhands && item_state)
- t_state = item_state
- else
- t_state = icon_state
+ t_state = override_state || item_state || icon_state
//Find a valid icon file from variables+arguments
var/file2use
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index 7c6d0e8cdc..8097859aac 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -28,10 +28,8 @@
if(stat != DEAD)
handle_brain_damage()
- /* BUG_PROBABLE_CAUSE
if(stat != DEAD)
handle_liver()
- */
if(stat == DEAD)
stop_sound_channel(CHANNEL_HEARTBEAT)
@@ -690,36 +688,17 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
var/obj/item/organ/liver/liver = getorganslot(ORGAN_SLOT_LIVER)
if((!dna && !liver) || (NOLIVER in dna.species.species_traits))
return
- if(liver)
- if(liver.damage < liver.maxHealth)
- liver.organ_flags |= ORGAN_FAILING
- liver_failure()
- else
+ if(!liver || liver.organ_flags & ORGAN_FAILING)
liver_failure()
-/mob/living/carbon/proc/undergoing_liver_failure()
- var/obj/item/organ/liver/liver = getorganslot(ORGAN_SLOT_LIVER)
- if(liver && liver.failing)
- return TRUE
-
-/mob/living/carbon/proc/return_liver_damage()
- var/obj/item/organ/liver/liver = getorganslot(ORGAN_SLOT_LIVER)
- if(liver)
- return liver.damage
-
-/mob/living/carbon/proc/applyLiverDamage(var/d)
- var/obj/item/organ/liver/L = getorganslot(ORGAN_SLOT_LIVER)
- if(L)
- L.damage += d
-
/mob/living/carbon/proc/liver_failure()
reagents.end_metabolization(src, keep_liverless = TRUE) //Stops trait-based effects on reagents, to prevent permanent buffs
reagents.metabolize(src, can_overdose=FALSE, liverless = TRUE)
if(HAS_TRAIT(src, TRAIT_STABLELIVER))
return
adjustToxLoss(4, TRUE, TRUE)
- if(prob(30))
- to_chat(src, "You feel a stabbing pain in your abdomen!")
+ if(prob(15))
+ to_chat(src, "You feel a stabbing pain in your abdomen!")
////////////////
diff --git a/code/modules/mob/living/carbon/update_icons.dm b/code/modules/mob/living/carbon/update_icons.dm
index 5e9892701d..a431059a89 100644
--- a/code/modules/mob/living/carbon/update_icons.dm
+++ b/code/modules/mob/living/carbon/update_icons.dm
@@ -90,9 +90,9 @@
if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
return
- if(client && hud_used && hud_used.inv_slots[SLOT_WEAR_MASK])
+ if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_MASK]
- inv.update_icon()
+ inv?.update_icon()
if(wear_mask)
if(!(head && (head.flags_inv & HIDEMASK)))
@@ -110,7 +110,7 @@
if(wear_neck)
if(!(head && (head.flags_inv & HIDENECK)))
- overlays_standing[NECK_LAYER] = wear_neck.build_worn_icon(default_layer = NECK_LAYER, default_icon_file = 'icons/mob/clothing/neck.dmi', override_state = wear_mask.icon_state)
+ overlays_standing[NECK_LAYER] = wear_neck.build_worn_icon(default_layer = NECK_LAYER, default_icon_file = 'icons/mob/clothing/neck.dmi', override_state = wear_neck.icon_state)
update_hud_neck(wear_neck)
apply_overlay(NECK_LAYER)
@@ -118,9 +118,9 @@
/mob/living/carbon/update_inv_back()
remove_overlay(BACK_LAYER)
- if(client && hud_used && hud_used.inv_slots[SLOT_BACK])
+ if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_BACK]
- inv.update_icon()
+ inv?.update_icon()
if(back)
overlays_standing[BACK_LAYER] = back.build_worn_icon(default_layer = BACK_LAYER, default_icon_file = 'icons/mob/clothing/back.dmi', override_state = back.icon_state)
@@ -134,9 +134,9 @@
if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
return
- if(client && hud_used && hud_used.inv_slots[SLOT_BACK])
+ if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_HEAD]
- inv.update_icon()
+ inv?.update_icon()
if(head)
overlays_standing[HEAD_LAYER] = head.build_worn_icon(default_layer = HEAD_LAYER, default_icon_file = 'icons/mob/clothing/head.dmi', override_state = head.icon_state)
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 35b49cce8e..f90b285d2d 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -354,7 +354,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
if(cultslurring)
message = cultslur(message)
-
+
if(clockcultslurring)
message = CLOCK_CULT_SLUR(message)
diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
index 3c3612f434..439bedf3cc 100644
--- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
+++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
@@ -400,10 +400,9 @@
action.button_icon_state = "wrap_[active]"
action.UpdateButtonIcon()
-/obj/effect/proc_holder/wrap/Click()
- if(!istype(usr, /mob/living/simple_animal/hostile/poison/giant_spider/nurse))
+/obj/effect/proc_holder/wrap/Trigger(mob/living/simple_animal/hostile/poison/giant_spider/nurse/user)
+ if(!istype(user))
return TRUE
- var/mob/living/simple_animal/hostile/poison/giant_spider/nurse/user = usr
activate(user)
return TRUE
@@ -444,7 +443,7 @@
check_flags = AB_CHECK_CONSCIOUS
button_icon_state = "lay_eggs"
-/datum/action/innate/spider/lay_eggs/IsAvailable()
+/datum/action/innate/spider/lay_eggs/IsAvailable(silent = FALSE)
if(..())
if(!istype(owner, /mob/living/simple_animal/hostile/poison/giant_spider/nurse))
return 0
@@ -508,7 +507,7 @@
desc = "Send a command to all living spiders."
button_icon_state = "command"
-/datum/action/innate/spider/comm/IsAvailable()
+/datum/action/innate/spider/comm/IsAvailable(silent = FALSE)
if(!istype(owner, /mob/living/simple_animal/hostile/poison/giant_spider/nurse/midwife))
return FALSE
return TRUE
diff --git a/code/modules/mob/living/simple_animal/slime/powers.dm b/code/modules/mob/living/simple_animal/slime/powers.dm
index bf80ab9ff4..4f8e271d6f 100644
--- a/code/modules/mob/living/simple_animal/slime/powers.dm
+++ b/code/modules/mob/living/simple_animal/slime/powers.dm
@@ -11,7 +11,7 @@
background_icon_state = "bg_alien"
var/needs_growth = NO_GROWTH_NEEDED
-/datum/action/innate/slime/IsAvailable()
+/datum/action/innate/slime/IsAvailable(silent = FALSE)
if(..())
var/mob/living/simple_animal/slime/S = owner
if(needs_growth == GROWTH_NEEDED)
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index dd40648191..9c1a23174e 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -513,7 +513,7 @@
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "sniper_zoom"
-/datum/action/item_action/toggle_scope_zoom/IsAvailable()
+/datum/action/item_action/toggle_scope_zoom/IsAvailable(silent = FALSE)
. = ..()
if(!.)
var/obj/item/gun/G = target
diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
index b7f32421aa..da461ef4ff 100644
--- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
@@ -43,8 +43,8 @@ All effects don't start immediately, but rather get worse over time; the rate is
booze_power *= 0.7
C.drunkenness = max((C.drunkenness + (sqrt(volume) * booze_power * ALCOHOL_RATE)), 0) //Volume, power, and server alcohol rate effect how quickly one gets drunk
var/obj/item/organ/liver/L = C.getorganslot(ORGAN_SLOT_LIVER)
- if (istype(L))
- C.applyLiverDamage((max(sqrt(volume) * (boozepwr ** ALCOHOL_EXPONENT) * L.alcohol_tolerance, 0))/150)
+ if(L)
+ L.applyOrganDamage((max(sqrt(volume) * (boozepwr ** ALCOHOL_EXPONENT) * L.alcohol_tolerance, 0))/150)
return ..()
/datum/reagent/consumable/ethanol/reaction_obj(obj/O, reac_volume)
@@ -1646,7 +1646,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_icon_state = "pina_colada"
glass_name = "Pina Colada"
glass_desc = "If you like pina coladas, and getting caught in the rain... well, you'll like this drink."
-
+
/datum/reagent/consumable/ethanol/grasshopper
name = "Grasshopper"
description = "A fresh and sweet dessert shooter. Difficult to look manly while drinking this."
@@ -2354,7 +2354,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/hotlime_miami/on_mob_life(mob/living/carbon/M)
M.set_drugginess(50)
M.adjustStaminaLoss(-2)
- return ..()
+ return ..()
/datum/reagent/consumable/ethanol/fruit_wine
name = "Fruit Wine"
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index 46002287dd..ecceb6e8bf 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -263,9 +263,9 @@
/datum/reagent/medicine/silver_sulfadiazine/overdose_start(mob/living/M)
metabolization_rate = 15 * REAGENTS_METABOLISM
M.adjustBruteLoss(2*REM, 0)
- if(iscarbon(M))
- var/mob/living/carbon/C = M
- C.applyLiverDamage(1)
+ var/obj/item/organ/liver/L = M.getorganslot(ORGAN_SLOT_LIVER)
+ if(L)
+ L.applyOrganDamage(1)
..()
. = 1
@@ -326,9 +326,9 @@
datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M)
metabolization_rate = 15 * REAGENTS_METABOLISM
M.adjustBruteLoss(2*REM, 0)
- if(iscarbon(M))
- var/mob/living/carbon/C = M
- C.applyLiverDamage(1)
+ var/obj/item/organ/liver/L = M.getorganslot(ORGAN_SLOT_LIVER)
+ if(L)
+ L.applyOrganDamage(1)
..()
. = 1
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index b73838e6c1..c2f14e69ec 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -1070,11 +1070,11 @@
to_chat(M, "You start feeling your guts twisting painfully!")
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "[type]_overdose", /datum/mood_event/overdose, name)
-/datum/reagent/iron/overdose_process(mob/living/carbon/C)
+/datum/reagent/iron/overdose_process(mob/living/M)
if(prob(20))
- var/obj/item/organ/liver/L = C.getorganslot(ORGAN_SLOT_LIVER)
- if (istype(L))
- C.applyLiverDamage(2) //mild until the fabled med rework comes out. the organ damage galore
+ var/obj/item/organ/liver/L = M.getorganslot(ORGAN_SLOT_LIVER)
+ if(L)
+ L.applyOrganDamage(2)
..()
/datum/reagent/gold
diff --git a/code/modules/spells/spell.dm b/code/modules/spells/spell.dm
index 03488fa8a9..143fe508b6 100644
--- a/code/modules/spells/spell.dm
+++ b/code/modules/spells/spell.dm
@@ -45,6 +45,12 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
/obj/effect/proc_holder/singularity_pull()
return
+/obj/effect/proc_holder/Click()
+ return Trigger(usr, FALSE)
+
+/obj/effect/proc_holder/proc/Trigger(mob/user)
+ return TRUE
+
/obj/effect/proc_holder/proc/InterceptClickOn(mob/living/caller, params, atom/A)
if(caller.ranged_ability != src || ranged_ability_user != caller) //I'm not actually sure how these would trigger, but, uh, safety, I guess?
to_chat(caller, "[caller.ranged_ability.name] has been disabled.")
@@ -150,8 +156,8 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
if(mobs_blacklist)
mobs_blacklist = typecacheof(mobs_blacklist)
-/obj/effect/proc_holder/spell/proc/cast_check(skipcharge = FALSE, mob/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell
- if(!can_cast(user, skipcharge))
+/obj/effect/proc_holder/spell/proc/cast_check(skipcharge = FALSE, mob/user = usr, skip_can_cast = FALSE) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell
+ if(!skip_can_cast && !can_cast(user, skipcharge))
return FALSE
if(!skipcharge)
@@ -181,17 +187,22 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
return TRUE
/obj/effect/proc_holder/spell/proc/invocation(mob/user = usr) //spelling the spell out and setting it on recharge/reducing charges amount
+ var/mob/living/L
+ if(isliving(user))
+ L = user
switch(invocation_type)
if("shout")
- if(prob(50))//Auto-mute? Fuck that noise
- user.say(invocation, forced = "spell")
- else
- user.say(replacetext(invocation," ","`"), forced = "spell")
+ if(!L || L.can_speak_vocal(invocation))
+ if(prob(50))//Auto-mute? Fuck that noise
+ user.say(invocation, forced = "spell")
+ else
+ user.say(replacetext(invocation," ","`"), forced = "spell")
if("whisper")
- if(prob(50))
- user.whisper(invocation)
- else
- user.whisper(replacetext(invocation," ","`"))
+ if(!L || L.can_speak_vocal(invocation))
+ if(prob(50))
+ user.whisper(invocation)
+ else
+ user.whisper(replacetext(invocation," ","`"))
if("emote")
user.visible_message(invocation, invocation_emote_self) //same style as in mob/living/emote.dm
@@ -210,8 +221,8 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
qdel(action)
return ..()
-/obj/effect/proc_holder/spell/Click()
- if(cast_check())
+/obj/effect/proc_holder/spell/Trigger(mob/user, skip_can_cast = TRUE)
+ if(cast_check(FALSE, user, skip_can_cast))
choose_targets()
return 1
@@ -432,7 +443,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
return 1
/obj/effect/proc_holder/spell/proc/can_cast(mob/user = usr, skipcharge = FALSE, silent = FALSE)
- var/magic_flags = SEND_SIGNAL(user, COMSIG_MOB_SPELL_CAST_CHECK, src)
+ var/magic_flags = SEND_SIGNAL(user, COMSIG_MOB_SPELL_CAN_CAST, src)
if(magic_flags & SPELL_SKIP_ALL_REQS)
return TRUE
@@ -448,9 +459,8 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
to_chat(user, "You can't cast this spell here.")
return FALSE
- if(!skipcharge)
- if(!charge_check(user))
- return FALSE
+ if(!skipcharge && !charge_check(user, silent))
+ return FALSE
if(user.stat && !stat_allowed && !(magic_flags & SPELL_SKIP_STAT))
if(!silent)
diff --git a/code/modules/spells/spell_types/aimed.dm b/code/modules/spells/spell_types/aimed.dm
index 786026a1bc..1a904b1076 100644
--- a/code/modules/spells/spell_types/aimed.dm
+++ b/code/modules/spells/spell_types/aimed.dm
@@ -11,12 +11,11 @@
var/current_amount = 0 //How many projectiles left.
var/projectiles_per_fire = 1 //Projectiles per fire. Probably not a good thing to use unless you override ready_projectile().
-/obj/effect/proc_holder/spell/aimed/Click()
- var/mob/living/user = usr
+/obj/effect/proc_holder/spell/aimed/Trigger(mob/user, skip_can_cast = TRUE)
if(!istype(user))
return
var/msg
- if(!can_cast(user, FALSE, TRUE))
+ if(!skip_can_cast && !can_cast(user, FALSE, TRUE))
msg = "You can no longer cast [name]!"
remove_ranged_ability(msg)
return
diff --git a/code/modules/spells/spell_types/lightning.dm b/code/modules/spells/spell_types/lightning.dm
index 81b26cf464..d0c3c4166c 100644
--- a/code/modules/spells/spell_types/lightning.dm
+++ b/code/modules/spells/spell_types/lightning.dm
@@ -15,9 +15,9 @@
action_icon_state = "lightning"
-/obj/effect/proc_holder/spell/targeted/tesla/Click()
- if(!ready && cast_check())
- StartChargeup()
+/obj/effect/proc_holder/spell/targeted/tesla/Trigger(mob/user, skip_can_cast = TRUE)
+ if(!ready && cast_check(FALSE, user, skip_can_cast))
+ StartChargeup(user)
return 1
/obj/effect/proc_holder/spell/targeted/tesla/proc/StartChargeup(mob/user = usr)
diff --git a/code/modules/spells/spell_types/mime.dm b/code/modules/spells/spell_types/mime.dm
index a3bb81ae55..8f39da5031 100644
--- a/code/modules/spells/spell_types/mime.dm
+++ b/code/modules/spells/spell_types/mime.dm
@@ -16,12 +16,12 @@
action_icon_state = "mime"
action_background_icon_state = "bg_mime"
-/obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall/Click()
- if(usr && usr.mind)
- if(!usr.mind.miming)
+/obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall/Trigger(mob/user, skip_can_cast = TRUE)
+ if(user.mind)
+ if(!user.mind.miming)
to_chat(usr, "You must dedicate yourself to silence first.")
return
- invocation = "[usr.real_name] looks as if a wall is in front of [usr.p_them()]."
+ invocation = "[user.real_name] looks as if a wall is in front of [user.p_them()]."
else
invocation_type ="none"
..()
@@ -41,17 +41,12 @@
action_icon_state = "mime"
action_background_icon_state = "bg_mime"
-/obj/effect/proc_holder/spell/targeted/mime/speak/Click()
- if(!usr)
- return
- if(!ishuman(usr))
- return
- var/mob/living/carbon/human/H = usr
- if(H.mind.miming)
+/obj/effect/proc_holder/spell/targeted/mime/speak/Trigger(mob/user, skip_can_cast = TRUE)
+ if(user.mind?.miming)
still_recharging_msg = "You can't break your vow of silence that fast!"
else
still_recharging_msg = "You'll have to wait before you can give your vow of silence again!"
- ..()
+ return ..()
/obj/effect/proc_holder/spell/targeted/mime/speak/cast(list/targets,mob/user = usr)
for(var/mob/living/carbon/human/H in targets)
@@ -82,15 +77,15 @@
action_icon_state = "mime"
action_background_icon_state = "bg_mime"
-/obj/effect/proc_holder/spell/targeted/forcewall/mime/Click()
- if(usr && usr.mind)
- if(!usr.mind.miming)
+/obj/effect/proc_holder/spell/targeted/forcewall/mime/Trigger(mob/user, skip_can_cast = TRUE)
+ if(user.mind)
+ if(!user.mind.miming)
to_chat(usr, "You must dedicate yourself to silence first.")
return
- invocation = "[usr.real_name] looks as if a blockade is in front of [usr.p_them()]."
+ invocation = "[user.real_name] looks as if a blockade is in front of [user.p_them()]."
else
invocation_type ="none"
- ..()
+ return ..()
/obj/effect/proc_holder/spell/aimed/finger_guns
name = "Finger Guns"
@@ -114,19 +109,18 @@
base_icon_state = "mime"
-/obj/effect/proc_holder/spell/aimed/finger_guns/Click()
- var/mob/living/carbon/human/owner = usr
- if(owner.incapacitated())
- to_chat(owner, "You can't properly point your fingers while incapacitated.")
+/obj/effect/proc_holder/spell/aimed/finger_guns/Trigger(mob/user, skip_can_cast = TRUE)
+ if(user.incapacitated())
+ to_chat(user, "You can't properly point your fingers while incapacitated.")
return
- if(usr && usr.mind)
- if(!usr.mind.miming)
+ if(user.mind)
+ if(!user.mind.miming)
to_chat(usr, "You must dedicate yourself to silence first.")
return
- invocation = "[usr.real_name] fires [usr.p_their()] finger gun!"
+ invocation = "[user.real_name] fires [user.p_their()] finger gun!"
else
invocation_type ="none"
- ..()
+ return ..()
/obj/effect/proc_holder/spell/targeted/touch/mimerope
name = "Invisible Rope"
@@ -144,8 +138,8 @@
action_background_icon_state = "bg_mime"
hand_path = /obj/item/melee/touch_attack/mimerope
-/obj/effect/proc_holder/spell/targeted/touch/mimerope/Click()
- if(usr && usr.mind)
+/obj/effect/proc_holder/spell/targeted/touch/mimerope/Trigger(mob/user, skip_can_cast = TRUE)
+ if(user.mind)
if(!usr.mind.miming)
to_chat(usr, "You must dedicate yourself to silence first.")
return
diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/liver.dm
index 73225fc41c..117a45cdbc 100755
--- a/code/modules/surgery/organs/liver.dm
+++ b/code/modules/surgery/organs/liver.dm
@@ -1,7 +1,6 @@
#define LIVER_DEFAULT_HEALTH 100 //amount of damage required for liver failure
#define LIVER_DEFAULT_TOX_TOLERANCE 3 //amount of toxins the liver can filter out
#define LIVER_DEFAULT_TOX_LETHALITY 0.01 //lower values lower how harmful toxins are to the liver
-#define LIVER_SWELLING_MOVE_MODIFY "pharma"
/obj/item/organ/liver
name = "liver"
@@ -15,12 +14,14 @@
healing_factor = STANDARD_ORGAN_HEALING
decay_factor = STANDARD_ORGAN_DECAY
+ high_threshold_passed = "You feel a stange ache in your abdomen, almost like a stitch. This pain is encumbering your movements."
+ high_threshold_cleared = "The stitching ache in your abdomen passes away, unencumbering your movements."
+ now_fixed = "The stabbing pain in your abdomen slowly calms down into a more tolerable ache."
+
var/alcohol_tolerance = ALCOHOL_RATE//affects how much damage the liver takes from alcohol
- var/failing //is this liver failing?
var/toxTolerance = LIVER_DEFAULT_TOX_TOLERANCE//maximum amount of toxins the liver can just shrug off
var/toxLethality = LIVER_DEFAULT_TOX_LETHALITY//affects how much damage toxins do to the liver
var/filterToxins = TRUE //whether to filter toxins
- var/swelling = 0
var/cachedmoveCalc = 1
/obj/item/organ/liver/on_life()
@@ -28,8 +29,6 @@
if(istype(C))
if(!(organ_flags & ORGAN_FAILING))//can't process reagents with a failing liver
- //slowly heal liver damage
- damage = max(0, damage - 0.1)
if(filterToxins && !HAS_TRAIT(owner, TRAIT_TOXINLOVER))
//handle liver toxin filtration
@@ -46,42 +45,41 @@
if(damage > 10 && prob(damage/3))//the higher the damage the higher the probability
to_chat(C, "You feel a dull pain in your abdomen.")
- if(damage > maxHealth)//cap liver damage
- damage = maxHealth
-
- if(swelling >= 10)
- pharmacokinesis()
-
/obj/item/organ/liver/prepare_eat()
var/obj/S = ..()
S.reagents.add_reagent(/datum/reagent/iron, 5)
return S
-//Just in case
+/obj/item/organ/liver/applyOrganDamage(d, maximum = maxHealth)
+ . = ..()
+ if(!.)
+ return
+ if(damage >= high_threshold)
+ var/move_calc = 1+((round(damage) - high_threshold)/(high_threshold/3))
+ owner.add_movespeed_modifier(MOVESPEED_ID_CIRRHOSIS, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = move_calc)
+ sizeMoveMod(move_calc, owner)
+ else
+ owner.remove_movespeed_modifier(MOVESPEED_ID_CIRRHOSIS)
+ sizeMoveMod(1, owner)
+
+/obj/item/organ/liver/Insert(mob/living/carbon/M, special = FALSE, drop_if_replaced = TRUE)
+ . = ..()
+ if(. && damage >= high_threshold)
+ var/move_calc = 1+((round(damage) - high_threshold)/(high_threshold/3))
+ M.add_movespeed_modifier(MOVESPEED_ID_CIRRHOSIS, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = move_calc)
+ sizeMoveMod(move_calc, owner)
+
/obj/item/organ/liver/Remove(special = FALSE)
if(!QDELETED(owner))
- owner.remove_movespeed_modifier(LIVER_SWELLING_MOVE_MODIFY)
- owner.ResetBloodVol() //At the moment, this shouldn't allow application twice. You either have this OR a thirsty ferret.
+ owner.remove_movespeed_modifier(MOVESPEED_ID_CIRRHOSIS)
sizeMoveMod(1, owner)
return ..()
-//Applies some of the effects to the patient.
-/obj/item/organ/liver/proc/pharmacokinesis()
- var/moveCalc = 1+((round(swelling) - 9)/3)
- if(moveCalc == cachedmoveCalc)//reduce calculations
- return
- if(prob(5))
- to_chat(owner, "You feel a stange ache in your side, almost like a stitch. This pain is affecting your movements and making you feel lightheaded.")
- var/mob/living/carbon/human/H = owner
- H.add_movespeed_modifier(LIVER_SWELLING_MOVE_MODIFY, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc)
- H.AdjustBloodVol(moveCalc/3)
- sizeMoveMod(moveCalc, H)
-
-/obj/item/organ/liver/proc/sizeMoveMod(var/value, mob/living/carbon/human/H)
+/obj/item/organ/liver/proc/sizeMoveMod(value, mob/living/carbon/C)
if(cachedmoveCalc == value)
return
- H.next_move_modifier /= cachedmoveCalc
- H.next_move_modifier *= value
+ C.next_move_modifier /= cachedmoveCalc
+ C.next_move_modifier *= value
cachedmoveCalc = value
/obj/item/organ/liver/fly
diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm
index b091af0f92..d95901bdbe 100644
--- a/code/modules/surgery/organs/organ_internal.dm
+++ b/code/modules/surgery/organs/organ_internal.dm
@@ -143,8 +143,9 @@
var/healing_amount = -(maxHealth * healing_factor)
///Damage decrements again by a percent of its maxhealth, up to a total of 4 extra times depending on the owner's health
healing_amount -= owner.satiety > 0 ? 4 * healing_factor * owner.satiety / MAX_SATIETY : 0
- applyOrganDamage(healing_amount) //to FERMI_TWEAK
- //Make it so each threshold is stuck.
+ if(healing_amount)
+ applyOrganDamage(healing_amount) //to FERMI_TWEAK
+ //Make it so each threshold is stuck.
/obj/item/organ/examine(mob/user)
. = ..()
@@ -205,14 +206,15 @@
///Adjusts an organ's damage by the amount "d", up to a maximum amount, which is by default max damage
/obj/item/organ/proc/applyOrganDamage(var/d, var/maximum = maxHealth) //use for damaging effects
if(!d) //Micro-optimization.
- return
+ return FALSE
if(maximum < damage)
- return
+ return FALSE
damage = CLAMP(damage + d, 0, maximum)
- var/mess = check_damage_thresholds(owner)
+ var/mess = check_damage_thresholds()
prev_damage = damage
if(mess && owner)
to_chat(owner, mess)
+ return TRUE
///SETS an organ's damage to the amount "d", and in doing so clears or sets the failing flag, good for when you have an effect that should fix an organ if broken
/obj/item/organ/proc/setOrganDamage(var/d) //use mostly for admin heals
@@ -224,7 +226,7 @@
* description: By checking our current damage against our previous damage, we can decide whether we've passed an organ threshold.
* If we have, send the corresponding threshold message to the owner, if such a message exists.
*/
-/obj/item/organ/proc/check_damage_thresholds(var/M)
+/obj/item/organ/proc/check_damage_thresholds()
if(damage == prev_damage)
return
var/delta = damage - prev_damage
diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm
index 7c849dbd68..671d31530a 100644
--- a/code/modules/surgery/organs/vocal_cords.dm
+++ b/code/modules/surgery/organs/vocal_cords.dm
@@ -74,7 +74,7 @@
..()
cords = target
-/datum/action/item_action/organ_action/colossus/IsAvailable()
+/datum/action/item_action/organ_action/colossus/IsAvailable(silent = FALSE)
if(world.time < cords.next_command)
return FALSE
if(!owner)
@@ -632,7 +632,7 @@
..()
cords = target
-/datum/action/item_action/organ_action/velvet/IsAvailable()
+/datum/action/item_action/organ_action/velvet/IsAvailable(silent = FALSE)
return TRUE
/datum/action/item_action/organ_action/velvet/Trigger()
diff --git a/code/modules/uplink/uplink_items/uplink_clothing.dm b/code/modules/uplink/uplink_items/uplink_clothing.dm
index aad9834612..d6336bd982 100644
--- a/code/modules/uplink/uplink_items/uplink_clothing.dm
+++ b/code/modules/uplink/uplink_items/uplink_clothing.dm
@@ -83,4 +83,10 @@
name = "Thieving Gloves"
desc = "A pair of gloves that are insulated and frictionless, allowing you to steal easily from anyone you see."
item = /obj/item/clothing/gloves/thief
- cost = 4
\ No newline at end of file
+ cost = 4
+
+/datum/uplink_item/suits/wallwalkers
+ name = "Wall Walking Boots"
+ desc = "Through bluespace magic stolen from an organisation that hoards technology, these boots simply allow you to slip through the atoms that make up anything, but only while walking, for safety reasons. As well as this, they unfortunately cause minor breath loss as the majority of atoms in your lungs are sucked out into any solid object you walk through."
+ item = /obj/item/clothing/shoes/wallwalkers
+ cost = 6
\ No newline at end of file
diff --git a/code/modules/uplink/uplink_items/uplink_devices.dm b/code/modules/uplink/uplink_items/uplink_devices.dm
index 1a7345a3ae..194281ded6 100644
--- a/code/modules/uplink/uplink_items/uplink_devices.dm
+++ b/code/modules/uplink/uplink_items/uplink_devices.dm
@@ -20,6 +20,12 @@
item = /obj/item/emagrecharge
cost = 2
+/datum/uplink_item/device_tools/bluespacerecharge
+ name = "Bluespace Crystal Recharging Device"
+ desc = "A small device intended for recharging Wall Walking boots. Using it will add six charges to them. Use ten bluespace crystals on this recharger to add three more charges to it. "
+ item = /obj/item/bluespacerecharge
+ cost = 2
+
/datum/uplink_item/device_tools/phantomthief
name = "Syndicate Mask"
desc = "A cheap plastic mask fitted with an adrenaline autoinjector, which can be used by simply tensing your muscles"
diff --git a/html/changelogs/AutoChangeLog-pr-10986.yml b/html/changelogs/AutoChangeLog-pr-10986.yml
new file mode 100644
index 0000000000..bac7b9692a
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10986.yml
@@ -0,0 +1,4 @@
+author: "Seris02"
+delete-after: True
+changes:
+ - rscadd: "wall walking boots"
diff --git a/html/changelogs/AutoChangeLog-pr-11275.yml b/html/changelogs/AutoChangeLog-pr-11275.yml
new file mode 100644
index 0000000000..5a3ce31631
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11275.yml
@@ -0,0 +1,5 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - rscadd: "Reenabled the swarmers event. Also blacklisted another dozen other machineries and structures that may be critical to the shift or station integrity from swarmers' HUNGER for materials."
+ - bugfix: "Fixed find_safe_turfs() searching for turfs with concentration of oxygen lower than 16 rather higher."
diff --git a/html/changelogs/AutoChangeLog-pr-11811.yml b/html/changelogs/AutoChangeLog-pr-11811.yml
new file mode 100644
index 0000000000..010a0caa86
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11811.yml
@@ -0,0 +1,6 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Liver failure is back!"
+ - tweak: "standarized a few (prefs off) side effects from enlargment chems on livers to do organ damage instead without the blood volume whackiness."
+ - tweak: "High liver damage now slows mobs down."
diff --git a/html/changelogs/AutoChangeLog-pr-11817.yml b/html/changelogs/AutoChangeLog-pr-11817.yml
new file mode 100644
index 0000000000..9d9e0a779b
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11817.yml
@@ -0,0 +1,5 @@
+author: "Putnam3145"
+delete-after: True
+changes:
+ - rscadd: "Latejoin changelings for dynamic"
+ - bugfix: "Average threat calculation works now"
diff --git a/html/changelogs/AutoChangeLog-pr-11819.yml b/html/changelogs/AutoChangeLog-pr-11819.yml
new file mode 100644
index 0000000000..6619f26aba
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11819.yml
@@ -0,0 +1,5 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Wizard robes & co work again now."
+ - bugfix: "Fixed some spell casting message spam."
diff --git a/html/changelogs/AutoChangeLog-pr-11824.yml b/html/changelogs/AutoChangeLog-pr-11824.yml
new file mode 100644
index 0000000000..2b91fc5564
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11824.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "fixed yet another few airless issues with the space hermit ruin."
diff --git a/icons/mob/clothing/feet.dmi b/icons/mob/clothing/feet.dmi
index 578970a21c..1e09dce605 100644
Binary files a/icons/mob/clothing/feet.dmi and b/icons/mob/clothing/feet.dmi differ
diff --git a/icons/mob/clothing/feet_digi.dmi b/icons/mob/clothing/feet_digi.dmi
index fbc105b634..626c67a71c 100644
Binary files a/icons/mob/clothing/feet_digi.dmi and b/icons/mob/clothing/feet_digi.dmi differ
diff --git a/icons/mob/clothing/uniform_digi.dmi b/icons/mob/clothing/uniform_digi.dmi
index 80e8f80b94..9deb214335 100644
Binary files a/icons/mob/clothing/uniform_digi.dmi and b/icons/mob/clothing/uniform_digi.dmi differ
diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi
index bd8d52a1e6..c4e000b700 100644
Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ
diff --git a/icons/obj/module.dmi b/icons/obj/module.dmi
index ace24db5ff..a647bebd57 100644
Binary files a/icons/obj/module.dmi and b/icons/obj/module.dmi differ
diff --git a/icons/turf/mining.dmi b/icons/turf/mining.dmi
index 6561438228..335cff453e 100644
Binary files a/icons/turf/mining.dmi and b/icons/turf/mining.dmi differ
diff --git a/icons/turf/smoothrocks.dmi b/icons/turf/smoothrocks.dmi
index 20314cff5b..ba2bbce955 100644
Binary files a/icons/turf/smoothrocks.dmi and b/icons/turf/smoothrocks.dmi differ
diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm
index 28a776082f..198e6c5c24 100644
--- a/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm
+++ b/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm
@@ -54,15 +54,15 @@
return..()
var/mob/living/carbon/human/H = M
- var/obj/item/organ/genital/breasts/B = M.getorganslot(ORGAN_SLOT_BREASTS)
//If they've opted out, then route processing though liver.
if(!(H.client?.prefs.cit_toggles & BREAST_ENLARGEMENT))
var/obj/item/organ/liver/L = H.getorganslot(ORGAN_SLOT_LIVER)
if(L)
- L.swelling += 0.05
+ L.applyOrganDamage(0.25)
else
H.adjustToxLoss(1)
return..()
+ var/obj/item/organ/genital/breasts/B = M.getorganslot(ORGAN_SLOT_BREASTS)
//otherwise proceed as normal
if(!B) //If they don't have breasts, give them breasts.
@@ -95,7 +95,8 @@
/datum/reagent/fermi/breast_enlarger/overdose_process(mob/living/carbon/M) //Turns you into a female if male and ODing, doesn't touch nonbinary and object genders.
if(!(M.client?.prefs.cit_toggles & FORCED_FEM))
var/obj/item/organ/liver/L = M.getorganslot(ORGAN_SLOT_LIVER)
- L.swelling+= 0.05
+ if(L)
+ L.applyOrganDamage(0.25)
return ..()
var/obj/item/organ/genital/penis/P = M.getorganslot(ORGAN_SLOT_PENIS)
@@ -130,7 +131,8 @@
var/obj/item/organ/genital/breasts/B = M.getorganslot(ORGAN_SLOT_BREASTS)
if(!(M.client?.prefs.cit_toggles & BREAST_ENLARGEMENT) || !B)
var/obj/item/organ/liver/L = M.getorganslot(ORGAN_SLOT_LIVER)
- L.swelling-= 0.05
+ if(L)
+ L.applyOrganDamage(-0.25)
return ..()
B.modify_size(-0.05)
return ..()
@@ -208,14 +210,14 @@
if(!ishuman(M))
return ..()
var/mob/living/carbon/human/H = M
- var/obj/item/organ/genital/penis/P = H.getorganslot(ORGAN_SLOT_PENIS)
if(!(H.client?.prefs.cit_toggles & PENIS_ENLARGEMENT))
var/obj/item/organ/liver/L = H.getorganslot(ORGAN_SLOT_LIVER)
if(L)
- L.swelling += 0.05
+ L.applyOrganDamage(0.25)
else
H.adjustToxLoss(1)
return ..()
+ var/obj/item/organ/genital/penis/P = H.getorganslot(ORGAN_SLOT_PENIS)
//otherwise proceed as normal
if(!P)//They do have a preponderance for escapism, or so I've heard.
@@ -241,7 +243,8 @@
return ..()
if(!(M.client?.prefs.cit_toggles & FORCED_MASC))
var/obj/item/organ/liver/L = M.getorganslot(ORGAN_SLOT_LIVER)
- L.swelling+= 0.05
+ if(L)
+ L.applyOrganDamage(0.25)
return..()
var/obj/item/organ/genital/breasts/B = M.getorganslot(ORGAN_SLOT_BREASTS)
@@ -278,7 +281,8 @@
var/obj/item/organ/genital/penis/P = H.getorganslot(ORGAN_SLOT_PENIS)
if(!(H.client?.prefs.cit_toggles & PENIS_ENLARGEMENT) || !P)
var/obj/item/organ/liver/L = M.getorganslot(ORGAN_SLOT_LIVER)
- L.swelling-= 0.05
+ if(L)
+ L.applyOrganDamage(-0.25)
return..()
P.modify_size(-0.1)