diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm
index b849e272e7..7a3f872666 100644
--- a/code/__DEFINES/antagonists.dm
+++ b/code/__DEFINES/antagonists.dm
@@ -72,3 +72,8 @@
#define CAT_STRUCTURE "Structures"
#define MARTIALART_HUNTER "hunter-fu"
+
+//Blob
+/// blob gets a free reroll every X time
+#define BLOB_REROLL_TIME 2400
+#define BLOB_REFLECTOR_COST 15
\ No newline at end of file
diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm
index 56cf681a27..b98431c253 100644
--- a/code/__DEFINES/components.dm
+++ b/code/__DEFINES/components.dm
@@ -206,7 +206,7 @@
#define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living)
#define COMSIG_LIVING_IGNITED "living_ignite" //from base of mob/living/IgniteMob() (/mob/living)
#define COMSIG_LIVING_EXTINGUISHED "living_extinguished" //from base of mob/living/ExtinguishMob() (/mob/living)
-#define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //from base of mob/living/electrocute_act(): (shock_damage)
+#define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //from base of mob/living/electrocute_act(): (shock_damage, source, siemens_coeff, flags)
#define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock" //sent by stuff like stunbatons and tasers: ()
#define COMSIG_LIVING_REVIVE "living_revive" //from base of mob/living/revive() (full_heal, admin_revive)
#define COMSIG_MOB_CLIENT_LOGIN "comsig_mob_client_login" //sent when a mob/login() finishes: (client)
@@ -224,6 +224,7 @@
// /mob/living/carbon signals
#define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity))
+#define COMSIG_CARBON_IDENTITY_TRANSFERRED_TO "carbon_id_transferred_to" //from datum/dna/transfer_identity(): (datum/dna, transfer_SE)
// /mob/living/simple_animal/hostile signals
#define COMSIG_HOSTILE_ATTACKINGTARGET "hostile_attackingtarget"
@@ -289,6 +290,9 @@
#define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target)
#define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker)
#define COMSIG_HUMAN_DISARM_HIT "human_disarm_hit" //Hit by successful disarm attack (mob/living/carbon/human/attacker,zone_targeted)
+#define COMSIG_HUMAN_PREFS_COPIED_TO "human_prefs_copied_to" //from datum/preferences/copy_to(): (datum/preferences, icon_updates, roundstart_checks)
+#define COMSIG_HUMAN_HARDSET_DNA "human_hardset_dna" //from mob/living/carbon/human/hardset_dna(): (ui, se, newreal_name, newblood_type, datum/species, newfeatures)
+#define COMSIG_HUMAN_ON_RANDOMIZE "humman_on_randomize" //from base of proc/randomize_human()
// /datum/species signals
#define COMSIG_SPECIES_GAIN "species_gain" //from datum/species/on_species_gain(): (datum/species/new_species, datum/species/old_species)
diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm
index c1686560d6..69e7ac99fc 100644
--- a/code/__DEFINES/mobs.dm
+++ b/code/__DEFINES/mobs.dm
@@ -210,6 +210,17 @@
#define MAX_CHICKENS 50
+///Flags used by the flags parameter of electrocute act.
+
+///Makes it so that the shock doesn't take gloves into account.
+#define SHOCK_NOGLOVES (1 << 0)
+///Used when the shock is from a tesla bolt.
+#define SHOCK_TESLA (1 << 1)
+///Used when an illusion shocks something. Makes the shock deal stamina damage and not trigger certain secondary effects.
+#define SHOCK_ILLUSION (1 << 2)
+///The shock doesn't stun.
+#define SHOCK_NOSTUN (1 << 3)
+
#define INCORPOREAL_MOVE_BASIC 1
#define INCORPOREAL_MOVE_SHADOW 2 // leaves a trail of shadows
diff --git a/code/__HELPERS/_cit_helpers.dm b/code/__HELPERS/_cit_helpers.dm
index 4ae30838e4..ffc1bcc6b7 100644
--- a/code/__HELPERS/_cit_helpers.dm
+++ b/code/__HELPERS/_cit_helpers.dm
@@ -107,38 +107,6 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE)
if(!src.holder) return
message_admins("[key_name_admin(usr)] manually reloaded mentors")
-//Flavor Text
-/mob/proc/set_flavor()
- set name = "Set Flavor Text"
- set desc = "Sets an extended description of your character's features."
- set category = "IC"
-
- var/new_flavor = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", flavor_text, MAX_FAVOR_LEN, TRUE)
- if(!isnull(new_flavor))
- flavor_text = html_decode(new_flavor)
- to_chat(src, "Your flavor text has been updated.")
-
-//Flavor Text
-/mob/proc/set_flavor_2()
- set name = "Set Temporary Flavor Text"
- set desc = "Sets a description of your character's current appearance. Use this for emotions, poses etc."
- set category = "IC"
-
- var/new_flavor = stripped_multiline_input(usr, "Set the temporary flavor text in your 'examine' verb. This should be used only for things pertaining to the current round!", "Short-Term Flavor Text", flavor_text_2, MAX_FAVOR_LEN, TRUE)
- if(!isnull(new_flavor))
- flavor_text_2 = html_decode(new_flavor)
- to_chat(src, "Your temporary flavor text has been updated.")
-
-/mob/proc/print_flavor_text(flavor,temp = FALSE)
- if(!flavor)
- return
- // We are decoding and then encoding to not only get correct amount of characters, but also to prevent partial escaping characters being shown.
- var/msg = html_decode(replacetext(flavor, "\n", " "))
- if(length_char(msg) <= 40)
- return "[html_encode(msg)]"
- else
- return "[html_encode(copytext_char(msg, 1, 37))]... More..."
-
//LOOC toggles
/client/verb/listen_looc()
set name = "Show/Hide LOOC"
diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm
index ffad931cd8..04d4c2888a 100644
--- a/code/_globalvars/lists/mobs.dm
+++ b/code/_globalvars/lists/mobs.dm
@@ -29,7 +29,6 @@ GLOBAL_LIST_EMPTY(available_ai_shells)
GLOBAL_LIST_INIT(simple_animals, list(list(),list(),list(),list())) // One for each AI_* status define
GLOBAL_LIST_EMPTY(spidermobs) //all sentient spider mobs
GLOBAL_LIST_EMPTY(bots_list)
-GLOBAL_LIST_EMPTY(living_cameras)
GLOBAL_LIST_EMPTY(aiEyes)
GLOBAL_LIST_EMPTY(language_datum_instances)
diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm
index 8257b744d6..b9118da5f1 100644
--- a/code/_onclick/hud/blob_overmind.dm
+++ b/code/_onclick/hud/blob_overmind.dm
@@ -48,7 +48,7 @@
if(isovermind(usr))
var/mob/camera/blob/B = usr
if(!B.placed)
- B.place_blob_core(B.base_point_rate, 0)
+ B.place_blob_core(0)
B.transport_core()
/obj/screen/blob/Blobbernaut
@@ -91,26 +91,26 @@
var/mob/camera/blob/B = usr
B.create_factory()
-/obj/screen/blob/ReadaptChemical
+/obj/screen/blob/ReadaptStrain
icon_state = "ui_chemswap"
- name = "Readapt Chemical (40)"
- desc = "Randomly rerolls your chemical for 40 resources."
+ name = "Readapt Strain (40)"
+ desc = "Allows you to choose a new strain from 4 random choices for 40 resources."
-/obj/screen/blob/ReadaptChemical/MouseEntered(location,control,params)
+/obj/screen/blob/ReadaptStrain/MouseEntered(location,control,params)
if(hud && hud.mymob && isovermind(hud.mymob))
var/mob/camera/blob/B = hud.mymob
- if(B.free_chem_rerolls)
- name = "Readapt Chemical (FREE)"
- desc = "Randomly rerolls your chemical for free."
+ if(B.free_strain_rerolls)
+ name = "Readapt Strain (FREE)"
+ desc = "Randomly rerolls your strain for free."
else
name = initial(name)
desc = initial(desc)
..()
-/obj/screen/blob/ReadaptChemical/Click()
+/obj/screen/blob/ReadaptStrain/Click()
if(isovermind(usr))
var/mob/camera/blob/B = usr
- B.chemical_reroll()
+ B.strain_reroll()
/obj/screen/blob/RelocateCore
icon_state = "ui_swap"
@@ -175,7 +175,7 @@
using.hud = src
static_inventory += using
- using = new /obj/screen/blob/ReadaptChemical()
+ using = new /obj/screen/blob/ReadaptStrain()
using.screen_loc = ui_storage1
using.hud = src
static_inventory += using
diff --git a/code/controllers/subsystem/mobs.dm b/code/controllers/subsystem/mobs.dm
index 56cdf2fa03..8caf2a4623 100644
--- a/code/controllers/subsystem/mobs.dm
+++ b/code/controllers/subsystem/mobs.dm
@@ -26,18 +26,16 @@ SUBSYSTEM_DEF(mobs)
var/seconds = wait * 0.1
if (!resumed)
src.currentrun = GLOB.mob_living_list.Copy()
- if (GLOB.living_cameras.len)
- src.currentrun += GLOB.living_cameras
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
var/times_fired = src.times_fired
while(currentrun.len)
- var/mob/M = currentrun[currentrun.len]
+ var/mob/living/L = currentrun[currentrun.len]
currentrun.len--
- if(M)
- M.Life(seconds, times_fired)
+ if(L)
+ L.Life(seconds, times_fired)
else
- GLOB.mob_living_list.Remove(M)
+ GLOB.mob_living_list.Remove(L)
if (MC_TICK_CHECK)
return
diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm
index e9e725faeb..20e0d647c5 100644
--- a/code/controllers/subsystem/vote.dm
+++ b/code/controllers/subsystem/vote.dm
@@ -370,7 +370,7 @@ SUBSYSTEM_DEF(vote)
var/list/runnable_storytellers = config.get_runnable_storytellers()
for(var/T in runnable_storytellers)
var/datum/dynamic_storyteller/S = T
- runnable_storytellers[S] *= scores[initial(S.name)]
+ runnable_storytellers[S] *= stored_gamemode_votes[initial(S.name)]
var/datum/dynamic_storyteller/S = pickweightAllowZero(runnable_storytellers)
GLOB.dynamic_storyteller_type = S
if("map")
diff --git a/code/datums/action.dm b/code/datums/action.dm
index f1df2a80d8..144f5f7946 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -426,6 +426,7 @@
/datum/action/item_action/hands_free
check_flags = AB_CHECK_CONSCIOUS
+ required_mobility_flags = NONE
/datum/action/item_action/hands_free/activate
name = "Activate"
diff --git a/code/datums/dna.dm b/code/datums/dna.dm
index 2f4dba9c38..2973a44a68 100644
--- a/code/datums/dna.dm
+++ b/code/datums/dna.dm
@@ -51,10 +51,11 @@
if(ishuman(destination))
var/mob/living/carbon/human/H = destination
H.give_genitals(TRUE)//This gives the body the genitals of this DNA. Used for any transformations based on DNA
- destination.flavor_text = destination.dna.features["flavor_text"] //Update the flavor_text to use new dna text
if(transfer_SE)
destination.dna.struc_enzymes = struc_enzymes
+ SEND_SIGNAL(destination, COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, src, transfer_SE)
+
/datum/dna/proc/copy_dna(datum/dna/new_dna)
new_dna.unique_enzymes = unique_enzymes
new_dna.struc_enzymes = struc_enzymes
@@ -284,7 +285,6 @@
if(newfeatures)
dna.features = newfeatures
- flavor_text = dna.features["flavor_text"] //Update the flavor_text to use new dna text
if(mrace)
var/datum/species/newrace = new mrace.type
@@ -306,6 +306,8 @@
dna.struc_enzymes = se
domutcheck()
+ SEND_SIGNAL(src, COMSIG_HUMAN_HARDSET_DNA, ui, se, newreal_name, newblood_type, mrace, newfeatures)
+
if(mrace || newfeatures || ui)
update_body()
update_hair()
diff --git a/code/datums/elements/flavor_text.dm b/code/datums/elements/flavor_text.dm
new file mode 100644
index 0000000000..54729d5f83
--- /dev/null
+++ b/code/datums/elements/flavor_text.dm
@@ -0,0 +1,146 @@
+GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code
+
+/datum/element/flavor_text
+ element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH
+ id_arg_index = 3
+ var/flavor_name = "Flavor Text"
+ var/list/texts_by_atom = list()
+ var/addendum = "This can also be used for OOC notes and preferences!"
+ var/always_show = FALSE
+ var/max_len = MAX_FAVOR_LEN
+ var/can_edit = TRUE
+
+/datum/element/flavor_text/Attach(datum/target, text = "", _name = "Flavor Text", _addendum, _max_len = MAX_FAVOR_LEN, _always_show = FALSE, _edit = TRUE)
+ . = ..()
+
+ if(. == ELEMENT_INCOMPATIBLE || !isatom(target)) //no reason why this shouldn't work on atoms too.
+ return ELEMENT_INCOMPATIBLE
+
+ if(_max_len)
+ max_len = _max_len
+ texts_by_atom[target] = copytext(text, 1, max_len)
+ if(_name)
+ flavor_name = _name
+ if(!isnull(addendum))
+ addendum = _addendum
+ always_show = _always_show
+ can_edit = _edit
+
+ RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/show_flavor)
+
+ if(can_edit && ismob(target)) //but only mobs receive the proc/verb for the time being
+ var/mob/M = target
+ LAZYOR(GLOB.mobs_with_editable_flavor_text[M], src)
+ M.verbs |= /mob/proc/manage_flavor_tests
+
+/datum/element/flavor_text/Detach(atom/A)
+ . = ..()
+ UnregisterSignal(A, COMSIG_PARENT_EXAMINE)
+ texts_by_atom -= A
+ if(can_edit && ismob(A))
+ var/mob/M = A
+ LAZYREMOVE(GLOB.mobs_with_editable_flavor_text[M], src)
+ if(!GLOB.mobs_with_editable_flavor_text[M])
+ GLOB.mobs_with_editable_flavor_text -= M
+ M.verbs -= /mob/proc/manage_flavor_tests
+
+/datum/element/flavor_text/proc/show_flavor(atom/target, mob/user, list/examine_list)
+ if(!always_show && isliving(target))
+ var/mob/living/L = target
+ var/unknown = L.get_visible_name() == "Unknown"
+ if(!unknown && iscarbon(target))
+ var/mob/living/carbon/C = L
+ unknown = (C.wear_mask && (C.wear_mask.flags_inv & HIDEFACE)) || (C.head && (C.head.flags_inv & HIDEFACE))
+ if(unknown)
+ if(!("...?" in examine_list)) //can't think of anything better in case of multiple flavor texts.
+ examine_list += "...?"
+ return
+ var/text = texts_by_atom[target]
+ if(!text)
+ return
+ var/msg = replacetext(text, "\n", " ")
+ if(length_char(msg) <= 40)
+ examine_list += "[html_encode(msg)]"
+ else
+ examine_list += "[html_encode(copytext_char(msg, 1, 37))]... More..."
+
+/datum/element/flavor_text/Topic(href, href_list)
+ . = ..()
+ if(.)
+ return
+ if(href_list["show_flavor"])
+ var/atom/target = locate(href_list["show_flavor"])
+ var/text = texts_by_atom[target]
+ if(text)
+ usr << browse("
[target.name][replacetext(texts_by_atom[target], "\n", "
")]", "window=[target.name];size=500x200")
+ onclose(usr, "[target.name]")
+ return TRUE
+
+/mob/proc/manage_flavor_tests()
+ set name = "Manage Flavor Texts"
+ set desc = "Used to manage your various flavor texts."
+ set category = "IC"
+
+ var/list/L = GLOB.mobs_with_editable_flavor_text[src]
+
+ if(length(L) == 1)
+ var/datum/element/flavor_text/F = L[1]
+ F.set_flavor(src)
+ return
+
+ var/list/choices = list()
+
+ for(var/i in L)
+ var/datum/element/flavor_text/F = i
+ choices[F.flavor_name] = F
+
+ var/chosen = input(src, "Which flavor text would you like to modify?") as null|anything in choices
+ if(!chosen)
+ return
+ var/datum/element/flavor_text/F = choices[chosen]
+ F.set_flavor(src)
+
+/datum/element/flavor_text/proc/set_flavor(mob/user)
+ if(!(user in texts_by_atom))
+ return FALSE
+
+ var/lower_name = lowertext(flavor_name)
+ var/new_text = stripped_multiline_input(user, "Set the [lower_name] displayed on 'examine'. [addendum]", flavor_name, texts_by_atom[usr], max_len, TRUE)
+ if(!isnull(new_text) && (user in texts_by_atom))
+ texts_by_atom[user] = html_decode(new_text)
+ to_chat(src, "Your [lower_name] has been updated.")
+ return TRUE
+ return FALSE
+
+//subtypes with additional hooks for DNA and preferences.
+/datum/element/flavor_text/carbon
+
+/datum/element/flavor_text/carbon/Attach(datum/target, text = "", _name = "Flavor Text", _addendum, _max_len = MAX_FAVOR_LEN, _always_show = FALSE, _edit = TRUE)
+ if(!iscarbon(target))
+ return ELEMENT_INCOMPATIBLE
+ . = ..()
+ if(. == ELEMENT_INCOMPATIBLE)
+ return
+ RegisterSignal(target, COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, .proc/update_dna_flavor_text)
+ if(ishuman(target))
+ RegisterSignal(target, COMSIG_HUMAN_PREFS_COPIED_TO, .proc/update_prefs_flavor_text)
+ RegisterSignal(target, COMSIG_HUMAN_HARDSET_DNA, .proc/update_dna_flavor_text)
+ RegisterSignal(target, COMSIG_HUMAN_ON_RANDOMIZE, .proc/unset_flavor)
+
+/datum/element/flavor_text/carbon/Detach(mob/living/carbon/C)
+ . = ..()
+ UnregisterSignal(C, list(COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, COMSIG_HUMAN_PREFS_COPIED_TO, COMSIG_HUMAN_HARDSET_DNA, COMSIG_HUMAN_ON_RANDOMIZE))
+
+/datum/element/flavor_text/carbon/proc/update_dna_flavor_text(mob/living/carbon/C)
+ texts_by_atom[C] = C.dna.features["flavor_text"]
+
+/datum/element/flavor_text/carbon/proc/update_prefs_flavor_text(mob/living/carbon/human/H, datum/preferences/P, icon_updates = TRUE, roundstart_checks = TRUE)
+ texts_by_atom[H] = P.features["flavor_text"]
+
+/datum/element/flavor_text/carbon/set_flavor(mob/living/carbon/user)
+ . = ..()
+ if(. && user.dna)
+ user.dna.features["flavor_text"] = texts_by_atom[user]
+
+/datum/element/flavor_text/carbon/proc/unset_flavor(mob/living/carbon/user)
+ texts_by_atom[user] = ""
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index 5fe141d2cd..bd81b79694 100755
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -15,6 +15,7 @@
var/message_cooldown = 0
var/ai_message_cooldown = 0
var/tmp_alertlevel = 0
+ var/static/security_level_cd // used to stop mass spam.
var/const/STATE_DEFAULT = 1
var/const/STATE_CALLSHUTTLE = 2
var/const/STATE_CANCELSHUTTLE = 3
@@ -94,16 +95,18 @@
I = pda.id
if (I && istype(I))
if(ACCESS_CAPTAIN in I.access)
+ if(security_level_cd > world.time)
+ to_chat(usr, "Security level protocols are currently on cooldown. Please stand by.")
+ return
var/old_level = GLOB.security_level
if(!tmp_alertlevel)
tmp_alertlevel = SEC_LEVEL_GREEN
if(tmp_alertlevel < SEC_LEVEL_GREEN)
tmp_alertlevel = SEC_LEVEL_GREEN
- if(tmp_alertlevel == SEC_LEVEL_BLUE)
- tmp_alertlevel = SEC_LEVEL_BLUE
if(tmp_alertlevel > SEC_LEVEL_AMBER)
tmp_alertlevel = SEC_LEVEL_AMBER //Cannot engage delta with this
set_security_level(tmp_alertlevel)
+ security_level_cd = world.time + 15 SECONDS
if(GLOB.security_level != old_level)
to_chat(usr, "Authorization confirmed. Modifying security level.")
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
@@ -376,19 +379,21 @@
if("ai-announce")
make_announcement(usr, 1)
if("ai-securitylevel")
+ if(security_level_cd > world.time)
+ to_chat(usr, "Security level protocols are currently on cooldown. Please stand by.")
+ return
tmp_alertlevel = text2num( href_list["newalertlevel"] )
if(!tmp_alertlevel)
- tmp_alertlevel = 0
+ tmp_alertlevel = SEC_LEVEL_GREEN
var/old_level = GLOB.security_level
if(!tmp_alertlevel)
tmp_alertlevel = SEC_LEVEL_GREEN
if(tmp_alertlevel < SEC_LEVEL_GREEN)
tmp_alertlevel = SEC_LEVEL_GREEN
- if(tmp_alertlevel == SEC_LEVEL_BLUE)
- tmp_alertlevel = SEC_LEVEL_BLUE
if(tmp_alertlevel > SEC_LEVEL_AMBER)
tmp_alertlevel = SEC_LEVEL_AMBER //Cannot engage delta with this
set_security_level(tmp_alertlevel)
+ security_level_cd = world.time + 15 SECONDS
if(GLOB.security_level != old_level)
//Only notify people if an actual change happened
var/security_level = get_security_level()
diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm
index 8c3ffa3cfc..e75a18dca8 100644
--- a/code/game/objects/effects/anomalies.dm
+++ b/code/game/objects/effects/anomalies.dm
@@ -138,13 +138,13 @@
name = "flux wave anomaly"
icon_state = "electricity2"
density = TRUE
- var/canshock = 0
+ var/canshock = FALSE
var/shockdamage = 20
var/explosive = TRUE
/obj/effect/anomaly/flux/anomalyEffect()
..()
- canshock = 1
+ canshock = TRUE
for(var/mob/living/M in range(0, src))
mobShock(M)
@@ -159,18 +159,8 @@
/obj/effect/anomaly/flux/proc/mobShock(mob/living/M)
if(canshock && istype(M))
- canshock = 0 //Just so you don't instakill yourself if you slam into the anomaly five times in a second.
- if(iscarbon(M))
- if(ishuman(M))
- M.electrocute_act(shockdamage, "[name]", safety=1)
- return
- M.electrocute_act(shockdamage, "[name]")
- return
- else
- M.adjustFireLoss(shockdamage)
- M.visible_message("[M] was shocked by \the [name]!", \
- "You feel a powerful shock coursing through your body!", \
- "You hear a heavy electrical crack.")
+ canshock = FALSE //Just so you don't instakill yourself if you slam into the anomaly five times in a second.
+ M.electrocute_act(shockdamage, "[name]", flags = SHOCK_NOGLOVES)
/obj/effect/anomaly/flux/detonate()
if(explosive)
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index 677502e069..9d0d5a0445 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -230,7 +230,7 @@ GLOBAL_LIST_EMPTY(PDAs)
var/mutable_appearance/overlay = mutable_appearance(icon, screen_state)
overlay.pixel_x = overlays_x_offset
overlay.pixel_y = overlays_y_offset
- . += overlay
+ . += new /mutable_appearance(overlay)
if(id)
overlay.icon_state = current_overlays[PDA_OVERLAY_ID]
. += new /mutable_appearance(overlay)
@@ -242,7 +242,7 @@ GLOBAL_LIST_EMPTY(PDAs)
. += new /mutable_appearance(overlay)
if(pai)
overlay.icon_state = "[current_overlays[PDA_OVERLAY_PAI]][pai.pai ? "" : "_off"]"
- . += new /mutable_appearance(overlay)
+ . += overlay
new_overlays = FALSE
new_alert = FALSE
diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm
index ea7d57255f..e1b0cbb661 100644
--- a/code/game/objects/items/handcuffs.dm
+++ b/code/game/objects/items/handcuffs.dm
@@ -342,15 +342,25 @@
/obj/item/restraints/legcuffs/bola/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(..() || !iscarbon(hit_atom))//if it gets caught or the target can't be cuffed,
return//abort
- var/mob/living/carbon/C = hit_atom
+ ensnare(hit_atom)
+
+/**
+ * Attempts to legcuff someone with the bola
+ *
+ * Arguments:
+ * * C - the carbon that we will try to ensnare
+ */
+/obj/item/restraints/legcuffs/bola/proc/ensnare(mob/living/carbon/C)
if(!C.legcuffed && C.get_num_legs(FALSE) >= 2)
visible_message("\The [src] ensnares [C]!")
C.legcuffed = src
forceMove(C)
+ C.update_equipment_speed_mods()
C.update_inv_legcuffed()
SSblackbox.record_feedback("tally", "handcuffs", 1, type)
to_chat(C, "\The [src] ensnares you!")
- C.DefaultCombatKnockdown(knockdown)
+ C.Knockdown(knockdown)
+ playsound(src, 'sound/effects/snap.ogg', 50, TRUE)
/obj/item/restraints/legcuffs/bola/tactical//traitor variant
name = "reinforced bola"
diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm
index d3e966f2fa..32e07284ec 100644
--- a/code/game/objects/items/robot/robot_items.dm
+++ b/code/game/objects/items/robot/robot_items.dm
@@ -109,7 +109,7 @@
if(scooldown < world.time)
if(M.health >= 0)
if(ishuman(M)||ismonkey(M))
- M.electrocute_act(5, "[user]", safety = 1)
+ M.electrocute_act(5, "[user]", flags = SHOCK_NOGLOVES)
user.visible_message("[user] electrocutes [M] with [user.p_their()] touch!", \
"You electrocute [M] with your touch!")
else
diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index 6cb351cb74..6865660d0b 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -464,6 +464,7 @@ GLOBAL_LIST_INIT(cardboard_recipes, list ( \
new /datum/stack_recipe("egg box", /obj/item/storage/fancy/egg_box), \
new /datum/stack_recipe("donk-pockets box", /obj/item/storage/box/donkpockets), \
new /datum/stack_recipe("monkey cube box", /obj/item/storage/box/monkeycubes), \
+ new /datum/stack_recipe("nugget box", /obj/item/storage/fancy/nugget_box), \
new /datum/stack_recipe("box (internals)", /obj/item/storage/box/otwo), \
null, \
new /datum/stack_recipe("security-styled box", /obj/item/storage/box/seclooking), \
diff --git a/code/game/objects/items/storage/fancy.dm b/code/game/objects/items/storage/fancy.dm
index f2c50b359e..3bc90d3615 100644
--- a/code/game/objects/items/storage/fancy.dm
+++ b/code/game/objects/items/storage/fancy.dm
@@ -357,6 +357,20 @@
STR.max_items = 8
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/tinychocolate))
+/obj/item/storage/fancy/nugget_box
+ name = "nugget box"
+ desc = "A cardboard box used for holding chicken nuggies."
+ icon = 'icons/obj/food/containers.dmi'
+ icon_state = "nuggetbox"
+ icon_type = "nugget"
+ spawn_type = /obj/item/reagent_containers/food/snacks/nugget
+
+/obj/item/storage/fancy/nugget_box/ComponentInitialize()
+ . = ..()
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
+ STR.max_items = 6
+ STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/nugget))
+
/*
* Ring Box
*/
diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm
index 2fd6cf9f4c..e582aa7e67 100644
--- a/code/game/objects/obj_defense.dm
+++ b/code/game/objects/obj_defense.dm
@@ -244,7 +244,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
if(has_buckled_mobs())
for(var/m in buckled_mobs)
var/mob/living/buckled_mob = m
- buckled_mob.electrocute_act((CLAMP(round(strength/400), 10, 90) + rand(-5, 5)), src, tesla_shock = 1)
+ buckled_mob.electrocute_act((CLAMP(round(strength/400), 10, 90) + rand(-5, 5)), src, flags = SHOCK_TESLA)
/obj/proc/reset_shocked()
obj_flags &= ~BEING_SHOCKED
diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm
index fcd1f80a4f..3e35c12314 100644
--- a/code/game/objects/structures/ai_core.dm
+++ b/code/game/objects/structures/ai_core.dm
@@ -255,7 +255,7 @@
return
return ..()
-/obj/structure/AIcore/update_icon()
+/obj/structure/AIcore/update_icon_state()
switch(state)
if(EMPTY_CORE)
icon_state = "0"
diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm
index 32e40bedec..a793459c5d 100644
--- a/code/game/objects/structures/aliens.dm
+++ b/code/game/objects/structures/aliens.dm
@@ -234,8 +234,7 @@
if(status == BURST)
obj_integrity = integrity_failure * max_integrity
-/obj/structure/alien/egg/update_icon()
- ..()
+/obj/structure/alien/egg/update_icon_state()
switch(status)
if(GROWING)
icon_state = "[base_icon]_growing"
diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm
index 8dc7caa5ad..0991351102 100644
--- a/code/game/objects/structures/bedsheet_bin.dm
+++ b/code/game/objects/structures/bedsheet_bin.dm
@@ -303,7 +303,7 @@ LINEN BINS
. += "There are [amount] sheets in the bin."
-/obj/structure/bedsheetbin/update_icon()
+/obj/structure/bedsheetbin/update_icon_state()
switch(amount)
if(0)
icon_state = "linenbin-empty"
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index c932dd96e8..e19feea582 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -58,30 +58,40 @@
return ..()
/obj/structure/closet/update_icon()
- cut_overlays()
- if(opened & icon_door_override)
- add_overlay("[icon_door]_open")
+ . = ..()
+ if(!opened)
layer = OBJ_LAYER
- return
- else if(opened)
- add_overlay("[icon_state]_open")
- return
- if(icon_door)
- add_overlay("[icon_door]_door")
else
layer = BELOW_OBJ_LAYER
- add_overlay("[icon_state]_door")
- if(welded)
- add_overlay("welded")
- if(!secure)
- return
- if(broken)
- add_overlay("off")
- add_overlay("sparking")
- else if(locked)
- add_overlay("locked")
+
+/obj/structure/closet/update_overlays()
+ . = ..()
+ closet_update_overlays(.)
+
+/obj/structure/closet/proc/closet_update_overlays(list/new_overlays)
+ . = new_overlays
+ if(!opened)
+ if(icon_door)
+ . += "[icon_door]_door"
+ else
+ . += "[icon_state]_door"
+ if(welded)
+ . += "welded"
+ if(!secure)
+ return
+ if(broken)
+ . += "off"
+ . += "sparking"
+ else if(locked)
+ . += "locked"
+ else
+ . += "unlocked"
else
- add_overlay("unlocked")
+ if(icon_door_override)
+ . += "[icon_door]_open"
+ else
+ . += "[icon_state]_open"
+
/obj/structure/closet/examine(mob/user)
. = ..()
diff --git a/code/game/objects/structures/crates_lockers/closets/bodybag.dm b/code/game/objects/structures/crates_lockers/closets/bodybag.dm
index 1c34850274..5ec3851128 100644
--- a/code/game/objects/structures/crates_lockers/closets/bodybag.dm
+++ b/code/game/objects/structures/crates_lockers/closets/bodybag.dm
@@ -38,10 +38,10 @@
tagged = 0
update_icon()
-/obj/structure/closet/body_bag/update_icon()
- ..()
+/obj/structure/closet/body_bag/update_overlays()
+ . = ..()
if (tagged)
- add_overlay("bodybag_label")
+ . += "bodybag_label"
/obj/structure/closet/body_bag/close()
if(..())
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index 4f6d6729fc..b0dfec6318 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -33,12 +33,13 @@
return 1
return !density
-/obj/structure/closet/crate/update_icon()
+/obj/structure/closet/crate/update_icon_state()
icon_state = "[initial(icon_state)][opened ? "open" : ""]"
- cut_overlays()
+/obj/structure/closet/crate/closet_update_overlays(list/new_overlays)
+ . = new_overlays
if(manifest)
- add_overlay("manifest")
+ . += "manifest"
/obj/structure/closet/crate/attack_hand(mob/user)
. = ..()
diff --git a/code/game/objects/structures/crates_lockers/crates/bins.dm b/code/game/objects/structures/crates_lockers/crates/bins.dm
index bc3697a550..b57af43d3e 100644
--- a/code/game/objects/structures/crates_lockers/crates/bins.dm
+++ b/code/game/objects/structures/crates_lockers/crates/bins.dm
@@ -14,15 +14,15 @@
..()
update_icon()
-/obj/structure/closet/crate/bin/update_icon()
- ..()
+/obj/structure/closet/crate/bin/closet_update_overlays(list/new_overlays)
+ . = new_overlays
cut_overlays()
if(contents.len == 0)
- add_overlay("largebing")
+ . += "largebing"
else if(contents.len >= storage_capacity)
- add_overlay("largebinr")
+ . += "largebinr"
else
- add_overlay("largebino")
+ . += "largebino"
/obj/structure/closet/crate/bin/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/storage/bag/trash))
diff --git a/code/game/objects/structures/crates_lockers/crates/critter.dm b/code/game/objects/structures/crates_lockers/crates/critter.dm
index 3c0021b513..3dbbfd5c23 100644
--- a/code/game/objects/structures/crates_lockers/crates/critter.dm
+++ b/code/game/objects/structures/crates_lockers/crates/critter.dm
@@ -22,14 +22,14 @@
return ..()
-/obj/structure/closet/crate/critter/update_icon()
- cut_overlays()
+/obj/structure/closet/crate/critter/closet_update_overlays(list/new_overlays)
+ . = new_overlays
if(opened)
- add_overlay("crittercrate_door_open")
+ . += "crittercrate_door_open"
else
- add_overlay("crittercrate_door")
+ . += "crittercrate_door"
if(manifest)
- add_overlay("manifest")
+ . += "manifest"
/obj/structure/closet/crate/critter/return_air()
if(tank)
diff --git a/code/game/objects/structures/crates_lockers/crates/secure.dm b/code/game/objects/structures/crates_lockers/crates/secure.dm
index 602adfb367..4ac69253d3 100644
--- a/code/game/objects/structures/crates_lockers/crates/secure.dm
+++ b/code/game/objects/structures/crates_lockers/crates/secure.dm
@@ -13,14 +13,14 @@
return 0
. = ..()
-/obj/structure/closet/crate/secure/update_icon()
- ..()
+/obj/structure/closet/crate/secure/update_overlays()
+ . += ..()
if(broken)
- add_overlay("securecrateemag")
+ . += "securecrateemag"
else if(locked)
- add_overlay("securecrater")
+ . += "securecrater"
else
- add_overlay("securecrateg")
+ . += "securecrateg"
/obj/structure/closet/crate/secure/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1)
if(prob(tamperproof) && damage_amount >= DAMAGE_PRECISION)
diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm
index 8a5b678f22..c332a07edf 100644
--- a/code/game/objects/structures/displaycase.dm
+++ b/code/game/objects/structures/displaycase.dm
@@ -84,7 +84,7 @@
alarmed.burglaralert(src)
playsound(src, 'sound/effects/alert.ogg', 50, 1)
-/obj/structure/displaycase/update_icon()
+/obj/structure/displaycase/update_icon_state()
var/icon/I
if(open)
I = icon('icons/obj/stationobjs.dmi',"glassbox_open")
diff --git a/code/game/objects/structures/divine.dm b/code/game/objects/structures/divine.dm
index 1da8a26b52..bca96e67d1 100644
--- a/code/game/objects/structures/divine.dm
+++ b/code/game/objects/structures/divine.dm
@@ -44,7 +44,7 @@
addtimer(CALLBACK(src, /atom/.proc/update_icon), time_between_uses)
-/obj/structure/healingfountain/update_icon()
+/obj/structure/healingfountain/update_icon_state()
if(last_process + time_between_uses > world.time)
icon_state = "fountain"
else
diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm
index f35e9e7d55..79600d5bf2 100644
--- a/code/game/objects/structures/door_assembly.dm
+++ b/code/game/objects/structures/door_assembly.dm
@@ -260,13 +260,13 @@
update_name()
update_icon()
-/obj/structure/door_assembly/update_icon()
- cut_overlays()
+/obj/structure/door_assembly/update_overlays()
+ . = ..()
if(!glass)
- add_overlay(get_airlock_overlay("fill_construction", icon))
+ . += get_airlock_overlay("fill_construction", icon)
else if(glass)
- add_overlay(get_airlock_overlay("glass_construction", overlays_file))
- add_overlay(get_airlock_overlay("panel_c[state+1]", overlays_file))
+ . += get_airlock_overlay("glass_construction", overlays_file)
+ . += get_airlock_overlay("panel_c[state+1]", overlays_file)
/obj/structure/door_assembly/proc/update_name()
name = ""
diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm
index 2124c83d7d..9b736517be 100644
--- a/code/game/objects/structures/extinguisher.dm
+++ b/code/game/objects/structures/extinguisher.dm
@@ -116,7 +116,7 @@
opened = !opened
update_icon()
-/obj/structure/extinguisher_cabinet/update_icon()
+/obj/structure/extinguisher_cabinet/update_icon_state()
if(!opened)
icon_state = "extinguisher_closed"
return
diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm
index 52441c2987..e44698f96e 100644
--- a/code/game/objects/structures/false_walls.dm
+++ b/code/game/objects/structures/false_walls.dm
@@ -64,7 +64,7 @@
update_icon()
air_update_turf(TRUE)
-/obj/structure/falsewall/update_icon()//Calling icon_update will refresh the smoothwalls if it's closed, otherwise it will make sure the icon is correct if it's open
+/obj/structure/falsewall/update_icon_state()//Calling icon_update will refresh the smoothwalls if it's closed, otherwise it will make sure the icon is correct if it's open
if(opening)
if(density)
icon_state = "fwall_opening"
diff --git a/code/game/objects/structures/fireaxe.dm b/code/game/objects/structures/fireaxe.dm
index 8457a397a9..0f3a23dd0f 100644
--- a/code/game/objects/structures/fireaxe.dm
+++ b/code/game/objects/structures/fireaxe.dm
@@ -140,30 +140,30 @@
update_icon()
return
-/obj/structure/fireaxecabinet/update_icon()
- cut_overlays()
+/obj/structure/fireaxecabinet/update_overlays()
+ . = ..()
if(fireaxe)
- add_overlay("axe")
+ . += "axe"
if(!open)
var/hp_percent = obj_integrity/max_integrity * 100
if(broken)
- add_overlay("glass4")
+ . += "glass4"
else
switch(hp_percent)
if(-INFINITY to 40)
- add_overlay("glass3")
+ . += "glass3"
if(40 to 60)
- add_overlay("glass2")
+ . += "glass2"
if(60 to 80)
- add_overlay("glass1")
+ . += "glass1"
if(80 to INFINITY)
- add_overlay("glass")
+ . += "glass"
if(locked)
- add_overlay("locked")
+ . += "locked"
else
- add_overlay("unlocked")
+ . += "unlocked"
else
- add_overlay("glass_raised")
+ . += "glass_raised"
/obj/structure/fireaxecabinet/proc/toggle_lock(mob/user)
to_chat(user, " Resetting circuitry...")
diff --git a/code/game/objects/structures/fireplace.dm b/code/game/objects/structures/fireplace.dm
index b670fe5cf0..ee8f285230 100644
--- a/code/game/objects/structures/fireplace.dm
+++ b/code/game/objects/structures/fireplace.dm
@@ -69,21 +69,22 @@
else
. = ..()
-/obj/structure/fireplace/update_icon()
- cut_overlays()
- if(lit)
- switch(burn_time_remaining())
- if(0 to 500)
- add_overlay("fireplace_fire0")
- if(500 to 1000)
- add_overlay("fireplace_fire1")
- if(1000 to 1500)
- add_overlay("fireplace_fire2")
- if(1500 to 2000)
- add_overlay("fireplace_fire3")
- if(2000 to MAXIMUM_BURN_TIMER)
- add_overlay("fireplace_fire4")
- add_overlay("fireplace_glow")
+/obj/structure/fireplace/update_overlays()
+ . = ..()
+ if(!lit)
+ return
+ switch(burn_time_remaining())
+ if(0 to 500)
+ . += "fireplace_fire0"
+ if(500 to 1000)
+ . += "fireplace_fire1"
+ if(1000 to 1500)
+ . += "fireplace_fire2"
+ if(1500 to 2000)
+ . += "fireplace_fire3"
+ if(2000 to MAXIMUM_BURN_TIMER)
+ . += "fireplace_fire4"
+ . += "fireplace_glow"
/obj/structure/fireplace/proc/adjust_light()
if(!lit)
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index 0f43040c87..61983dcb4f 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -22,7 +22,7 @@
. = ..()
update_icon()
-/obj/structure/grille/update_icon()
+/obj/structure/grille/update_icon_state()
if(QDELETED(src) || broken)
return
diff --git a/code/game/objects/structures/guncase.dm b/code/game/objects/structures/guncase.dm
index 701a4d071c..ede7e31e0d 100644
--- a/code/game/objects/structures/guncase.dm
+++ b/code/game/objects/structures/guncase.dm
@@ -22,17 +22,17 @@
break
update_icon()
-/obj/structure/guncase/update_icon()
- cut_overlays()
+/obj/structure/guncase/update_overlays()
+ . = ..()
if(case_type && LAZYLEN(contents))
var/mutable_appearance/gun_overlay = mutable_appearance(icon, case_type)
for(var/i in 1 to contents.len)
gun_overlay.pixel_x = 3 * (i - 1)
- add_overlay(gun_overlay)
+ . += gun_overlay
if(open)
- add_overlay("[icon_state]_open")
+ . += "[icon_state]_open"
else
- add_overlay("[icon_state]_door")
+ . += "[icon_state]_door"
/obj/structure/guncase/attackby(obj/item/I, mob/user, params)
if(iscyborg(user) || isalien(user))
diff --git a/code/game/objects/structures/headpike.dm b/code/game/objects/structures/headpike.dm
index 81433b562d..581ce850de 100644
--- a/code/game/objects/structures/headpike.dm
+++ b/code/game/objects/structures/headpike.dm
@@ -28,14 +28,14 @@
. = ..()
pixel_x = rand(-8, 8)
-/obj/structure/headpike/update_icon()
- ..()
+/obj/structure/headpike/update_overlays()
+ . = ..()
var/obj/item/bodypart/head/H = locate() in contents
- var/mutable_appearance/MA = new()
if(H)
+ var/mutable_appearance/MA = new()
MA.copy_overlays(H)
MA.pixel_y = 12
- add_overlay(H)
+ . += H
/obj/structure/headpike/attack_hand(mob/user)
. = ..()
diff --git a/code/game/objects/structures/holosign.dm b/code/game/objects/structures/holosign.dm
index fc1e642468..7ac3aba246 100644
--- a/code/game/objects/structures/holosign.dm
+++ b/code/game/objects/structures/holosign.dm
@@ -189,7 +189,7 @@
if(!shockcd)
if(ismob(user))
var/mob/living/M = user
- M.electrocute_act(15,"Energy Barrier", safety=1)
+ M.electrocute_act(15,"Energy Barrier", flags = SHOCK_NOGLOVES)
shockcd = TRUE
addtimer(CALLBACK(src, .proc/cooldown), 5)
@@ -201,6 +201,6 @@
return
var/mob/living/M = AM
- M.electrocute_act(15,"Energy Barrier", safety=1)
+ M.electrocute_act(15,"Energy Barrier", flags = SHOCK_NOGLOVES)
shockcd = TRUE
addtimer(CALLBACK(src, .proc/cooldown), 5)
diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm
index 58c8a739dc..b10ca8002c 100644
--- a/code/game/objects/structures/janicart.dm
+++ b/code/game/objects/structures/janicart.dm
@@ -161,20 +161,20 @@
updateUsrDialog()
-/obj/structure/janitorialcart/update_icon()
- cut_overlays()
+/obj/structure/janitorialcart/update_overlays()
+ . = ..()
if(mybag)
- add_overlay("cart_garbage")
+ . += "cart_garbage"
if(mymop)
- add_overlay("cart_mop")
+ . += "cart_mop"
if(mybroom)
- add_overlay("cart_broom")
+ . += "cart_broom"
if(myspray)
- add_overlay("cart_spray")
+ . += "cart_spray"
if(myreplacer)
- add_overlay("cart_replacer")
+ . += "cart_replacer"
if(signs)
- add_overlay("cart_sign[signs]")
+ . += "cart_sign[signs]"
if(reagents.total_volume > 0)
- add_overlay("cart_water")
+ . += "cart_water"
diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm
index b3f415bafe..53a1f609d1 100644
--- a/code/game/objects/structures/ladders.dm
+++ b/code/game/objects/structures/ladders.dm
@@ -55,7 +55,7 @@
down.update_icon()
up = down = null
-/obj/structure/ladder/update_icon()
+/obj/structure/ladder/update_icon_state()
if(up && down)
icon_state = "ladder11"
diff --git a/code/game/objects/structures/life_candle.dm b/code/game/objects/structures/life_candle.dm
index 0ae0e29459..a64dc6c6a9 100644
--- a/code/game/objects/structures/life_candle.dm
+++ b/code/game/objects/structures/life_candle.dm
@@ -46,7 +46,7 @@
STOP_PROCESSING(SSobj, src)
set_light(0)
-/obj/structure/life_candle/update_icon()
+/obj/structure/life_candle/update_icon_state()
if(linked_minds.len)
icon_state = icon_state_active
else
diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm
index caad9e7bd4..f52fa0576a 100644
--- a/code/game/objects/structures/mineral_doors.dm
+++ b/code/game/objects/structures/mineral_doors.dm
@@ -118,7 +118,7 @@
update_icon()
isSwitchingStates = 0
-/obj/structure/mineral_door/update_icon()
+/obj/structure/mineral_door/update_icon_state()
if(state)
icon_state = "[initial_state]open"
else
diff --git a/code/game/objects/structures/mop_bucket.dm b/code/game/objects/structures/mop_bucket.dm
index a9e12c1404..e1bb143fef 100644
--- a/code/game/objects/structures/mop_bucket.dm
+++ b/code/game/objects/structures/mop_bucket.dm
@@ -23,7 +23,7 @@
else
return ..()
-/obj/structure/mopbucket/update_icon()
- cut_overlays()
+/obj/structure/mopbucket/update_overlays()
+ . = ..()
if(reagents.total_volume > 0)
- add_overlay("mopbucket_water")
\ No newline at end of file
+ . += "mopbucket_water"
\ No newline at end of file
diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm
index bf891ef223..8cf5b1ee66 100644
--- a/code/game/objects/structures/morgue.dm
+++ b/code/game/objects/structures/morgue.dm
@@ -45,9 +45,6 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
..()
update_icon()
-/obj/structure/bodycontainer/update_icon()
- return
-
/obj/structure/bodycontainer/relaymove(mob/user)
if(user.stat || !isturf(loc))
return
@@ -174,7 +171,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
to_chat(user, "You turn the speaker function [beeper ? "on" : "off"].")
return TRUE
-/obj/structure/bodycontainer/morgue/update_icon()
+/obj/structure/bodycontainer/morgue/update_icon_state()
if (!connected || connected.loc != src) // Open or tray is gone.
icon_state = "morgue0"
else
@@ -228,20 +225,17 @@ GLOBAL_LIST_EMPTY(crematoriums)
GLOB.crematoriums.Add(src)
..()
-/obj/structure/bodycontainer/crematorium/update_icon()
+/obj/structure/bodycontainer/crematorium/update_icon_state()
if(!connected || connected.loc != src)
icon_state = "crema0"
else
-
- if(src.contents.len > 1)
- src.icon_state = "crema2"
+ if(contents.len > 1)
+ icon_state = "crema2"
else
- src.icon_state = "crema1"
+ icon_state = "crema1"
if(locked)
- src.icon_state = "crema_active"
-
- return
+ icon_state = "crema_active"
/obj/structure/bodycontainer/crematorium/proc/cremate(mob/user)
if(locked)
diff --git a/code/game/objects/structures/musician.dm b/code/game/objects/structures/musician.dm
index bdc7825feb..bba51035fe 100644
--- a/code/game/objects/structures/musician.dm
+++ b/code/game/objects/structures/musician.dm
@@ -203,7 +203,8 @@
if(lines.len)
var/bpm_string = "BPM: "
if(findtext(lines[1], bpm_string, 1, length(bpm_string) + 1))
- tempo = sanitize_tempo(600 / text2num(copytext(lines[1], length(bpm_string) + 1)))
+ var/divisor = text2num(copytext(lines[1], length(bpm_string) + 1)) || 120 // default
+ tempo = sanitize_tempo(600 / round(divisor, 1))
lines.Cut(1, 2)
else
tempo = sanitize_tempo(5) // default 120 BPM
diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm
index 92c4d0a066..2a7fc9aeb6 100644
--- a/code/game/objects/structures/safe.dm
+++ b/code/game/objects/structures/safe.dm
@@ -13,7 +13,7 @@ FLOOR SAFES
anchored = TRUE
density = TRUE
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
- interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_UI_INTERACT
+ interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_UI_INTERACT
var/open = FALSE //is the safe open?
var/tumbler_1_pos //the tumbler position- from 0 to 72
var/tumbler_1_open //the tumbler position to open at- 0 to 72
@@ -73,7 +73,7 @@ FLOOR SAFES
num = 0
return num
-/obj/structure/safe/update_icon()
+/obj/structure/safe/update_icon_state()
if(open)
icon_state = "[initial(icon_state)]-open"
else
diff --git a/code/game/objects/structures/stairs.dm b/code/game/objects/structures/stairs.dm
index f2c4e628e0..d1a2a6f9f6 100644
--- a/code/game/objects/structures/stairs.dm
+++ b/code/game/objects/structures/stairs.dm
@@ -54,7 +54,7 @@
return FALSE
return ..()
-/obj/structure/stairs/update_icon()
+/obj/structure/stairs/update_icon_state()
if(isTerminator())
icon_state = "stairs_t"
else
diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm
index 5fabcafd75..6a8175b921 100644
--- a/code/game/objects/structures/tank_dispenser.dm
+++ b/code/game/objects/structures/tank_dispenser.dm
@@ -25,18 +25,18 @@
new /obj/item/tank/internals/plasma(src)
update_icon()
-/obj/structure/tank_dispenser/update_icon()
- cut_overlays()
+/obj/structure/tank_dispenser/update_overlays()
+ . = ..()
switch(oxygentanks)
if(1 to 3)
- add_overlay("oxygen-[oxygentanks]")
+ . += "oxygen-[oxygentanks]"
if(4 to TANK_DISPENSER_CAPACITY)
- add_overlay("oxygen-4")
+ . += "oxygen-4"
switch(plasmatanks)
if(1 to 4)
- add_overlay("plasma-[plasmatanks]")
+ . += "plasma-[plasmatanks]"
if(5 to TANK_DISPENSER_CAPACITY)
- add_overlay("plasma-5")
+ . += "plasma-5"
/obj/structure/tank_dispenser/attackby(obj/item/I, mob/user, params)
var/full
diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
index 392c802ed8..04f113a0c8 100644
--- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
+++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
@@ -19,7 +19,7 @@
empty_pod()
return ..()
-/obj/structure/transit_tube_pod/update_icon()
+/obj/structure/transit_tube_pod/update_icon_state()
if(contents.len)
icon_state = "pod_occupied"
else
diff --git a/code/game/objects/structures/traps.dm b/code/game/objects/structures/traps.dm
index fa9c052aa3..8044bb9bb7 100644
--- a/code/game/objects/structures/traps.dm
+++ b/code/game/objects/structures/traps.dm
@@ -82,7 +82,7 @@
icon_state = "trap-shock"
/obj/structure/trap/stun/trap_effect(mob/living/L)
- L.electrocute_act(30, src, safety=1) // electrocute act does a message.
+ L.electrocute_act(30, src, flags = SHOCK_NOGLOVES) // electrocute act does a message.
L.DefaultCombatKnockdown(100)
/obj/structure/trap/fire
@@ -146,7 +146,7 @@
/obj/structure/trap/cult/trap_effect(mob/living/L)
to_chat(L, "With a crack, the hostile constructs come out of hiding, stunning you!")
- L.electrocute_act(10, src, safety = TRUE) // electrocute act does a message.
+ L.electrocute_act(10, src, flags = SHOCK_NOGLOVES) // electrocute act does a message.
L.DefaultCombatKnockdown(20)
new /mob/living/simple_animal/hostile/construct/proteon/hostile(loc)
new /mob/living/simple_animal/hostile/construct/proteon/hostile(loc)
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index 78df9b5d57..5f806e7fc4 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -72,7 +72,7 @@
update_icon()
-/obj/structure/toilet/update_icon()
+/obj/structure/toilet/update_icon_state()
icon_state = "toilet[open][cistern]"
@@ -216,8 +216,6 @@
density = FALSE
use_power = NO_POWER_USE
var/on = FALSE
- var/obj/effect/mist/mymist = null
- var/ismist = 0 //needs a var so we can make it linger~
var/watertemp = "normal" //freezing, normal, or boiling
var/datum/looping_sound/showering/soundloop
@@ -240,6 +238,7 @@
/obj/machinery/shower/interact(mob/M)
on = !on
update_icon()
+ handle_mist()
add_fingerprint(M)
if(on)
START_PROCESSING(SSmachines, src)
@@ -280,31 +279,30 @@
return TRUE
-/obj/machinery/shower/update_icon() //this is terribly unreadable, but basically it makes the shower mist up
- cut_overlays() //once it's been on for a while, in addition to handling the water overlay.
- if(mymist)
- qdel(mymist)
-
+/obj/machinery/shower/update_overlays()
+ . = ..()
if(on)
- add_overlay(mutable_appearance('icons/obj/watercloset.dmi', "water", ABOVE_MOB_LAYER))
- if(watertemp == "freezing")
- return
- if(!ismist)
- spawn(50)
- if(src && on)
- ismist = 1
- mymist = new /obj/effect/mist(loc)
- else
- ismist = 1
- mymist = new /obj/effect/mist(loc)
- else if(ismist)
- ismist = 1
- mymist = new /obj/effect/mist(loc)
- spawn(250)
- if(!on && mymist)
- qdel(mymist)
- ismist = 0
+ . += mutable_appearance('icons/obj/watercloset.dmi', "water", ABOVE_MOB_LAYER)
+/obj/machinery/shower/proc/handle_mist()
+ // If there is no mist, and the shower was turned on (on a non-freezing temp): make mist in 5 seconds
+ // If there was already mist, and the shower was turned off (or made cold): remove the existing mist in 25 sec
+ var/obj/effect/mist/mist = locate() in loc
+ if(!mist && on && watertemp != "freezing")
+ addtimer(CALLBACK(src, .proc/make_mist), 5 SECONDS)
+
+ if(mist && (!on || watertemp == "freezing"))
+ addtimer(CALLBACK(src, .proc/clear_mist), 25 SECONDS)
+
+/obj/machinery/shower/proc/make_mist()
+ var/obj/effect/mist/mist = locate() in loc
+ if(!mist && on && watertemp != "freezing")
+ new /obj/effect/mist(loc)
+
+/obj/machinery/shower/proc/clear_mist()
+ var/obj/effect/mist/mist = locate() in loc
+ if(mist && (!on || watertemp == "freezing"))
+ qdel(mist)
/obj/machinery/shower/Crossed(atom/movable/AM)
..()
@@ -692,7 +690,7 @@
open = !open
update_icon()
-/obj/structure/curtain/update_icon()
+/obj/structure/curtain/update_icon_state()
if(!open)
icon_state = "closed"
layer = WALL_OBJ_LAYER
diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm
index e824567b50..531367585e 100644
--- a/code/game/objects/structures/windoor_assembly.dm
+++ b/code/game/objects/structures/windoor_assembly.dm
@@ -47,7 +47,7 @@
setDir(ini_dir)
move_update_air(T)
-/obj/structure/windoor_assembly/update_icon()
+/obj/structure/windoor_assembly/update_icon_state()
icon_state = "[facing]_[secure ? "secure_" : ""]windoor_assembly[state]"
/obj/structure/windoor_assembly/CanPass(atom/movable/mover, turf/target)
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index d4925c8604..5dd4e7d987 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -18,7 +18,6 @@
var/obj/item/stack/sheet/glass_type = /obj/item/stack/sheet/glass
var/cleanable_type = /obj/effect/decal/cleanable/glass
var/glass_amount = 1
- var/mutable_appearance/crack_overlay
can_be_unanchored = TRUE
resistance_flags = ACID_PROOF
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100)
@@ -337,22 +336,19 @@
queue_smooth_neighbors(src)
//merges adjacent full-tile windows into one
-/obj/structure/window/update_icon()
- if(!QDELETED(src))
- if(!fulltile)
- return
+/obj/structure/window/update_overlays()
+ . = ..()
+ if(QDELETED(src) || !fulltile)
+ return
+ var/ratio = obj_integrity / max_integrity
+ ratio = CEILING(ratio*4, 1) * 25
- var/ratio = obj_integrity / max_integrity
- ratio = CEILING(ratio*4, 1) * 25
+ if(smooth)
+ queue_smooth(src)
- if(smooth)
- queue_smooth(src)
-
- cut_overlay(crack_overlay)
- if(ratio > 75)
- return
- crack_overlay = mutable_appearance('icons/obj/structures.dmi', "damage[ratio]", -(layer+0.1))
- add_overlay(crack_overlay)
+ if(ratio > 75)
+ return
+ . += mutable_appearance('icons/obj/structures.dmi', "damage[ratio]", -(layer+0.1))
/obj/structure/window/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
diff --git a/code/modules/VR/vr_sleeper.dm b/code/modules/VR/vr_sleeper.dm
index 29d7224950..e79784290b 100644
--- a/code/modules/VR/vr_sleeper.dm
+++ b/code/modules/VR/vr_sleeper.dm
@@ -63,7 +63,7 @@
addtimer(CALLBACK(src, .proc/emagNotify), 150)
return TRUE
-/obj/machinery/vr_sleeper/update_icon()
+/obj/machinery/vr_sleeper/update_icon_state()
icon_state = "[initial(icon_state)][state_open ? "-open" : ""]"
/obj/machinery/vr_sleeper/open_machine()
diff --git a/code/modules/admin/create_mob.dm b/code/modules/admin/create_mob.dm
index 9784aa7cd1..4d1cb1a7de 100644
--- a/code/modules/admin/create_mob.dm
+++ b/code/modules/admin/create_mob.dm
@@ -40,6 +40,9 @@
H.dna.features["insect_wings"] = pick(GLOB.insect_wings_list)
H.dna.features["deco_wings"] = pick(GLOB.deco_wings_list)
H.dna.features["insect_fluff"] = pick(GLOB.insect_fluffs_list)
+ H.dna.features["flavor_text"] = "" //Oh no.
+
+ SEND_SIGNAL(H, COMSIG_HUMAN_ON_RANDOMIZE)
H.update_body()
H.update_hair()
diff --git a/code/modules/antagonists/abductor/equipment/abduction_gear.dm b/code/modules/antagonists/abductor/equipment/abduction_gear.dm
index c2a3f953f5..39cdf8a5fa 100644
--- a/code/modules/antagonists/abductor/equipment/abduction_gear.dm
+++ b/code/modules/antagonists/abductor/equipment/abduction_gear.dm
@@ -419,8 +419,9 @@
Congratulations! You are now trained for invasive xenobiology research!"}
-/obj/item/paper/guides/antag/abductor/update_icon()
- return
+/obj/item/paper/guides/antag/abductor/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/update_icon_blocker)
/obj/item/paper/guides/antag/abductor/AltClick()
return //otherwise it would fold into a paperplane.
@@ -442,6 +443,10 @@
w_class = WEIGHT_CLASS_NORMAL
actions_types = list(/datum/action/item_action/toggle_mode)
+/obj/item/abductor/baton/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/update_icon_updates_onmob)
+
/obj/item/abductor/baton/proc/toggle(mob/living/user=usr)
mode = (mode+1)%BATON_MODES
var/txt
@@ -458,7 +463,7 @@
to_chat(usr, "You switch the baton to [txt] mode.")
update_icon()
-/obj/item/abductor/baton/update_icon()
+/obj/item/abductor/baton/update_icon_state()
switch(mode)
if(BATON_STUN)
icon_state = "wonderprodStun"
diff --git a/code/modules/antagonists/abductor/machinery/experiment.dm b/code/modules/antagonists/abductor/machinery/experiment.dm
index b5233606cf..96bcd27a3b 100644
--- a/code/modules/antagonists/abductor/machinery/experiment.dm
+++ b/code/modules/antagonists/abductor/machinery/experiment.dm
@@ -223,7 +223,7 @@
return
-/obj/machinery/abductor/experiment/update_icon()
+/obj/machinery/abductor/experiment/update_icon_state()
if(state_open)
icon_state = "experiment-open"
else
diff --git a/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm b/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm
index 261677a74b..b720d3590e 100644
--- a/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm
+++ b/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm
@@ -20,7 +20,7 @@
/mob/living/simple_animal/hostile/blob/update_icons()
if(overmind)
- add_atom_colour(overmind.blob_reagent_datum.color, FIXED_COLOUR_PRIORITY)
+ add_atom_colour(overmind.blobstrain.color, FIXED_COLOUR_PRIORITY)
else
remove_atom_colour(FIXED_COLOUR_PRIORITY)
@@ -34,7 +34,7 @@
for(var/i in 1 to 2)
var/obj/effect/temp_visual/heal/H = new /obj/effect/temp_visual/heal(get_turf(src)) //hello yes you are being healed
if(overmind)
- H.color = overmind.blob_reagent_datum.complementary_color
+ H.color = overmind.blobstrain.complementary_color
else
H.color = "#000000"
adjustHealth(-maxHealth*0.0125)
@@ -142,8 +142,10 @@
// Create the reagents to put into the air
create_reagents(10)
- if(overmind && overmind.blob_reagent_datum)
- reagents.add_reagent(overmind.blob_reagent_datum.type, 10)
+
+
+ if(overmind && overmind.blobstrain)
+ overmind.blobstrain.on_sporedeath(src)
else
reagents.add_reagent(/datum/reagent/toxin/spore, 10)
@@ -167,14 +169,14 @@
/mob/living/simple_animal/hostile/blob/blobspore/update_icons()
if(overmind)
- add_atom_colour(overmind.blob_reagent_datum.complementary_color, FIXED_COLOUR_PRIORITY)
+ add_atom_colour(overmind.blobstrain.complementary_color, FIXED_COLOUR_PRIORITY)
else
remove_atom_colour(FIXED_COLOUR_PRIORITY)
if(is_zombie)
copy_overlays(oldguy, TRUE)
var/mutable_appearance/blob_head_overlay = mutable_appearance('icons/mob/blob.dmi', "blob_head")
if(overmind)
- blob_head_overlay.color = overmind.blob_reagent_datum.complementary_color
+ blob_head_overlay.color = overmind.blobstrain.complementary_color
color = initial(color)//looks better.
add_overlay(blob_head_overlay)
@@ -243,14 +245,14 @@
adjustHealth(-maxHealth*0.1)
var/obj/effect/temp_visual/heal/H = new /obj/effect/temp_visual/heal(get_turf(src)) //hello yes you are being healed
if(overmind)
- H.color = overmind.blob_reagent_datum.complementary_color
+ H.color = overmind.blobstrain.complementary_color
else
H.color = "#000000"
if(locate(/obj/structure/blob/node) in blobs_in_area)
adjustHealth(-maxHealth*0.05)
var/obj/effect/temp_visual/heal/H = new /obj/effect/temp_visual/heal(get_turf(src))
if(overmind)
- H.color = overmind.blob_reagent_datum.complementary_color
+ H.color = overmind.blobstrain.complementary_color
else
H.color = "#000000"
if(damagesources)
@@ -259,7 +261,7 @@
var/image/I = new('icons/mob/blob.dmi', src, "nautdamage", MOB_LAYER+0.01)
I.appearance_flags = RESET_COLOR
if(overmind)
- I.color = overmind.blob_reagent_datum.complementary_color
+ I.color = overmind.blobstrain.complementary_color
flick_overlay_view(I, src, 8)
/mob/living/simple_animal/hostile/blob/blobbernaut/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
@@ -274,16 +276,14 @@
/mob/living/simple_animal/hostile/blob/blobbernaut/AttackingTarget()
. = ..()
if(. && isliving(target) && overmind)
- var/mob/living/L = target
- var/mob_protection = L.get_permeability_protection()
- overmind.blob_reagent_datum.reaction_mob(L, VAPOR, 20, 0, mob_protection, overmind)//this will do between 10 and 20 damage(reduced by mob protection), depending on chemical, plus 4 from base brute damage.
+ overmind.blobstrain.blobbernaut_attack(target)
/mob/living/simple_animal/hostile/blob/blobbernaut/update_icons()
..()
if(overmind) //if we have an overmind, we're doing chemical reactions instead of pure damage
melee_damage_lower = 4
melee_damage_upper = 4
- attacktext = overmind.blob_reagent_datum.blobbernaut_message
+ attacktext = overmind.blobstrain.blobbernaut_message
else
melee_damage_lower = initial(melee_damage_lower)
melee_damage_upper = initial(melee_damage_upper)
diff --git a/code/modules/antagonists/blob/blob/blobs/core.dm b/code/modules/antagonists/blob/blob/blobs/core.dm
index 58f79e1c73..38484c70b0 100644
--- a/code/modules/antagonists/blob/blob/blobs/core.dm
+++ b/code/modules/antagonists/blob/blob/blobs/core.dm
@@ -8,12 +8,8 @@
explosion_block = 6
point_return = -1
health_regen = 0 //we regen in Life() instead of when pulsed
- var/core_regen = 2
- var/resource_delay = 0
- var/point_rate = 2
-
-/obj/structure/blob/core/Initialize(mapload, client/new_overmind = null, new_rate = 2, placed = 0)
+/obj/structure/blob/core/Initialize(mapload, client/new_overmind = null, placed = 0)
GLOB.blob_cores += src
START_PROCESSING(SSobj, src)
GLOB.poi_list |= src
@@ -22,7 +18,6 @@
return INITIALIZE_HINT_QDEL
if(overmind)
update_icon()
- point_rate = new_rate
addtimer(CALLBACK(src, .proc/generate_announcement), 1800)
. = ..()
@@ -37,7 +32,7 @@
color = null
var/mutable_appearance/blob_overlay = mutable_appearance('icons/mob/blob.dmi', "blob")
if(overmind)
- blob_overlay.color = overmind.blob_reagent_datum.color
+ blob_overlay.color = overmind.blobstrain.color
add_overlay(blob_overlay)
add_overlay(mutable_appearance('icons/mob/blob.dmi', "blob_core_overlay"))
@@ -60,17 +55,13 @@
if(overmind) //we should have an overmind, but...
overmind.update_health_hud()
-/obj/structure/blob/core/Life()
+/obj/structure/blob/core/process()
if(QDELETED(src))
return
if(!overmind)
qdel(src)
- else
- if(resource_delay <= world.time)
- resource_delay = world.time + 10 // 1 second
- overmind.add_points(point_rate)
- obj_integrity = min(max_integrity, obj_integrity+core_regen)
if(overmind)
+ overmind.blobstrain.core_process()
overmind.update_health_hud()
Pulse_Area(overmind, 12, 4, 3)
for(var/obj/structure/blob/normal/B in range(1, src))
diff --git a/code/modules/antagonists/blob/blob/blobs/node.dm b/code/modules/antagonists/blob/blob/blobs/node.dm
index 23f37bca29..14fbc741c0 100644
--- a/code/modules/antagonists/blob/blob/blobs/node.dm
+++ b/code/modules/antagonists/blob/blob/blobs/node.dm
@@ -22,7 +22,7 @@
color = null
var/mutable_appearance/blob_overlay = mutable_appearance('icons/mob/blob.dmi', "blob")
if(overmind)
- blob_overlay.color = overmind.blob_reagent_datum.color
+ blob_overlay.color = overmind.blobstrain.color
add_overlay(blob_overlay)
add_overlay(mutable_appearance('icons/mob/blob.dmi', "blob_node_overlay"))
@@ -31,6 +31,6 @@
STOP_PROCESSING(SSobj, src)
return ..()
-/obj/structure/blob/node/Life()
+/obj/structure/blob/node/process()
if(overmind)
Pulse_Area(overmind, 10, 3, 2)
diff --git a/code/modules/antagonists/blob/blob/blobstrains/_blobstrain.dm b/code/modules/antagonists/blob/blob/blobstrains/_blobstrain.dm
new file mode 100644
index 0000000000..8b6f4bd687
--- /dev/null
+++ b/code/modules/antagonists/blob/blob/blobstrains/_blobstrain.dm
@@ -0,0 +1,74 @@
+GLOBAL_LIST_INIT(valid_blobstrains, subtypesof(/datum/blobstrain) - list(/datum/blobstrain/reagent, /datum/blobstrain/multiplex))
+
+/datum/blobstrain
+ var/name
+ var/description
+ var/color = "#000000"
+ var/complementary_color = "#000000" //a color that's complementary to the normal blob color
+ var/shortdesc = null //just damage and on_mob effects, doesn't include special, blob-tile only effects
+ var/effectdesc = null //any long, blob-tile specific effects
+ var/analyzerdescdamage = "Unknown. Report this bug to a coder, or just adminhelp."
+ var/analyzerdesceffect = "N/A"
+ var/blobbernaut_message = "slams" //blobbernaut attack verb
+ var/message = "The blob strikes you" //message sent to any mob hit by the blob
+ var/message_living = null //extension to first mob sent to only living mobs i.e. silicons have no skin to be burnt
+ var/core_regen = 2
+ var/resource_delay = 0
+ var/point_rate = 2
+ var/mob/camera/blob/overmind
+
+/datum/blobstrain/New(mob/camera/blob/new_overmind)
+ if (!istype(new_overmind))
+ stack_trace("blobstrain created without overmind")
+ overmind = new_overmind
+
+/datum/blobstrain/proc/on_gain()
+ overmind.color = complementary_color
+ for(var/BL in GLOB.blobs)
+ var/obj/structure/blob/B = BL
+ B.update_icon()
+ for(var/BLO in overmind.blob_mobs)
+ var/mob/living/simple_animal/hostile/blob/BM = BLO
+ BM.update_icons() //If it's getting a new strain, tell it what it does!
+ to_chat(BM, "Your overmind's blob strain is now: [name]!")
+ to_chat(BM, "The [name] strain [shortdesc ? "[shortdesc]" : "[description]"]")
+
+/datum/blobstrain/proc/on_lose()
+
+/datum/blobstrain/proc/on_sporedeath(mob/living/spore)
+
+/datum/blobstrain/proc/send_message(mob/living/M)
+ var/totalmessage = message
+ if(message_living && !issilicon(M))
+ totalmessage += message_living
+ totalmessage += "!"
+ to_chat(M, "[totalmessage]")
+
+/datum/blobstrain/proc/core_process()
+ if(resource_delay <= world.time)
+ resource_delay = world.time + 10 // 1 second
+ overmind.add_points(point_rate)
+ overmind.blob_core.obj_integrity = min(overmind.blob_core.max_integrity, overmind.blob_core.obj_integrity+core_regen)
+
+/datum/blobstrain/proc/attack_living(var/mob/living/L) // When the blob attacks people
+ send_message(L)
+
+/datum/blobstrain/proc/blobbernaut_attack(mob/living/L) // When this blob's blobbernaut attacks people
+
+/datum/blobstrain/proc/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag, coefficient = 1) //when the blob takes damage, do this
+ return coefficient*damage
+
+/datum/blobstrain/proc/death_reaction(obj/structure/blob/B, damage_flag, coefficient = 1) //when a blob dies, do this
+ return
+
+/datum/blobstrain/proc/expand_reaction(obj/structure/blob/B, obj/structure/blob/newB, turf/T, mob/camera/blob/O, coefficient = 1) //when the blob expands, do this
+ return
+
+/datum/blobstrain/proc/tesla_reaction(obj/structure/blob/B, power, coefficient = 1) //when the blob is hit by a tesla bolt, do this
+ return 1 //return 0 to ignore damage
+
+/datum/blobstrain/proc/extinguish_reaction(obj/structure/blob/B, coefficient = 1) //when the blob is hit with water, do this
+ return
+
+/datum/blobstrain/proc/emp_reaction(obj/structure/blob/B, severity, coefficient = 1) //when the blob is hit with an emp, do this
+ return
diff --git a/code/modules/antagonists/blob/blob/blobstrains/_reagent.dm b/code/modules/antagonists/blob/blob/blobstrains/_reagent.dm
new file mode 100644
index 0000000000..f47c3b3378
--- /dev/null
+++ b/code/modules/antagonists/blob/blob/blobstrains/_reagent.dm
@@ -0,0 +1,33 @@
+/datum/blobstrain/reagent // Blobs that mess with reagents, all "legacy" ones
+ var/datum/reagent/reagent
+
+/datum/blobstrain/reagent/New(mob/camera/blob/new_overmind)
+ . = ..()
+ reagent = new reagent()
+
+
+/datum/blobstrain/reagent/attack_living(var/mob/living/L)
+ var/mob_protection = L.get_permeability_protection()
+ reagent.reaction_mob(L, VAPOR, 25, 1, mob_protection, overmind)
+ send_message(L)
+
+/datum/blobstrain/reagent/blobbernaut_attack(mob/living/L)
+ var/mob_protection = L.get_permeability_protection()
+ reagent.reaction_mob(L, VAPOR, 20, 0, mob_protection, overmind)//this will do between 10 and 20 damage(reduced by mob protection), depending on chemical, plus 4 from base brute damage.
+
+/datum/blobstrain/reagent/on_sporedeath(mob/living/spore)
+ spore.reagents.add_reagent(reagent.type, 10)
+
+// These can only be applied by blobs. They are what (reagent) blobs are made out of.
+/datum/reagent/blob
+ name = "Unknown"
+ description = "shouldn't exist and you should adminhelp immediately."
+ color = "#FFFFFF"
+ taste_description = "bad code and slime"
+ can_synth = FALSE
+
+
+/datum/reagent/blob/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+ if(M.stat == DEAD || istype(M, /mob/living/simple_animal/hostile/blob))
+ return 0 //the dead, and blob mobs, don't cause reactions
+ return round(reac_volume * min(1.5 - touch_protection, 1), 0.1) //full touch protection means 50% volume, any prot below 0.5 means 100% volume.
diff --git a/code/modules/antagonists/blob/blob/blobstrains/blazing_oil.dm b/code/modules/antagonists/blob/blob/blobstrains/blazing_oil.dm
new file mode 100644
index 0000000000..97b974e28f
--- /dev/null
+++ b/code/modules/antagonists/blob/blob/blobstrains/blazing_oil.dm
@@ -0,0 +1,41 @@
+
+//sets you on fire, does burn damage, explodes into flame when burnt, weak to water
+/datum/blobstrain/reagent/blazing_oil
+ name = "Blazing Oil"
+ description = "will do medium burn damage and set targets on fire."
+ effectdesc = "will also release bursts of flame when burnt, but takes damage from water."
+ analyzerdescdamage = "Does medium burn damage and sets targets on fire."
+ analyzerdesceffect = "Releases fire when burnt, but takes damage from water and other extinguishing liquids."
+ color = "#B68D00"
+ complementary_color = "#BE5532"
+ blobbernaut_message = "splashes"
+ message = "The blob splashes you with burning oil"
+ message_living = ", and you feel your skin char and melt"
+ reagent = /datum/reagent/blob/blazing_oil
+
+/datum/blobstrain/reagent/blazing_oil/extinguish_reaction(obj/structure/blob/B)
+ B.take_damage(1.5, BURN, "energy")
+
+/datum/blobstrain/reagent/blazing_oil/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
+ if(damage_type == BURN && damage_flag != "energy")
+ for(var/turf/open/T in range(1, B))
+ var/obj/structure/blob/C = locate() in T
+ if(!(C && C.overmind && C.overmind.blobstrain.type == B.overmind.blobstrain.type) && prob(80))
+ new /obj/effect/hotspot(T)
+ if(damage_flag == "fire")
+ return 0
+ return ..()
+
+/datum/reagent/blob/blazing_oil
+ name = "Blazing Oil"
+ taste_description = "burning oil"
+ color = "#B68D00"
+
+/datum/reagent/blob/blazing_oil/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+ reac_volume = ..()
+ M.adjust_fire_stacks(round(reac_volume/10))
+ M.IgniteMob()
+ if(M)
+ M.apply_damage(0.8*reac_volume, BURN)
+ if(iscarbon(M))
+ M.emote("scream")
diff --git a/code/modules/antagonists/blob/blob/blobstrains/cryogenic_poison.dm b/code/modules/antagonists/blob/blob/blobstrains/cryogenic_poison.dm
new file mode 100644
index 0000000000..9b8edcd0e5
--- /dev/null
+++ b/code/modules/antagonists/blob/blob/blobstrains/cryogenic_poison.dm
@@ -0,0 +1,32 @@
+//does brute, burn, and toxin damage, and cools targets down
+/datum/blobstrain/reagent/cryogenic_poison
+ name = "Cryogenic Poison"
+ description = "will inject targets with a freezing poison that does high damage over time."
+ analyzerdescdamage = "Injects targets with a freezing poison that will gradually solidify the target's internal organs."
+ color = "#8BA6E9"
+ complementary_color = "#7D6EB4"
+ blobbernaut_message = "injects"
+ message = "The blob stabs you"
+ message_living = ", and you feel like your insides are solidifying"
+ reagent = /datum/reagent/blob/cryogenic_poison
+
+/datum/reagent/blob/cryogenic_poison
+ name = "Cryogenic Poison"
+ description = "will inject targets with a freezing poison that does high damage over time."
+ color = "#8BA6E9"
+ taste_description = "brain freeze"
+
+/datum/reagent/blob/cryogenic_poison/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+ reac_volume = ..()
+ if(M.reagents)
+ M.reagents.add_reagent("frostoil", 0.3*reac_volume)
+ M.reagents.add_reagent("ice", 0.3*reac_volume)
+ M.reagents.add_reagent("cryogenic_poison", 0.3*reac_volume)
+ M.apply_damage(0.2*reac_volume, BRUTE)
+
+/datum/reagent/blob/cryogenic_poison/on_mob_life(mob/living/carbon/M)
+ M.adjustBruteLoss(0.3*REAGENTS_EFFECT_MULTIPLIER, 0)
+ M.adjustFireLoss(0.3*REAGENTS_EFFECT_MULTIPLIER, 0)
+ M.adjustToxLoss(0.3*REAGENTS_EFFECT_MULTIPLIER, 0)
+ . = 1
+ ..()
diff --git a/code/modules/antagonists/blob/blob/blobstrains/electromagnetic_web.dm b/code/modules/antagonists/blob/blob/blobstrains/electromagnetic_web.dm
new file mode 100644
index 0000000000..0e665603c9
--- /dev/null
+++ b/code/modules/antagonists/blob/blob/blobstrains/electromagnetic_web.dm
@@ -0,0 +1,33 @@
+//does burn damage and EMPs, slightly fragile
+/datum/blobstrain/reagent/electromagnetic_web
+ name = "Electromagnetic Web"
+ color = "#83ECEC"
+ complementary_color = "#EC8383"
+ reagent = /datum/reagent/blob/electromagnetic_web
+
+/datum/blobstrain/reagent/electromagnetic_web/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
+ if(damage_type == BRUTE) //take full brute
+ switch(B.brute_resist)
+ if(0.5)
+ return damage * 2
+ if(0.25)
+ return damage * 4
+ if(0.1)
+ return damage * 10
+ return damage * 1.25 //a laser will do 25 damage, which will kill any normal blob
+
+/datum/blobstrain/reagent/electromagnetic_web/death_reaction(obj/structure/blob/B, damage_flag)
+ if(damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser")
+ empulse(B.loc, 1, 3) //less than screen range, so you can stand out of range to avoid it
+
+/datum/reagent/blob/electromagnetic_web
+ name = "Electromagnetic Web"
+ taste_description = "pop rocks"
+ color = "#83ECEC"
+
+/datum/reagent/blob/electromagnetic_web/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+ reac_volume = ..()
+ if(prob(reac_volume*2))
+ M.emp_act(EMP_LIGHT)
+ if(M)
+ M.apply_damage(reac_volume, BURN)
diff --git a/code/modules/antagonists/blob/blob/blobstrains/energized_jelly.dm b/code/modules/antagonists/blob/blob/blobstrains/energized_jelly.dm
new file mode 100644
index 0000000000..66ce3c303d
--- /dev/null
+++ b/code/modules/antagonists/blob/blob/blobstrains/energized_jelly.dm
@@ -0,0 +1,34 @@
+//does tons of oxygen damage and a little stamina, immune to tesla bolts, weak to EMP
+/datum/blobstrain/reagent/energized_jelly
+ name = "Energized Jelly"
+ description = "will cause low stamina and high oxygen damage, and cause targets to be unable to breathe."
+ effectdesc = "will also conduct electricity, but takes damage from EMPs."
+ analyzerdescdamage = "Does low stamina damage, high oxygen damage, and prevents targets from breathing."
+ analyzerdesceffect = "Is immune to electricity and will easily conduct it, but is weak to EMPs."
+ color = "#EFD65A"
+ complementary_color = "#00E5B1"
+ reagent = /datum/reagent/blob/energized_jelly
+
+/datum/blobstrain/reagent/energized_jelly/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
+ if((damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") && B.obj_integrity - damage <= 0 && prob(10))
+ do_sparks(rand(2, 4), FALSE, B)
+ return ..()
+
+/datum/blobstrain/reagent/energized_jelly/tesla_reaction(obj/structure/blob/B, power)
+ return 0
+
+/datum/blobstrain/reagent/energized_jelly/emp_reaction(obj/structure/blob/B, severity)
+ var/damage = rand(30, 50) - severity * rand(10, 15)
+ B.take_damage(damage, BURN, "energy")
+
+/datum/reagent/blob/energized_jelly
+ name = "Energized Jelly"
+ taste_description = "gelatin"
+ color = "#EFD65A"
+
+/datum/reagent/blob/energized_jelly/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+ reac_volume = ..()
+ M.losebreath += round(0.2*reac_volume)
+ M.adjustStaminaLoss(0.4*reac_volume)
+ if(M)
+ M.apply_damage(0.6*reac_volume, OXY)
diff --git a/code/modules/antagonists/blob/blob/blobstrains/explosive_lattice.dm b/code/modules/antagonists/blob/blob/blobstrains/explosive_lattice.dm
new file mode 100644
index 0000000000..f8fd2e2f0d
--- /dev/null
+++ b/code/modules/antagonists/blob/blob/blobstrains/explosive_lattice.dm
@@ -0,0 +1,40 @@
+//does aoe brute damage when hitting targets, is immune to explosions
+/datum/blobstrain/reagent/explosive_lattice
+ name = "Explosive Lattice"
+ description = "will do brute damage in an area around targets."
+ effectdesc = "will also resist explosions, but takes increased damage from fire and other energy sources."
+ analyzerdescdamage = "Does medium brute damage and causes damage to everyone near its targets."
+ analyzerdesceffect = "Is highly resistant to explosions, but takes increased damage from fire and other energy sources."
+ color = "#8B2500"
+ complementary_color = "#00668B"
+ blobbernaut_message = "blasts"
+ message = "The blob blasts you"
+ reagent = /datum/reagent/blob/explosive_lattice
+
+/datum/blobstrain/reagent/explosive_lattice/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
+ if(damage_flag == "bomb")
+ return 0
+ else if(damage_flag != "melee" && damage_flag != "bullet" && damage_flag != "laser")
+ return damage * 1.5
+ return ..()
+
+/datum/reagent/blob/explosive_lattice
+ name = "Explosive Lattice"
+ taste_description = "the bomb"
+ color = "#8B2500"
+
+/datum/reagent/blob/explosive_lattice/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+ var/initial_volume = reac_volume
+ reac_volume = ..()
+ if(reac_volume >= 10) //if it's not a spore cloud, bad time incoming
+ var/obj/effect/temp_visual/explosion/fast/E = new /obj/effect/temp_visual/explosion/fast(get_turf(M))
+ E.alpha = 150
+ for(var/mob/living/L in orange(get_turf(M), 1))
+ if(ROLE_BLOB in L.faction) //no friendly fire
+ continue
+ var/aoe_volume = ..(L, TOUCH, initial_volume, 0, L.get_permeability_protection(), O)
+ L.apply_damage(0.4*aoe_volume, BRUTE)
+ if(M)
+ M.apply_damage(0.6*reac_volume, BRUTE)
+ else
+ M.apply_damage(0.6*reac_volume, BRUTE)
diff --git a/code/modules/antagonists/blob/blob/blobstrains/multiplex.dm b/code/modules/antagonists/blob/blob/blobstrains/multiplex.dm
new file mode 100644
index 0000000000..191da6c51f
--- /dev/null
+++ b/code/modules/antagonists/blob/blob/blobstrains/multiplex.dm
@@ -0,0 +1,40 @@
+/datum/blobstrain/multiplex
+ var/list/blobstrains
+ var/typeshare
+
+/datum/blobstrain/multiplex/New(mob/camera/blob/new_overmind, list/blobstrains)
+ . = ..()
+ for (var/bt in blobstrains)
+ if (ispath(bt, /datum/blobstrain))
+ src.blobstrains += new bt(overmind)
+ else if (istype(bt, /datum/blobstrain))
+ var/datum/blobstrain/bts = bt
+ bts.overmind = overmind
+ src.blobstrains += bt
+ typeshare = (0.8 * length(src.blobstrains)) - (length(src.blobstrains)-1) // 1 is 80%, 2 are 60% etc
+
+/datum/blobstrain/multiplex/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag, coefficient = 1) //when the blob takes damage, do this
+ for (var/datum/blobstrain/bt in blobstrains)
+ . += bt.damage_reaction(B, damage, damage_type, damage_flag, coefficient*typeshare)
+
+/datum/blobstrain/multiplex/death_reaction(obj/structure/blob/B, damage_flag, coefficient = 1) //when a blob dies, do this
+ for (var/datum/blobstrain/bt in blobstrains)
+ . += bt.death_reaction(B, damage_flag, coefficient*typeshare)
+
+/datum/blobstrain/multiplex/expand_reaction(obj/structure/blob/B, obj/structure/blob/newB, turf/T, mob/camera/blob/O, coefficient = 1) //when the blob expands, do this
+ for (var/datum/blobstrain/bt in blobstrains)
+ . += bt.expand_reaction(B, newB, T, O, coefficient*typeshare)
+
+/datum/blobstrain/multiplex/tesla_reaction(obj/structure/blob/B, power, coefficient = 1) //when the blob is hit by a tesla bolt, do this
+ for (var/datum/blobstrain/bt in blobstrains)
+ . += bt.tesla_reaction(B, power, coefficient*typeshare)
+ if (prob(. / length(blobstrains) * 100))
+ return 1
+
+/datum/blobstrain/multiplex/extinguish_reaction(obj/structure/blob/B, coefficient = 1) //when the blob is hit with water, do this
+ for (var/datum/blobstrain/bt in blobstrains)
+ . += bt.extinguish_reaction(B, coefficient*typeshare)
+
+/datum/blobstrain/multiplex/emp_reaction(obj/structure/blob/B, severity, coefficient = 1) //when the blob is hit with an emp, do this
+ for (var/datum/blobstrain/bt in blobstrains)
+ . += bt.emp_reaction(B, severity, coefficient*typeshare)
diff --git a/code/modules/antagonists/blob/blob/blobstrains/networked_fibers.dm b/code/modules/antagonists/blob/blob/blobstrains/networked_fibers.dm
new file mode 100644
index 0000000000..fac3470c7a
--- /dev/null
+++ b/code/modules/antagonists/blob/blob/blobstrains/networked_fibers.dm
@@ -0,0 +1,38 @@
+//does massive brute and burn damage, but can only expand manually
+/datum/blobstrain/reagent/networked_fibers
+ name = "Networked Fibers"
+ description = "will do high brute and burn damage and will generate resources quicker, but can only expand manually."
+ shortdesc = "will do high brute and burn damage."
+ effectdesc = "will move your core when manually expanding near it."
+ analyzerdescdamage = "Does high brute and burn damage."
+ analyzerdesceffect = "Is highly mobile and generates resources rapidly."
+ color = "#CDC0B0"
+ complementary_color = "#FFF68F"
+ reagent = /datum/reagent/blob/networked_fibers
+
+/datum/blobstrain/reagent/networked_fibers/expand_reaction(obj/structure/blob/B, obj/structure/blob/newB, turf/T, mob/camera/blob/O)
+ if(!O && newB.overmind)
+ if(!istype(B, /obj/structure/blob/node))
+ newB.overmind.add_points(1)
+ qdel(newB)
+ else
+ var/area/A = get_area(T)
+ if(!isspaceturf(T) && !istype(A, /area/shuttle))
+ for(var/obj/structure/blob/core/C in range(1, newB))
+ if(C.overmind == O)
+ newB.forceMove(get_turf(C))
+ C.forceMove(T)
+ C.setDir(get_dir(newB, C))
+ O.add_points(1)
+
+//does massive brute and burn damage, but can only expand manually
+/datum/reagent/blob/networked_fibers
+ name = "Networked Fibers"
+ taste_description = "efficiency"
+ color = "#CDC0B0"
+
+/datum/reagent/blob/networked_fibers/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+ reac_volume = ..()
+ M.apply_damage(0.6*reac_volume, BRUTE)
+ if(M)
+ M.apply_damage(0.6*reac_volume, BURN)
diff --git a/code/modules/antagonists/blob/blob/blobstrains/pressurized_slime.dm b/code/modules/antagonists/blob/blob/blobstrains/pressurized_slime.dm
new file mode 100644
index 0000000000..6a984e66a2
--- /dev/null
+++ b/code/modules/antagonists/blob/blob/blobstrains/pressurized_slime.dm
@@ -0,0 +1,51 @@
+//does low brute damage, oxygen damage, and stamina damage and wets tiles when damaged
+/datum/blobstrain/reagent/pressurized_slime
+ name = "Pressurized Slime"
+ description = "will do low brute, oxygen, and stamina damage, and wet tiles under targets."
+ effectdesc = "will also wet tiles near blobs that are attacked or killed."
+ analyzerdescdamage = "Does low brute damage, low oxygen damage, drains stamina, and wets tiles under targets, extinguishing them."
+ analyzerdesceffect = "When attacked or killed, lubricates nearby tiles, extinguishing anything on them."
+ color = "#AAAABB"
+ complementary_color = "#BBBBAA"
+ blobbernaut_message = "emits slime at"
+ message = "The blob splashes into you"
+ message_living = ", and you gasp for breath"
+ reagent = /datum/reagent/blob/pressurized_slime
+
+/datum/blobstrain/reagent/pressurized_slime/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
+ if((damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") || damage_type != BURN)
+ extinguisharea(B, damage)
+ return ..()
+
+/datum/blobstrain/reagent/pressurized_slime/death_reaction(obj/structure/blob/B, damage_flag)
+ if(damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser")
+ B.visible_message("The blob ruptures, spraying the area with liquid!")
+ extinguisharea(B, 50)
+
+/datum/blobstrain/reagent/pressurized_slime/proc/extinguisharea(obj/structure/blob/B, probchance)
+ for(var/turf/open/T in range(1, B))
+ if(prob(probchance))
+ T.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS)
+ for(var/obj/O in T)
+ O.extinguish()
+ for(var/mob/living/L in T)
+ L.adjust_fire_stacks(-2.5)
+ L.ExtinguishMob()
+
+/datum/reagent/blob/pressurized_slime
+ name = "Pressurized Slime"
+ taste_description = "a sponge"
+ color = "#AAAABB"
+
+/datum/reagent/blob/pressurized_slime/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+ reac_volume = ..()
+ var/turf/open/T = get_turf(M)
+ if(istype(T) && prob(reac_volume))
+ T.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS)
+ M.adjust_fire_stacks(-(reac_volume / 10))
+ M.ExtinguishMob()
+ M.apply_damage(0.4*reac_volume, BRUTE)
+ if(M)
+ M.apply_damage(0.4*reac_volume, OXY)
+ if(M)
+ M.adjustStaminaLoss(0.2*reac_volume)
diff --git a/code/modules/antagonists/blob/blob/blobstrains/reactive_spines.dm b/code/modules/antagonists/blob/blob/blobstrains/reactive_spines.dm
new file mode 100644
index 0000000000..fca56d1402
--- /dev/null
+++ b/code/modules/antagonists/blob/blob/blobstrains/reactive_spines.dm
@@ -0,0 +1,30 @@
+//does brute damage through armor and bio resistance
+/datum/blobstrain/reagent/reactive_spines
+ name = "Reactive Spines"
+ description = "will do medium brute damage through armor and bio resistance."
+ effectdesc = "will also react when attacked with brute damage, attacking all near the attacked blob."
+ analyzerdescdamage = "Does medium brute damage, ignoring armor and bio resistance."
+ analyzerdesceffect = "When attacked with brute damage, will lash out, attacking everything near it."
+ color = "#9ACD32"
+ complementary_color = "#FFA500"
+ blobbernaut_message = "stabs"
+ message = "The blob stabs you"
+ reagent = /datum/reagent/blob/reactive_spines
+
+/datum/blobstrain/reagent/reactive_spines/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
+ if(damage && damage_type == BRUTE && B.obj_integrity - damage > 0) //is there any damage, is it brute, and will we be alive
+ if(damage_flag == "melee")
+ B.visible_message("The blob retaliates, lashing out!")
+ for(var/atom/A in range(1, B))
+ A.blob_act(B)
+ return ..()
+
+/datum/reagent/blob/reactive_spines
+ name = "Reactive Spines"
+ taste_description = "rock"
+ color = "#9ACD32"
+
+/datum/reagent/blob/reactive_spines/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+ if(M.stat == DEAD || istype(M, /mob/living/simple_animal/hostile/blob))
+ return 0 //the dead, and blob mobs, don't cause reactions
+ M.adjustBruteLoss(0.8*reac_volume)
diff --git a/code/modules/antagonists/blob/blob/blobstrains/regenerative_materia.dm b/code/modules/antagonists/blob/blob/blobstrains/regenerative_materia.dm
new file mode 100644
index 0000000000..25511e01ff
--- /dev/null
+++ b/code/modules/antagonists/blob/blob/blobstrains/regenerative_materia.dm
@@ -0,0 +1,33 @@
+//does toxin damage, hallucination, targets think they're not hurt at all
+/datum/blobstrain/reagent/regenerative_materia
+ name = "Regenerative Materia"
+ description = "will do toxin damage and cause targets to believe they are fully healed."
+ analyzerdescdamage = "Does toxin damage and injects a toxin that causes the target to believe they are fully healed."
+ color = "#C8A5DC"
+ complementary_color = "#CD7794"
+ message_living = ", and you feel alive"
+ reagent = /datum/reagent/blob/regenerative_materia
+
+/datum/reagent/blob/regenerative_materia
+ name = "Regenerative Materia"
+ taste_description = "heaven"
+ color = "#C8A5DC"
+
+/datum/reagent/blob/regenerative_materia/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+ reac_volume = ..()
+ M.adjust_drugginess(reac_volume)
+ if(M.reagents)
+ M.reagents.add_reagent("regenerative_materia", 0.2*reac_volume)
+ M.reagents.add_reagent("spore", 0.2*reac_volume)
+ M.apply_damage(0.7*reac_volume, TOX)
+
+/datum/reagent/blob/regenerative_materia/on_mob_life(mob/living/carbon/C)
+ C.adjustToxLoss(1*REAGENTS_EFFECT_MULTIPLIER)
+ C.hal_screwyhud = SCREWYHUD_HEALTHY //fully healed, honest
+ ..()
+
+/datum/reagent/blob/regenerative_materia/on_mob_delete(mob/living/M)
+ if(iscarbon(M))
+ var/mob/living/carbon/N = M
+ N.hal_screwyhud = 0
+ ..()
diff --git a/code/modules/antagonists/blob/blob/blobstrains/replicating_foam.dm b/code/modules/antagonists/blob/blob/blobstrains/replicating_foam.dm
new file mode 100644
index 0000000000..00743c671e
--- /dev/null
+++ b/code/modules/antagonists/blob/blob/blobstrains/replicating_foam.dm
@@ -0,0 +1,34 @@
+/datum/blobstrain/reagent/replicating_foam
+ description = "will do medium brute damage and occasionally expand again when expanding."
+ shortdesc = "will do medium brute damage."
+ effectdesc = "will also expand when attacked with burn damage, but takes more brute damage."
+ color = "#7B5A57"
+ complementary_color = "#57787B"
+ analyzerdescdamage = "Does medium brute damage."
+ analyzerdesceffect = "Expands when attacked with burn damage, will occasionally expand again when expanding, and is fragile to brute damage."
+ reagent = /datum/reagent/blob/replicating_foam
+
+
+/datum/blobstrain/reagent/replicating_foam/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
+ if(damage_type == BRUTE)
+ damage = damage * 2
+ else if(damage_type == BURN && damage > 0 && B.obj_integrity - damage > 0 && prob(60))
+ var/obj/structure/blob/newB = B.expand(null, null, 0)
+ if(newB)
+ newB.obj_integrity = B.obj_integrity - damage
+ newB.update_icon()
+ return ..()
+
+
+/datum/blobstrain/reagent/replicating_foam/expand_reaction(obj/structure/blob/B, obj/structure/blob/newB, turf/T, mob/camera/blob/O)
+ if(prob(30))
+ newB.expand(null, null, 0) //do it again!
+
+/datum/reagent/blob/replicating_foam
+ name = "Replicating Foam"
+ taste_description = "duplication"
+ color = "#7B5A57"
+
+/datum/reagent/blob/replicating_foam/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+ reac_volume = ..()
+ M.apply_damage(0.7*reac_volume, BRUTE)
diff --git a/code/modules/antagonists/blob/blob/blobstrains/shifting_fragments.dm b/code/modules/antagonists/blob/blob/blobstrains/shifting_fragments.dm
new file mode 100644
index 0000000000..dbb3d6fb9b
--- /dev/null
+++ b/code/modules/antagonists/blob/blob/blobstrains/shifting_fragments.dm
@@ -0,0 +1,35 @@
+//does brute damage, shifts away when damaged
+/datum/blobstrain/reagent/shifting_fragments
+ description = "will do medium brute damage."
+ effectdesc = "will also cause blob parts to shift away when attacked."
+ analyzerdescdamage = "Does medium brute damage."
+ analyzerdesceffect = "When attacked, may shift away from the attacker."
+ color = "#C8963C"
+ complementary_color = "#3C6EC8"
+ reagent = /datum/reagent/blob/shifting_fragments
+
+/datum/blobstrain/reagent/shifting_fragments/expand_reaction(obj/structure/blob/B, obj/structure/blob/newB, turf/T, mob/camera/blob/O)
+ if(istype(B, /obj/structure/blob/normal) || (istype(B, /obj/structure/blob/shield) && prob(25)))
+ newB.forceMove(get_turf(B))
+ B.forceMove(T)
+
+/datum/blobstrain/reagent/shifting_fragments/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
+ if((damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") && damage > 0 && B.obj_integrity - damage > 0 && prob(60-damage))
+ var/list/blobstopick = list()
+ for(var/obj/structure/blob/OB in orange(1, B))
+ if((istype(OB, /obj/structure/blob/normal) || (istype(OB, /obj/structure/blob/shield) && prob(25))) && OB.overmind && OB.overmind.blobstrain.type == B.overmind.blobstrain.type)
+ blobstopick += OB //as long as the blob picked is valid; ie, a normal or shield blob that has the same chemical as we do, we can swap with it
+ if(blobstopick.len)
+ var/obj/structure/blob/targeted = pick(blobstopick) //randomize the blob chosen, because otherwise it'd tend to the lower left
+ var/turf/T = get_turf(targeted)
+ targeted.forceMove(get_turf(B))
+ B.forceMove(T) //swap the blobs
+ return ..()
+
+/datum/reagent/blob/shifting_fragments
+ name = "Shifting Fragments"
+ color = "#C8963C"
+
+/datum/reagent/blob/shifting_fragments/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+ reac_volume = ..()
+ M.apply_damage(0.7*reac_volume, BRUTE)
diff --git a/code/modules/antagonists/blob/blob/blobstrains/synchronous_mesh.dm b/code/modules/antagonists/blob/blob/blobstrains/synchronous_mesh.dm
new file mode 100644
index 0000000000..d58fb5b37d
--- /dev/null
+++ b/code/modules/antagonists/blob/blob/blobstrains/synchronous_mesh.dm
@@ -0,0 +1,38 @@
+//does brute damage, bonus damage for each nearby blob, and spreads damage out
+/datum/blobstrain/reagent/synchronous_mesh
+ name = "Synchronous Mesh"
+ description = "will do massively increased brute damage for each blob near the target."
+ effectdesc = "will also spread damage between each blob near the attacked blob."
+ analyzerdescdamage = "Does brute damage, increasing for each blob near the target."
+ analyzerdesceffect = "When attacked, spreads damage between all blobs near the attacked blob."
+ color = "#65ADA2"
+ complementary_color = "#AD6570"
+ blobbernaut_message = "synchronously strikes"
+ message = "The blobs strike you"
+
+/datum/blobstrain/reagent/synchronous_mesh/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
+ if(damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") //the cause isn't fire or bombs, so split the damage
+ var/damagesplit = 1 //maximum split is 9, reducing the damage each blob takes to 11% but doing that damage to 9 blobs
+ for(var/obj/structure/blob/C in orange(1, B))
+ if(!istype(C, /obj/structure/blob/core) && !istype(C, /obj/structure/blob/node) && C.overmind && C.overmind.blobstrain.type == B.overmind.blobstrain.type) //if it doesn't have the same chemical or is a core or node, don't split damage to it
+ damagesplit += 1
+ for(var/obj/structure/blob/C in orange(1, B))
+ if(!istype(C, /obj/structure/blob/core) && !istype(C, /obj/structure/blob/node) && C.overmind && C.overmind.blobstrain.type == B.overmind.blobstrain.type) //only hurt blobs that have the same overmind chemical and aren't cores or nodes
+ C.take_damage(damage/damagesplit, CLONE, 0, 0)
+ return damage / damagesplit
+ else
+ return damage * 1.25
+
+/datum/reagent/blob/synchronous_mesh
+ name = "Synchronous Mesh"
+ taste_description = "toxic mold"
+ color = "#65ADA2"
+
+/datum/reagent/blob/synchronous_mesh/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+ reac_volume = ..()
+ M.apply_damage(0.2*reac_volume, BRUTE)
+ if(M && reac_volume)
+ for(var/obj/structure/blob/B in range(1, M)) //if the target is completely surrounded, this is 2.4*reac_volume bonus damage, total of 2.6*reac_volume
+ if(M)
+ B.blob_attack_animation(M) //show them they're getting a bad time
+ M.apply_damage(0.3*reac_volume, BRUTE)
diff --git a/code/modules/antagonists/blob/blob/blobstrains/zombifying_pods.dm b/code/modules/antagonists/blob/blob/blobstrains/zombifying_pods.dm
new file mode 100644
index 0000000000..b2bb9d5115
--- /dev/null
+++ b/code/modules/antagonists/blob/blob/blobstrains/zombifying_pods.dm
@@ -0,0 +1,46 @@
+//kills sleeping targets and turns them into blob zombies, produces fragile spores when killed or on expanding
+/datum/blobstrain/reagent/zombifying_pods
+ name = "Zombifying Pods"
+ description = "will do very low toxin damage and harvest sleeping targets for additional resources and a blob zombie."
+ effectdesc = "will also produce fragile spores when killed and on expanding."
+ shortdesc = "will do very low toxin damage and harvest sleeping targets for additional resources(for your overmind) and a blob zombie."
+ analyzerdescdamage = "Does very low toxin damage and kills unconscious humans, turning them into blob zombies."
+ analyzerdesceffect = "Produces spores when expanding and when killed."
+ color = "#E88D5D"
+ complementary_color = "#823ABB"
+ message_living = ", and you feel tired"
+ reagent = /datum/reagent/blob/zombifying_pods
+
+/datum/blobstrain/reagent/zombifying_pods/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
+ if((damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") && damage <= 20 && B.obj_integrity - damage <= 0 && prob(30)) //if the cause isn't fire or a bomb, the damage is less than 21, we're going to die from that damage, 20% chance of a shitty spore.
+ B.visible_message("A spore floats free of the blob!")
+ var/mob/living/simple_animal/hostile/blob/blobspore/weak/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(B.loc)
+ BS.overmind = B.overmind
+ BS.update_icons()
+ B.overmind.blob_mobs.Add(BS)
+ return ..()
+
+/datum/blobstrain/reagent/zombifying_pods/expand_reaction(obj/structure/blob/B, obj/structure/blob/newB, turf/T, mob/camera/blob/O)
+ if(prob(10))
+ var/mob/living/simple_animal/hostile/blob/blobspore/weak/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(T)
+ BS.overmind = B.overmind
+ BS.update_icons()
+ newB.overmind.blob_mobs.Add(BS)
+
+/datum/reagent/blob/zombifying_pods
+ name = "Zombifying Pods"
+ color = "#E88D5D"
+
+/datum/reagent/blob/zombifying_pods/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+ reac_volume = ..()
+ M.apply_damage(0.6*reac_volume, TOX)
+ if(O && ishuman(M) && M.stat == UNCONSCIOUS)
+ M.death() //sleeping in a fight? bad plan.
+ var/points = rand(5, 10)
+ var/mob/living/simple_animal/hostile/blob/blobspore/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(get_turf(M))
+ BS.overmind = O
+ BS.update_icons()
+ O.blob_mobs.Add(BS)
+ BS.Zombify(M)
+ O.add_points(points)
+ to_chat(O, "Gained [points] resources from the zombification of [M].")
diff --git a/code/modules/antagonists/blob/blob/overmind.dm b/code/modules/antagonists/blob/blob/overmind.dm
index 18e13118fe..aed64e4039 100644
--- a/code/modules/antagonists/blob/blob/overmind.dm
+++ b/code/modules/antagonists/blob/blob/overmind.dm
@@ -20,25 +20,25 @@ GLOBAL_LIST_EMPTY(blob_nodes)
pass_flags = PASSBLOB
faction = list(ROLE_BLOB)
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
- call_life = TRUE
hud_type = /datum/hud/blob_overmind
var/obj/structure/blob/core/blob_core = null // The blob overmind's core
var/blob_points = 0
var/max_blob_points = 250
var/last_attack = 0
- var/datum/reagent/blob/blob_reagent_datum = new/datum/reagent/blob()
+ var/datum/blobstrain/blobstrain
var/list/blob_mobs = list()
var/list/resource_blobs = list()
- var/free_chem_rerolls = 1 //one free chemical reroll
+ var/free_strain_rerolls = 1 //one free strain reroll
+ var/last_reroll_time = 0 //time since we last rerolled, used to give free rerolls
var/nodes_required = 1 //if the blob needs nodes to place resource and factory blobs
var/placed = 0
- var/base_point_rate = 2 //for blob core placement
var/manualplace_min_time = 600 //in deciseconds //a minute, to get bearings
var/autoplace_max_time = 3600 //six minutes, as long as should be needed
var/list/blobs_legit = list()
var/max_count = 0 //The biggest it got before death
var/blobwincount = 400
var/victory_in_progress = FALSE
+ var/rerolling = FALSE
/mob/camera/blob/Initialize(mapload, starting_points = 60)
validate_location()
@@ -50,13 +50,14 @@ GLOBAL_LIST_EMPTY(blob_nodes)
name = new_name
real_name = new_name
last_attack = world.time
- var/datum/reagent/blob/BC = pick((subtypesof(/datum/reagent/blob)))
- blob_reagent_datum = new BC
- color = blob_reagent_datum.complementary_color
+ var/datum/blobstrain/BS = pick(GLOB.valid_blobstrains)
+ set_strain(BS)
+ color = blobstrain.complementary_color
if(blob_core)
blob_core.update_icon()
SSshuttle.registerHostileEnvironment(src)
- .= ..()
+ . = ..()
+ START_PROCESSING(SSobj, src)
/mob/camera/blob/proc/validate_location()
var/turf/T = get_turf(src)
@@ -70,13 +71,28 @@ GLOBAL_LIST_EMPTY(blob_nodes)
CRASH("No blobspawnpoints and blob spawned in nullspace.")
forceMove(T)
+/mob/camera/blob/proc/set_strain(datum/blobstrain/new_strain)
+ if (ispath(new_strain))
+ var/hadstrain = FALSE
+ if (istype(blobstrain))
+ blobstrain.on_lose()
+ qdel(blobstrain)
+ hadstrain = TRUE
+ blobstrain = new new_strain(src)
+ blobstrain.on_gain()
+ if (hadstrain)
+ to_chat(src, "Your strain is now: [blobstrain.name]!")
+ to_chat(src, "The [blobstrain.name] strain [blobstrain.description]")
+ if(blobstrain.effectdesc)
+ to_chat(src, "The [blobstrain.name] strain [blobstrain.effectdesc]")
+
/mob/camera/blob/proc/is_valid_turf(turf/T)
var/area/A = get_area(T)
if((A && !A.blob_allowed) || !T || !is_station_level(T.z) || isspaceturf(T))
return FALSE
return TRUE
-/mob/camera/blob/Life()
+/mob/camera/blob/process()
if(!blob_core)
if(!placed)
if(manualplace_min_time && world.time >= manualplace_min_time)
@@ -84,7 +100,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
to_chat(src, "You will automatically place your blob core in [DisplayTimeText(autoplace_max_time - world.time)].")
manualplace_min_time = 0
if(autoplace_max_time && world.time >= autoplace_max_time)
- place_blob_core(base_point_rate, 1)
+ place_blob_core(1)
else
qdel(src)
else if(!victory_in_progress && (blobs_legit.len >= blobwincount))
@@ -94,11 +110,12 @@ GLOBAL_LIST_EMPTY(blob_nodes)
max_blob_points = INFINITY
blob_points = INFINITY
addtimer(CALLBACK(src, .proc/victory), 450)
+ else if(!free_strain_rerolls && (last_reroll_time + BLOB_REROLL_TIMEYou have gained another free strain re-roll.")
+ free_strain_rerolls = 1
if(!victory_in_progress && max_count < blobs_legit.len)
max_count = blobs_legit.len
- ..()
-
/mob/camera/blob/proc/victory()
sound_to_playing_players('sound/machines/alarm.ogg')
@@ -129,7 +146,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
continue
if(!A.blob_allowed)
continue
- A.color = blob_reagent_datum.color
+ A.color = blobstrain.color
A.name = "blob"
A.icon = 'icons/mob/blob.dmi'
A.icon_state = "blob_shield"
@@ -162,6 +179,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
blobs_legit = null
SSshuttle.clearHostileEnvironment(src)
+ STOP_PROCESSING(SSobj, src)
return ..()
@@ -173,9 +191,9 @@ GLOBAL_LIST_EMPTY(blob_nodes)
add_points(0)
/mob/camera/blob/examine(mob/user)
- . = ..()
- if(blob_reagent_datum)
- . += "Its chemical is [blob_reagent_datum.name]."
+ ..()
+ if(blobstrain)
+ to_chat(user, "Its strain is [blobstrain.name].")
/mob/camera/blob/update_health_hud()
if(blob_core)
@@ -214,7 +232,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
src.log_talk(message, LOG_SAY)
var/message_a = say_quote(message)
- var/rendered = "\[Blob Telepathy\] [name]([blob_reagent_datum.name]) [message_a]"
+ var/rendered = "\[Blob Telepathy\] [name]([blobstrain.name]) [message_a]"
for(var/mob/M in GLOB.mob_list)
if(isovermind(M) || istype(M, /mob/living/simple_animal/hostile/blob))
@@ -233,8 +251,8 @@ GLOBAL_LIST_EMPTY(blob_nodes)
stat(null, "Core Health: [blob_core.obj_integrity]")
stat(null, "Power Stored: [blob_points]/[max_blob_points]")
stat(null, "Blobs to Win: [blobs_legit.len]/[blobwincount]")
- if(free_chem_rerolls)
- stat(null, "You have [free_chem_rerolls] Free Chemical Reroll\s Remaining")
+ if(free_strain_rerolls)
+ stat(null, "You have [free_strain_rerolls] Free Strain Reroll\s Remaining")
if(!placed)
if(manualplace_min_time)
stat(null, "Time Before Manual Placement: [max(round((manualplace_min_time - world.time)*0.1, 0.1), 0)]")
diff --git a/code/modules/antagonists/blob/blob/powers.dm b/code/modules/antagonists/blob/blob/powers.dm
index fe492831b8..641019ef33 100644
--- a/code/modules/antagonists/blob/blob/powers.dm
+++ b/code/modules/antagonists/blob/blob/powers.dm
@@ -7,7 +7,7 @@
// Power verbs
-/mob/camera/blob/proc/place_blob_core(point_rate, placement_override , pop_override = FALSE)
+/mob/camera/blob/proc/place_blob_core(placement_override, pop_override = FALSE)
if(placed && placement_override != -1)
return 1
if(!placement_override)
@@ -47,7 +47,7 @@
if(placed && blob_core)
blob_core.forceMove(loc)
else
- var/obj/structure/blob/core/core = new(get_turf(src), src, point_rate, 1)
+ var/obj/structure/blob/core/core = new(get_turf(src), src, 1)
core.overmind = src
blobs_legit += src
blob_core = core
@@ -71,13 +71,13 @@
var/list/nodes = list()
for(var/i in 1 to GLOB.blob_nodes.len)
var/obj/structure/blob/node/B = GLOB.blob_nodes[i]
- nodes["Blob Node #[i] ([B.overmind ? "[B.overmind.blob_reagent_datum.name]":"No Chemical"])"] = B
+ nodes["Blob Node #[i] ([B.overmind ? "[B.overmind.blobstrain.name]":"No Strain"])"] = B
var/node_name = input(src, "Choose a node to jump to.", "Node Jump") in nodes
var/obj/structure/blob/node/chosen_node = nodes[node_name]
if(chosen_node)
forceMove(chosen_node.loc)
-/mob/camera/blob/proc/createSpecial(price, blobType, nearEquals, needsNode, turf/T)
+/mob/camera/blob/proc/createSpecial(price, blobstrain, nearEquals, needsNode, turf/T)
if(!T)
T = get_turf(src)
var/obj/structure/blob/B = (locate(/obj/structure/blob) in T)
@@ -93,12 +93,12 @@
return //handholdotron 2000
if(nearEquals)
for(var/obj/structure/blob/L in orange(nearEquals, T))
- if(L.type == blobType)
+ if(L.type == blobstrain)
to_chat(src, "There is a similar blob nearby, move more than [nearEquals] tiles away from it!")
return
if(!can_buy(price))
return
- var/obj/structure/blob/N = B.change_to(blobType, src)
+ var/obj/structure/blob/N = B.change_to(blobstrain, src)
return N
/mob/camera/blob/verb/toggle_node_req()
@@ -123,6 +123,7 @@
if(!can_buy(15))
return
if(S.obj_integrity < S.max_integrity * 0.5)
+ add_points(BLOB_REFLECTOR_COST)
to_chat(src, "This shield blob is too damaged to be modified properly!")
return
to_chat(src, "You secrete a reflective ooze over the shield blob, allowing it to reflect projectiles at the cost of reduced intregrity.")
@@ -166,7 +167,9 @@
if(!can_buy(40))
return
- var/list/mob/candidates = pollGhostCandidates("Do you want to play as a [blob_reagent_datum.name] blobbernaut?", ROLE_BLOB, null, ROLE_BLOB, 50) //players must answer rapidly
+ B.naut = TRUE //temporary placeholder to prevent creation of more than one per factory.
+ to_chat(src, "You attempt to produce a blobbernaut.")
+ var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as a [blobstrain.name] blobbernaut?", ROLE_BLOB, null, ROLE_BLOB, 50) //players must answer rapidly
if(LAZYLEN(candidates)) //if we got at least one candidate, they're a blobbernaut now.
B.max_integrity = initial(B.max_integrity) * 0.25 //factories that produced a blobbernaut have much lower health
B.obj_integrity = min(B.obj_integrity, B.max_integrity)
@@ -188,8 +191,8 @@
to_chat(blobber, "You are a blobbernaut!")
to_chat(blobber, "You are powerful, hard to kill, and slowly regenerate near nodes and cores, but will slowly die if not near the blob or if the factory that made you is killed.")
to_chat(blobber, "You can communicate with other blobbernauts and overminds via :b")
- to_chat(blobber, "Your overmind's blob reagent is: [blob_reagent_datum.name]!")
- to_chat(blobber, "The [blob_reagent_datum.name] reagent [blob_reagent_datum.shortdesc ? "[blob_reagent_datum.shortdesc]" : "[blob_reagent_datum.description]"]")
+ to_chat(blobber, "Your overmind's blob reagent is: [blobstrain.name]!")
+ to_chat(blobber, "The [blobstrain.name] reagent [blobstrain.shortdesc ? "[blobstrain.shortdesc]" : "[blobstrain.description]"]")
else
to_chat(src, "You could not conjure a sentience for your blobbernaut. Your points have been refunded. Try again later.")
add_points(40)
@@ -265,9 +268,7 @@
continue
if(L.stat != DEAD)
attacksuccess = TRUE
- var/mob_protection = L.get_permeability_protection()
- blob_reagent_datum.reaction_mob(L, VAPOR, 25, 1, mob_protection, src)
- blob_reagent_datum.send_message(L)
+ blobstrain.attack_living(L)
var/obj/structure/blob/B = locate() in T
if(B)
if(attacksuccess) //if we successfully attacked a turf with a blob on it, don't refund shit
@@ -331,41 +332,38 @@
if(BM.stat == CONSCIOUS)
BM.say(speak_text)
-/mob/camera/blob/verb/chemical_reroll()
+/mob/camera/blob/verb/strain_reroll()
set category = "Blob"
- set name = "Reactive Chemical Adaptation (40)"
- set desc = "Replaces your chemical with a random, different one."
- if(free_chem_rerolls || can_buy(40))
- set_chemical()
- if(free_chem_rerolls)
- free_chem_rerolls--
+ set name = "Reactive Strain Adaptation (40)"
+ set desc = "Replaces your strain with a random, different one."
+ if(!rerolling && (free_strain_rerolls || can_buy(40)))
+ rerolling = TRUE
+ reroll_strain()
+ rerolling = FALSE
+ if(free_strain_rerolls)
+ free_strain_rerolls--
+ last_reroll_time = world.time
-/mob/camera/blob/proc/set_chemical()
- var/datum/reagent/blob/BC = pick((subtypesof(/datum/reagent/blob) - blob_reagent_datum.type))
- blob_reagent_datum = new BC
- color = blob_reagent_datum.complementary_color
- for(var/BL in GLOB.blobs)
- var/obj/structure/blob/B = BL
- B.update_icon()
- for(var/BLO in blob_mobs)
- var/mob/living/simple_animal/hostile/blob/BM = BLO
- BM.update_icons() //If it's getting a new chemical, tell it what it does!
- to_chat(BM, "Your overmind's blob reagent is now: [blob_reagent_datum.name]!")
- to_chat(BM, "The [blob_reagent_datum.name] reagent [blob_reagent_datum.shortdesc ? "[blob_reagent_datum.shortdesc]" : "[blob_reagent_datum.description]"]")
- to_chat(src, "Your reagent is now: [blob_reagent_datum.name]!")
- to_chat(src, "The [blob_reagent_datum.name] reagent [blob_reagent_datum.description]")
- if(blob_reagent_datum.effectdesc)
- to_chat(src, "The [blob_reagent_datum.name] reagent [blob_reagent_datum.effectdesc]")
+/mob/camera/blob/proc/reroll_strain()
+ var/list/choices = list()
+ while (length(choices) < 4)
+ var/datum/blobstrain/bs = pick((GLOB.valid_blobstrains))
+ choices[initial(bs.name)] = bs
+
+ var/choice = input(usr, "Please choose a new strain","Strain") as anything in choices
+ if (choice && choices[choice] && !QDELETED(src))
+ var/datum/blobstrain/bs = choices[choice]
+ set_strain(bs)
/mob/camera/blob/verb/blob_help()
set category = "Blob"
set name = "*Blob Help*"
set desc = "Help on how to blob."
to_chat(src, "As the overmind, you can control the blob!")
- to_chat(src, "Your blob reagent is: [blob_reagent_datum.name]!")
- to_chat(src, "The [blob_reagent_datum.name] reagent [blob_reagent_datum.description]")
- if(blob_reagent_datum.effectdesc)
- to_chat(src, "The [blob_reagent_datum.name] reagent [blob_reagent_datum.effectdesc]")
+ to_chat(src, "Your blob reagent is: [blobstrain.name]!")
+ to_chat(src, "The [blobstrain.name] reagent [blobstrain.description]")
+ if(blobstrain.effectdesc)
+ to_chat(src, "The [blobstrain.name] reagent [blobstrain.effectdesc]")
to_chat(src, "You can expand, which will attack people, damage objects, or place a Normal Blob if the tile is clear.")
to_chat(src, "Normal Blobs will expand your reach and can be upgraded into special blobs that perform certain functions.")
to_chat(src, "You can upgrade normal blobs into the following types of blob:")
diff --git a/code/modules/antagonists/blob/blob/theblob.dm b/code/modules/antagonists/blob/blob/theblob.dm
index fc78f859f2..444b10684b 100644
--- a/code/modules/antagonists/blob/blob/theblob.dm
+++ b/code/modules/antagonists/blob/blob/theblob.dm
@@ -83,16 +83,10 @@
/obj/structure/blob/update_icon() //Updates color based on overmind color if we have an overmind.
if(overmind)
- add_atom_colour(overmind.blob_reagent_datum.color, FIXED_COLOUR_PRIORITY)
+ add_atom_colour(overmind.blobstrain.color, FIXED_COLOUR_PRIORITY)
else
remove_atom_colour(FIXED_COLOUR_PRIORITY)
-/obj/structure/blob/process()
- Life()
-
-/obj/structure/blob/proc/Life()
- return
-
/obj/structure/blob/proc/Pulse_Area(mob/camera/blob/pulsing_overmind, claim_range = 10, pulse_range = 3, expand_range = 2)
if(QDELETED(pulsing_overmind))
pulsing_overmind = overmind
@@ -148,10 +142,10 @@
O.setDir(dir)
if(controller)
var/mob/camera/blob/BO = controller
- O.color = BO.blob_reagent_datum.color
+ O.color = BO.blobstrain.color
O.alpha = 200
else if(overmind)
- O.color = overmind.blob_reagent_datum.color
+ O.color = overmind.blobstrain.color
if(A)
O.do_attack_animation(A) //visually attack the whatever
return O //just in case you want to do something to the animation.
@@ -192,7 +186,7 @@
B.forceMove(T)
B.update_icon()
if(B.overmind && expand_reaction)
- B.overmind.blob_reagent_datum.expand_reaction(src, B, T, controller)
+ B.overmind.blobstrain.expand_reaction(src, B, T, controller)
return B
else
blob_attack_animation(T, controller)
@@ -209,14 +203,14 @@
return
if(severity > 0)
if(overmind)
- overmind.blob_reagent_datum.emp_reaction(src, severity)
+ overmind.blobstrain.emp_reaction(src, severity)
if(prob(100 - severity * 30))
new /obj/effect/temp_visual/emp(get_turf(src))
/obj/structure/blob/tesla_act(power)
..()
if(overmind)
- if(overmind.blob_reagent_datum.tesla_reaction(src, power))
+ if(overmind.blobstrain.tesla_reaction(src, power))
take_damage(power/400, BURN, "energy")
else
take_damage(power/400, BURN, "energy")
@@ -224,7 +218,7 @@
/obj/structure/blob/extinguish()
..()
if(overmind)
- overmind.blob_reagent_datum.extinguish_reaction(src)
+ overmind.blobstrain.extinguish_reaction(src)
/obj/structure/blob/hulk_damage()
return 15
@@ -243,13 +237,13 @@
else
return ..()
-/obj/structure/blob/proc/chemeffectreport()
+/obj/structure/blob/proc/chemeffectreport(mob/user)
RETURN_TYPE(/list)
. = list()
if(overmind)
- . += "Material: [overmind.blob_reagent_datum.name]."
- . += "Material Effects: [overmind.blob_reagent_datum.analyzerdescdamage]"
- . += "Material Properties: [overmind.blob_reagent_datum.analyzerdesceffect]
"
+ to_chat(user, "Material: [overmind.blobstrain.name].")
+ to_chat(user, "Material Effects: [overmind.blobstrain.analyzerdescdamage]")
+ to_chat(user, "Material Properties: [overmind.blobstrain.analyzerdesceffect]
")
else
. += "No Material Detected!
"
@@ -288,7 +282,7 @@
armor_protection = armor.getRating(damage_flag)
damage_amount = round(damage_amount * (100 - armor_protection)*0.01, 0.1)
if(overmind && damage_flag)
- damage_amount = overmind.blob_reagent_datum.damage_reaction(src, damage_amount, damage_type, damage_flag)
+ damage_amount = overmind.blobstrain.damage_reaction(src, damage_amount, damage_type, damage_flag)
return damage_amount
/obj/structure/blob/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
@@ -298,7 +292,7 @@
/obj/structure/blob/obj_destruction(damage_flag)
if(overmind)
- overmind.blob_reagent_datum.death_reaction(src, damage_flag)
+ overmind.blobstrain.death_reaction(src, damage_flag)
..()
/obj/structure/blob/proc/change_to(type, controller)
@@ -332,8 +326,8 @@
/obj/structure/blob/proc/get_chem_name()
if(overmind)
- return overmind.blob_reagent_datum.name
- return "an unknown variant"
+ return overmind.blobstrain.name
+ return "some kind of organic tissue"
/obj/structure/blob/normal
name = "normal blob"
diff --git a/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm b/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm
index db286dd6fe..a8925dfb7b 100644
--- a/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm
+++ b/code/modules/antagonists/bloodsucker/objects/bloodsucker_crypt.dm
@@ -258,7 +258,7 @@
/obj/structure/bloodsucker/vassalrack/proc/torture_victim(mob/living/user, mob/living/target)
var/datum/antagonist/bloodsucker/bloodsuckerdatum = user.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
// Check Bloodmob/living/M, force = FALSE, check_loc = TRUE
- var/convert_cost = 200 + 200 * bloodsuckerdatum.vassals
+ var/convert_cost = 200 + 200 * bloodsuckerdatum.vassals
if(user.blood_volume < convert_cost + 5)
to_chat(user, "You don't have enough blood to initiate the Dark Communion with [target].")
return
@@ -449,7 +449,7 @@
/obj/structure/bloodsucker/candelabrum/Destroy()
STOP_PROCESSING(SSobj, src)
-/obj/structure/bloodsucker/candelabrum/update_icon()
+/obj/structure/bloodsucker/candelabrum/update_icon_state()
icon_state = "candelabrum[lit ? "_lit" : ""]"
/obj/structure/bloodsucker/candelabrum/examine(mob/user)
diff --git a/code/modules/antagonists/bloodsucker/powers/mesmerize.dm b/code/modules/antagonists/bloodsucker/powers/mesmerize.dm
index d5354c1af9..3be5eb02e9 100644
--- a/code/modules/antagonists/bloodsucker/powers/mesmerize.dm
+++ b/code/modules/antagonists/bloodsucker/powers/mesmerize.dm
@@ -126,15 +126,12 @@
to_chat(user, "[target] is fixed in place by your hypnotic gaze.")
target.next_move = world.time + power_time // <--- Use direct change instead. We want an unmodified delay to their next move // target.changeNext_move(power_time) // check click.dm
target.notransform = TRUE // <--- Fuck it. We tried using next_move, but they could STILL resist. We're just doing a hard freeze.
-
- UnregisterSignal(target, COMSIG_MOVABLE_MOVED)
-
- spawn(power_time)
- if(istype(target) && success)
- target.notransform = FALSE
- // They Woke Up! (Notice if within view)
- if(istype(user) && target.stat == CONSCIOUS && (target in view(10, get_turf(user))) )
- to_chat(user, "[target] has snapped out of their trance.")
+ spawn(power_time)
+ if(istype(target) && success)
+ target.notransform = FALSE
+ // They Woke Up! (Notice if within view)
+ if(istype(user) && target.stat == CONSCIOUS && (target in view(10, get_turf(user))) )
+ to_chat(user, "[target] has snapped out of their trance.")
/datum/action/bloodsucker/targeted/mesmerize/ContinueActive(mob/living/user, mob/living/target)
return ..() && CheckCanUse() && CheckCanTarget(target)
diff --git a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm
index 1b4d26ac86..62382966f0 100644
--- a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm
+++ b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm
@@ -251,6 +251,7 @@
return TRUE
/obj/effect/clockwork/sigil/transmission/update_icon()
+ . = ..()
var/power_charge = get_clockwork_power()
if(GLOB.ratvar_awakens)
alpha = 255
diff --git a/code/modules/antagonists/clockcult/clock_mobs.dm b/code/modules/antagonists/clockcult/clock_mobs.dm
index 9bdf03cbc7..2f00fd4e4a 100644
--- a/code/modules/antagonists/clockcult/clock_mobs.dm
+++ b/code/modules/antagonists/clockcult/clock_mobs.dm
@@ -37,7 +37,7 @@
/mob/living/simple_animal/hostile/clockwork/ratvar_act()
fully_heal(TRUE)
-/mob/living/simple_animal/hostile/clockwork/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
+/mob/living/simple_animal/hostile/clockwork/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
return 0 //ouch, my metal-unlikely-to-be-damaged-by-electricity-body
/mob/living/simple_animal/hostile/clockwork/examine(mob/user)
diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm
index 3dc199b56d..edeb74eeaf 100644
--- a/code/modules/antagonists/cult/cult_items.dm
+++ b/code/modules/antagonists/cult/cult_items.dm
@@ -264,7 +264,7 @@
/obj/item/restraints/legcuffs/bola/cult/pickup(mob/living/user)
if(!iscultist(user))
to_chat(user, "The bola seems to take on a life of its own!")
- throw_impact(user)
+ ensnare(user)
/obj/item/restraints/legcuffs/bola/cult/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(iscultist(hit_atom))
@@ -372,7 +372,7 @@
max = 40
prefix = "darkened"
-/obj/item/sharpener/cult/update_icon()
+/obj/item/sharpener/cult/update_icon_state()
var/old_state = icon_state
icon_state = "cult_sharpener[used ? "_used" : ""]"
if(old_state != icon_state)
@@ -688,7 +688,7 @@
qdel(spear_act)
..()
-/obj/item/twohanded/cult_spear/update_icon()
+/obj/item/twohanded/cult_spear/update_icon_state()
icon_state = "bloodspear[wielded]"
/obj/item/twohanded/cult_spear/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm
index c6c29a385b..1963bf16e3 100644
--- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm
+++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm
@@ -31,6 +31,7 @@
var/interior = ""
var/proper_bomb = TRUE //Please
var/obj/effect/countdown/nuclearbomb/countdown
+ var/nuclear_cooldown //used to stop global spam.
/obj/machinery/nuclearbomb/Initialize()
. = ..()
@@ -416,12 +417,16 @@
return
timing = !timing
if(timing)
+ if(nuclear_cooldown > world.time)
+ to_chat(usr, "[src]'s timer protocols are currently on cooldown, please stand by.")
+ return
previous_level = get_security_level()
detonation_timer = world.time + (timer_set * 10)
for(var/obj/item/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list)
S.switch_mode_to(TRACK_INFILTRATOR)
countdown.start()
set_security_level("delta")
+ nuclear_cooldown = world.time + 15 SECONDS
if(GLOB.war_declared)
var/area/A = get_area(src)
diff --git a/code/modules/antagonists/overthrow/overthrow_converter.dm b/code/modules/antagonists/overthrow/overthrow_converter.dm
index 99d1a52de8..eec6163107 100644
--- a/code/modules/antagonists/overthrow/overthrow_converter.dm
+++ b/code/modules/antagonists/overthrow/overthrow_converter.dm
@@ -49,7 +49,7 @@
else
to_chat(user, "[user] fails to implant [M].")
-/obj/item/overthrow_converter/update_icon()
+/obj/item/overthrow_converter/update_icon_state()
if(uses)
icon_state = "implanter1"
else
diff --git a/code/modules/antagonists/revenant/revenant_abilities.dm b/code/modules/antagonists/revenant/revenant_abilities.dm
index d2e71615e3..a99e3900b0 100644
--- a/code/modules/antagonists/revenant/revenant_abilities.dm
+++ b/code/modules/antagonists/revenant/revenant_abilities.dm
@@ -213,7 +213,7 @@
continue
L.Beam(M,icon_state="purple_lightning",time=5)
if(!M.anti_magic_check(FALSE, TRUE))
- M.electrocute_act(shock_damage, L, safety=TRUE)
+ M.electrocute_act(shock_damage, L, flags = SHOCK_NOGLOVES)
do_sparks(4, FALSE, M)
playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1)
diff --git a/code/modules/antagonists/slaughter/slaughter.dm b/code/modules/antagonists/slaughter/slaughter.dm
index 8a01622c87..475438ba52 100644
--- a/code/modules/antagonists/slaughter/slaughter.dm
+++ b/code/modules/antagonists/slaughter/slaughter.dm
@@ -76,8 +76,9 @@
icon_state = "demon_heart-on"
decay_factor = 0
-/obj/item/organ/heart/demon/update_icon()
- return //always beating visually
+/obj/item/organ/heart/demon/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/update_icon_blocker)
/obj/item/organ/heart/demon/attack(mob/M, mob/living/carbon/user, obj/target)
if(M != user)
diff --git a/code/modules/antagonists/swarmer/swarmer.dm b/code/modules/antagonists/swarmer/swarmer.dm
index 92852c6c7f..292fb10202 100644
--- a/code/modules/antagonists/swarmer/swarmer.dm
+++ b/code/modules/antagonists/swarmer/swarmer.dm
@@ -492,8 +492,8 @@
playsound(src,'sound/effects/sparks4.ogg',50,1)
do_teleport(target, F, 0, channel = TELEPORT_CHANNEL_BLUESPACE)
-/mob/living/simple_animal/hostile/swarmer/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE)
- if(!tesla_shock)
+/mob/living/simple_animal/hostile/swarmer/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
+ if(!(flags & SHOCK_TESLA))
return FALSE
return ..()
@@ -584,7 +584,7 @@
var/mob/living/L = AM
if(!istype(L, /mob/living/simple_animal/hostile/swarmer))
playsound(loc,'sound/effects/snap.ogg',50, 1, -1)
- L.electrocute_act(0, src, 1, 1, 1)
+ L.electrocute_act(0, src, 1, flags = SHOCK_NOGLOVES|SHOCK_ILLUSION)
if(iscyborg(L))
L.DefaultCombatKnockdown(100)
qdel(src)
diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm
index 28bb543828..3dfc0d859d 100644
--- a/code/modules/assembly/bomb.dm
+++ b/code/modules/assembly/bomb.dm
@@ -19,15 +19,17 @@
/obj/item/onetankbomb/examine(mob/user)
bombtank.examine(user)
-/obj/item/onetankbomb/update_icon()
- cut_overlays()
+/obj/item/onetankbomb/update_icon_state()
if(bombtank)
icon = bombtank.icon
icon_state = bombtank.icon_state
+
+/obj/item/onetankbomb/update_overlays()
+ . = ..()
if(bombassembly)
- add_overlay(bombassembly.icon_state)
- copy_overlays(bombassembly)
- add_overlay("bomb_assembly")
+ . += bombassembly.icon_state
+ . += bombassembly.overlays
+ . += "bomb_assembly"
/obj/item/onetankbomb/wrench_act(mob/living/user, obj/item/I)
to_chat(user, "You disassemble [src]!")
diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm
index 4d2b8de586..07ddd4c042 100644
--- a/code/modules/atmospherics/machinery/airalarm.dm
+++ b/code/modules/atmospherics/machinery/airalarm.dm
@@ -624,10 +624,7 @@
"set_internal_pressure" = 0
))
-/obj/machinery/airalarm/update_icon()
- set_light(0)
- cut_overlays()
- SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays)
+/obj/machinery/airalarm/update_icon_state()
if(stat & NOPOWER)
icon_state = "alarm0"
return
@@ -636,35 +633,39 @@
icon_state = "alarmx"
return
- if(panel_open)
- switch(buildstage)
- if(2)
- icon_state = "alarmx"
- if(1)
- icon_state = "alarm_b2"
- if(0)
- icon_state = "alarm_b1"
+ if(!panel_open)
+ icon_state = "alarm1"
return
- icon_state = "alarm1"
+ switch(buildstage)
+ if(2)
+ icon_state = "alarmx"
+ if(1)
+ icon_state = "alarm_b2"
+ if(0)
+ icon_state = "alarm_b1"
+
+/obj/machinery/airalarm/update_overlays()
+ . = ..()
+ SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays)
var/overlay_state = AALARM_OVERLAY_OFF
var/area/A = get_base_area(src)
switch(max(danger_level, A.atmosalm))
if(0)
- add_overlay(AALARM_OVERLAY_GREEN)
overlay_state = AALARM_OVERLAY_GREEN
light_color = LIGHT_COLOR_GREEN
- set_light(brightness_on)
if(1)
- add_overlay(AALARM_OVERLAY_WARN)
overlay_state = AALARM_OVERLAY_WARN
light_color = LIGHT_COLOR_LAVA
- set_light(brightness_on)
if(2)
- add_overlay(AALARM_OVERLAY_DANGER)
overlay_state = AALARM_OVERLAY_DANGER
light_color = LIGHT_COLOR_RED
- set_light(brightness_on)
+
+ if(overlay_state != AALARM_OVERLAY_OFF)
+ . += overlay_state
+ set_light(brightness_on)
+ else
+ set_light(0)
SSvis_overlays.add_vis_overlay(src, icon, overlay_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir)
update_light()
diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm
index 0d335da482..0b26cfc2f0 100644
--- a/code/modules/atmospherics/machinery/portable/canister.dm
+++ b/code/modules/atmospherics/machinery/portable/canister.dm
@@ -34,7 +34,6 @@
var/restricted = FALSE
req_access = list()
- var/update = 0
var/static/list/label2types = list(
"n2" = /obj/machinery/portable_atmospherics/canister/nitrogen,
"o2" = /obj/machinery/portable_atmospherics/canister/oxygen,
@@ -213,61 +212,26 @@
air_contents.gases[/datum/gas/oxygen] = (O2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
air_contents.gases[/datum/gas/nitrogen] = (N2STANDARD * maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
-#define HOLDING (1<<0)
-#define CONNECTED (1<<1)
-#define EMPTY (1<<2)
-#define LOW (1<<3)
-#define MEDIUM (1<<4)
-#define FULL (1<<5)
-#define DANGER (1<<6)
-/obj/machinery/portable_atmospherics/canister/update_icon()
+/obj/machinery/portable_atmospherics/canister/update_icon_state()
if(stat & BROKEN)
- cut_overlays()
icon_state = "[icon_state]-1"
- return
- var/last_update = update
- update = 0
+/obj/machinery/portable_atmospherics/canister/update_overlays()
+ . = ..()
if(holding)
- update |= HOLDING
+ . += "can-open"
if(connected_port)
- update |= CONNECTED
+ . += "can-connector"
var/pressure = air_contents.return_pressure()
- if(pressure < 10)
- update |= EMPTY
- else if(pressure < 5 * ONE_ATMOSPHERE)
- update |= LOW
- else if(pressure < 10 * ONE_ATMOSPHERE)
- update |= MEDIUM
- else if(pressure < 40 * ONE_ATMOSPHERE)
- update |= FULL
- else
- update |= DANGER
-
- if(update == last_update)
- return
-
- cut_overlays()
- if(update & HOLDING)
- add_overlay("can-open")
- if(update & CONNECTED)
- add_overlay("can-connector")
- if(update & LOW)
- add_overlay("can-o0")
- else if(update & MEDIUM)
- add_overlay("can-o1")
- else if(update & FULL)
- add_overlay("can-o2")
- else if(update & DANGER)
- add_overlay("can-o3")
-#undef HOLDING
-#undef CONNECTED
-#undef EMPTY
-#undef LOW
-#undef MEDIUM
-#undef FULL
-#undef DANGER
+ if(pressure >= 40 * ONE_ATMOSPHERE)
+ . += "can-o3"
+ else if(pressure >= 10 * ONE_ATMOSPHERE)
+ . += "can-o2"
+ else if(pressure >= 5 * ONE_ATMOSPHERE)
+ . += "can-o1"
+ else if(pressure >= 10)
+ . += "can-o0"
/obj/machinery/portable_atmospherics/canister/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > temperature_resistance)
diff --git a/code/modules/atmospherics/machinery/portable/pump.dm b/code/modules/atmospherics/machinery/portable/pump.dm
index ddb907a2ad..3603e46490 100644
--- a/code/modules/atmospherics/machinery/portable/pump.dm
+++ b/code/modules/atmospherics/machinery/portable/pump.dm
@@ -29,14 +29,16 @@
QDEL_NULL(pump)
return ..()
-/obj/machinery/portable_atmospherics/pump/update_icon()
+/obj/machinery/portable_atmospherics/pump/update_icon_state()
icon_state = "psiphon:[on]"
- cut_overlays()
+
+/obj/machinery/portable_atmospherics/pump/update_overlays()
+ . = ..()
if(holding)
- add_overlay("siphon-open")
+ . += "siphon-open"
if(connected_port)
- add_overlay("siphon-connector")
+ . += "siphon-connector"
/obj/machinery/portable_atmospherics/pump/process_atmos()
..()
diff --git a/code/modules/atmospherics/machinery/portable/scrubber.dm b/code/modules/atmospherics/machinery/portable/scrubber.dm
index 0c902e0426..3dfce7c1bf 100644
--- a/code/modules/atmospherics/machinery/portable/scrubber.dm
+++ b/code/modules/atmospherics/machinery/portable/scrubber.dm
@@ -5,6 +5,7 @@
var/on = FALSE
var/volume_rate = 1000
+ var/use_overlays = TRUE
volume = 1000
var/list/scrubbing = list(/datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/bz, /datum/gas/nitryl, /datum/gas/tritium, /datum/gas/hypernoblium, /datum/gas/water_vapor)
@@ -15,14 +16,17 @@
air_update_turf()
return ..()
-/obj/machinery/portable_atmospherics/scrubber/update_icon()
+/obj/machinery/portable_atmospherics/scrubber/update_icon_state()
icon_state = "pscrubber:[on]"
- cut_overlays()
+/obj/machinery/portable_atmospherics/scrubber/update_overlays()
+ . = ..()
+ if(!use_overlays)
+ return
if(holding)
- add_overlay("scrubber-open")
+ . += "scrubber-open"
if(connected_port)
- add_overlay("scrubber-connector")
+ . += "scrubber-connector"
/obj/machinery/portable_atmospherics/scrubber/process_atmos()
..()
@@ -117,11 +121,12 @@
volume = 50000
var/movable = FALSE
+ use_overlays = FALSE
/obj/machinery/portable_atmospherics/scrubber/huge/movable
movable = TRUE
-/obj/machinery/portable_atmospherics/scrubber/huge/update_icon()
+/obj/machinery/portable_atmospherics/scrubber/huge/update_icon_state()
icon_state = "scrubber:[on]"
/obj/machinery/portable_atmospherics/scrubber/huge/process_atmos()
diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm
index e693abc8e4..4f155d4174 100644
--- a/code/modules/awaymissions/gateway.dm
+++ b/code/modules/awaymissions/gateway.dm
@@ -53,11 +53,8 @@ GLOBAL_DATUM(the_gateway, /obj/machinery/gateway/centerstation)
ready = TRUE
return ready
-/obj/machinery/gateway/update_icon()
- if(active)
- icon_state = "on"
- return
- icon_state = "off"
+/obj/machinery/gateway/update_icon_state()
+ icon_state = active ? "on" : "off"
/obj/machinery/gateway/attack_hand(mob/user)
. = ..()
@@ -100,11 +97,8 @@ GLOBAL_DATUM(the_gateway, /obj/machinery/gateway/centerstation)
var/obj/machinery/gateway/centeraway/awaygate = null
can_link = TRUE
-/obj/machinery/gateway/centerstation/update_icon()
- if(active)
- icon_state = "oncenter"
- return
- icon_state = "offcenter"
+/obj/machinery/gateway/centerstation/update_icon_state()
+ icon_state = active ? "oncenter" : "offcenter"
/obj/machinery/gateway/centerstation/process()
if((stat & (NOPOWER)) && use_power)
@@ -185,11 +179,8 @@ GLOBAL_DATUM(the_gateway, /obj/machinery/gateway/centerstation)
stationgate = locate(/obj/machinery/gateway/centerstation)
-/obj/machinery/gateway/centeraway/update_icon()
- if(active)
- icon_state = "oncenter"
- return
- icon_state = "offcenter"
+/obj/machinery/gateway/centeraway/update_icon_state()
+ icon_state = active ? "oncenter" : "offcenter"
/obj/machinery/gateway/centeraway/toggleon(mob/user)
if(!detect())
diff --git a/code/modules/awaymissions/mission_code/Academy.dm b/code/modules/awaymissions/mission_code/Academy.dm
index f24cb065dd..a1453f6aa1 100644
--- a/code/modules/awaymissions/mission_code/Academy.dm
+++ b/code/modules/awaymissions/mission_code/Academy.dm
@@ -337,8 +337,9 @@
icon_state = "1"
color = rgb(0,0,255)
-/obj/structure/ladder/unbreakable/rune/update_icon()
- return
+/obj/structure/ladder/unbreakable/rune/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/update_icon_blocker)
/obj/structure/ladder/unbreakable/rune/show_fluff_message(up,mob/user)
user.visible_message("[user] activates \the [src].","You activate \the [src].")
diff --git a/code/modules/awaymissions/pamphlet.dm b/code/modules/awaymissions/pamphlet.dm
index 7cbbde096d..74bcb4b302 100644
--- a/code/modules/awaymissions/pamphlet.dm
+++ b/code/modules/awaymissions/pamphlet.dm
@@ -35,5 +35,6 @@
environs."
//we don't want the silly text overlay!
-/obj/item/paper/pamphlet/update_icon()
- return
+/obj/item/paper/pamphlet/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/update_icon_blocker)
diff --git a/code/modules/buildmode/buttons.dm b/code/modules/buildmode/buttons.dm
index e72dbde064..c219f18cec 100644
--- a/code/modules/buildmode/buttons.dm
+++ b/code/modules/buildmode/buttons.dm
@@ -27,7 +27,7 @@
update_icon()
return 1
-/obj/screen/buildmode/mode/update_icon()
+/obj/screen/buildmode/mode/update_icon_state()
icon_state = bd.mode.get_button_iconstate()
/obj/screen/buildmode/help
@@ -44,9 +44,8 @@
screen_loc = "NORTH,WEST+2"
name = "Change Dir"
-/obj/screen/buildmode/bdir/update_icon()
+/obj/screen/buildmode/bdir/update_icon_state()
dir = bd.build_dir
- return
/obj/screen/buildmode/bdir/Click()
bd.toggle_dirswitch()
diff --git a/code/modules/cargo/packs/organic.dm b/code/modules/cargo/packs/organic.dm
index cdac6f49f2..ffc0d757b5 100644
--- a/code/modules/cargo/packs/organic.dm
+++ b/code/modules/cargo/packs/organic.dm
@@ -193,8 +193,8 @@
/obj/item/reagent_containers/food/snacks/meat/slab/bear,
/obj/item/reagent_containers/food/snacks/meat/slab/xeno,
/obj/item/reagent_containers/food/snacks/meat/slab/spider,
+ /obj/item/reagent_containers/food/snacks/spidereggs,
/obj/item/reagent_containers/food/snacks/meat/rawcrab,
- /obj/item/reagent_containers/food/snacks/meat/rawbacon,
/obj/item/reagent_containers/food/snacks/spiderleg,
/obj/item/reagent_containers/food/snacks/carpmeat,
/obj/item/reagent_containers/food/snacks/meat/slab/human)
diff --git a/code/modules/cargo/supplypod.dm b/code/modules/cargo/supplypod.dm
index e82a2141eb..aaa1afb004 100644
--- a/code/modules/cargo/supplypod.dm
+++ b/code/modules/cargo/supplypod.dm
@@ -78,15 +78,14 @@
. = ..()
setStyle(style, TRUE) //Upon initialization, give the supplypod an iconstate, name, and description based on the "style" variable. This system is important for the centcom_podlauncher to function correctly
-/obj/structure/closet/supplypod/update_icon()
- cut_overlays()
+/obj/structure/closet/supplypod/closet_update_overlays(list/new_overlays)
+ . = new_overlays
if (style == STYLE_SEETHROUGH || style == STYLE_INVISIBLE) //If we're invisible, we dont bother adding any overlays
return
+ if (opened)
+ . += "[icon_state]_open"
else
- if (opened)
- add_overlay("[icon_state]_open")
- else
- add_overlay("[icon_state]_door")
+ . += "[icon_state]_door"
/obj/structure/closet/supplypod/proc/setStyle(chosenStyle, var/duringInit = FALSE) //Used to give the sprite an icon state, name, and description
if (!duringInit && style == chosenStyle) //Check if the input style is already the same as the pod's style. This happens in centcom_podlauncher, and as such we set the style to STYLE_CENTCOM.
diff --git a/code/modules/cargo/supplypod_beacon.dm b/code/modules/cargo/supplypod_beacon.dm
index 668698d2e9..b749d4def6 100644
--- a/code/modules/cargo/supplypod_beacon.dm
+++ b/code/modules/cargo/supplypod_beacon.dm
@@ -31,14 +31,14 @@
ready = FALSE
update_icon()
-/obj/item/supplypod_beacon/update_icon()
- cut_overlays()
+/obj/item/supplypod_beacon/update_overlays()
+ . = ..()
if (launched)
- add_overlay("sp_green")
+ . += "sp_green"
else if (ready)
- add_overlay("sp_yellow")
+ . += "sp_yellow"
else if (linked)
- add_overlay("sp_orange")
+ . += "sp_orange"
/obj/item/supplypod_beacon/proc/endLaunch()
launched = FALSE
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index a9cf45744e..a9deba070a 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -2429,6 +2429,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
character.Digitigrade_Leg_Swap(TRUE)
+ SEND_SIGNAL(character, COMSIG_HUMAN_PREFS_COPIED_TO, src, icon_updates, roundstart_checks)
+
//let's be sure the character updates
if(icon_updates)
character.update_body()
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index ef2ee331a9..7e2d73190a 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -441,17 +441,14 @@ BLIND // can't see anything
return TRUE
-/obj/item/clothing/update_icon() // Polychrome stuff
- ..()
+/obj/item/clothing/update_overlays() // Polychrome stuff
+ . = ..()
if(hasprimary) //Checks if the overlay is enabled
- var/mutable_appearance/primary_overlay = mutable_appearance(icon, "[item_color]-primary") //Automagically picks overlays
- primary_overlay.color = primary_color //Colors the greyscaled overlay
- add_overlay(primary_overlay) //Applies the coloured overlay onto the item sprite. but NOT the mob sprite.
+ var/mutable_appearance/primary_overlay = mutable_appearance(icon, "[item_color]-primary", color = primary_color) //Automagically picks overlays
+ . += primary_overlay //Applies the coloured overlay onto the item sprite. but NOT the mob sprite.
if(hassecondary)
- var/mutable_appearance/secondary_overlay = mutable_appearance(icon, "[item_color]-secondary")
- secondary_overlay.color = secondary_color
- add_overlay(secondary_overlay)
+ var/mutable_appearance/secondary_overlay = mutable_appearance(icon, "[item_color]-secondary", color = secondary_color)
+ . += secondary_overlay
if(hastertiary)
- var/mutable_appearance/tertiary_overlay = mutable_appearance(icon, "[item_color]-tertiary")
- tertiary_overlay.color = tertiary_color
- add_overlay(tertiary_overlay)
\ No newline at end of file
+ var/mutable_appearance/tertiary_overlay = mutable_appearance(icon, "[item_color]-tertiary", color = tertiary_color)
+ . += tertiary_overlay
\ No newline at end of file
diff --git a/code/modules/clothing/ears/_ears.dm b/code/modules/clothing/ears/_ears.dm
index 6775279ef6..1c31e19202 100644
--- a/code/modules/clothing/ears/_ears.dm
+++ b/code/modules/clothing/ears/_ears.dm
@@ -35,16 +35,15 @@
. = ..()
update_icon()
-/obj/item/clothing/ears/headphones/update_icon()
+/obj/item/clothing/ears/headphones/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/update_icon_updates_onmob)
+
+/obj/item/clothing/ears/headphones/update_icon_state()
icon_state = "[initial(icon_state)]_[headphones_on? "on" : "off"]"
item_state = "[initial(item_state)]_[headphones_on? "on" : "off"]"
/obj/item/clothing/ears/headphones/proc/toggle(owner)
headphones_on = !headphones_on
update_icon()
- var/mob/living/carbon/human/H = owner
- if(istype(H))
- H.update_inv_ears()
- H.update_inv_neck()
- H.update_inv_head()
to_chat(owner, "You turn the music [headphones_on? "on. Untz Untz Untz!" : "off."]")
diff --git a/code/modules/clothing/glasses/engine_goggles.dm b/code/modules/clothing/glasses/engine_goggles.dm
index 0132fa8596..2a64445776 100644
--- a/code/modules/clothing/glasses/engine_goggles.dm
+++ b/code/modules/clothing/glasses/engine_goggles.dm
@@ -31,6 +31,10 @@
START_PROCESSING(SSobj, src)
update_icon()
+/obj/item/clothing/glasses/meson/engine/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/update_icon_updates_onmob)
+
/obj/item/clothing/glasses/meson/engine/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
@@ -120,18 +124,8 @@
pic = new('icons/turf/overlays.dmi', place, "redOverlay", AREA_LAYER)
flick_overlay(pic, list(user.client), 8)
-/obj/item/clothing/glasses/meson/engine/update_icon()
+/obj/item/clothing/glasses/meson/engine/update_icon_state()
icon_state = "trayson-[mode]"
- update_mob()
-
-/obj/item/clothing/glasses/meson/engine/proc/update_mob()
- item_state = icon_state
- if(isliving(loc))
- var/mob/living/user = loc
- if(user.get_item_by_slot(SLOT_GLASSES) == src)
- user.update_inv_glasses()
- else
- user.update_inv_hands()
/obj/item/clothing/glasses/meson/engine/tray //atmos techs have lived far too long without tray goggles while those damned engineers get their dual-purpose gogles all to themselves
name = "optical t-ray scanner"
diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm
index e7a8243889..29b0aa9552 100644
--- a/code/modules/clothing/head/hardhat.dm
+++ b/code/modules/clothing/head/hardhat.dm
@@ -16,6 +16,11 @@
dog_fashion = /datum/dog_fashion/head
+
+/obj/item/clothing/head/hardhat/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/update_icon_updates_onmob)
+
/obj/item/clothing/head/hardhat/attack_self(mob/living/user)
toggle_helmet_light(user)
@@ -27,15 +32,9 @@
turn_off(user)
update_icon()
-/obj/item/clothing/head/hardhat/update_icon()
+/obj/item/clothing/head/hardhat/update_icon_state()
icon_state = "hardhat[on]_[item_color]"
item_state = "hardhat[on]_[item_color]"
- if(ishuman(loc))
- var/mob/living/carbon/human/H = loc
- H.update_inv_head()
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon(force = TRUE)
/obj/item/clothing/head/hardhat/proc/turn_on(mob/user)
set_light(brightness_on, power_on)
@@ -132,11 +131,10 @@
if(!up)
. += mutable_appearance('icons/mob/head.dmi', "weldvisor")
-/obj/item/clothing/head/hardhat/weldhat/update_icon()
- cut_overlays()
+/obj/item/clothing/head/hardhat/weldhat/update_overlays()
+ . = ..()
if(!up)
- add_overlay("weldvisor")
- ..()
+ . += "weldvisor"
/obj/item/clothing/head/hardhat/weldhat/orange
icon_state = "hardhat0_orange"
diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm
index e176943aa9..3b1b92ea78 100644
--- a/code/modules/clothing/head/helmet.dm
+++ b/code/modules/clothing/head/helmet.dm
@@ -258,7 +258,11 @@
//LightToggle
-/obj/item/clothing/head/helmet/update_icon()
+/obj/item/clothing/head/helment/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/update_icon_updates_onmob)
+
+/obj/item/clothing/head/helmet/update_icon_state()
var/state = "[initial(icon_state)]"
if(F)
if(F.on)
@@ -268,10 +272,6 @@
icon_state = state
- if(ishuman(loc))
- var/mob/living/carbon/human/H = loc
- H.update_inv_head()
-
/obj/item/clothing/head/helmet/ui_action_click(mob/user, action)
if(istype(action, /datum/action/item_action/toggle_helmet_flashlight))
toggle_helmlight()
diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm
index 4be949a65e..0b58ea234c 100644
--- a/code/modules/clothing/head/misc_special.dm
+++ b/code/modules/clothing/head/misc_special.dm
@@ -197,16 +197,19 @@
. = ..()
update_icon()
-/obj/item/clothing/head/wig/update_icon()
- cut_overlays()
+/obj/item/clothing/head/wig/update_icon_state()
var/datum/sprite_accessory/S = GLOB.hair_styles_list[hair_style]
if(!S)
+ icon = 'icons/obj/clothing/hats.dmi'
icon_state = "pwig"
- else
- var/mutable_appearance/M = mutable_appearance(S.icon,S.icon_state)
+
+/obj/item/clothing/head/wig/update_overlays()
+ . = ..()
+ var/datum/sprite_accessory/S = GLOB.hair_styles_list[hair_style]
+ if(S)
+ var/mutable_appearance/M = mutable_appearance(S.icon, S.icon_state, color = hair_color)
M.appearance_flags |= RESET_COLOR
- M.color = hair_color
- add_overlay(M)
+ . += M
/obj/item/clothing/head/wig/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
. = list()
diff --git a/code/modules/clothing/shoes/bananashoes.dm b/code/modules/clothing/shoes/bananashoes.dm
index ffb7771d2f..08f12deb1f 100644
--- a/code/modules/clothing/shoes/bananashoes.dm
+++ b/code/modules/clothing/shoes/bananashoes.dm
@@ -10,11 +10,15 @@
/obj/item/clothing/shoes/clown_shoes/banana_shoes/Initialize()
. = ..()
- AddComponent(/datum/component/material_container, list(/datum/material/bananium), 200000, TRUE, /obj/item/stack)
- AddComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 75)
if(always_noslip)
clothing_flags |= NOSLIP
+/obj/item/clothing/shoes/clown_shoes/banana_shoes/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/update_icon_updates_onmob)
+ AddComponent(/datum/component/material_container, list(/datum/material/bananium), 200000, TRUE, /obj/item/stack)
+ AddComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 75)
+
/obj/item/clothing/shoes/clown_shoes/banana_shoes/step_action()
. = ..()
var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container)
@@ -55,12 +59,5 @@
else
to_chat(user, "You need bananium to turn the prototype shoes on!")
-/obj/item/clothing/shoes/clown_shoes/banana_shoes/update_icon()
- if(on)
- icon_state = "clown_prototype_on"
- else
- icon_state = "clown_prototype_off"
- usr.update_inv_shoes()
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
+/obj/item/clothing/shoes/clown_shoes/banana_shoes/update_icon_state()
+ icon_state = "clown_prototype_[on? "on" : "off"]"
\ No newline at end of file
diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm
index 3d06fba285..81fedcf57c 100644
--- a/code/modules/clothing/spacesuits/chronosuit.dm
+++ b/code/modules/clothing/spacesuits/chronosuit.dm
@@ -220,7 +220,7 @@
teleport_now.Remove(user)
if(user.wear_suit == src)
if(hard_landing)
- user.electrocute_act(35, src, safety = 1)
+ user.electrocute_act(35, src, flags = SHOCK_NOGLOVES)
user.DefaultCombatKnockdown(200)
if(!silent)
to_chat(user, "\nroot@ChronosuitMK4# chronowalk4 --stop\n")
diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm
index d9e4f17649..ee77321fa5 100644
--- a/code/modules/clothing/spacesuits/hardsuit.dm
+++ b/code/modules/clothing/spacesuits/hardsuit.dm
@@ -275,7 +275,7 @@
visor_flags_inv = HIDEMASK|HIDEEYES|HIDEFACE|HIDEFACIALHAIR
visor_flags = STOPSPRESSUREDAMAGE
-/obj/item/clothing/head/helmet/space/hardsuit/syndi/update_icon()
+/obj/item/clothing/head/helmet/space/hardsuit/syndi/update_icon_state()
icon_state = "hardsuit[on]-[item_color]"
/obj/item/clothing/head/helmet/space/hardsuit/syndi/Initialize()
@@ -336,7 +336,7 @@
linkedsuit.update_icon()
user.update_inv_wear_suit()
user.update_inv_w_uniform()
-
+ user.update_equipment_speed_mods()
/obj/item/clothing/suit/space/hardsuit/syndi
name = "blood-red hardsuit"
@@ -362,9 +362,6 @@
armor = list("melee" = 60, "bullet" = 60, "laser" = 50, "energy" = 25, "bomb" = 55, "bio" = 100, "rad" = 70, "fire" = 100, "acid" = 100)
heat_protection = HEAD
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
- visor_flags_inv = 0
- visor_flags = 0
- on = FALSE
resistance_flags = FIRE_PROOF | ACID_PROOF
/obj/item/clothing/head/helmet/space/hardsuit/syndi/elite/debug
@@ -946,15 +943,9 @@
var/datum/action/A = X
A.UpdateButtonIcon()
-/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/update_icon()
- var/mutable_appearance/helm_overlay = mutable_appearance(icon, "knight_cydonia_overlay")
-
- if(energy_color)
- helm_overlay.color = energy_color
-
- cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
-
- add_overlay(helm_overlay)
+/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/update_overlays()
+ . = ..()
+ . += mutable_appearance(icon, "knight_cydonia_overlay", color = energy_color)
/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
. = ..()
@@ -983,15 +974,9 @@
set_light(1)
update_icon()
-/obj/item/clothing/suit/space/hardsuit/lavaknight/update_icon()
- var/mutable_appearance/suit_overlay = mutable_appearance(icon, "knight_cydonia_overlay")
-
- if(energy_color)
- suit_overlay.color = energy_color
-
- cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
-
- add_overlay(suit_overlay)
+/obj/item/clothing/suit/space/hardsuit/lavaknight/update_overlays()
+ . = ..()
+ . += mutable_appearance(icon, "knight_cydonia_overlay", color = energy_color)
/obj/item/clothing/suit/space/hardsuit/lavaknight/worn_overlays(isinhands = FALSE, icon_file, style_flags = NONE)
. = ..()
diff --git a/code/modules/clothing/spacesuits/syndi.dm b/code/modules/clothing/spacesuits/syndi.dm
index aca98df232..662e333f59 100644
--- a/code/modules/clothing/spacesuits/syndi.dm
+++ b/code/modules/clothing/spacesuits/syndi.dm
@@ -79,7 +79,6 @@
/obj/item/clothing/head/helmet/space/syndicate/contract
name = "contractor helmet"
desc = "A specialised black and gold helmet that's more compact than its standard Syndicate counterpart. Can be ultra-compressed into even the tightest of spaces."
- slowdown = 0.55
w_class = WEIGHT_CLASS_SMALL
icon_state = "syndicate-contract-helm"
item_state = "syndicate-contract-helm"
@@ -91,6 +90,7 @@
w_class = WEIGHT_CLASS_SMALL
icon_state = "syndicate-contract"
item_state = "syndicate-contract"
+ mutantrace_variation = STYLE_DIGITIGRADE|STYLE_SNEK_TAURIC|STYLE_PAW_TAURIC
//Black-green syndicate space suit
/obj/item/clothing/head/helmet/space/syndicate/black/green
diff --git a/code/modules/events/pirates.dm b/code/modules/events/pirates.dm
index ab9ab96678..47cde0899b 100644
--- a/code/modules/events/pirates.dm
+++ b/code/modules/events/pirates.dm
@@ -157,7 +157,7 @@
active = FALSE
STOP_PROCESSING(SSobj,src)
-/obj/machinery/shuttle_scrambler/update_icon()
+/obj/machinery/shuttle_scrambler/update_icon_state()
if(active)
icon_state = "dominator-blue"
else
diff --git a/code/modules/food_and_drinks/food/customizables.dm b/code/modules/food_and_drinks/food/customizables.dm
index 2a313361c4..bd20ad8d69 100644
--- a/code/modules/food_and_drinks/food/customizables.dm
+++ b/code/modules/food_and_drinks/food/customizables.dm
@@ -318,14 +318,17 @@
..()
update_icon()
-/obj/item/reagent_containers/glass/bowl/update_icon()
- cut_overlays()
+
+/obj/item/reagent_containers/glass/bowl/update_icon_state()
+ if(!reagents || !reagents.total_volume)
+ icon_state = "bowl"
+
+/obj/item/reagent_containers/glass/bowl/update_overlays()
+ . = ..()
if(reagents && reagents.total_volume)
var/mutable_appearance/filling = mutable_appearance('icons/obj/food/soupsalad.dmi', "fullbowl")
filling.color = mix_color_from_reagents(reagents.reagent_list)
- add_overlay(filling)
- else
- icon_state = "bowl"
+ . += filling
#undef INGREDIENTS_FILL
#undef INGREDIENTS_SCATTER
diff --git a/code/modules/food_and_drinks/food/snacks_burgers.dm b/code/modules/food_and_drinks/food/snacks_burgers.dm
index 35b17e67f0..9a4ef2ce89 100644
--- a/code/modules/food_and_drinks/food/snacks_burgers.dm
+++ b/code/modules/food_and_drinks/food/snacks_burgers.dm
@@ -323,6 +323,14 @@
tastes = list("bun" = 4, "bacon" = 2)
foodtype = GRAIN | MEAT
+/obj/item/reagent_containers/food/snacks/burger/empoweredburger
+ name = "empowered burger"
+ desc = "It's shockingly good, if you live off of electricity that is."
+ icon_state = "empoweredburger"
+ list_reagents = list(/datum/reagent/consumable/nutriment = 8, /datum/reagent/consumable/liquidelectricity = 5)
+ tastes = list("bun" = 2, "pure electricity" = 4)
+ foodtype = GRAIN | TOXIC
+
/obj/item/reagent_containers/food/snacks/burger/soylent
name = "soylent burger"
desc = "A eco-friendly burger made using upcycled low value biomass."
@@ -331,6 +339,14 @@
tastes = list("bun" = 2, "assistant" = 4)
foodtype = GRAIN | MEAT | DAIRY
+/obj/item/reagent_containers/food/snacks/burger/crab
+ name = "crab burger"
+ desc = "A delicious patty of the crabby kind, slapped in between a bun."
+ icon_state = "crabburger"
+ bonus_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/vitamin = 3)
+ tastes = list("bun" = 2, "crab meat" = 4)
+ foodtype = GRAIN | MEAT
+
/obj/item/reagent_containers/food/snacks/burger/rib
name = "mcrib"
desc = "An elusive rib shaped burger with limited availablity across the galaxy. Not as good as you remember it."
diff --git a/code/modules/food_and_drinks/food/snacks_other.dm b/code/modules/food_and_drinks/food/snacks_other.dm
index 7dc2188100..6c71318807 100644
--- a/code/modules/food_and_drinks/food/snacks_other.dm
+++ b/code/modules/food_and_drinks/food/snacks_other.dm
@@ -579,6 +579,16 @@
icon_state = "peachcanmaint"
tastes = list("peaches" = 1, "tin" = 7)
+/obj/item/reagent_containers/food/snacks/crab_rangoon
+ name = "Crab Rangoon"
+ desc = "Has many names, like crab puffs, cheese wontons, crab dumplings? Whatever you call them, they're a fabulous blast of cream cheesy crab."
+ icon_state = "crabrangoon"
+ list_reagents = list(/datum/reagent/consumable/nutriment = 10, /datum/reagent/consumable/nutriment/vitamin = 5)
+ filling_color = "#f2efdc"
+ w_class = WEIGHT_CLASS_SMALL
+ tastes = list("cream cheese" = 4, "crab" = 3, "crispiness" = 2)
+ foodtype = MEAT | DAIRY | GRAIN
+
/obj/item/reagent_containers/food/snacks/chocolatestrawberry
name = "Chocolate dipped strawberries"
desc = "A strawberry dipped in a bit of chocolate."
diff --git a/code/modules/food_and_drinks/food/snacks_soup.dm b/code/modules/food_and_drinks/food/snacks_soup.dm
index a0e1ebcb39..3d70b32f2e 100644
--- a/code/modules/food_and_drinks/food/snacks_soup.dm
+++ b/code/modules/food_and_drinks/food/snacks_soup.dm
@@ -228,6 +228,22 @@
tastes = list("beet" = 1)
foodtype = VEGETABLES
+/obj/item/reagent_containers/food/snacks/soup/onion
+ name = "french onion soup"
+ desc = "Good enough to make a grown mime cry."
+ icon_state = "onionsoup"
+ bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 5)
+ tastes = list("caramelized onions" = 1)
+ foodtype = VEGETABLES
+
+/obj/item/reagent_containers/food/snacks/soup/bisque
+ name = "bisque"
+ desc = "A classic entree from Space-France."
+ icon_state = "bisque"
+ bonus_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/vitamin = 6)
+ tastes = list("creamy texture" = 1, "crab" = 4)
+ foodtype = MEAT
+
/obj/item/reagent_containers/food/snacks/soup/electron
name = "electron soup"
desc = "A gastronomic curiosity of ethereal origin. It is famed for the minature weather system formed over a properly prepared soup."
diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
index 24f60300fa..5117439049 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
@@ -21,12 +21,12 @@
add_overlay("grjam")
/obj/machinery/gibber/RefreshParts()
- var/gib_time = 40
+ gibtime = 40
+ meat_produced = 0
for(var/obj/item/stock_parts/matter_bin/B in component_parts)
meat_produced += B.rating
for(var/obj/item/stock_parts/manipulator/M in component_parts)
- gib_time -= 5 * M.rating
- gibtime = gib_time
+ gibtime -= 5 * M.rating
if(M.rating >= 2)
ignore_clothing = TRUE
@@ -38,18 +38,18 @@
if(M.rating >= 2)
. += "Gibber has been upgraded to process inorganic materials."
-/obj/machinery/gibber/update_icon()
- cut_overlays()
+/obj/machinery/gibber/update_overlays()
+ . = ..()
if (dirty)
- add_overlay("grbloody")
+ . += "grbloody"
if(stat & (NOPOWER|BROKEN))
return
if (!occupant)
- add_overlay("grjam")
+ . += "grjam"
else if (operating)
- add_overlay("gruse")
+ . += "gruse"
else
- add_overlay("gridle")
+ . += "gridle"
/obj/machinery/gibber/attack_paw(mob/user)
return attack_hand(user)
diff --git a/code/modules/food_and_drinks/kitchen_machinery/grill.dm b/code/modules/food_and_drinks/kitchen_machinery/grill.dm
index c52389cd56..547ed244c0 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/grill.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/grill.dm
@@ -15,7 +15,7 @@
. = ..()
grill_loop = new(list(src), FALSE)
-/obj/machinery/grill/update_icon()
+/obj/machinery/grill/update_icon_state()
if(grilled_item)
icon_state = "grill"
else if(grill_fuel)
diff --git a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm
index 24dd99e5e0..2adff414e8 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm
@@ -85,7 +85,7 @@
. += "- Capacity: [max_n_of_items] items."
. += "- Cook time reduced by [(efficiency - 1) * 25]%."
-/obj/machinery/microwave/update_icon()
+/obj/machinery/microwave/update_icon_state()
if(broken)
icon_state = "mwb"
else if(dirty_anim_playing)
diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
index 7619f68448..67a636eb9c 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
@@ -42,7 +42,7 @@
..()
update_icon()
-/obj/machinery/smartfridge/update_icon()
+/obj/machinery/smartfridge/update_icon_state()
if(!stat)
if(visible_contents)
switch(contents.len)
@@ -289,13 +289,12 @@
..()
update_icon()
-/obj/machinery/smartfridge/drying_rack/update_icon()
- ..()
- cut_overlays()
+/obj/machinery/smartfridge/drying_rack/update_overlays()
+ . = ..()
if(drying)
- add_overlay("drying_rack_drying")
+ . += "drying_rack_drying"
if(contents.len)
- add_overlay("drying_rack_filled")
+ . += "drying_rack_filled"
/obj/machinery/smartfridge/drying_rack/process()
..()
diff --git a/code/modules/food_and_drinks/recipes/food_mixtures.dm b/code/modules/food_and_drinks/recipes/food_mixtures.dm
index 0b297648c5..c15c1cd2f5 100644
--- a/code/modules/food_and_drinks/recipes/food_mixtures.dm
+++ b/code/modules/food_and_drinks/recipes/food_mixtures.dm
@@ -1,6 +1,7 @@
/datum/crafting_recipe/food
var/real_parts
category = CAT_FOOD
+ time = 5
/datum/crafting_recipe/food/New()
real_parts = parts.Copy()
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_burger.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_burger.dm
index cf96c01e7b..5789b8daeb 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_burger.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_burger.dm
@@ -150,6 +150,24 @@
result = /obj/item/reagent_containers/food/snacks/burger/chicken
subcategory = CAT_BURGER
+/datum/crafting_recipe/food/crabburger
+ name = "Crab Burger"
+ reqs = list(
+ /obj/item/reagent_containers/food/snacks/meat/crab = 2,
+ /obj/item/reagent_containers/food/snacks/bun = 1
+ )
+ result = /obj/item/reagent_containers/food/snacks/burger/crab
+ subcategory = CAT_BURGER
+
+/datum/crafting_recipe/food/empoweredburger
+ name = "Empowered Burger"
+ reqs = list(
+ /obj/item/stack/sheet/mineral/plasma = 2,
+ /obj/item/reagent_containers/food/snacks/bun = 1
+ )
+ result = /obj/item/reagent_containers/food/snacks/burger/empoweredburger
+ subcategory = CAT_BURGER
+
/datum/crafting_recipe/food/fishburger
name = "Fish burger"
reqs = list(
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm
index 6a622d6719..479e116801 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_misc.dm
@@ -171,3 +171,16 @@
)
result = /obj/item/reagent_containers/food/snacks/salad/ricepudding
subcategory = CAT_MISCFOOD
+
+/datum/crafting_recipe/food/butterbear //ITS ALIVEEEEEE!
+ name = "Living bear/butter hybrid"
+ reqs = list(
+ /obj/item/organ/brain = 1,
+ /obj/item/organ/heart = 1,
+ /obj/item/reagent_containers/food/snacks/butter = 10,
+ /obj/item/reagent_containers/food/snacks/meat/slab = 5,
+ /datum/reagent/blood = 50,
+ /datum/reagent/teslium = 1 //To shock the whole thing into life
+ )
+ result = /mob/living/simple_animal/hostile/bear/butter
+ subcategory = CAT_MISCFOOD
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_seafood.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_seafood.dm
index 4fc12f0777..45083e0374 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_seafood.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_seafood.dm
@@ -97,6 +97,17 @@
result = /obj/item/reagent_containers/food/snacks/tuna
subcategory = CAT_SEAFOOD
+/datum/crafting_recipe/food/crab_rangoon
+ name = "Crab Rangoon"
+ reqs = list(
+ /obj/item/reagent_containers/food/snacks/doughslice = 1,
+ /datum/reagent/consumable/cream = 5,
+ /obj/item/reagent_containers/food/snacks/cheesewedge = 1,
+ /obj/item/reagent_containers/food/snacks/meat/crab = 1
+ )
+ result = /obj/item/reagent_containers/food/snacks/crab_rangoon
+ subcategory = CAT_SEAFOOD
+
/datum/crafting_recipe/food/cubancarp
name = "Cuban carp"
reqs = list(
diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_soup.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_soup.dm
index 0c966faf33..ac49537adf 100644
--- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_soup.dm
+++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_soup.dm
@@ -24,6 +24,16 @@
result = /obj/item/reagent_containers/food/snacks/soup/beet
subcategory = CAT_SOUP
+/datum/crafting_recipe/food/bisque
+ name = "Bisque"
+ reqs = list(
+ /datum/reagent/water = 10,
+ /obj/item/reagent_containers/food/snacks/meat/crab = 1,
+ /obj/item/reagent_containers/food/snacks/salad/boiledrice = 1
+ )
+ result = /obj/item/reagent_containers/food/snacks/soup/bisque
+ subcategory = CAT_SOUP
+
/datum/crafting_recipe/food/bloodsoup
name = "Blood soup"
reqs = list(
@@ -67,6 +77,17 @@
result = /obj/item/reagent_containers/food/snacks/soup/tomato/eyeball
subcategory = CAT_SOUP
+/datum/crafting_recipe/food/onionsoup
+ name = "French onion soup"
+ reqs = list(
+ /datum/reagent/water = 10,
+ /obj/item/reagent_containers/glass/bowl = 1,
+ /obj/item/reagent_containers/food/snacks/grown/onion = 1,
+ /obj/item/reagent_containers/food/snacks/cheesewedge = 1,
+ )
+ result = /obj/item/reagent_containers/food/snacks/soup/onion
+ subcategory = CAT_SOUP
+
/datum/crafting_recipe/food/hotchili
name = "Hot chili"
reqs = list(
diff --git a/code/modules/games/cas.dm b/code/modules/games/cas.dm
index 4fbb931b32..77db8dbe3f 100644
--- a/code/modules/games/cas.dm
+++ b/code/modules/games/cas.dm
@@ -93,7 +93,7 @@
qdel(SC)
update_icon()
-/obj/item/toy/cards/deck/cas/update_icon()
+/obj/item/toy/cards/deck/cas/update_icon_state()
if(cards.len < 26)
icon_state = "deck_[deckstyle]_low"
@@ -136,7 +136,7 @@
Flip()
return TRUE
-/obj/item/toy/cards/singlecard/cas/update_icon()
+/obj/item/toy/cards/singlecard/cas/update_icon_state()
if(flipped)
icon_state = "[card_face]_flipped"
else
diff --git a/code/modules/holodeck/items.dm b/code/modules/holodeck/items.dm
index e6aed7a8ca..884769ebd4 100644
--- a/code/modules/holodeck/items.dm
+++ b/code/modules/holodeck/items.dm
@@ -196,7 +196,7 @@
if(numbuttons == numready)
begin_event()
-/obj/machinery/readybutton/update_icon()
+/obj/machinery/readybutton/update_icon_state()
if(ready)
icon_state = "auth_on"
else
diff --git a/code/modules/hydroponics/beekeeping/honeycomb.dm b/code/modules/hydroponics/beekeeping/honeycomb.dm
index 5bb2936c1e..1a3e1bc1be 100644
--- a/code/modules/hydroponics/beekeeping/honeycomb.dm
+++ b/code/modules/hydroponics/beekeeping/honeycomb.dm
@@ -20,13 +20,13 @@
update_icon()
-/obj/item/reagent_containers/honeycomb/update_icon()
- cut_overlays()
+/obj/item/reagent_containers/honeycomb/update_overlays()
+ . = ..()
var/mutable_appearance/honey_overlay = mutable_appearance(icon, "honey")
if(honey_color)
honey_overlay.icon_state = "greyscale_honey"
honey_overlay.color = honey_color
- add_overlay(honey_overlay)
+ . += honey_overlay
/obj/item/reagent_containers/honeycomb/proc/set_reagent(reagent)
diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm
index f7715e7320..6a3fd56208 100644
--- a/code/modules/hydroponics/biogenerator.dm
+++ b/code/modules/hydroponics/biogenerator.dm
@@ -61,7 +61,7 @@
/obj/machinery/biogenerator/on_reagent_change(changetype) //When the reagents change, change the icon as well.
update_icon()
-/obj/machinery/biogenerator/update_icon()
+/obj/machinery/biogenerator/update_icon_state()
if(panel_open)
icon_state = "biogen-empty-o"
else if(!src.beaker)
diff --git a/code/modules/hydroponics/fermenting_barrel.dm b/code/modules/hydroponics/fermenting_barrel.dm
index ab6625b46d..1c31113332 100644
--- a/code/modules/hydroponics/fermenting_barrel.dm
+++ b/code/modules/hydroponics/fermenting_barrel.dm
@@ -64,7 +64,7 @@
to_chat(user, "You close [src], letting you draw from its tap.")
update_icon()
-/obj/structure/fermenting_barrel/update_icon()
+/obj/structure/fermenting_barrel/update_icon_state()
if(open)
icon_state = "barrel_open"
else
diff --git a/code/modules/hydroponics/gene_modder.dm b/code/modules/hydroponics/gene_modder.dm
index fe6d13f69e..4e545c13ee 100644
--- a/code/modules/hydroponics/gene_modder.dm
+++ b/code/modules/hydroponics/gene_modder.dm
@@ -53,17 +53,18 @@
min_wchance = 0
min_wrate = 0
-/obj/machinery/plantgenes/update_icon()
- ..()
- cut_overlays()
+/obj/machinery/plantgenes/update_icon_state()
if((stat & (BROKEN|NOPOWER)))
icon_state = "dnamod-off"
else
icon_state = "dnamod"
+
+/obj/machinery/plantgenes/update_overlays()
+ . = ..()
if(seed)
- add_overlay("dnamod-dna")
+ . += "dnamod-dna"
if(panel_open)
- add_overlay("dnamod-open")
+ . += "dnamod-open"
/obj/machinery/plantgenes/attackby(obj/item/I, mob/user, params)
if(default_deconstruction_screwdriver(user, "dnamod", "dnamod", I))
diff --git a/code/modules/hydroponics/plant_genes.dm b/code/modules/hydroponics/plant_genes.dm
index 272f44267e..b3ec36e0bb 100644
--- a/code/modules/hydroponics/plant_genes.dm
+++ b/code/modules/hydroponics/plant_genes.dm
@@ -250,14 +250,14 @@
/datum/plant_gene/trait/cell_charge/on_slip(obj/item/reagent_containers/food/snacks/grown/G, mob/living/carbon/C)
var/power = G.seed.potency*rate
if(prob(power))
- C.electrocute_act(round(power), G, 1, 1)
+ C.electrocute_act(round(power), G, 1, SHOCK_NOGLOVES)
/datum/plant_gene/trait/cell_charge/on_squash(obj/item/reagent_containers/food/snacks/grown/G, atom/target)
if(iscarbon(target))
var/mob/living/carbon/C = target
var/power = G.seed.potency*rate
if(prob(power))
- C.electrocute_act(round(power), G, 1, 1)
+ C.electrocute_act(round(power), G, 1, SHOCK_NOGLOVES)
/datum/plant_gene/trait/cell_charge/on_consume(obj/item/reagent_containers/food/snacks/grown/G, mob/living/carbon/target)
if(!G.reagents.total_volume)
diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm
index 2a0cf8c334..9026c45f82 100644
--- a/code/modules/integrated_electronics/core/assemblies.dm
+++ b/code/modules/integrated_electronics/core/assemblies.dm
@@ -305,17 +305,17 @@
/obj/item/electronic_assembly/proc/can_move()
return FALSE
-/obj/item/electronic_assembly/update_icon()
+/obj/item/electronic_assembly/update_icon_state()
if(opened)
icon_state = initial(icon_state) + "-open"
else
icon_state = initial(icon_state)
- cut_overlays()
+
+/obj/item/electronic_assembly/update_overlays()
+ . = ..()
if(detail_color == COLOR_ASSEMBLY_BLACK) //Black colored overlay looks almost but not exactly like the base sprite, so just cut the overlay and avoid it looking kinda off.
return
- var/mutable_appearance/detail_overlay = mutable_appearance('icons/obj/assemblies/electronic_setups.dmi', "[icon_state]-color")
- detail_overlay.color = detail_color
- add_overlay(detail_overlay)
+ . += mutable_appearance('icons/obj/assemblies/electronic_setups.dmi', "[icon_state]-color", color = detail_color)
/obj/item/electronic_assembly/proc/return_total_complexity()
. = 0
diff --git a/code/modules/integrated_electronics/core/detailer.dm b/code/modules/integrated_electronics/core/detailer.dm
index 52739c7940..9720bccfe5 100644
--- a/code/modules/integrated_electronics/core/detailer.dm
+++ b/code/modules/integrated_electronics/core/detailer.dm
@@ -34,18 +34,17 @@
.=..()
update_icon()
-/obj/item/integrated_electronics/detailer/update_icon()
- cut_overlays()
- var/mutable_appearance/detail_overlay = mutable_appearance('icons/obj/assemblies/electronic_tools.dmi', "detailer-color")
- detail_overlay.color = detail_color
- add_overlay(detail_overlay)
+/obj/item/integrated_electronics/detailer/update_overlays()
+ . = ..()
+ . += mutable_appearance('icons/obj/assemblies/electronic_tools.dmi', "detailer-color", color = detail_color)
+
/obj/item/integrated_electronics/detailer/attack_self(mob/user)
var/color_choice = input(user, "Select color.", "Assembly Detailer") as null|anything in color_list
if(!color_list[color_choice])
return
if(!in_range(src, user))
- return
+ return
if(color_choice == "custom")
detail_color = input(user,"","Choose Color",detail_color) as color|null
else
diff --git a/code/modules/integrated_electronics/core/wirer.dm b/code/modules/integrated_electronics/core/wirer.dm
index 9550f9b4ae..95f46564cb 100644
--- a/code/modules/integrated_electronics/core/wirer.dm
+++ b/code/modules/integrated_electronics/core/wirer.dm
@@ -15,7 +15,7 @@
var/datum/integrated_io/selected_io = null
var/mode = WIRE
-/obj/item/integrated_electronics/wirer/update_icon()
+/obj/item/integrated_electronics/wirer/update_icon_state()
icon_state = "wirer-[mode]"
/obj/item/integrated_electronics/wirer/proc/wire(var/datum/integrated_io/io, mob/user)
@@ -27,7 +27,7 @@
selected_io = io
to_chat(user, "You attach a data wire to \the [selected_io.holder]'s [selected_io.name] data channel.")
mode = WIRING
- update_icon()
+ update_icon()
if(WIRING)
if(io == selected_io)
to_chat(user, "Wiring \the [selected_io.holder]'s [selected_io.name] into itself is rather pointless.")
diff --git a/code/modules/keybindings/bindings_mob.dm b/code/modules/keybindings/bindings_mob.dm
index 964ee65047..36b4775c34 100644
--- a/code/modules/keybindings/bindings_mob.dm
+++ b/code/modules/keybindings/bindings_mob.dm
@@ -61,16 +61,28 @@
if(client.keys_held["Ctrl"])
switch(SSinput.movement_keys[_key])
if(NORTH)
- northface()
+ if(client.keys_held["Shift"])
+ northshift()
+ else
+ northface()
return
if(SOUTH)
- southface()
+ if(client.keys_held["Shift"])
+ southshift()
+ else
+ southface()
return
if(WEST)
- westface()
+ if(client.keys_held["Shift"])
+ westshift()
+ else
+ westface()
return
if(EAST)
- eastface()
+ if(client.keys_held["Shift"])
+ eastshift()
+ else
+ eastface()
return
return ..()
diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm
index bfd0ae03cb..89fa3ac6cf 100644
--- a/code/modules/library/lib_items.dm
+++ b/code/modules/library/lib_items.dm
@@ -147,11 +147,8 @@
qdel(src)
-/obj/structure/bookcase/update_icon()
- if(contents.len < 5)
- icon_state = "book-[contents.len]"
- else
- icon_state = "book-5"
+/obj/structure/bookcase/update_icon_state()
+ icon_state = "book-[min(length(contents), 5)]"
/obj/structure/bookcase/manuals/medical
diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm
index 5165d95340..e83ac26153 100644
--- a/code/modules/mining/equipment/explorer_gear.dm
+++ b/code/modules/mining/equipment/explorer_gear.dm
@@ -110,12 +110,12 @@
AddComponent(/datum/component/spraycan_paintable)
update_icon()
-/obj/item/clothing/head/helmet/space/hostile_environment/update_icon()
- ..()
- cut_overlays()
+
+/obj/item/clothing/head/helmet/space/hostile_environment/update_overlays()
+ . = ..()
var/mutable_appearance/glass_overlay = mutable_appearance(icon, "hostile_env_glass")
glass_overlay.appearance_flags = RESET_COLOR
- add_overlay(glass_overlay)
+ . += glass_overlay
/obj/item/clothing/head/helmet/space/hostile_environment/worn_overlays(isinhands, icon_file, style_flags = NONE)
. = ..()
diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm
index d4b86d5138..b515ebbc13 100644
--- a/code/modules/mining/equipment/kinetic_crusher.dm
+++ b/code/modules/mining/equipment/kinetic_crusher.dm
@@ -155,19 +155,16 @@
else
set_light(0)
-/obj/item/twohanded/kinetic_crusher/update_icon()
- ..()
- cut_overlays()
- if(!charged)
- add_overlay("[icon_state]_uncharged")
- if(light_on)
- add_overlay("[icon_state]_lit")
- spawn(1)
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
+/obj/item/twohanded/kinetic_crusher/update_icon_state()
item_state = "crusher[wielded]"
+/obj/item/twohanded/kinetic_crusher/update_overlays()
+ . = ..()
+ if(!charged)
+ . += "[icon_state]_uncharged"
+ if(light_on)
+ . += "[icon_state]_lit"
+
//destablizing force
/obj/item/projectile/destabilizer
name = "destabilizing force"
diff --git a/code/modules/mining/equipment/marker_beacons.dm b/code/modules/mining/equipment/marker_beacons.dm
index 9d595664ff..8853a56911 100644
--- a/code/modules/mining/equipment/marker_beacons.dm
+++ b/code/modules/mining/equipment/marker_beacons.dm
@@ -40,7 +40,7 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list(
. += "Use in-hand to place a [singular_name]."
. += "Alt-click to select a color. Current color is [picked_color]."
-/obj/item/stack/marker_beacon/update_icon()
+/obj/item/stack/marker_beacon/update_icon_state()
icon_state = "[initial(icon_state)][lowertext(picked_color)]"
/obj/item/stack/marker_beacon/attack_self(mob/user)
diff --git a/code/modules/mining/equipment/regenerative_core.dm b/code/modules/mining/equipment/regenerative_core.dm
index e8ba72e62f..ae451ba1a8 100644
--- a/code/modules/mining/equipment/regenerative_core.dm
+++ b/code/modules/mining/equipment/regenerative_core.dm
@@ -129,14 +129,13 @@
. = ..()
update_icon()
-/obj/item/organ/regenerative_core/update_icon()
+/obj/item/organ/regenerative_core/update_icon_state()
icon_state = inert ? "legion_soul_inert" : "legion_soul"
- cut_overlays()
+
+/obj/item/organ/regenerative_core/update_overlays()
+ . = ..()
if(!inert && !preserved)
- add_overlay("legion_soul_crackle")
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
+ . += "legion_soul_crackle"
/obj/item/organ/regenerative_core/legion/go_inert()
..()
diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm
index 68e70dc882..b9f85a5c8f 100644
--- a/code/modules/mining/equipment/survival_pod.dm
+++ b/code/modules/mining/equipment/survival_pod.dm
@@ -139,11 +139,10 @@
icon = 'icons/obj/lavaland/survival_pod.dmi'
icon_state = "sleeper"
-/obj/machinery/sleeper/survival_pod/update_icon()
- if(state_open)
- cut_overlays()
- else
- add_overlay("sleeper_cover")
+/obj/machinery/sleeper/survival_pod/update_overlays()
+ . = ..()
+ if(!state_open)
+ . += "sleeper_cover"
//Computer
/obj/item/gps/computer
@@ -190,8 +189,9 @@
flags_1 = NODECONSTRUCT_1
var/empty = FALSE
-/obj/machinery/smartfridge/survival_pod/update_icon()
- return
+/obj/machinery/stasis/survival_pod/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/update_icon_blocker)
/obj/machinery/smartfridge/survival_pod/Initialize(mapload)
. = ..()
diff --git a/code/modules/mining/lavaland/ash_flora.dm b/code/modules/mining/lavaland/ash_flora.dm
index 43c8dec129..38830fd824 100644
--- a/code/modules/mining/lavaland/ash_flora.dm
+++ b/code/modules/mining/lavaland/ash_flora.dm
@@ -201,15 +201,15 @@
icon = 'icons/obj/lavaland/ash_flora.dmi'
icon_state = "mushroom_bowl"
-/obj/item/reagent_containers/glass/bowl/mushroom_bowl/update_icon()
- cut_overlays()
- if(reagents && reagents.total_volume)
- var/mutable_appearance/filling = mutable_appearance('icons/obj/lavaland/ash_flora.dmi', "fullbowl")
- filling.color = mix_color_from_reagents(reagents.reagent_list)
- add_overlay(filling)
- else
+/obj/item/reagent_containers/glass/bowl/mushroom_bowl/update_icon_state()
+ if(!reagents || !reagents.total_volume)
icon_state = "mushroom_bowl"
+/obj/item/reagent_containers/glass/bowl/mushroom_bowl/update_overlays()
+ . = ..()
+ if(reagents && reagents.total_volume)
+ . += mutable_appearance('icons/obj/lavaland/ash_flora.dmi', "fullbowl", color = mix_color_from_reagents(reagents.reagent_list))
+
/obj/item/reagent_containers/glass/bowl/mushroom_bowl/attackby(obj/item/I,mob/user, params)
if(istype(I, /obj/item/reagent_containers/food/snacks))
var/obj/item/reagent_containers/food/snacks/S = I
diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm
index 343083456d..5faa465b8c 100644
--- a/code/modules/mining/lavaland/necropolis_chests.dm
+++ b/code/modules/mining/lavaland/necropolis_chests.dm
@@ -561,7 +561,7 @@
desc = "A flask with an almost-holy aura emitting from it. The label on the bottle says: 'erqo'hyy tvi'rf lbh jv'atf'."
list_reagents = list(/datum/reagent/flightpotion = 5)
-/obj/item/reagent_containers/glass/bottle/potion/update_icon()
+/obj/item/reagent_containers/glass/bottle/potion/update_icon_state()
if(reagents.total_volume)
icon_state = "potionflask"
else
@@ -1072,6 +1072,10 @@
var/teleporting = FALSE //if we ARE teleporting
var/friendly_fire_check = FALSE //if the blasts we make will consider our faction against the faction of hit targets
+/obj/item/hierophant_club/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/update_icon_updates_onmob)
+
/obj/item/hierophant_club/examine(mob/user)
. = ..()
. += "The[beacon ? " beacon is not currently":"re is a beacon"] attached."
@@ -1134,13 +1138,8 @@
chaser_speed = max(chaser_speed + health_percent, 0.5) //one tenth of a second faster for each missing 10% of health
blast_range -= round(health_percent * 10) //one additional range for each missing 10% of health
-/obj/item/hierophant_club/update_icon()
- icon_state = "hierophant_club[timer <= world.time ? "_ready":""][(beacon && !QDELETED(beacon)) ? "":"_beacon"]"
- item_state = icon_state
- if(ismob(loc))
- var/mob/M = loc
- M.update_inv_hands()
- M.update_inv_back()
+/obj/item/hierophant_club/update_icon_state()
+ icon_state = item_state = "hierophant_club[timer <= world.time ? "_ready":""][(beacon && !QDELETED(beacon)) ? "":"_beacon"]"
/obj/item/hierophant_club/proc/prepare_icon_update()
update_icon()
diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm
index 0f0ca8bf0c..2f6e8a9b7c 100644
--- a/code/modules/mining/machine_redemption.dm
+++ b/code/modules/mining/machine_redemption.dm
@@ -341,9 +341,8 @@
..()
update_icon()
-/obj/machinery/mineral/ore_redemption/update_icon()
+/obj/machinery/mineral/ore_redemption/update_icon_state()
if(powered())
icon_state = initial(icon_state)
else
icon_state = "[initial(icon_state)]-off"
- return
diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm
index 78b1a665db..dd3b13d8dd 100644
--- a/code/modules/mining/machine_vending.dm
+++ b/code/modules/mining/machine_vending.dm
@@ -87,7 +87,7 @@
..()
update_icon()
-/obj/machinery/mineral/equipment_vendor/update_icon()
+/obj/machinery/mineral/equipment_vendor/update_icon_state()
if(powered())
icon_state = initial(icon_state)
else
diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm
index 4f9bad2f0f..c7c34b0389 100644
--- a/code/modules/mining/ores_coins.dm
+++ b/code/modules/mining/ores_coins.dm
@@ -20,25 +20,24 @@
mats_per_stack = MINERAL_MATERIAL_AMOUNT
var/list/stack_overlays
-/obj/item/stack/ore/update_icon()
+/obj/item/stack/ore/update_overlays()
+ . = ..()
var/difference = min(ORESTACK_OVERLAYS_MAX, amount) - (LAZYLEN(stack_overlays)+1)
if(difference == 0)
return
else if(difference < 0 && LAZYLEN(stack_overlays)) //amount < stack_overlays, remove excess.
- cut_overlays()
if (LAZYLEN(stack_overlays)-difference <= 0)
- stack_overlays = null;
+ stack_overlays = null
else
stack_overlays.len += difference
else if(difference > 0) //amount > stack_overlays, add some.
- cut_overlays()
for(var/i in 1 to difference)
var/mutable_appearance/newore = mutable_appearance(icon, icon_state)
newore.pixel_x = rand(-8,8)
newore.pixel_y = rand(-8,8)
LAZYADD(stack_overlays, newore)
if (stack_overlays)
- add_overlay(stack_overlays)
+ . += stack_overlays
/obj/item/stack/ore/welder_act(mob/living/user, obj/item/I)
if(!refined_type)
diff --git a/code/modules/mining/point_bank.dm b/code/modules/mining/point_bank.dm
index 8d0bb4e1e4..11f23a5d7c 100644
--- a/code/modules/mining/point_bank.dm
+++ b/code/modules/mining/point_bank.dm
@@ -41,9 +41,8 @@
..()
update_icon()
-/obj/machinery/point_bank/update_icon()
+/obj/machinery/point_bank/update_icon_state()
if(powered())
icon_state = initial(icon_state)
else
icon_state = "[initial(icon_state)]-off"
- return
\ No newline at end of file
diff --git a/code/modules/mob/camera/camera.dm b/code/modules/mob/camera/camera.dm
index ff1d9231f7..a381cc512a 100644
--- a/code/modules/mob/camera/camera.dm
+++ b/code/modules/mob/camera/camera.dm
@@ -11,17 +11,6 @@
invisibility = INVISIBILITY_ABSTRACT // No one can see us
sight = SEE_SELF
move_on_shuttle = FALSE
- var/call_life = FALSE //TRUE if Life() should be called on this camera every tick of the mobs subystem, as if it were a living mob
-
-/mob/camera/Initialize()
- . = ..()
- if(call_life)
- GLOB.living_cameras += src
-
-/mob/camera/Destroy()
- . = ..()
- if(call_life)
- GLOB.living_cameras -= src
/mob/camera/experience_pressure_difference()
return
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index b891525e42..87c8598541 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -14,6 +14,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
move_resist = INFINITY
see_invisible = SEE_INVISIBLE_OBSERVER
see_in_dark = 100
+ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
invisibility = INVISIBILITY_OBSERVER
hud_type = /datum/hud/ghost
movement_type = GROUND | FLYING
@@ -132,6 +133,8 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
. = ..()
AddElement(/datum/element/ghost_role_eligibility)
grant_all_languages()
+ show_data_huds()
+ data_huds_on = 1
/mob/dead/observer/get_photo_description(obj/item/camera/camera)
if(!invisibility || camera.see_ghosts)
@@ -289,7 +292,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES
if(world.time < roundstart_quit_limit)
penalty += roundstart_quit_limit - world.time
- var/maximumRoundEnd = SSautotransfer.starttime + SSautotransfer.voteinterval * SSautotransfer.maxvotes
+ var/maximumRoundEnd = SSautotransfer.starttime + SSautotransfer.voteinterval * SSautotransfer.maxvotes
if(penalty - SSshuttle.realtimeofstart > maximumRoundEnd + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
penalty = CANT_REENTER_ROUND
diff --git a/code/modules/mob/living/brain/MMI.dm b/code/modules/mob/living/brain/MMI.dm
index 2a57506df6..77844a4788 100644
--- a/code/modules/mob/living/brain/MMI.dm
+++ b/code/modules/mob/living/brain/MMI.dm
@@ -14,20 +14,20 @@
var/force_replace_ai_name = FALSE
var/overrides_aicore_laws = FALSE // Whether the laws on the MMI, if any, override possible pre-existing laws loaded on the AI core.
-/obj/item/mmi/update_icon()
+/obj/item/mmi/update_icon_state()
if(!brain)
icon_state = "mmi_off"
- return
- if(istype(brain, /obj/item/organ/brain/alien))
+ else if(istype(brain, /obj/item/organ/brain/alien))
icon_state = "mmi_brain_alien"
- braintype = "Xenoborg" //HISS....Beep.
else
icon_state = "mmi_brain"
- braintype = "Cyborg"
+
+/obj/item/mmi/update_overlays()
+ . = ..()
if(brainmob && brainmob.stat != DEAD)
- add_overlay("mmi_alive")
+ . += "mmi_alive"
else
- add_overlay("mmi_dead")
+ . += "mmi_dead"
/obj/item/mmi/Initialize()
. = ..()
@@ -68,6 +68,10 @@
name = "Man-Machine Interface: [brainmob.real_name]"
update_icon()
+ if(istype(brain, /obj/item/organ/brain/alien))
+ braintype = "Xenoborg" //HISS....Beep.
+ else
+ braintype = "Cyborg"
SSblackbox.record_feedback("amount", "mmis_filled", 1)
@@ -85,7 +89,7 @@
to_chat(user, "You unlock and upend the MMI, spilling the brain onto the floor.")
eject_brain(user)
update_icon()
- name = "Man-Machine Interface"
+ name = initial(name)
/obj/item/mmi/proc/eject_brain(mob/user)
brainmob.container = null //Reset brainmob mmi var.
@@ -129,7 +133,10 @@
name = "Man-Machine Interface: [brainmob.real_name]"
update_icon()
- return
+ if(istype(brain, /obj/item/organ/brain/alien))
+ braintype = "Xenoborg" //HISS....Beep.
+ else
+ braintype = "Cyborg"
/obj/item/mmi/proc/replacement_ai_name()
return brainmob.name
diff --git a/code/modules/mob/living/brain/posibrain.dm b/code/modules/mob/living/brain/posibrain.dm
index e2d6b095fe..224b5ad807 100644
--- a/code/modules/mob/living/brain/posibrain.dm
+++ b/code/modules/mob/living/brain/posibrain.dm
@@ -184,11 +184,10 @@ GLOBAL_VAR(posibrain_notify_cooldown)
return
-/obj/item/mmi/posibrain/update_icon()
+/obj/item/mmi/posibrain/update_icon_state()
if(searching)
icon_state = "[initial(icon_state)]-searching"
- return
- if(brainmob && brainmob.key)
+ else if(brainmob && brainmob.key)
icon_state = "[initial(icon_state)]-occupied"
else
icon_state = initial(icon_state)
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 32e3696bc5..d7fce8a437 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -397,6 +397,7 @@
W.layer = initial(W.layer)
W.plane = initial(W.plane)
changeNext_move(0)
+ update_equipment_speed_mods() // In case cuffs ever change speed
/mob/living/carbon/proc/clear_cuffs(obj/item/I, cuff_break)
if(!I.loc || buckled)
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index 5bbc6d6a64..1ea2fa1130 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -238,19 +238,19 @@
var/obj/item/organ/O = X
O.emp_act(severity)
-/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
- if(tesla_shock && (flags_1 & TESLA_IGNORE_1))
+/mob/living/carbon/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
+ if((flags & SHOCK_TESLA) && (flags_1 & TESLA_IGNORE_1))
return FALSE
if(HAS_TRAIT(src, TRAIT_SHOCKIMMUNE))
return FALSE
shock_damage *= siemens_coeff
if(dna && dna.species)
shock_damage *= dna.species.siemens_coeff
- if(shock_damage<1 && !override)
+ if(shock_damage < 1)
return 0
if(reagents.has_reagent(/datum/reagent/teslium))
shock_damage *= 1.5 //If the mob has teslium in their body, shocks are 50% more damaging!
- if(illusion)
+ if((flags & SHOCK_ILLUSION))
adjustStaminaLoss(shock_damage)
else
take_overall_damage(0,shock_damage)
@@ -262,16 +262,13 @@
jitteriness += 1000 //High numbers for violent convulsions
do_jitter_animation(jitteriness)
stuttering += 2
- if((!tesla_shock || (tesla_shock && siemens_coeff > 0.5)) && stun)
+ if((!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && (flags & SHOCK_NOSTUN))
Stun(40)
spawn(20)
jitteriness = max(jitteriness - 990, 10) //Still jittery, but vastly less
- if((!tesla_shock || (tesla_shock && siemens_coeff > 0.5)) && stun)
+ if((!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && (flags & SHOCK_NOSTUN))
DefaultCombatKnockdown(60)
- if(override)
- return override
- else
- return shock_damage
+ return shock_damage
/mob/living/carbon/proc/help_shake_act(mob/living/carbon/M)
if(on_fire)
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index fec82b357f..cb21534d25 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -25,15 +25,10 @@
var/list/obscured = check_obscured_slots()
var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE))
- if(ishuman(src)) //user just returned, y'know, the user's own species. dumb.
- var/mob/living/carbon/human/H = src
- var/datum/species/pref_species = H.dna.species
- if(get_visible_name() == "Unknown") // same as flavor text, but hey it works.
- . += "You can't make out what species they are."
- else if(skipface)
- . += "You can't make out what species they are."
- else
- . += "[t_He] [t_is] a [H.dna.custom_species ? H.dna.custom_species : pref_species.name]!"
+ if(skipface || get_visible_name() == "Unknown")
+ . += "You can't make out what species they are."
+ else
+ . += "[t_He] [t_is] a [dna.custom_species ? dna.custom_species : dna.species.name]!"
//uniform
if(w_uniform && !(SLOT_W_UNIFORM in obscured))
@@ -389,18 +384,8 @@
else if(isobserver(user) && traitstring)
. += "Traits: [traitstring]"
- //No flavor text unless the face can be seen. Prevents certain metagaming with impersonation.
- var/invisible_man = skipface || get_visible_name() == "Unknown"
- if(invisible_man)
- . += "...?"
- else
- var/flavor = print_flavor_text(flavor_text)
- if(flavor)
- . += flavor
- var/temp_flavor = print_flavor_text(flavor_text_2,TRUE)
- if(temp_flavor)
- . += temp_flavor
- SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .)
+ SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) //This also handles flavor texts now
+
. += "*---------*"
/mob/living/proc/status_effect_examines(pronoun_replacement) //You can include this in any mob's examine() to show the examine texts of status effects!
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index feb19ceaae..1b57796250 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -9,8 +9,6 @@
verbs += /mob/living/proc/mob_sleep
verbs += /mob/living/proc/lay_down
verbs += /mob/living/carbon/human/proc/underwear_toggle //fwee
- verbs += /mob/proc/set_flavor
- verbs += /mob/proc/set_flavor_2
//initialize limbs first
create_bodyparts()
@@ -40,6 +38,8 @@
. = ..()
if(!CONFIG_GET(flag/disable_human_mood))
AddComponent(/datum/component/mood)
+ AddElement(/datum/element/flavor_text/carbon)
+ AddElement(/datum/element/flavor_text, "", "Temporary Flavor Text", "This should be used only for things pertaining to the current round!")
/mob/living/carbon/human/Destroy()
QDEL_NULL(physiology)
@@ -959,7 +959,7 @@
var/health_deficiency = ((100 + stambufferinfluence) - health + (getStaminaLoss()*0.75))//CIT CHANGE - reduces the impact of staminaloss and makes stamina buffer influence it
if(health_deficiency >= 40)
add_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN, override = TRUE, multiplicative_slowdown = ((health_deficiency-39) / 75), blacklisted_movetypes = FLOATING|FLYING)
- add_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING, override = TRUE, multiplicative_slowdown = ((health_deficiency-39) / 25), movetypes = FLOATING)
+ add_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING, override = TRUE, multiplicative_slowdown = ((health_deficiency-39) / 25), movetypes = FLYING, blacklisted_movetypes = FLOATING)
else
remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN)
remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING)
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 5bedce359b..4ef5a3ca04 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -397,8 +397,8 @@
//Added a safety check in case you want to shock a human mob directly through electrocute_act.
-/mob/living/carbon/human/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
- if(tesla_shock)
+/mob/living/carbon/human/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
+ if(flags & SHOCK_TESLA)
var/total_coeff = 1
if(gloves)
var/obj/item/clothing/gloves/G = gloves
@@ -413,20 +413,20 @@
siemens_coeff = total_coeff
if(flags_1 & TESLA_IGNORE_1)
siemens_coeff = 0
- else if(!safety)
+ else if(!(flags & SHOCK_NOGLOVES))
var/gloves_siemens_coeff = 1
if(gloves)
var/obj/item/clothing/gloves/G = gloves
gloves_siemens_coeff = G.siemens_coefficient
siemens_coeff = gloves_siemens_coeff
- if(undergoing_cardiac_arrest() && !illusion)
+ if(undergoing_cardiac_arrest() && !(flags & SHOCK_ILLUSION))
if(shock_damage * siemens_coeff >= 1 && prob(25))
var/obj/item/organ/heart/heart = getorganslot(ORGAN_SLOT_HEART)
heart.beating = TRUE
if(stat == CONSCIOUS)
to_chat(src, "You feel your heart beating again!")
siemens_coeff *= physiology.siemens_coeff
- . = ..(shock_damage,source,siemens_coeff,safety,override,tesla_shock, illusion, stun)
+ . = ..()
if(.)
electrocution_animation(40)
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index 122a06b17b..580b0aaaf0 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -147,7 +147,7 @@
/mob/living/carbon/human/equipped_speed_mods()
. = ..()
- for(var/sloties in get_all_slots())
+ for(var/sloties in get_all_slots() - list(l_store, r_store, s_store))
var/obj/item/thing = sloties
. += thing?.slowdown
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 85a7a09d5c..1cb30a657b 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -816,9 +816,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
//A little rename so we don't have to use tail_lizard or tail_human when naming the sprites.
if(bodypart == "tail_lizard" || bodypart == "tail_human" || bodypart == "mam_tail" || bodypart == "xenotail")
bodypart = "tail"
- else if(bodypart == "waggingtail_lizard")
- bodypart = "waggingtail"
- if(bodypart == "mam_waggingtail" || bodypart == "waggingtail_human")
+ if(bodypart == "mam_waggingtail" || bodypart == "waggingtail_human" || bodypart == "waggingtail_lizard")
bodypart = "tailwag"
if(bodypart == "mam_ears" || bodypart == "ears")
bodypart = "ears"
diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
index 70abba5a01..e229860cf7 100644
--- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
@@ -100,6 +100,9 @@
var/obj/item/light_eater/blade
decay_factor = 0
+/obj/item/organ/heart/nightmare/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/update_icon_blocker)
/obj/item/organ/heart/nightmare/attack(mob/M, mob/living/carbon/user, obj/target)
if(M != user)
@@ -130,9 +133,6 @@
/obj/item/organ/heart/nightmare/Stop()
return 0
-/obj/item/organ/heart/nightmare/update_icon()
- return //always beating visually
-
/obj/item/organ/heart/nightmare/on_death()
if(!owner)
return
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index 2bf17bc265..d3199d6f8b 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -1,4 +1,5 @@
-/mob/living/Life(seconds, times_fired)
+/mob/living/proc/Life(seconds, times_fired)
+ set waitfor = FALSE
set invisibility = 0
if(digitalinvis)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index a2a69cb49a..0c69c5c744 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -794,6 +794,13 @@
what.forceMove(drop_location())
log_combat(src, who, "stripped [what] off")
+ if(Adjacent(who)) //update inventory window
+ who.show_inv(src)
+ else
+ src << browse(null,"window=mob[REF(who)]")
+
+ who.update_equipment_speed_mods() // Updates speed in case stripped speed affecting item
+
// The src mob is trying to place an item on someone
// Override if a certain mob should be behave differently when placing items (can't, for example)
/mob/living/stripPanelEquip(obj/item/what, mob/who, where)
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index af8dc6dca9..27ecaf30d5 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -427,14 +427,14 @@
take_bodypart_damage(acidpwr * min(1, acid_volume * 0.1))
return 1
-/mob/living/proc/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
- SEND_SIGNAL(src, COMSIG_LIVING_ELECTROCUTE_ACT, shock_damage)
- if(tesla_shock && (flags_1 & TESLA_IGNORE_1))
+/mob/living/proc/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
+ SEND_SIGNAL(src, COMSIG_LIVING_ELECTROCUTE_ACT, shock_damage, source, siemens_coeff, flags)
+ if((flags & SHOCK_TESLA) && (flags_1 & TESLA_IGNORE_1))
return FALSE
if(HAS_TRAIT(src, TRAIT_SHOCKIMMUNE))
return FALSE
if(shock_damage > 0)
- if(!illusion)
+ if(!(flags & SHOCK_ILLUSION))
adjustFireLoss(shock_damage)
visible_message(
"[src] was shocked by \the [source]!", \
diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm
index f278d22891..410e5b28db 100644
--- a/code/modules/mob/living/living_movement.dm
+++ b/code/modules/mob/living/living_movement.dm
@@ -1,6 +1,10 @@
/mob/living/Moved()
. = ..()
update_turf_movespeed(loc)
+ if(is_shifted)
+ is_shifted = FALSE
+ pixel_x = get_standard_pixel_x_offset(lying)
+ pixel_y = get_standard_pixel_y_offset(lying)
/mob/living/CanPass(atom/movable/mover, turf/target)
if((mover.pass_flags & PASSMOB))
diff --git a/code/modules/mob/living/silicon/silicon_defense.dm b/code/modules/mob/living/silicon/silicon_defense.dm
index 5d1d2610b9..a93bc8662e 100644
--- a/code/modules/mob/living/silicon/silicon_defense.dm
+++ b/code/modules/mob/living/silicon/silicon_defense.dm
@@ -85,11 +85,11 @@
return
return ..()
-/mob/living/silicon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
+/mob/living/silicon/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
if(buckled_mobs)
for(var/mob/living/M in buckled_mobs)
unbuckle_mob(M)
- M.electrocute_act(shock_damage/100, source, siemens_coeff, safety, tesla_shock, illusion, stun) //Hard metal shell conducts!
+ M.electrocute_act(shock_damage/100, source, siemens_coeff, flags) //Hard metal shell conducts!
return 0 //So borgs they don't die trying to fix wiring
/mob/living/silicon/emp_act(severity)
diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm
index 64b783b692..708c9ea2cd 100644
--- a/code/modules/mob/living/simple_animal/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs.dm
@@ -103,7 +103,7 @@
/mob/living/simple_animal/hostile/construct/narsie_act()
return
-/mob/living/simple_animal/hostile/construct/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
+/mob/living/simple_animal/hostile/construct/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
return 0
/mob/living/simple_animal/hostile/construct/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
index 726eda6c45..0d344f1a9b 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
@@ -277,7 +277,7 @@
// Why would bees pay attention to drones?
return 1
-/mob/living/simple_animal/drone/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
+/mob/living/simple_animal/drone/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
return 0 //So they don't die trying to fix wiring
/mob/living/simple_animal/drone/can_see_reagents()
diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm
index 9ad3cbd373..ff42512666 100644
--- a/code/modules/mob/living/simple_animal/guardian/guardian.dm
+++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm
@@ -633,8 +633,9 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
"}
-/obj/item/paper/guides/antag/guardian/update_icon()
- return
+/obj/item/paper/guides/antag/guardian/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/update_icon_blocker)
/obj/item/paper/guides/antag/guardian/wizard
name = "Guardian Guide"
diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm
index b019019c71..dca7bc7006 100644
--- a/code/modules/mob/living/simple_animal/hostile/bear.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bear.dm
@@ -99,9 +99,57 @@
to_chat(user, "You strap the armor plating to [A] and sharpen [A.p_their()] claws with the nail filer. This was a great idea.")
qdel(src)
-
-
-
+mob/living/simple_animal/hostile/bear/butter //The mighty companion to Cak. Several functions used from it.
+ name = "Terrygold"
+ icon_state = "butterbear"
+ icon_living = "butterbear"
+ icon_dead = "butterbear_dead"
+ desc = "I can't believe its not a bear!"
+ faction = list("neutral", "russian")
+ obj_damage = 11
+ melee_damage_lower = 1
+ melee_damage_upper = 1
+ armour_penetration = 0
+ response_harm = "takes a bite out of"
+ attacked_sound = 'sound/items/eatfood.ogg'
+ deathmessage = "loses its false life and collapses!"
+ butcher_results = list(/obj/item/reagent_containers/food/snacks/butter = 6, /obj/item/reagent_containers/food/snacks/meat/slab = 3, /obj/item/organ/brain = 1, /obj/item/organ/heart = 1)
+ attack_sound = 'sound/weapons/slap.ogg'
+ attacktext = "slaps"
+
+/mob/living/simple_animal/hostile/bear/butter/Life() //Heals butter bear really fast when he takes damage.
+ if(stat)
+ return
+ if(health < maxHealth)
+ heal_overall_damage(10) //Fast life regen, makes it hard for you to get eaten to death.
+
+/mob/living/simple_animal/hostile/bear/butter/attack_hand(mob/living/L) //Borrowed code from Cak, feeds people if they hit you. More nutriment but less vitamin to represent BUTTER.
+ ..()
+ if(L.a_intent == INTENT_HARM && L.reagents && !stat)
+ L.reagents.add_reagent(/datum/reagent/consumable/nutriment, 1)
+ L.reagents.add_reagent(/datum/reagent/consumable/nutriment/vitamin, 0.1)
+
+/mob/living/simple_animal/hostile/bear/butter/CheckParts(list/parts) //Borrowed code from Cak, allows the brain used to actually control the bear.
+ ..()
+ var/obj/item/organ/brain/B = locate(/obj/item/organ/brain) in contents
+ if(!B || !B.brainmob || !B.brainmob.mind)
+ return
+ B.brainmob.mind.transfer_to(src)
+ to_chat(src, "You are a butter bear! You're a mostly harmless bear/butter hybrid that everyone loves. People can take bites out of you if they're hungry, but you regenerate health \
+ so quickly that it generally doesn't matter. You're remarkably resilient to any damage besides this and it's hard for you to really die at all. You should go around and bring happiness and \
+ free butter to the station!")
+ var/new_name = stripped_input(src, "Enter your name, or press \"Cancel\" to stick with Terrygold.", "Name Change")
+ if(new_name)
+ to_chat(src, "Your name is now \"new_name\"!")
+ name = new_name
+
+mob/living/simple_animal/hostile/bear/butter/AttackingTarget() //Makes some attacks by the butter bear slip those who dare cross its path.
+ if(isliving(target))
+ var/mob/living/L = target
+ if((L.mobility_flags & MOBILITY_STAND))
+ L.Knockdown(20)
+ playsound(loc, 'sound/misc/slip.ogg', 15)
+ L.visible_message("[L] slips on butter!")
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
index d544671d3e..52083721b7 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
@@ -244,8 +244,9 @@ Difficulty: Very Hard
var/list/stored_items = list()
var/list/blacklist = list()
-/obj/machinery/smartfridge/black_box/update_icon()
- return
+/obj/machinery/smartfridge/black_box/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/update_icon_blocker)
/obj/machinery/smartfridge/black_box/accept_check(obj/item/O)
if(!istype(O))
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm
index 1ddd9079b2..50c6025378 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm
@@ -275,7 +275,7 @@ GLOBAL_LIST_INIT(AISwarmerCapsByType, list(/mob/living/simple_animal/hostile/swa
else
var/mob/living/L = target
L.attack_animal(src)
- L.electrocute_act(10, src, safety = TRUE) //safety = TRUE means we don't check gloves... Ok?
+ L.electrocute_act(10, src, flags = SHOCK_NOGLOVES)
return TRUE
else
return ..()
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index e6cdf81e38..5225534cee 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -202,9 +202,6 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA
if(self_message)
show_message(self_message, MSG_AUDIBLE, deaf_message, MSG_VISUAL)
-/mob/proc/Life()
- set waitfor = FALSE
-
/mob/proc/get_item_by_slot(slot_id)
return null
@@ -506,14 +503,6 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
unset_machine()
src << browse(null, t1)
- if(href_list["flavor_more"])
- usr << browse(text("[][]", name, replacetext(flavor_text, "\n", "
")), text("window=[];size=500x200", name))
- onclose(usr, "[name]")
-
- if(href_list["flavor2_more"])
- usr << browse(text("[][]", name, replacetext(flavor_text_2, "\n", "
")), text("window=[];size=500x200", name))
- onclose(usr, "[name]")
-
if(href_list["refresh"])
if(machine && in_range(src, usr))
show_inv(machine)
@@ -708,6 +697,38 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
client.last_turn = world.time + MOB_FACE_DIRECTION_DELAY
return TRUE
+/mob/verb/eastshift()
+ set hidden = TRUE
+ if(!canface())
+ return FALSE
+ if(pixel_x <= 16)
+ pixel_x++
+ is_shifted = TRUE
+
+/mob/verb/westshift()
+ set hidden = TRUE
+ if(!canface())
+ return FALSE
+ if(pixel_x >= -16)
+ pixel_x--
+ is_shifted = TRUE
+
+/mob/verb/northshift()
+ set hidden = TRUE
+ if(!canface())
+ return FALSE
+ if(pixel_y <= 16)
+ pixel_y++
+ is_shifted = TRUE
+
+/mob/verb/southshift()
+ set hidden = TRUE
+ if(!canface())
+ return FALSE
+ if(pixel_y >= -16)
+ pixel_y--
+ is_shifted = TRUE
+
/mob/proc/IsAdvancedToolUser()//This might need a rename but it should replace the can this mob use things check
return FALSE
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 6725e29610..f638281f27 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -38,6 +38,7 @@
var/resting = 0 //Carbon
var/lying = 0
var/lying_prev = 0
+ var/is_shifted = FALSE
//MOVEMENT SPEED
var/list/movespeed_modification //Lazy list, see mob_movespeed.dm
@@ -124,6 +125,3 @@
var/siliconaccesstoggle = FALSE
var/voluntary_ghosted = FALSE //whether or not they voluntarily ghosted.
-
- var/flavor_text = ""
- var/flavor_text_2 = "" //version of the above that only lasts for the current round.
diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm
index a83720dc23..d722197bd9 100644
--- a/code/modules/modular_computers/computers/item/computer.dm
+++ b/code/modules/modular_computers/computers/item/computer.dm
@@ -26,6 +26,7 @@
var/icon_state_unpowered = null // Icon state when the computer is turned off.
var/icon_state_powered = null // Icon state when the computer is turned on.
var/icon_state_menu = "menu" // Icon state overlay when the computer is turned on, but no program is loaded that would override the screen.
+ var/display_overlays = TRUE // If FALSE, don't draw overlays on this device at all
var/max_hardware_size = 0 // Maximal hardware w_class. Tablets/PDAs have 1, laptops 2, consoles 4.
var/steel_sheet_cost = 5 // Amount of steel sheets refunded when disassembling an empty frame of this computer.
@@ -208,20 +209,26 @@
else if(obj_integrity < max_integrity)
. += "It is damaged."
-/obj/item/modular_computer/update_icon()
- cut_overlays()
+/obj/item/modular_computer/update_icon_state()
if(!enabled)
icon_state = icon_state_unpowered
else
icon_state = icon_state_powered
+
+
+/obj/item/modular_computer/update_overlays()
+ . = ..()
+ if(!display_overlays)
+ return
+ if(enabled)
if(active_program)
- add_overlay(active_program.program_icon_state ? active_program.program_icon_state : icon_state_menu)
+ . += active_program.program_icon_state ? active_program.program_icon_state : icon_state_menu
else
- add_overlay(icon_state_menu)
+ . += icon_state_menu
if(obj_integrity <= integrity_failure * max_integrity)
- add_overlay("bsod")
- add_overlay("broken")
+ . += "bsod"
+ . += "broken"
// On-click handling. Turns on the computer if it's off and opens the GUI.
diff --git a/code/modules/modular_computers/computers/item/laptop.dm b/code/modules/modular_computers/computers/item/laptop.dm
index 1f19cf64ff..a4d2e74657 100644
--- a/code/modules/modular_computers/computers/item/laptop.dm
+++ b/code/modules/modular_computers/computers/item/laptop.dm
@@ -18,6 +18,7 @@
screen_on = 0 // Starts closed
var/start_open = TRUE // unless this var is set to 1
var/icon_state_closed = "laptop-closed"
+ display_overlays = FALSE
var/w_class_open = WEIGHT_CLASS_BULKY
/obj/item/modular_computer/laptop/examine(mob/user)
@@ -31,12 +32,11 @@
if(start_open && !screen_on)
toggle_open()
-/obj/item/modular_computer/laptop/update_icon()
- if(screen_on)
- ..()
- else
- cut_overlays()
+/obj/item/modular_computer/laptop/update_icon_state()
+ if(!screen_on)
icon_state = icon_state_closed
+ else
+ . = ..()
/obj/item/modular_computer/laptop/attack_self(mob/user)
if(!screen_on)
@@ -97,6 +97,7 @@
w_class = w_class_open
screen_on = !screen_on
+ display_overlays = screen_on
update_icon()
diff --git a/code/modules/modular_computers/computers/item/processor.dm b/code/modules/modular_computers/computers/item/processor.dm
index b86d4e5d0d..295ecc66c0 100644
--- a/code/modules/modular_computers/computers/item/processor.dm
+++ b/code/modules/modular_computers/computers/item/processor.dm
@@ -16,15 +16,15 @@
machinery_computer.cpu = null
machinery_computer = null
-/obj/item/modular_computer/processor/New(comp)
+/obj/item/modular_computer/processor/Initialize(mapload)
. = ..()
- if(!comp || !istype(comp, /obj/machinery/modular_computer))
+ if(!loc || !istype(loc, /obj/machinery/modular_computer))
CRASH("Inapropriate type passed to obj/item/modular_computer/processor/New()! Aborting.")
return
// Obtain reference to machinery computer
all_components = list()
idle_threads = list()
- machinery_computer = comp
+ machinery_computer = loc
machinery_computer.cpu = src
hardware_flag = machinery_computer.hardware_flag
max_hardware_size = machinery_computer.max_hardware_size
@@ -34,14 +34,11 @@
integrity_failure = machinery_computer.integrity_failure
base_active_power_usage = machinery_computer.base_active_power_usage
base_idle_power_usage = machinery_computer.base_idle_power_usage
+ machinery_computer.RegisterSignal(src, COMSIG_ATOM_UPDATED_ICON, /atom/proc/update_icon) //when we update_icon, also update the computer
/obj/item/modular_computer/processor/relay_qdel()
qdel(machinery_computer)
-/obj/item/modular_computer/processor/update_icon()
- if(machinery_computer)
- return machinery_computer.update_icon()
-
// This thing is not meant to be used on it's own, get topic data from our machinery owner.
//obj/item/modular_computer/processor/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
// if(!machinery_computer)
diff --git a/code/modules/modular_computers/computers/item/tablet.dm b/code/modules/modular_computers/computers/item/tablet.dm
index 0818ce8034..bc9d62acbe 100644
--- a/code/modules/modular_computers/computers/item/tablet.dm
+++ b/code/modules/modular_computers/computers/item/tablet.dm
@@ -15,14 +15,11 @@
var/has_variants = TRUE
var/finish_color = null
-/obj/item/modular_computer/tablet/update_icon()
- ..()
+/obj/item/modular_computer/tablet/update_icon_state()
if(has_variants)
if(!finish_color)
finish_color = pick("red","blue","brown","green","black")
- icon_state = "tablet-[finish_color]"
- icon_state_unpowered = "tablet-[finish_color]"
- icon_state_powered = "tablet-[finish_color]"
+ icon_state = icon_state_powered = icon_state_unpowered = "tablet-[finish_color]"
/obj/item/modular_computer/tablet/syndicate_contract_uplink
name = "contractor tablet"
diff --git a/code/modules/modular_computers/computers/machinery/modular_computer.dm b/code/modules/modular_computers/computers/machinery/modular_computer.dm
index a1f13878c1..89c6166a0d 100644
--- a/code/modules/modular_computers/computers/machinery/modular_computer.dm
+++ b/code/modules/modular_computers/computers/machinery/modular_computer.dm
@@ -48,26 +48,28 @@
if(cpu)
. |= cpu.emag_act(user)
-/obj/machinery/modular_computer/update_icon()
- cut_overlays()
- icon_state = icon_state_powered
+/obj/machinery/modular_computer/update_icon_state()
+ if(cpu?.enabled)
+ icon_state = icon_state_powered
+ else if(stat & NOPOWER || !(cpu?.use_power()))
+ icon_state = icon_state_unpowered
+/obj/machinery/modular_computer/update_overlays()
+ . = ..()
if(!cpu || !cpu.enabled)
if (!(stat & NOPOWER) && (cpu && cpu.use_power()))
- add_overlay(screen_icon_screensaver)
- else
- icon_state = icon_state_unpowered
+ . += screen_icon_screensaver
set_light(0)
else
set_light(light_strength)
if(cpu.active_program)
- add_overlay(cpu.active_program.program_icon_state ? cpu.active_program.program_icon_state : screen_icon_state_menu)
+ . += cpu.active_program.program_icon_state ? cpu.active_program.program_icon_state : screen_icon_state_menu
else
- add_overlay(screen_icon_state_menu)
+ . += screen_icon_state_menu
if(cpu && cpu.obj_integrity <= cpu.integrity_failure * cpu.max_integrity)
- add_overlay("bsod")
- add_overlay("broken")
+ . += "bsod"
+ . += "broken"
// Eject ID card from computer, if it has ID slot with card inside.
/obj/machinery/modular_computer/proc/eject_id()
diff --git a/code/modules/newscaster/newscaster_machine.dm b/code/modules/newscaster/newscaster_machine.dm
index 93d5dc3b31..95a24817a0 100644
--- a/code/modules/newscaster/newscaster_machine.dm
+++ b/code/modules/newscaster/newscaster_machine.dm
@@ -53,7 +53,7 @@ GLOBAL_LIST_EMPTY(allCasters)
picture = null
return ..()
-/obj/machinery/newscaster/update_icon()
+/obj/machinery/newscaster/update_icon_state()
if(stat & (NOPOWER|BROKEN))
icon_state = "newscaster_off"
else
diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm
index f75569ef7a..1a93661c76 100644
--- a/code/modules/paperwork/clipboard.dm
+++ b/code/modules/paperwork/clipboard.dm
@@ -25,14 +25,14 @@
QDEL_NULL(toppaper) //let movable/Destroy handle the rest
return ..()
-/obj/item/clipboard/update_icon()
- cut_overlays()
+/obj/item/clipboard/update_overlays()
+ . = ..()
if(toppaper)
- add_overlay(toppaper.icon_state)
- copy_overlays(toppaper)
+ . += toppaper.icon_state
+ . += toppaper.overlays
if(haspen)
- add_overlay("clipboard_pen")
- add_overlay("clipboard_over")
+ . += "clipboard_pen"
+ . += "clipboard_over"
/obj/item/clipboard/attackby(obj/item/W, mob/user, params)
diff --git a/code/modules/paperwork/contract.dm b/code/modules/paperwork/contract.dm
index 5f7db07190..2c02903d3e 100644
--- a/code/modules/paperwork/contract.dm
+++ b/code/modules/paperwork/contract.dm
@@ -7,13 +7,14 @@
var/datum/mind/target
item_flags = NOBLUDGEON
+/obj/item/paper/contract/ComponentInitialize()
+ return
+ . = ..()
+ AddElement(/datum/element/update_icon_blocker)
+
/obj/item/paper/contract/proc/update_text()
return
-/obj/item/paper/contract/update_icon()
- return
-
-
/obj/item/paper/contract/employment
icon_state = "paper_words"
diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm
index 4cd44af5ab..a599ec9deb 100644
--- a/code/modules/paperwork/folders.dm
+++ b/code/modules/paperwork/folders.dm
@@ -28,11 +28,10 @@
icon_state = "folder_white"
-/obj/item/folder/update_icon()
- cut_overlays()
+/obj/item/folder/update_overlays()
+ . = ..()
if(contents.len)
- add_overlay("folder_paper")
-
+ . += "folder_paper"
/obj/item/folder/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/paper) || istype(W, /obj/item/photo) || istype(W, /obj/item/documents))
diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm
index 20f4ab0c86..88b6230b7d 100644
--- a/code/modules/paperwork/paper.dm
+++ b/code/modules/paperwork/paper.dm
@@ -78,8 +78,7 @@
return get_dist(src, target) < 2
return ..()
-/obj/item/paper/update_icon()
-
+/obj/item/paper/update_icon_state()
if(resistance_flags & ON_FIRE)
icon_state = "paper_onfire"
return
@@ -379,8 +378,9 @@
icon_state = "scrap"
slot_flags = null
-/obj/item/paper/crumpled/update_icon()
- return
+/obj/item/paper/crumpled/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/update_icon_blocker)
/obj/item/paper/crumpled/bloody
icon_state = "scrap_bloodied"
diff --git a/code/modules/paperwork/paper_cutter.dm b/code/modules/paperwork/paper_cutter.dm
index 0f57d53111..0a7bf011a7 100644
--- a/code/modules/paperwork/paper_cutter.dm
+++ b/code/modules/paperwork/paper_cutter.dm
@@ -34,13 +34,13 @@
return (BRUTELOSS)
-/obj/item/papercutter/update_icon()
- ..()
- cut_overlays()
+/obj/item/papercutter/update_icon_state()
icon_state = (storedcutter ? "[initial(icon_state)]-cutter" : "[initial(icon_state)]")
- if(storedpaper)
- add_overlay("paper")
+/obj/item/papercutter/update_overlays()
+ . = ..()
+ if(storedpaper)
+ . += "paper"
/obj/item/papercutter/attackby(obj/item/P, mob/user, params)
if(istype(P, /obj/item/paper) && !storedpaper)
diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm
index 5648bc7af8..b8bcbedbbe 100644
--- a/code/modules/paperwork/paperbin.dm
+++ b/code/modules/paperwork/paperbin.dm
@@ -51,7 +51,7 @@
else if(istype(over_object, /obj/screen/inventory/hand))
var/obj/screen/inventory/hand/H = over_object
M.putItemFromInventoryInHandIfPossible(src, H.held_index)
-
+
else
. = ..()
@@ -125,14 +125,16 @@
. += "It doesn't contain anything."
-/obj/item/paper_bin/update_icon()
+/obj/item/paper_bin/update_icon_state()
if(total_paper < 1)
icon_state = "paper_bin0"
else
icon_state = "[initial(icon_state)]"
- cut_overlays()
+
+/obj/item/paper_bin/update_overlays()
+ . = ..()
if(bin_pen)
- add_overlay(mutable_appearance(bin_pen.icon, bin_pen.icon_state))
+ . += mutable_appearance(bin_pen.icon, bin_pen.icon_state)
/obj/item/paper_bin/construction
name = "construction paper bin"
diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm
index 06c16810b7..a9baf60c0c 100644
--- a/code/modules/paperwork/paperplane.dm
+++ b/code/modules/paperwork/paperplane.dm
@@ -55,12 +55,12 @@
sleep(10)
return (BRUTELOSS)
-/obj/item/paperplane/update_icon()
- cut_overlays()
+/obj/item/paperplane/update_overlays()
+ . = ..()
var/list/stamped = internalPaper.stamped
if(stamped)
for(var/S in stamped)
- add_overlay("paperplane_[S]")
+ . += "paperplane_[S]"
/obj/item/paperplane/attack_self(mob/user)
to_chat(user, "You unfold [src].")
diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm
index a98f057c4a..227e22d499 100644
--- a/code/modules/paperwork/pen.dm
+++ b/code/modules/paperwork/pen.dm
@@ -179,9 +179,10 @@
sharpness = IS_SHARP
var/on = FALSE
-/obj/item/pen/edagger/Initialize()
+/obj/item/pen/edagger/ComponentInitialize()
. = ..()
AddComponent(/datum/component/butchering, 60, 100, 0, 'sound/weapons/blade1.ogg')
+ AddElement(/datum/element/update_icon_updates_onmob)
/obj/item/pen/edagger/get_sharpness()
return on * sharpness
@@ -209,10 +210,9 @@
to_chat(user, "[src] is now active.")
update_icon()
-/obj/item/pen/edagger/update_icon()
+/obj/item/pen/edagger/update_icon_state()
if(on)
- icon_state = "edagger"
- item_state = "edagger"
+ icon_state = item_state = "edagger"
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
else
diff --git a/code/modules/photography/photos/frame.dm b/code/modules/photography/photos/frame.dm
index d20a71d1c6..67559c0381 100644
--- a/code/modules/photography/photos/frame.dm
+++ b/code/modules/photography/photos/frame.dm
@@ -43,10 +43,10 @@
return list()
return ..()
-/obj/item/wallframe/picture/update_icon()
- cut_overlays()
+/obj/item/wallframe/picture/update_overlays()
+ . = ..()
if(displayed)
- add_overlay(image(displayed))
+ . += image(displayed)
/obj/item/wallframe/picture/after_attach(obj/O)
..()
@@ -145,10 +145,10 @@
if(framed)
framed.show(user)
-/obj/structure/sign/picture_frame/update_icon()
- cut_overlays()
+/obj/structure/sign/picture_frame/update_overlays()
+ . = ..()
if(framed)
- add_overlay(image(framed))
+ . += image(framed)
/obj/structure/sign/picture_frame/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
diff --git a/code/modules/photography/photos/photo.dm b/code/modules/photography/photos/photo.dm
index d45a119553..2f827f7d51 100644
--- a/code/modules/photography/photos/photo.dm
+++ b/code/modules/photography/photos/photo.dm
@@ -32,7 +32,7 @@
if(setdesc && P.picture_desc)
desc = P.picture_desc
-/obj/item/photo/update_icon()
+/obj/item/photo/update_icon_state()
if(!istype(picture) || !picture.picture_image)
return
var/icon/I = picture.get_small_icon()
diff --git a/code/modules/pool/pool_controller.dm b/code/modules/pool/pool_controller.dm
index 6f28a7c8dd..c9bc6be3e5 100644
--- a/code/modules/pool/pool_controller.dm
+++ b/code/modules/pool/pool_controller.dm
@@ -297,8 +297,7 @@
mist_on()
update_icon()
-/obj/machinery/pool/controller/update_icon()
- . = ..()
+/obj/machinery/pool/controller/update_icon_state()
icon_state = "poolc_[temperature]"
/obj/machinery/pool/controller/proc/CanUpTemp(mob/user)
@@ -412,7 +411,7 @@
/obj/machinery/pool/controller/proc/mist_on() //Spawn /obj/effect/mist (from the shower) on all linked pool tiles
if(mist_state)
return
- mist_off() //make sure it cycles and deletes everything
+ mist_off() //make sure it cycles and deletes everything
mist_state = TRUE
for(var/X in linked_turfs)
var/turf/open/pool/W = X
diff --git a/code/modules/power/antimatter/control.dm b/code/modules/power/antimatter/control.dm
index 1ff398bdd3..568ad893a2 100644
--- a/code/modules/power/antimatter/control.dm
+++ b/code/modules/power/antimatter/control.dm
@@ -151,10 +151,11 @@
return
-/obj/machinery/power/am_control_unit/update_icon()
+/obj/machinery/power/am_control_unit/update_icon_state()
if(active)
icon_state = "control_on"
- else icon_state = "control"
+ else
+ icon_state = "control"
//No other icons for it atm
diff --git a/code/modules/power/antimatter/shielding.dm b/code/modules/power/antimatter/shielding.dm
index 624c4c0316..766c4d4392 100644
--- a/code/modules/power/antimatter/shielding.dm
+++ b/code/modules/power/antimatter/shielding.dm
@@ -107,10 +107,9 @@
check_stability()
-/obj/machinery/am_shielding/update_icon()
+/obj/machinery/am_shielding/update_icon_state()
dirs = 0
coredirs = 0
- cut_overlays()
for(var/direction in GLOB.alldirs)
var/turf/T = get_step(loc, direction)
for(var/obj/machinery/machine in T)
@@ -137,8 +136,10 @@
icon_state = "[prefix]shield_[icondirs]"
+/obj/machinery/am_shielding/update_overlays()
+ . = ..()
if(core_check())
- add_overlay("core[control_unit && control_unit.active]")
+ . += "core[control_unit?.active]"
if(!processing)
setup_core()
else if(processing)
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index b9d4d1adf1..8d5de661ae 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -130,7 +130,7 @@ By design, d1 is the smallest direction and d2 is the highest
invisibility = i ? INVISIBILITY_MAXIMUM : 0
update_icon()
-/obj/structure/cable/update_icon()
+/obj/structure/cable/update_icon_state()
icon_state = "[d1]-[d2]"
color = null
add_atom_colour(cable_color, FIXED_COLOUR_PRIORITY)
diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm
index a15580498c..93fe7e8fa6 100644
--- a/code/modules/power/cell.dm
+++ b/code/modules/power/cell.dm
@@ -58,16 +58,16 @@
else
return PROCESS_KILL
-/obj/item/stock_parts/cell/update_icon()
- cut_overlays()
+/obj/item/stock_parts/cell/update_overlays()
+ . = ..()
if(grown_battery)
- add_overlay(image('icons/obj/power.dmi',"grown_wires"))
+ . += image('icons/obj/power.dmi',"grown_wires")
if(charge < 0.01)
return
else if(charge/maxcharge >=0.995)
- add_overlay("cell-o2")
+ . += "cell-o2"
else
- add_overlay("cell-o1")
+ . += "cell-o1"
/obj/item/stock_parts/cell/proc/percent() // return % charge of cell
return 100*charge/maxcharge
@@ -281,8 +281,9 @@
maxcharge = 50000
ratingdesc = FALSE
-/obj/item/stock_parts/cell/infinite/abductor/update_icon()
- return
+/obj/item/stock_parts/cell/infinite/abductor/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/update_icon_blocker)
/obj/item/stock_parts/cell/potato
diff --git a/code/modules/power/generator.dm b/code/modules/power/generator.dm
index 011a2e4fd2..6d63a57c88 100644
--- a/code/modules/power/generator.dm
+++ b/code/modules/power/generator.dm
@@ -30,19 +30,15 @@
SSair.atmos_machinery -= src
return ..()
-/obj/machinery/power/generator/update_icon()
-
- if(stat & (NOPOWER|BROKEN))
- cut_overlays()
- else
- cut_overlays()
-
+/obj/machinery/power/generator/update_overlays()
+ . = ..()
+ if(!(stat & (NOPOWER|BROKEN)))
var/L = min(round(lastgenlev/100000),11)
if(L != 0)
- add_overlay(image('icons/obj/power.dmi', "teg-op[L]"))
+ . += image('icons/obj/power.dmi', "teg-op[L]")
if(hot_circ && cold_circ)
- add_overlay("teg-oc[lastcirc]")
+ . += "teg-oc[lastcirc]"
#define GENRATE 800 // generator output coefficient from Q
diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm
index d0d1e2b475..582d72f6c0 100644
--- a/code/modules/power/gravitygenerator.dm
+++ b/code/modules/power/gravitygenerator.dm
@@ -44,8 +44,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
if(tesla_flags & TESLA_MACHINE_EXPLOSIVE)
qdel(src)//like the singulo, tesla deletes it. stops it from exploding over and over
-/obj/machinery/gravity_generator/update_icon()
- ..()
+/obj/machinery/gravity_generator/update_icon_state()
icon_state = "[get_status()]_[sprite_number]"
/obj/machinery/gravity_generator/proc/get_status()
@@ -156,6 +155,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
part.main_part = src
parts += part
part.update_icon()
+ part.RegisterSignal(src, COMSIG_ATOM_UPDATED_ICON, /atom/proc/update_icon)
/obj/machinery/gravity_generator/main/proc/connected_parts()
return parts.len == 8
@@ -235,7 +235,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
data["charging_state"] = charging_state
data["on"] = on
data["operational"] = (stat & BROKEN) ? FALSE : TRUE
-
+
return data
/obj/machinery/gravity_generator/main/ui_act(action, params)
@@ -259,11 +259,6 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
return "fix[min(broken_state, 3)]"
return on || charging_state != POWER_IDLE ? "on" : "off"
-/obj/machinery/gravity_generator/main/update_icon()
- ..()
- for(var/obj/O in parts)
- O.update_icon()
-
// Set the charging state based on power/breaker.
/obj/machinery/gravity_generator/main/proc/set_power()
var/new_state = FALSE
diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm
index 6cfcc5192a..8d041efb76 100644
--- a/code/modules/power/lighting.dm
+++ b/code/modules/power/lighting.dm
@@ -291,8 +291,7 @@
QDEL_NULL(cell)
return ..()
-/obj/machinery/light/update_icon()
- cut_overlays()
+/obj/machinery/light/update_icon_state()
switch(status) // set icon_states
if(LIGHT_OK)
var/area/A = get_base_area(src)
@@ -303,17 +302,20 @@
icon_state = "[base_state]_hijacked"
else
icon_state = "[base_state]"
- if(on)
- var/mutable_appearance/glowybit = mutable_appearance(overlayicon, base_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
- glowybit.alpha = CLAMP(light_power*250, 30, 200)
- add_overlay(glowybit)
if(LIGHT_EMPTY)
icon_state = "[base_state]-empty"
if(LIGHT_BURNED)
icon_state = "[base_state]-burned"
if(LIGHT_BROKEN)
icon_state = "[base_state]-broken"
- return
+
+/obj/machinery/light/update_overlays()
+ . = ..()
+ if(on && status == LIGHT_OK)
+ var/mutable_appearance/glowybit = mutable_appearance(overlayicon, base_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
+ glowybit.alpha = CLAMP(light_power*250, 30, 200)
+ . += glowybit
+
// update the icon_state and luminosity of the light depending on its state
/obj/machinery/light/proc/update(trigger = TRUE)
diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm
index 3a6a98d681..3c20f2f69c 100644
--- a/code/modules/power/port_gen.dm
+++ b/code/modules/power/port_gen.dm
@@ -39,7 +39,7 @@
/obj/machinery/power/port_gen/proc/handleInactive()
return
-/obj/machinery/power/port_gen/update_icon()
+/obj/machinery/power/port_gen/update_icon_state()
icon_state = "[base_icon]_[active]"
/obj/machinery/power/port_gen/process()
diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm
index be8d456f20..2e6ec57f77 100644
--- a/code/modules/power/singularity/collector.dm
+++ b/code/modules/power/singularity/collector.dm
@@ -204,14 +204,14 @@
if(loaded_tank && active && pulse_strength > RAD_COLLECTOR_EFFICIENCY)
stored_power += (pulse_strength-RAD_COLLECTOR_EFFICIENCY)*RAD_COLLECTOR_COEFFICIENT
-/obj/machinery/power/rad_collector/update_icon()
- cut_overlays()
+/obj/machinery/power/rad_collector/update_overlays()
+ . = ..()
if(loaded_tank)
- add_overlay("ptank")
+ . += "ptank"
if(stat & (NOPOWER|BROKEN))
return
if(active)
- add_overlay("on")
+ . += "on"
/obj/machinery/power/rad_collector/proc/toggle_power()
diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm
index e956742e92..d57f78e5b6 100644
--- a/code/modules/power/singularity/emitter.dm
+++ b/code/modules/power/singularity/emitter.dm
@@ -112,7 +112,7 @@
QDEL_NULL(sparks)
return ..()
-/obj/machinery/power/emitter/update_icon()
+/obj/machinery/power/emitter/update_icon_state()
if (active && powernet && avail(active_power_usage))
icon_state = icon_state_on
else
diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm
index 54aca32cf7..950e34098c 100644
--- a/code/modules/power/singularity/field_generator.dm
+++ b/code/modules/power/singularity/field_generator.dm
@@ -44,14 +44,14 @@ field_generator power level display
var/list/obj/machinery/field/generator/connected_gens
var/clean_up = 0
-/obj/machinery/field/generator/update_icon()
- cut_overlays()
+/obj/machinery/field/generator/update_overlays()
+ . = ..()
if(warming_up)
- add_overlay("+a[warming_up]")
+ . += "+a[warming_up]"
if(fields.len)
- add_overlay("+on")
+ . += "+on"
if(power_level)
- add_overlay("+p[power_level]")
+ . += "+p[power_level]"
/obj/machinery/field/generator/Initialize()
diff --git a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm
index 09fb3ad4e9..59792b6539 100644
--- a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm
+++ b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm
@@ -124,7 +124,7 @@
investigate_log("was moved whilst active; it powered down.", INVESTIGATE_SINGULO)
-/obj/structure/particle_accelerator/update_icon()
+/obj/structure/particle_accelerator/update_icon_state()
switch(construction_state)
if(PA_CONSTRUCTION_UNSECURED,PA_CONSTRUCTION_UNWIRED)
icon_state="[reference]"
diff --git a/code/modules/power/singularity/particle_accelerator/particle_control.dm b/code/modules/power/singularity/particle_accelerator/particle_control.dm
index f583fc138d..af83f7ebca 100644
--- a/code/modules/power/singularity/particle_accelerator/particle_control.dm
+++ b/code/modules/power/singularity/particle_accelerator/particle_control.dm
@@ -60,7 +60,7 @@
active = 0
connected_parts.Cut()
-/obj/machinery/particle_accelerator/control_box/update_icon()
+/obj/machinery/particle_accelerator/control_box/update_icon_state()
if(active)
icon_state = "control_boxp1"
else
diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm
index 774f7ba14d..47de07cd71 100644
--- a/code/modules/power/smes.dm
+++ b/code/modules/power/smes.dm
@@ -199,29 +199,25 @@
stat |= BROKEN
-/obj/machinery/power/smes/update_icon()
- cut_overlays()
- if(stat & BROKEN)
- return
-
- if(panel_open)
+/obj/machinery/power/smes/update_overlays()
+ . = ..()
+ if((stat & BROKEN) || panel_open)
return
if(outputting)
- add_overlay("smes-op1")
+ . += "smes-op1"
else
- add_overlay("smes-op0")
+ . += "smes-op0"
if(inputting)
- add_overlay("smes-oc1")
+ . += "smes-oc1"
else
if(input_attempt)
- add_overlay("smes-oc0")
+ . += "smes-oc0"
var/clevel = chargedisplay()
if(clevel>0)
- add_overlay("smes-og[clevel]")
-
+ . += "smes-og[clevel]"
/obj/machinery/power/smes/proc/chargedisplay()
return CLAMP(round(5.5*charge/capacity),0,5)
diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm
index 67cc371c3b..2548620a7f 100644
--- a/code/modules/power/supermatter/supermatter.dm
+++ b/code/modules/power/supermatter/supermatter.dm
@@ -807,7 +807,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
. = zapdir
if(target_mob)
- target_mob.electrocute_act(rand(5,10), "Supermatter Discharge Bolt", 1, stun = 0)
+ target_mob.electrocute_act(rand(5,10), "Supermatter Discharge Bolt", 1, SHOCK_NOSTUN)
if(prob(15))
supermatter_zap(target_mob, 5, power / 2)
supermatter_zap(target_mob, 5, power / 2)
diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm
index 13f53f14d0..1b08693d1c 100644
--- a/code/modules/power/tesla/energy_ball.dm
+++ b/code/modules/power/tesla/energy_ball.dm
@@ -297,7 +297,7 @@
else if(closest_mob)
var/shock_damage = (tesla_flags & TESLA_MOB_DAMAGE)? (min(round(power/600), 90) + rand(-5, 5)) : 0
- closest_mob.electrocute_act(shock_damage, source, 1, tesla_shock = 1, stun = (tesla_flags & TESLA_MOB_STUN))
+ closest_mob.electrocute_act(shock_damage, source, 1, SHOCK_TESLA | ((tesla_flags & TESLA_MOB_STUN) ? NONE : SHOCK_NOSTUN))
if(issilicon(closest_mob))
var/mob/living/silicon/S = closest_mob
if((tesla_flags & TESLA_MOB_STUN) && (tesla_flags & TESLA_MOB_DAMAGE))
diff --git a/code/modules/projectiles/ammunition/_ammunition.dm b/code/modules/projectiles/ammunition/_ammunition.dm
index 28b70bf276..ee6a25d8e4 100644
--- a/code/modules/projectiles/ammunition/_ammunition.dm
+++ b/code/modules/projectiles/ammunition/_ammunition.dm
@@ -39,8 +39,7 @@
QDEL_NULL(BB)
return ..()
-/obj/item/ammo_casing/update_icon()
- ..()
+/obj/item/ammo_casing/update_icon_state()
icon_state = "[initial(icon_state)][BB ? "-live" : ""]"
desc = "[initial(desc)][BB ? "" : " This one is spent."]"
diff --git a/code/modules/projectiles/ammunition/caseless/_caseless.dm b/code/modules/projectiles/ammunition/caseless/_caseless.dm
index db1aa6562c..33d096007d 100644
--- a/code/modules/projectiles/ammunition/caseless/_caseless.dm
+++ b/code/modules/projectiles/ammunition/caseless/_caseless.dm
@@ -11,6 +11,5 @@
else
return FALSE
-/obj/item/ammo_casing/caseless/update_icon()
- ..()
+/obj/item/ammo_casing/caseless/update_icon_state()
icon_state = "[initial(icon_state)]"
diff --git a/code/modules/projectiles/ammunition/caseless/foam.dm b/code/modules/projectiles/ammunition/caseless/foam.dm
index 311f76797c..91ed69f7a5 100644
--- a/code/modules/projectiles/ammunition/caseless/foam.dm
+++ b/code/modules/projectiles/ammunition/caseless/foam.dm
@@ -9,8 +9,7 @@
harmful = FALSE
var/modified = FALSE
-/obj/item/ammo_casing/caseless/foam_dart/update_icon()
- ..()
+/obj/item/ammo_casing/caseless/foam_dart/update_icon_state()
if (modified)
icon_state = "foamdart_empty"
desc = "It's nerf or nothing! ... Although, this one doesn't look too safe."
diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm
index 9ea50562dd..e45483569e 100644
--- a/code/modules/projectiles/guns/ballistic.dm
+++ b/code/modules/projectiles/guns/ballistic.dm
@@ -19,8 +19,7 @@
chamber_round()
update_icon()
-/obj/item/gun/ballistic/update_icon()
- ..()
+/obj/item/gun/ballistic/update_icon_state()
if(current_skin)
icon_state = "[unique_reskin[current_skin]][suppressed ? "-suppressed" : ""][sawn_off ? "-sawn" : ""]"
else
diff --git a/code/modules/projectiles/guns/ballistic/bow.dm b/code/modules/projectiles/guns/ballistic/bow.dm
index 0fc181f71c..83f95c2c54 100644
--- a/code/modules/projectiles/guns/ballistic/bow.dm
+++ b/code/modules/projectiles/guns/ballistic/bow.dm
@@ -44,7 +44,7 @@
to_chat(user, "You notch the arrow.")
update_icon()
-/obj/item/gun/ballistic/bow/update_icon()
+/obj/item/gun/ballistic/bow/update_icon_state()
icon_state = "[initial(icon_state)]_[get_ammo() ? (chambered ? "firing" : "loaded") : "unloaded"]"
/obj/item/gun/ballistic/bow/can_shoot()
@@ -63,4 +63,4 @@
icon_state = "pipebow"
item_state = "pipebow"
inaccuracy_modifier = 1.1 //Made of pipe and in a rush
- force = 0
\ No newline at end of file
+ force = 0
diff --git a/code/modules/projectiles/guns/ballistic/laser_gatling.dm b/code/modules/projectiles/guns/ballistic/laser_gatling.dm
index 82f6fa700b..366aa367b4 100644
--- a/code/modules/projectiles/guns/ballistic/laser_gatling.dm
+++ b/code/modules/projectiles/guns/ballistic/laser_gatling.dm
@@ -73,7 +73,7 @@
M.putItemFromInventoryInHandIfPossible(src, H.held_index)
-/obj/item/minigunpack/update_icon()
+/obj/item/minigunpack/update_icon_state()
if(armed)
icon_state = "notholstered"
else
diff --git a/code/modules/projectiles/guns/magic.dm b/code/modules/projectiles/guns/magic.dm
index f724f982d0..ce87eddc67 100644
--- a/code/modules/projectiles/guns/magic.dm
+++ b/code/modules/projectiles/guns/magic.dm
@@ -73,9 +73,6 @@
recharge_newshot()
return 1
-/obj/item/gun/magic/update_icon()
- return
-
/obj/item/gun/magic/shoot_with_empty_chamber(mob/living/user as mob|obj)
to_chat(user, "The [name] whizzles quietly.")
diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm
index 4857369363..f48020aeb5 100644
--- a/code/modules/projectiles/guns/magic/wand.dm
+++ b/code/modules/projectiles/guns/magic/wand.dm
@@ -21,7 +21,7 @@
. = ..()
. += "Has [charges] charge\s remaining."
-/obj/item/gun/magic/wand/update_icon()
+/obj/item/gun/magic/wand/update_icon_state()
icon_state = "[initial(icon_state)][charges ? "" : "-drained"]"
/obj/item/gun/magic/wand/attack(atom/target, mob/living/user)
diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
index be15bb70cf..2d177318aa 100644
--- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
@@ -144,14 +144,14 @@
..()
icon_state = "[(nopower_state && !powered()) ? nopower_state : initial(icon_state)]"
-/obj/machinery/chem_dispenser/update_icon()
- cut_overlays()
+/obj/machinery/chem_dispenser/update_overlays()
+ . = ..()
if(has_panel_overlay && panel_open)
- add_overlay(mutable_appearance(icon, "[initial(icon_state)]_panel-o"))
+ . += mutable_appearance(icon, "[initial(icon_state)]_panel-o")
if(beaker)
beaker_overlay = display_beaker()
- add_overlay(beaker_overlay)
+ . += beaker_overlay
/obj/machinery/chem_dispenser/emag_act(mob/user)
. = ..()
diff --git a/code/modules/reagents/chemistry/machinery/chem_heater.dm b/code/modules/reagents/chemistry/machinery/chem_heater.dm
index 4c4d0fdb6e..63e9d724a4 100644
--- a/code/modules/reagents/chemistry/machinery/chem_heater.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_heater.dm
@@ -22,7 +22,7 @@
beaker = null
update_icon()
-/obj/machinery/chem_heater/update_icon()
+/obj/machinery/chem_heater/update_icon_state()
if(beaker)
icon_state = "mixer1b"
else
diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm
index abfd00ed90..22ff88d793 100644
--- a/code/modules/reagents/chemistry/machinery/chem_master.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_master.dm
@@ -67,15 +67,17 @@
bottle = null
update_icon()
-/obj/machinery/chem_master/update_icon()
- cut_overlays()
- if (stat & BROKEN)
- add_overlay("waitlight")
+/obj/machinery/chem_master/update_icon_state()
if(beaker)
icon_state = "mixer1"
else
icon_state = "mixer0"
+/obj/machinery/chem_master/update_overlays()
+ . = ..()
+ if (stat & BROKEN)
+ . += "waitlight"
+
/obj/machinery/chem_master/blob_act(obj/structure/blob/B)
if (prob(50))
qdel(src)
diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm
index 7b25aa769d..25315f457d 100644
--- a/code/modules/reagents/chemistry/machinery/pandemic.dm
+++ b/code/modules/reagents/chemistry/machinery/pandemic.dm
@@ -109,16 +109,16 @@
update_icon()
playsound(loc, 'sound/machines/ping.ogg', 30, 1)
-/obj/machinery/computer/pandemic/update_icon()
+/obj/machinery/computer/pandemic/update_icon_state()
if(stat & BROKEN)
icon_state = (beaker ? "mixer1_b" : "mixer0_b")
- return
-
- icon_state = "mixer[(beaker) ? "1" : "0"][powered() ? "" : "_nopower"]"
- if(wait)
- add_overlay("waitlight")
else
- cut_overlays()
+ icon_state = "mixer[(beaker) ? "1" : "0"][powered() ? "" : "_nopower"]"
+
+/obj/machinery/computer/pandemic/update_overlays()
+ . = ..()
+ if(!(stat & BROKEN) && wait)
+ . += "waitlight"
/obj/machinery/computer/pandemic/ui_interact(mob/user, ui_key = "main", datum/tgui/ui, force_open = FALSE, datum/tgui/master_ui, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
index 85cdc33e72..75848f89b9 100644
--- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
+++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
@@ -66,7 +66,7 @@
AM.forceMove(drop_location())
holdingitems = list()
-/obj/machinery/reagentgrinder/update_icon()
+/obj/machinery/reagentgrinder/update_icon_state()
if(beaker)
icon_state = "juicer1"
else
diff --git a/code/modules/reagents/chemistry/machinery/smoke_machine.dm b/code/modules/reagents/chemistry/machinery/smoke_machine.dm
index 189f58fec3..0a08395c1b 100644
--- a/code/modules/reagents/chemistry/machinery/smoke_machine.dm
+++ b/code/modules/reagents/chemistry/machinery/smoke_machine.dm
@@ -34,7 +34,7 @@
for(var/obj/item/stock_parts/matter_bin/B in component_parts)
reagents.maximum_volume += REAGENTS_BASE_VOLUME * B.rating
-/obj/machinery/smoke_machine/update_icon()
+/obj/machinery/smoke_machine/update_icon_state()
if((!is_operational()) || (!on) || (reagents.total_volume == 0))
if (panel_open)
icon_state = "smoke0-o"
@@ -42,7 +42,6 @@
icon_state = "smoke0"
else
icon_state = "smoke1"
- return ..()
/obj/machinery/smoke_machine/RefreshParts()
var/new_volume = REAGENTS_BASE_VOLUME
diff --git a/code/modules/reagents/chemistry/reagents/blob_reagents.dm b/code/modules/reagents/chemistry/reagents/blob_reagents.dm
deleted file mode 100644
index fba0b47eb4..0000000000
--- a/code/modules/reagents/chemistry/reagents/blob_reagents.dm
+++ /dev/null
@@ -1,487 +0,0 @@
-// These can only be applied by blobs. They are what blobs are made out of.
-/datum/reagent/blob
- name = "Unknown"
- description = "shouldn't exist and you should adminhelp immediately."
- color = "#FFFFFF"
- taste_description = "bad code and slime"
- var/complementary_color = "#000000" //a color that's complementary to the normal blob color
- var/shortdesc = null //just damage and on_mob effects, doesn't include special, blob-tile only effects
- var/effectdesc = null //any long, blob-tile specific effects
- var/analyzerdescdamage = "Unknown. Report this bug to a coder, or just adminhelp."
- var/analyzerdesceffect = "N/A"
- var/blobbernaut_message = "slams" //blobbernaut attack verb
- var/message = "The blob strikes you" //message sent to any mob hit by the blob
- var/message_living = null //extension to first mob sent to only living mobs i.e. silicons have no skin to be burnt
- can_synth = FALSE
-
-/datum/reagent/blob/proc/send_message(mob/living/M)
- var/totalmessage = message
- if(message_living && !issilicon(M))
- totalmessage += message_living
- totalmessage += "!"
- to_chat(M, "[totalmessage]")
-
-/datum/reagent/blob/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
- if(M.stat == DEAD || istype(M, /mob/living/simple_animal/hostile/blob))
- return 0 //the dead, and blob mobs, don't cause reactions
- return round(reac_volume * min(1.5 - touch_protection, 1), 0.1) //full touch protection means 50% volume, any prot below 0.5 means 100% volume.
-
-/datum/reagent/blob/proc/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag) //when the blob takes damage, do this
- return damage
-
-/datum/reagent/blob/proc/death_reaction(obj/structure/blob/B, damage_flag) //when a blob dies, do this
- return
-
-/datum/reagent/blob/proc/expand_reaction(obj/structure/blob/B, obj/structure/blob/newB, turf/T, mob/camera/blob/O) //when the blob expands, do this
- return
-
-/datum/reagent/blob/proc/tesla_reaction(obj/structure/blob/B, power) //when the blob is hit by a tesla bolt, do this
- return 1 //return 0 to ignore damage
-
-/datum/reagent/blob/proc/extinguish_reaction(obj/structure/blob/B) //when the blob is hit with water, do this
- return
-
-/datum/reagent/blob/proc/emp_reaction(obj/structure/blob/B, severity) //when the blob is hit with an emp, do this
- return
-
-//does brute damage but can replicate when damaged and has a chance of expanding again
-/datum/reagent/blob/replicating_foam
- name = "Replicating Foam"
- description = "will do medium brute damage and occasionally expand again when expanding."
- shortdesc = "will do medium brute damage."
- effectdesc = "will also expand when attacked with burn damage, but takes more brute damage."
- taste_description = "duplication"
- analyzerdescdamage = "Does medium brute damage."
- analyzerdesceffect = "Expands when attacked with burn damage, will occasionally expand again when expanding, and is fragile to brute damage."
- color = "#7B5A57"
- complementary_color = "#57787B"
-
-/datum/reagent/blob/replicating_foam/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
- reac_volume = ..()
- M.apply_damage(0.7*reac_volume, BRUTE)
-
-/datum/reagent/blob/replicating_foam/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
- if(damage_type == BRUTE)
- damage = damage * 2
- else if(damage_type == BURN && damage > 0 && B.obj_integrity - damage > 0 && prob(60))
- var/obj/structure/blob/newB = B.expand(null, null, 0)
- if(newB)
- newB.obj_integrity = B.obj_integrity - damage
- newB.update_icon()
- return ..()
-
-/datum/reagent/blob/replicating_foam/expand_reaction(obj/structure/blob/B, obj/structure/blob/newB, turf/T, mob/camera/blob/O)
- if(prob(30))
- newB.expand(null, null, 0) //do it again!
-
-//does massive brute and burn damage, but can only expand manually
-/datum/reagent/blob/networked_fibers
- name = "Networked Fibers"
- description = "will do high brute and burn damage and will generate resources quicker, but can only expand manually."
- shortdesc = "will do high brute and burn damage."
- taste_description = "efficiency"
- effectdesc = "will move your core when manually expanding near it."
- analyzerdescdamage = "Does high brute and burn damage."
- analyzerdesceffect = "Is highly mobile and generates resources rapidly."
- color = "#CDC0B0"
- complementary_color = "#FFF68F"
-
-/datum/reagent/blob/networked_fibers/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
- reac_volume = ..()
- M.apply_damage(0.6*reac_volume, BRUTE)
- if(M)
- M.apply_damage(0.6*reac_volume, BURN)
-
-/datum/reagent/blob/networked_fibers/expand_reaction(obj/structure/blob/B, obj/structure/blob/newB, turf/T, mob/camera/blob/O)
- if(!O && newB.overmind)
- if(!istype(B, /obj/structure/blob/node))
- newB.overmind.add_points(1)
- qdel(newB)
- else
- var/area/A = get_area(T)
- if(!isspaceturf(T) && !istype(A, /area/shuttle))
- for(var/obj/structure/blob/core/C in range(1, newB))
- if(C.overmind == O)
- newB.forceMove(get_turf(C))
- C.forceMove(T)
- C.setDir(get_dir(newB, C))
- O.add_points(1)
-
-//does brute damage, shifts away when damaged
-/datum/reagent/blob/shifting_fragments
- name = "Shifting Fragments"
- description = "will do medium brute damage."
- effectdesc = "will also cause blob parts to shift away when attacked."
- taste_description = "something other-dimensional"
- analyzerdescdamage = "Does medium brute damage."
- analyzerdesceffect = "When attacked, may shift away from the attacker."
- color = "#C8963C"
- complementary_color = "#3C6EC8"
-
-/datum/reagent/blob/shifting_fragments/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
- reac_volume = ..()
- M.apply_damage(0.7*reac_volume, BRUTE)
-
-/datum/reagent/blob/shifting_fragments/expand_reaction(obj/structure/blob/B, obj/structure/blob/newB, turf/T, mob/camera/blob/O)
- if(istype(B, /obj/structure/blob/normal) || (istype(B, /obj/structure/blob/shield) && prob(25)))
- newB.forceMove(get_turf(B))
- B.forceMove(T)
-
-/datum/reagent/blob/shifting_fragments/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
- if((damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") && damage > 0 && B.obj_integrity - damage > 0 && prob(60-damage))
- var/list/blobstopick = list()
- for(var/obj/structure/blob/OB in orange(1, B))
- if((istype(OB, /obj/structure/blob/normal) || (istype(OB, /obj/structure/blob/shield) && prob(25))) && OB.overmind && OB.overmind.blob_reagent_datum.type == B.overmind.blob_reagent_datum.type)
- blobstopick += OB //as long as the blob picked is valid; ie, a normal or shield blob that has the same chemical as we do, we can swap with it
- if(blobstopick.len)
- var/obj/structure/blob/targeted = pick(blobstopick) //randomize the blob chosen, because otherwise it'd tend to the lower left
- var/turf/T = get_turf(targeted)
- targeted.forceMove(get_turf(B))
- B.forceMove(T) //swap the blobs
- return ..()
-
-//sets you on fire, does burn damage, explodes into flame when burnt, weak to water
-/datum/reagent/blob/blazing_oil
- name = "Blazing Oil"
- description = "will do medium burn damage and set targets on fire."
- effectdesc = "will also release bursts of flame when burnt, but takes damage from water."
- taste_description = "burning oil"
- analyzerdescdamage = "Does medium burn damage and sets targets on fire."
- analyzerdesceffect = "Releases fire when burnt, but takes damage from water and other extinguishing liquids."
- color = "#B68D00"
- complementary_color = "#BE5532"
- blobbernaut_message = "splashes"
- message = "The blob splashes you with burning oil"
- message_living = ", and you feel your skin char and melt"
-
-/datum/reagent/blob/blazing_oil/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
- reac_volume = ..()
- M.adjust_fire_stacks(round(reac_volume/10))
- M.IgniteMob()
- if(M)
- M.apply_damage(0.8*reac_volume, BURN)
- if(iscarbon(M))
- M.emote("scream")
-
-/datum/reagent/blob/blazing_oil/extinguish_reaction(obj/structure/blob/B)
- B.take_damage(1.5, BURN, "energy")
-
-/datum/reagent/blob/blazing_oil/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
- if(damage_type == BURN && damage_flag != "energy")
- for(var/turf/open/T in range(1, B))
- var/obj/structure/blob/C = locate() in T
- if(!(C && C.overmind && C.overmind.blob_reagent_datum.type == B.overmind.blob_reagent_datum.type) && prob(80))
- new /obj/effect/hotspot(T)
- if(damage_flag == "fire")
- return 0
- return ..()
-
-//does toxin damage, hallucination, targets think they're not hurt at all
-/datum/reagent/blob/regenerative_materia
- name = "Regenerative Materia"
- description = "will do toxin damage and cause targets to believe they are fully healed."
- analyzerdescdamage = "Does toxin damage and injects a toxin that causes the target to believe they are fully healed."
- taste_description = "heaven"
- color = "#5e7842"
- complementary_color = "#CD7794"
- message_living = ", and you feel alive"
-
-/datum/reagent/blob/regenerative_materia/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
- reac_volume = ..()
- M.adjust_drugginess(reac_volume)
- if(M.reagents)
- M.reagents.add_reagent(/datum/reagent/blob/regenerative_materia, 0.2*reac_volume)
- M.reagents.add_reagent(/datum/reagent/toxin/spore, 0.2*reac_volume)
- M.apply_damage(0.7*reac_volume, TOX)
-
-/datum/reagent/blob/regenerative_materia/on_mob_life(mob/living/carbon/C)
- C.adjustToxLoss(1*REM)
- C.hal_screwyhud = SCREWYHUD_HEALTHY //fully healed, honest
- ..()
-
-/datum/reagent/blob/regenerative_materia/on_mob_end_metabolize(mob/living/M)
- if(iscarbon(M))
- var/mob/living/carbon/N = M
- N.hal_screwyhud = 0
- ..()
-
-//kills sleeping targets and turns them into blob zombies, produces fragile spores when killed or on expanding
-/datum/reagent/blob/zombifying_pods
- name = "Zombifying Pods"
- description = "will do very low toxin damage and harvest sleeping targets for additional resources and a blob zombie."
- effectdesc = "will also produce fragile spores when killed and on expanding."
- taste_description = "fungi"
- shortdesc = "will do very low toxin damage and harvest sleeping targets for additional resources(for your overmind) and a blob zombie."
- analyzerdescdamage = "Does very low toxin damage and kills unconscious humans, turning them into blob zombies."
- analyzerdesceffect = "Produces spores when expanding and when killed."
- color = "#E88D5D"
- complementary_color = "#823ABB"
- message_living = ", and you feel tired"
-
-/datum/reagent/blob/zombifying_pods/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
- reac_volume = ..()
- M.apply_damage(0.6*reac_volume, TOX)
- if(O && ishuman(M) && M.stat == UNCONSCIOUS)
- M.death() //sleeping in a fight? bad plan.
- var/points = rand(5, 10)
- var/mob/living/simple_animal/hostile/blob/blobspore/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(get_turf(M))
- BS.overmind = O
- BS.update_icons()
- O.blob_mobs.Add(BS)
- BS.Zombify(M)
- O.add_points(points)
- to_chat(O, "Gained [points] resources from the zombification of [M].")
-
-/datum/reagent/blob/zombifying_pods/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
- if((damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") && damage <= 20 && B.obj_integrity - damage <= 0 && prob(30)) //if the cause isn't fire or a bomb, the damage is less than 21, we're going to die from that damage, 20% chance of a shitty spore.
- B.visible_message("A spore floats free of the blob!")
- var/mob/living/simple_animal/hostile/blob/blobspore/weak/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(B.loc)
- BS.overmind = B.overmind
- BS.update_icons()
- B.overmind.blob_mobs.Add(BS)
- return ..()
-
-/datum/reagent/blob/zombifying_pods/expand_reaction(obj/structure/blob/B, obj/structure/blob/newB, turf/T, mob/camera/blob/O)
- if(prob(10))
- var/mob/living/simple_animal/hostile/blob/blobspore/weak/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(T)
- BS.overmind = B.overmind
- BS.update_icons()
- newB.overmind.blob_mobs.Add(BS)
-
-//does tons of oxygen damage and a little stamina, immune to tesla bolts, weak to EMP
-/datum/reagent/blob/energized_jelly
- name = "Energized Jelly"
- description = "will cause low stamina and high oxygen damage, and cause targets to be unable to breathe."
- taste_description = "gelatin"
- effectdesc = "will also conduct electricity, but takes damage from EMPs."
- analyzerdescdamage = "Does low stamina damage, high oxygen damage, and prevents targets from breathing."
- analyzerdesceffect = "Is immune to electricity and will easily conduct it, but is weak to EMPs."
- color = "#EFD65A"
- complementary_color = "#00E5B1"
- message_living = ", and you feel a horrible tingling sensation"
-
-/datum/reagent/blob/energized_jelly/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
- reac_volume = ..()
- M.losebreath += round(0.2*reac_volume)
- M.adjustStaminaLoss(0.4*reac_volume)
- if(M)
- M.apply_damage(0.6*reac_volume, OXY)
-
-/datum/reagent/blob/energized_jelly/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
- if((damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") && B.obj_integrity - damage <= 0 && prob(10))
- do_sparks(rand(2, 4), FALSE, B)
- return ..()
-
-/datum/reagent/blob/energized_jelly/tesla_reaction(obj/structure/blob/B, power)
- return 0
-
-/datum/reagent/blob/energized_jelly/emp_reaction(obj/structure/blob/B, severity)
- var/damage = rand(30, 50) - severity * rand(10, 15)
- B.take_damage(damage, BURN, "energy")
-
-//does aoe brute damage when hitting targets, is immune to explosions
-/datum/reagent/blob/explosive_lattice
- name = "Explosive Lattice"
- description = "will do brute damage in an area around targets."
- taste_description = "the bomb"
- effectdesc = "will also resist explosions, but takes increased damage from fire and other energy sources."
- analyzerdescdamage = "Does medium brute damage and causes damage to everyone near its targets."
- analyzerdesceffect = "Is highly resistant to explosions, but takes increased damage from fire and other energy sources."
- color = "#8B2500"
- complementary_color = "#00668B"
- blobbernaut_message = "blasts"
- message = "The blob blasts you"
-
-/datum/reagent/blob/explosive_lattice/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
- var/initial_volume = reac_volume
- reac_volume = ..()
- if(reac_volume >= 10) //if it's not a spore cloud, bad time incoming
- var/obj/effect/temp_visual/explosion/fast/E = new /obj/effect/temp_visual/explosion/fast(get_turf(M))
- E.alpha = 150
- for(var/mob/living/L in orange(get_turf(M), 1))
- if(ROLE_BLOB in L.faction) //no friendly fire
- continue
- var/aoe_volume = ..(L, TOUCH, initial_volume, 0, L.get_permeability_protection(), O)
- L.apply_damage(0.4*aoe_volume, BRUTE)
- if(M)
- M.apply_damage(0.6*reac_volume, BRUTE)
- else
- M.apply_damage(0.6*reac_volume, BRUTE)
-
-/datum/reagent/blob/explosive_lattice/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
- if(damage_flag == "bomb")
- return 0
- else if(damage_flag != "melee" && damage_flag != "bullet" && damage_flag != "laser")
- return damage * 1.5
- return ..()
-
-//does brute, burn, and toxin damage, and cools targets down
-/datum/reagent/blob/cryogenic_poison
- name = "Cryogenic Poison"
- description = "will inject targets with a freezing poison that does high damage over time."
- analyzerdescdamage = "Injects targets with a freezing poison that will gradually solidify the target's internal organs."
- color = "#8BA6E9"
- taste_description = "brain freeze"
- complementary_color = "#7D6EB4"
- blobbernaut_message = "injects"
- message = "The blob stabs you"
- message_living = ", and you feel like your insides are solidifying"
-
-/datum/reagent/blob/cryogenic_poison/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
- reac_volume = ..()
- if(M.reagents)
- M.reagents.add_reagent(/datum/reagent/consumable/frostoil, 0.3*reac_volume)
- M.reagents.add_reagent(/datum/reagent/consumable/ice, 0.3*reac_volume)
- M.reagents.add_reagent(/datum/reagent/blob/cryogenic_poison, 0.3*reac_volume)
- M.apply_damage(0.2*reac_volume, BRUTE)
-
-/datum/reagent/blob/cryogenic_poison/on_mob_life(mob/living/carbon/M)
- M.adjustBruteLoss(0.3*REM, 0)
- M.adjustFireLoss(0.3*REM, 0)
- M.adjustToxLoss(0.3*REM, 0)
- . = 1
- ..()
-
-//does burn damage and EMPs, slightly fragile
-/datum/reagent/blob/electromagnetic_web
- name = "Electromagnetic Web"
- description = "will do high burn damage and EMP targets."
- taste_description = "pop rocks"
- effectdesc = "will also take massively increased damage and release an EMP when killed."
- analyzerdescdamage = "Does low burn damage and EMPs targets."
- analyzerdesceffect = "Is fragile to all types of damage, but takes massive damage from brute. In addition, releases a small EMP when killed."
- color = "#83ECEC"
- complementary_color = "#EC8383"
- blobbernaut_message = "lashes"
- message = "The blob lashes you"
- message_living = ", and you hear a faint buzzing"
-
-/datum/reagent/blob/electromagnetic_web/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
- reac_volume = ..()
- if(prob(reac_volume*2))
- M.emp_act(EMP_LIGHT)
- if(M)
- M.apply_damage(reac_volume, BURN)
-
-/datum/reagent/blob/electromagnetic_web/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
- if(damage_type == BRUTE) //take full brute
- switch(B.brute_resist)
- if(0.5)
- return damage * 2
- if(0.25)
- return damage * 4
- if(0.1)
- return damage * 10
- return damage * 1.25 //a laser will do 25 damage, which will kill any normal blob
-
-/datum/reagent/blob/electromagnetic_web/death_reaction(obj/structure/blob/B, damage_flag)
- if(damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser")
- empulse(B.loc, 1, 3) //less than screen range, so you can stand out of range to avoid it
-
-//does brute damage, bonus damage for each nearby blob, and spreads damage out
-/datum/reagent/blob/synchronous_mesh
- name = "Synchronous Mesh"
- description = "will do massively increased brute damage for each blob near the target."
- effectdesc = "will also spread damage between each blob near the attacked blob."
- taste_description = "toxic mold"
- analyzerdescdamage = "Does brute damage, increasing for each blob near the target."
- analyzerdesceffect = "When attacked, spreads damage between all blobs near the attacked blob."
- color = "#65ADA2"
- complementary_color = "#AD6570"
- blobbernaut_message = "synchronously strikes"
- message = "The blobs strike you"
-
-/datum/reagent/blob/synchronous_mesh/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
- reac_volume = ..()
- M.apply_damage(0.2*reac_volume, BRUTE)
- if(M && reac_volume)
- for(var/obj/structure/blob/B in range(1, M)) //if the target is completely surrounded, this is 2.4*reac_volume bonus damage, total of 2.6*reac_volume
- if(M)
- B.blob_attack_animation(M) //show them they're getting a bad time
- M.apply_damage(0.3*reac_volume, BRUTE)
-
-/datum/reagent/blob/synchronous_mesh/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
- if(damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") //the cause isn't fire or bombs, so split the damage
- var/damagesplit = 1 //maximum split is 9, reducing the damage each blob takes to 11% but doing that damage to 9 blobs
- for(var/obj/structure/blob/C in orange(1, B))
- if(!istype(C, /obj/structure/blob/core) && !istype(C, /obj/structure/blob/node) && C.overmind && C.overmind.blob_reagent_datum.type == B.overmind.blob_reagent_datum.type) //if it doesn't have the same chemical or is a core or node, don't split damage to it
- damagesplit += 1
- for(var/obj/structure/blob/C in orange(1, B))
- if(!istype(C, /obj/structure/blob/core) && !istype(C, /obj/structure/blob/node) && C.overmind && C.overmind.blob_reagent_datum.type == B.overmind.blob_reagent_datum.type) //only hurt blobs that have the same overmind chemical and aren't cores or nodes
- C.take_damage(damage/damagesplit, CLONE, 0, 0)
- return damage / damagesplit
- else
- return damage * 1.25
-
-//does brute damage through armor and bio resistance
-/datum/reagent/blob/reactive_spines
- name = "Reactive Spines"
- description = "will do medium brute damage through armor and bio resistance."
- taste_description = "rock"
- effectdesc = "will also react when attacked with brute damage, attacking all near the attacked blob."
- analyzerdescdamage = "Does medium brute damage, ignoring armor and bio resistance."
- analyzerdesceffect = "When attacked with brute damage, will lash out, attacking everything near it."
- color = "#9ACD32"
- complementary_color = "#FFA500"
- blobbernaut_message = "stabs"
- message = "The blob stabs you"
-
-/datum/reagent/blob/reactive_spines/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
- if(M.stat == DEAD || istype(M, /mob/living/simple_animal/hostile/blob))
- return 0 //the dead, and blob mobs, don't cause reactions
- M.adjustBruteLoss(0.8*reac_volume)
-
-/datum/reagent/blob/reactive_spines/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
- if(damage && damage_type == BRUTE && B.obj_integrity - damage > 0) //is there any damage, is it brute, and will we be alive
- if(damage_flag == "melee")
- B.visible_message("The blob retaliates, lashing out!")
- for(var/atom/A in range(1, B))
- A.blob_act(B)
- return ..()
-
-//does low brute damage, oxygen damage, and stamina damage and wets tiles when damaged
-/datum/reagent/blob/pressurized_slime
- name = "Pressurized Slime"
- description = "will do low brute, oxygen, and stamina damage, and wet tiles under targets."
- effectdesc = "will also wet tiles near blobs that are attacked or killed."
- taste_description = "a sponge"
- analyzerdescdamage = "Does low brute damage, low oxygen damage, drains stamina, and wets tiles under targets, extinguishing them."
- analyzerdesceffect = "When attacked or killed, wets nearby tiles, extinguishing anything on them."
- color = "#AAAABB"
- complementary_color = "#BBBBAA"
- blobbernaut_message = "emits slime at"
- message = "The blob splashes into you"
- message_living = ", and you gasp for breath"
-
-/datum/reagent/blob/pressurized_slime/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
- reac_volume = ..()
- var/turf/open/T = get_turf(M)
- if(istype(T) && prob(reac_volume))
- T.MakeSlippery(TURF_WET_WATER, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS)
- M.adjust_fire_stacks(-(reac_volume / 10))
- M.ExtinguishMob()
- M.apply_damage(0.4*reac_volume, BRUTE)
- if(M)
- M.apply_damage(0.4*reac_volume, OXY)
- if(M)
- M.adjustStaminaLoss(0.2*reac_volume)
-
-/datum/reagent/blob/pressurized_slime/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag)
- if((damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") || damage_type != BURN)
- extinguisharea(B, damage)
- return ..()
-
-/datum/reagent/blob/pressurized_slime/death_reaction(obj/structure/blob/B, damage_flag)
- if(damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser")
- B.visible_message("The blob ruptures, spraying the area with liquid!")
- extinguisharea(B, 50)
-
-/datum/reagent/blob/pressurized_slime/proc/extinguisharea(obj/structure/blob/B, probchance)
- for(var/turf/open/T in range(1, B))
- if(prob(probchance))
- T.MakeSlippery(TURF_WET_WATER, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS)
- for(var/obj/O in T)
- O.extinguish()
- for(var/mob/living/L in T)
- L.adjust_fire_stacks(-2.5)
- L.ExtinguishMob()
diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
index cd63fff0db..939d5c9707 100644
--- a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
@@ -213,7 +213,7 @@
shock_timer++
if(shock_timer >= rand(5,30)) //Random shocks are wildly unpredictable
shock_timer = 0
- M.electrocute_act(rand(5,20), "Teslium in their body", 1, 1) //Override because it's caused from INSIDE of you
+ M.electrocute_act(rand(5,20), "Teslium in their body", 1, SHOCK_NOGLOVES) //Override because it's caused from INSIDE of you
playsound(M, "sparks", 50, 1)
..()
diff --git a/code/modules/reagents/reagent_containers/blood_pack.dm b/code/modules/reagents/reagent_containers/blood_pack.dm
index 3296586c94..6be2e658c1 100644
--- a/code/modules/reagents/reagent_containers/blood_pack.dm
+++ b/code/modules/reagents/reagent_containers/blood_pack.dm
@@ -34,15 +34,11 @@
else
name = "blood pack"
-/obj/item/reagent_containers/blood/update_icon()
- cut_overlays()
-
+/obj/item/reagent_containers/blood/update_overlays()
+ . = ..()
var/v = min(round(reagents.total_volume / volume * 10), 10)
if(v > 0)
- var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "bloodpack1")
- filling.icon_state = "bloodpack[v]"
- filling.color = mix_color_from_reagents(reagents.reagent_list)
- add_overlay(filling)
+ . += mutable_appearance('icons/obj/reagentfillings.dmi', "bloodpack[v]", color = mix_color_from_reagents(reagents.reagent_list))
/obj/item/reagent_containers/blood/random
icon_state = "random_bloodpack"
@@ -120,7 +116,7 @@
else
if(!do_mob(user, C, 10))
return
-
+
to_chat(user, "You take a sip from the [src].")
user.visible_message("[user] puts the [src] up to their mouth.")
if(reagents.total_volume <= 0) // Safety: In case you spam clicked the blood bag on yourself, and it is now empty (below will divide by zero)
diff --git a/code/modules/reagents/reagent_containers/bottle.dm b/code/modules/reagents/reagent_containers/bottle.dm
index e4741bb858..cc1cd21bac 100644
--- a/code/modules/reagents/reagent_containers/bottle.dm
+++ b/code/modules/reagents/reagent_containers/bottle.dm
@@ -18,26 +18,27 @@
/obj/item/reagent_containers/glass/bottle/on_reagent_change(changetype)
update_icon()
-/obj/item/reagent_containers/glass/bottle/update_icon()
- cut_overlays()
+/obj/item/reagent_containers/glass/bottle/update_overlays()
+ . = ..()
+ if(!cached_icon)
+ cached_icon = icon_state
if(reagents.total_volume)
- var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "[icon_state]-10")
+ var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "[cached_icon]-10", color = mix_color_from_reagents(reagents.reagent_list))
var/percent = round((reagents.total_volume / volume) * 100)
switch(percent)
if(0 to 9)
- filling.icon_state = "[icon_state]-10"
+ filling.icon_state = "[cached_icon]-10"
if(10 to 29)
- filling.icon_state = "[icon_state]25"
+ filling.icon_state = "[cached_icon]25"
if(30 to 49)
- filling.icon_state = "[icon_state]50"
+ filling.icon_state = "[cached_icon]50"
if(50 to 69)
- filling.icon_state = "[icon_state]75"
+ filling.icon_state = "[cached_icon]75"
if(70 to INFINITY)
- filling.icon_state = "[icon_state]100"
+ filling.icon_state = "[cached_icon]100"
- filling.color = mix_color_from_reagents(reagents.reagent_list)
- add_overlay(filling)
+ . += filling
/obj/item/reagent_containers/glass/bottle/epinephrine
diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm
index 4e1de85fce..846637850b 100644
--- a/code/modules/reagents/reagent_containers/dropper.dm
+++ b/code/modules/reagents/reagent_containers/dropper.dm
@@ -86,12 +86,10 @@
update_icon()
-/obj/item/reagent_containers/dropper/update_icon()
- cut_overlays()
+/obj/item/reagent_containers/dropper/update_overlays()
+ . = ..()
if(reagents.total_volume)
- var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "dropper")
- filling.color = mix_color_from_reagents(reagents.reagent_list)
- add_overlay(filling)
+ . += mutable_appearance('icons/obj/reagentfillings.dmi', "dropper", color = mix_color_from_reagents(reagents.reagent_list))
/obj/item/reagent_containers/dropper/get_belt_overlay()
return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "pouch")
diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm
index bf888dc50a..74e99cc326 100644
--- a/code/modules/reagents/reagent_containers/glass.dm
+++ b/code/modules/reagents/reagent_containers/glass.dm
@@ -133,13 +133,13 @@
/obj/item/reagent_containers/glass/beaker/on_reagent_change(changetype)
update_icon()
-/obj/item/reagent_containers/glass/beaker/update_icon()
+/obj/item/reagent_containers/glass/beaker/update_overlays()
+ . = ..()
if(!cached_icon)
cached_icon = icon_state
- cut_overlays()
if(reagents.total_volume)
- var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "[cached_icon]10")
+ var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "[cached_icon]10", color = mix_color_from_reagents(reagents.reagent_list))
var/percent = round((reagents.total_volume / volume) * 100)
switch(percent)
@@ -157,9 +157,7 @@
filling.icon_state = "[cached_icon]80"
if(91 to INFINITY)
filling.icon_state = "[cached_icon]100"
-
- filling.color = mix_color_from_reagents(reagents.reagent_list)
- add_overlay(filling)
+ . += filling
/obj/item/reagent_containers/glass/beaker/jar
name = "honey jar"
@@ -215,11 +213,7 @@
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,40,50,60,120,180)
container_flags = TEMP_WEAK|APTFT_ALTCLICK|APTFT_VERB
-
-/obj/item/reagent_containers/glass/beaker/plastic/update_icon()
- icon_state = "beakerlarge" // hack to lets us reuse the large beaker reagent fill states
- ..()
- icon_state = "beakerwhite"
+ cached_icon = "beakerlarge"
/obj/item/reagent_containers/glass/beaker/meta
name = "metamaterial beaker"
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index f29b785c95..3c4be7969d 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -119,7 +119,7 @@
reagents.add_reagent_list(list_reagents)
update_icon()
-/obj/item/reagent_containers/hypospray/medipen/update_icon()
+/obj/item/reagent_containers/hypospray/medipen/update_icon_state()
if(reagents.total_volume > 0)
icon_state = initial(icon_state)
else
@@ -282,13 +282,12 @@
vial = new start_vial
update_icon()
-/obj/item/hypospray/mkii/update_icon()
- ..()
+/obj/item/hypospray/mkii/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/update_icon_updates_onmob)
+
+/obj/item/hypospray/mkii/update_icon_state()
icon_state = "[initial(icon_state)][vial ? "" : "-e"]"
- if(ismob(loc))
- var/mob/M = loc
- M.update_inv_hands()
- return
/obj/item/hypospray/mkii/examine(mob/user)
. = ..()
diff --git a/code/modules/reagents/reagent_containers/hypovial.dm b/code/modules/reagents/reagent_containers/hypovial.dm
index db2d73c697..8d99248d97 100644
--- a/code/modules/reagents/reagent_containers/hypovial.dm
+++ b/code/modules/reagents/reagent_containers/hypovial.dm
@@ -19,37 +19,15 @@
"pink hypovial" = "hypovial-pink"
)
always_reskinnable = TRUE
+ cached_icon = "hypovial"
/obj/item/reagent_containers/glass/bottle/vial/Initialize()
. = ..()
- if(!icon_state)
- icon_state = "hypovial"
update_icon()
/obj/item/reagent_containers/glass/bottle/vial/on_reagent_change()
update_icon()
-/obj/item/reagent_containers/glass/bottle/vial/update_icon()
- cut_overlays()
- if(reagents.total_volume)
- var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "hypovial10")
-
- var/percent = round((reagents.total_volume / volume) * 100)
- switch(percent)
- if(0 to 9)
- filling.icon_state = "hypovial10"
- if(10 to 29)
- filling.icon_state = "hypovial25"
- if(30 to 49)
- filling.icon_state = "hypovial50"
- if(50 to 85)
- filling.icon_state = "hypovial75"
- if(86 to INFINITY)
- filling.icon_state = "hypovial100"
-
- filling.color = mix_color_from_reagents(reagents.reagent_list)
- add_overlay(filling)
-
/obj/item/reagent_containers/glass/bottle/vial/tiny
name = "small hypovial"
//Shouldn't be possible to get this without adminbuse
@@ -80,27 +58,7 @@
"large purple hypovial" = "hypoviallarge-p",
"large black hypovial" = "hypoviallarge-t"
)
-
-/obj/item/reagent_containers/glass/bottle/vial/large/update_icon()
- cut_overlays()
- if(reagents.total_volume)
- var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "hypoviallarge10")
-
- var/percent = round((reagents.total_volume / volume) * 100)
- switch(percent)
- if(0 to 9)
- filling.icon_state = "hypoviallarge10"
- if(10 to 29)
- filling.icon_state = "hypoviallarge25"
- if(30 to 49)
- filling.icon_state = "hypoviallarge50"
- if(50 to 85)
- filling.icon_state = "hypoviallarge75"
- if(86 to INFINITY)
- filling.icon_state = "hypoviallarge100"
-
- filling.color = mix_color_from_reagents(reagents.reagent_list)
- add_overlay(filling)
+ cached_icon = "hypoviallarge"
/obj/item/reagent_containers/glass/bottle/vial/large/bluespace
possible_transfer_amounts = list(1,2,5,10,20)
diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm
index 45bf8591a8..b8957775b1 100644
--- a/code/modules/reagents/reagent_containers/syringes.dm
+++ b/code/modules/reagents/reagent_containers/syringes.dm
@@ -12,6 +12,7 @@
var/mode = SYRINGE_DRAW
var/busy = FALSE // needed for delayed drawing of blood
var/proj_piercing = 0 //does it pierce through thick clothes when shot with syringe gun
+ var/show_filling = TRUE
custom_materials = list(/datum/material/iron=10, /datum/material/glass=20)
reagent_flags = TRANSPARENT
@@ -21,6 +22,10 @@
mode = SYRINGE_INJECT
update_icon()
+/obj/item/reagent_containers/syringe/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/update_icon_updates_onmob)
+
/obj/item/reagent_containers/syringe/on_reagent_change(changetype)
update_icon()
@@ -152,29 +157,32 @@
mode = SYRINGE_DRAW
update_icon()
-
-/obj/item/reagent_containers/syringe/update_icon()
- cut_overlays()
- var/rounded_vol
- if(reagents && reagents.total_volume)
- rounded_vol = CLAMP(round((reagents.total_volume / volume * 15),5), 1, 15)
- var/image/filling_overlay = mutable_appearance('icons/obj/reagentfillings.dmi', "syringe[rounded_vol]")
- filling_overlay.color = mix_color_from_reagents(reagents.reagent_list)
- add_overlay(filling_overlay)
- else
- rounded_vol = 0
+/obj/item/reagent_containers/syringe/update_icon_state()
+ var/rounded_vol = get_rounded_vol()
icon_state = "[rounded_vol]"
item_state = "syringe_[rounded_vol]"
+
+/obj/item/reagent_containers/syringe/update_overlays()
+ . = ..()
+ if(show_filling)
+ var/rounded_vol = get_rounded_vol()
+ if(reagents && reagents.total_volume)
+ . += mutable_appearance('icons/obj/reagentfillings.dmi', "syringe[rounded_vol]", color = mix_color_from_reagents(reagents.reagent_list))
if(ismob(loc))
- var/mob/M = loc
var/injoverlay
switch(mode)
if (SYRINGE_DRAW)
injoverlay = "draw"
if (SYRINGE_INJECT)
injoverlay = "inject"
- add_overlay(injoverlay)
- M.update_inv_hands()
+ . += injoverlay
+
+///Used by update_icon() and update_overlays()
+/obj/item/reagent_containers/syringe/proc/get_rounded_vol()
+ if(reagents && reagents.total_volume)
+ return CLAMP(round((reagents.total_volume / volume * 15),5), 1, 15)
+ else
+ return 0
/obj/item/reagent_containers/syringe/epinephrine
name = "syringe (epinephrine)"
@@ -267,6 +275,7 @@
amount_per_transfer_from_this = 20
icon_state = "empty"
item_state = "syringe_empty"
+ show_filling = FALSE
var/emptrig = FALSE
/obj/item/reagent_containers/syringe/dart/afterattack(atom/target, mob/user , proximity)
@@ -317,28 +326,13 @@
/obj/item/reagent_containers/syringe/dart/attack_self(mob/user)
return
-/obj/item/reagent_containers/syringe/dart/update_icon()
- cut_overlays()
- var/rounded_vol
-
- rounded_vol = "empty"
- if(reagents && reagents.total_volume)
- if(volume/round(reagents.total_volume, 1) == 1)
- rounded_vol="full"
- mode = SYRINGE_INJECT
-
- icon_state = "[rounded_vol]"
- item_state = "syringe_[rounded_vol]"
- if(ismob(loc))
- var/mob/M = loc
- var/injoverlay
- switch(mode)
- if (SYRINGE_DRAW)
- injoverlay = "draw"
- if (SYRINGE_INJECT)
- injoverlay = "ready"
- add_overlay(injoverlay)
- M.update_inv_hands()
+/obj/item/reagent_containers/syringe/dart/update_icon_state()
+ var/empty_full = "empty"
+ if(round(reagents.total_volume, 1) == reagents.maximum_volume)
+ empty_full = "full"
+ mode = SYRINGE_INJECT
+ icon_state = "[empty_full]"
+ item_state = "syringe_[empty_full]"
/obj/item/reagent_containers/syringe/dart/emp_act(severity)
emptrig = TRUE
diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm
index 11c80b14ee..425c94cd65 100644
--- a/code/modules/recycling/conveyor2.dm
+++ b/code/modules/recycling/conveyor2.dm
@@ -252,7 +252,7 @@ GLOBAL_LIST_EMPTY(conveyors_by_id)
// update the icon depending on the position
-/obj/machinery/conveyor_switch/update_icon()
+/obj/machinery/conveyor_switch/update_icon_state()
if(position<0)
if(invert_icon)
icon_state = "switch-fwd"
diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm
index 78e18a01e2..65bfa1d98f 100644
--- a/code/modules/recycling/disposal/bin.dm
+++ b/code/modules/recycling/disposal/bin.dm
@@ -191,10 +191,6 @@
AM.pipe_eject(0)
update_icon()
-// update the icon & overlays to reflect mode & status
-/obj/machinery/disposal/update_icon()
- return
-
/obj/machinery/disposal/proc/flush()
flushing = TRUE
flushAnimation()
@@ -386,8 +382,8 @@
pressure_charging = TRUE
update_icon()
-/obj/machinery/disposal/bin/update_icon()
- cut_overlays()
+/obj/machinery/disposal/bin/update_overlays()
+ . = ..()
if(stat & BROKEN)
pressure_charging = FALSE
flush = FALSE
@@ -395,7 +391,7 @@
//flush handle
if(flush)
- add_overlay("dispover-handle")
+ . += "dispover-handle"
//only handle is shown if no power
if(stat & NOPOWER || panel_open)
@@ -403,13 +399,13 @@
//check for items in disposal - occupied light
if(contents.len > 0)
- add_overlay("dispover-full")
+ . += "dispover-full"
//charging and ready light
if(pressure_charging)
- add_overlay("dispover-charge")
+ . += "dispover-charge"
else if(full_pressure)
- add_overlay("dispover-ready")
+ . += "dispover-ready"
/obj/machinery/disposal/bin/proc/do_flush()
set waitfor = FALSE
diff --git a/code/modules/research/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm
index 10566b7de2..42b8a4dcbb 100644
--- a/code/modules/research/destructive_analyzer.dm
+++ b/code/modules/research/destructive_analyzer.dm
@@ -51,7 +51,7 @@ Note: Must be placed within 3 tiles of the R&D Console
update_icon()
reset_busy()
-/obj/machinery/rnd/destructive_analyzer/update_icon()
+/obj/machinery/rnd/destructive_analyzer/update_icon_state()
if(loaded_item)
icon_state = "d_analyzer_l"
else
diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm
index b43abf97b2..3d4bf2b4c9 100644
--- a/code/modules/research/experimentor.dm
+++ b/code/modules/research/experimentor.dm
@@ -514,7 +514,7 @@
update_icon()
recentlyExperimented = FALSE
-/obj/machinery/rnd/experimentor/update_icon()
+/obj/machinery/rnd/experimentor/update_icon_state()
icon_state = "h_lathe"
/obj/machinery/rnd/experimentor/proc/warn_admins(user, ReactionName)
diff --git a/code/modules/research/nanites/nanite_programs/suppression.dm b/code/modules/research/nanites/nanite_programs/suppression.dm
index 1c882cead3..dcc9521798 100644
--- a/code/modules/research/nanites/nanite_programs/suppression.dm
+++ b/code/modules/research/nanites/nanite_programs/suppression.dm
@@ -40,7 +40,7 @@
rogue_types = list(/datum/nanite_program/toxic)
/datum/nanite_program/shocking/on_trigger(comm_message)
- host_mob.electrocute_act(rand(5,10), "shock nanites", TRUE, TRUE)
+ host_mob.electrocute_act(rand(5,10), "shock nanites", 1, SHOCK_NOGLOVES)
/datum/nanite_program/stun
name = "Neural Shock"
diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm
index 9919a6bf26..cd08b7290a 100644
--- a/code/modules/shuttle/emergency.dm
+++ b/code/modules/shuttle/emergency.dm
@@ -2,6 +2,7 @@
#define ENGINES_START_TIME 100
#define ENGINES_STARTED (SSshuttle.emergency.mode == SHUTTLE_IGNITING)
#define IS_DOCKED (SSshuttle.emergency.mode == SHUTTLE_DOCKED || (ENGINES_STARTED))
+#define MAX_AUTH_INPUTS 6
#define NOT_BEGUN 0
#define STAGE_1 1
@@ -18,6 +19,9 @@
resistance_flags = INDESTRUCTIBLE
var/auth_need = 3
var/list/authorized = list()
+ var/auth_cooldown //these two vars are used to quell spam.
+ var/auth_combo = 0
+
var/hijack_last_stage_increase = 0
var/hijack_stage_time = 50
var/hijack_stage_cooldown = 50
@@ -92,6 +96,13 @@
to_chat(user, "The access level of your card is not high enough.")
return
+ if(auth_cooldown <= world.time)
+ auth_combo = 0
+
+ else if(auth_combo >= MAX_AUTH_INPUTS)
+ to_chat(user, "Authorizations controller lockdown engaged, please wait [CEILING(auth_cooldown - world.time, 1)] before trying again.")
+ return
+
var/old_len = authorized.len
switch(action)
@@ -116,6 +127,10 @@
minor_announce("[remaining] authorizations needed until shuttle is launched early", null, alert)
if(repeal)
minor_announce("Early launch authorization revoked, [remaining] authorizations needed")
+ auth_cooldown = world.time + 15 SECONDS
+ if(++auth_combo == MAX_AUTH_INPUTS) //C-c-combo breaker!
+ say("Authorization controller abuse detected, lockdown engaged.")
+ playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0)
/obj/machinery/computer/emergency_shuttle/proc/authorize(mob/user, source)
var/obj/item/card/id/ID = user.get_idcard(TRUE)
@@ -519,8 +534,9 @@
density = FALSE
clockwork = TRUE //it'd look weird
-/obj/machinery/computer/shuttle/pod/update_icon()
- return
+/obj/machinery/computer/shuttle/pod/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/update_icon_blocker)
/obj/machinery/computer/shuttle/pod/emag_act(mob/user)
. = SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT)
@@ -628,7 +644,7 @@
#undef ENGINES_START_TIME
#undef ENGINES_STARTED
#undef IS_DOCKED
-
+#undef MAX_AUTH_INPUTS
#undef NOT_BEGUN
#undef STAGE_1
#undef STAGE_2
diff --git a/code/modules/shuttle/manipulator.dm b/code/modules/shuttle/manipulator.dm
index dcfb0793b5..3ba2198b35 100644
--- a/code/modules/shuttle/manipulator.dm
+++ b/code/modules/shuttle/manipulator.dm
@@ -31,14 +31,14 @@
SSshuttle.manipulator = null
. = ..()
-/obj/machinery/shuttle_manipulator/update_icon()
- cut_overlays()
+/obj/machinery/shuttle_manipulator/update_overlays()
+ . = ..()
var/mutable_appearance/hologram_projection = mutable_appearance(icon, "hologram_on")
hologram_projection.pixel_y = 22
var/mutable_appearance/hologram_ship = mutable_appearance(icon, "hologram_whiteship")
hologram_ship.pixel_y = 27
- add_overlay(hologram_projection)
- add_overlay(hologram_ship)
+ . += hologram_projection
+ . += hologram_ship
/obj/machinery/shuttle_manipulator/can_interact(mob/user)
// Only admins can use this, but they can use it from anywhere
diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm
index 44a70f539d..2c466564ff 100644
--- a/code/modules/shuttle/shuttle.dm
+++ b/code/modules/shuttle/shuttle.dm
@@ -660,7 +660,7 @@
if(timeleft > 1 HOURS)
return "--:--"
else if(timeleft > 0)
- return "[add_leading(num2text((timeleft / 60) % 60), 2, "0")]:[add_leading(num2text(timeleft % 60), 2, " ")]"
+ return "[add_leading(num2text((timeleft / 60) % 60), 2, "0")]:[add_leading(num2text(timeleft % 60), 2, "0")]"
else
return "00:00"
diff --git a/code/modules/shuttle/special.dm b/code/modules/shuttle/special.dm
index f05adb9309..033187e353 100644
--- a/code/modules/shuttle/special.dm
+++ b/code/modules/shuttle/special.dm
@@ -21,7 +21,7 @@
desc = "Oh no, not again."
update_icon()
-/obj/machinery/power/emitter/energycannon/magical/update_icon()
+/obj/machinery/power/emitter/energycannon/magical/update_icon_state()
if(active)
icon_state = icon_state_on
else
diff --git a/code/modules/spells/spell_types/lightning.dm b/code/modules/spells/spell_types/lightning.dm
index 56d7dc771f..f4812e7462 100644
--- a/code/modules/spells/spell_types/lightning.dm
+++ b/code/modules/spells/spell_types/lightning.dm
@@ -69,10 +69,10 @@
playsound(get_turf(current), 'sound/magic/lightningshock.ogg', 50, 1, -1)
current.visible_message("[current] absorbs the spell, remaining unharmed!", "You absorb the spell, remaining unharmed!")
if(bounces < 1)
- current.electrocute_act(bolt_energy,"Lightning Bolt",safety=1)
+ current.electrocute_act(bolt_energy,"Lightning Bolt", flags = SHOCK_NOGLOVES)
playsound(get_turf(current), 'sound/magic/lightningshock.ogg', 50, 1, -1)
else
- current.electrocute_act(bolt_energy,"Lightning Bolt",safety=1)
+ current.electrocute_act(bolt_energy,"Lightning Bolt", flags = SHOCK_NOGLOVES)
playsound(get_turf(current), 'sound/magic/lightningshock.ogg', 50, 1, -1)
var/list/possible_targets = new
for(var/mob/living/M in view_or_range(range,target,"view"))
diff --git a/code/modules/spells/spell_types/wizard.dm b/code/modules/spells/spell_types/wizard.dm
index 124159e910..405bde212a 100644
--- a/code/modules/spells/spell_types/wizard.dm
+++ b/code/modules/spells/spell_types/wizard.dm
@@ -379,7 +379,7 @@
if(isliving(hit_atom))
var/mob/living/M = hit_atom
if(!M.anti_magic_check())
- M.electrocute_act(80, src, illusion = 1)
+ M.electrocute_act(80, src, SHOCK_ILLUSION)
qdel(src)
/obj/item/spellpacket/lightningbolt/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback)
diff --git a/code/modules/station_goals/shield.dm b/code/modules/station_goals/shield.dm
index b09dee04c7..cf0d79c742 100644
--- a/code/modules/station_goals/shield.dm
+++ b/code/modules/station_goals/shield.dm
@@ -118,7 +118,7 @@
anchored = FALSE
update_icon()
-/obj/machinery/satellite/update_icon()
+/obj/machinery/satellite/update_icon_state()
icon_state = active ? "sat_active" : "sat_inactive"
/obj/machinery/satellite/attackby(obj/item/I, mob/user, params)
diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm
index 8e47d6dbde..f97bc1d7c3 100644
--- a/code/modules/surgery/bodyparts/dismemberment.dm
+++ b/code/modules/surgery/bodyparts/dismemberment.dm
@@ -21,6 +21,7 @@
C.emote("scream")
SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "dismembered", /datum/mood_event/dismembered)
drop_limb()
+ C.update_equipment_speed_mods() // Update in case speed affecting item unequipped by dismemberment
C.bleed(40)
diff --git a/code/modules/surgery/emergency_cardioversion_recovery.dm b/code/modules/surgery/emergency_cardioversion_recovery.dm
index 25f499fa76..5646c43f00 100644
--- a/code/modules/surgery/emergency_cardioversion_recovery.dm
+++ b/code/modules/surgery/emergency_cardioversion_recovery.dm
@@ -35,7 +35,7 @@
"[user] screws up, causing [H] to flop around violently as they're zapped!",
"[user] screws up, causing [H] to flop around violently as they're zapped!")
H.emote("scream")
- H.electrocute_act(25, (tool), 1, FALSE, FALSE, FALSE, TRUE)
+ H.electrocute_act(25, (tool), 1, SHOCK_ILLUSION)
H.adjustFireLoss(10)
H.emote("flip")
H.Jitter(100)
@@ -50,7 +50,7 @@
var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain)
if(BR.organ_flags & ORGAN_FAILING)
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, -5)
- H.electrocute_act(0, (tool), 1, FALSE, FALSE, FALSE, TRUE)
+ H.electrocute_act(0, (tool), 1, SHOCK_ILLUSION)
//If we're using a defib, let the defib handle the revive.
if(istype(tool, /obj/item/twohanded/shockpaddles))
return
@@ -70,7 +70,7 @@
display_results(user, target, "You screw up, sending a current through their body!",
"[user] screws up, causing [H] to flop around violently as they're zapped!",
"[user] screws up, causing [H] to flop around violently as they're zapped!")
- H.electrocute_act(25, (tool), 1, FALSE, FALSE, FALSE, TRUE)
+ H.electrocute_act(25, (tool), 1, SHOCK_ILLUSION)
H.adjustFireLoss(10)
H.emote("flip")
H.adjustOrganLoss(ORGAN_SLOT_HEART, 10)
diff --git a/code/modules/surgery/organs/appendix.dm b/code/modules/surgery/organs/appendix.dm
index feace77018..9da20e4921 100644
--- a/code/modules/surgery/organs/appendix.dm
+++ b/code/modules/surgery/organs/appendix.dm
@@ -19,7 +19,7 @@
if(M)
M.adjustToxLoss(4, TRUE, TRUE) //forced to ensure people don't use it to gain tox as slime person
-/obj/item/organ/appendix/update_icon()
+/obj/item/organ/appendix/update_icon_state()
if(inflamed)
icon_state = "appendixinflamed"
name = "inflamed appendix"
diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm
index 37ee253d4b..daf3324980 100644
--- a/code/modules/surgery/organs/augments_arms.dm
+++ b/code/modules/surgery/organs/augments_arms.dm
@@ -31,7 +31,7 @@
else
CRASH("Invalid zone for [type]")
-/obj/item/organ/cyberimp/arm/update_icon()
+/obj/item/organ/cyberimp/arm/update_icon_state()
if(zone == BODY_ZONE_R_ARM)
transform = null
else // Mirroring the icon
diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm
index 8426440bbb..47a452cc76 100644
--- a/code/modules/surgery/organs/augments_chest.dm
+++ b/code/modules/surgery/organs/augments_chest.dm
@@ -178,14 +178,11 @@
on = FALSE
update_icon()
-/obj/item/organ/cyberimp/chest/thrusters/update_icon()
+/obj/item/organ/cyberimp/chest/thrusters/update_icon_state()
if(on)
icon_state = "imp_jetpack-on"
else
icon_state = "imp_jetpack"
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
/obj/item/organ/cyberimp/chest/thrusters/proc/move_react()
allow_thrust(0.01)
diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm
index 547ca38ead..ea98ecd32b 100644
--- a/code/modules/surgery/organs/heart.dm
+++ b/code/modules/surgery/organs/heart.dm
@@ -22,7 +22,7 @@
var/failed = FALSE //to prevent constantly running failing code
var/operated = FALSE //whether the heart's been operated on to fix some of its damages
-/obj/item/organ/heart/update_icon()
+/obj/item/organ/heart/update_icon_state()
if(beating)
icon_state = "[icon_base]-on"
else
diff --git a/code/modules/vehicles/pimpin_ride.dm b/code/modules/vehicles/pimpin_ride.dm
index c398b528d8..ef374f5db0 100644
--- a/code/modules/vehicles/pimpin_ride.dm
+++ b/code/modules/vehicles/pimpin_ride.dm
@@ -55,12 +55,12 @@
else
return ..()
-/obj/vehicle/ridden/janicart/update_icon()
- cut_overlays()
+/obj/vehicle/ridden/janicart/update_overlays()
+ . = ..()
if(mybag)
- add_overlay("cart_garbage")
+ . += "cart_garbage"
if(floorbuffer)
- add_overlay("cart_buffer")
+ . += "cart_buffer"
/obj/vehicle/ridden/janicart/attack_hand(mob/user)
. = ..()
diff --git a/html/changelogs/AutoChangeLog-pr-10702.yml b/html/changelogs/AutoChangeLog-pr-10702.yml
new file mode 100644
index 0000000000..b29bd95333
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-10702.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - tweak: "Added a few cooldowns to chill nuclear bomb and communications console security level change spam, as well as the emergency shuttle's authorization announcements."
diff --git a/html/changelogs/AutoChangeLog-pr-11349.yml b/html/changelogs/AutoChangeLog-pr-11349.yml
new file mode 100644
index 0000000000..77f33b58c5
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11349.yml
@@ -0,0 +1,4 @@
+author: "monster860"
+delete-after: True
+changes:
+ - rscadd: "Use Ctrl-Shift-direction key to shift your characters position. Use for ERP."
diff --git a/html/changelogs/AutoChangeLog-pr-11371.yml b/html/changelogs/AutoChangeLog-pr-11371.yml
new file mode 100644
index 0000000000..16c2df1819
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11371.yml
@@ -0,0 +1,6 @@
+author: "Naksu"
+delete-after: True
+changes:
+ - rscadd: "Time based free rerolls"
+ - refactor: "Refactored Blobs"
+ - balance: "Blob rerolls now give the blob 4 different options to choose from, rather than forcing a single random one."
diff --git a/html/changelogs/AutoChangeLog-pr-11382.yml b/html/changelogs/AutoChangeLog-pr-11382.yml
new file mode 100644
index 0000000000..5fe88159ba
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11382.yml
@@ -0,0 +1,4 @@
+author: "zeroisthebiggay"
+delete-after: True
+changes:
+ - rscadd: "tauric contractor space suits"
diff --git a/html/changelogs/AutoChangeLog-pr-11388.yml b/html/changelogs/AutoChangeLog-pr-11388.yml
new file mode 100644
index 0000000000..a6f13c843c
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11388.yml
@@ -0,0 +1,9 @@
+author: "Owai-Seek"
+delete-after: True
+changes:
+ - rscadd: "Butter Bear"
+ - rscadd: "Crab Burger, Bisque, Crab Rangoon, French Onion Soup, Empowered Burger, Chicken Nugget box."
+ - tweak: "+++ Spider Eggs to Exotic Meat crate. --- Bacon from Exotic Meat crate."
+ - tweak: "Tweaked Crab Recipes"
+ - imageadd: "Butter Bear aka Terrygold"
+ - balance: "Food Crafting is now 5 deciseconds instead of 30."
diff --git a/html/changelogs/AutoChangeLog-pr-11390.yml b/html/changelogs/AutoChangeLog-pr-11390.yml
new file mode 100644
index 0000000000..5b737fef75
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11390.yml
@@ -0,0 +1,4 @@
+author: "zeroisthebiggay"
+delete-after: True
+changes:
+ - tweak: "ghost hud and nv defaults on"
diff --git a/html/changelogs/AutoChangeLog-pr-11392.yml b/html/changelogs/AutoChangeLog-pr-11392.yml
new file mode 100644
index 0000000000..ea1d754983
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11392.yml
@@ -0,0 +1,4 @@
+author: "zeroisthebiggay"
+delete-after: True
+changes:
+ - bugfix: "syndicate elite hardsuit helmet doesnt hide masks anymore"
diff --git a/html/changelogs/AutoChangeLog-pr-11393.yml b/html/changelogs/AutoChangeLog-pr-11393.yml
new file mode 100644
index 0000000000..c4cef6922d
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11393.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Vampire mesmerize doesn't permanently disable combat mode."
diff --git a/html/changelogs/AutoChangeLog-pr-11395.yml b/html/changelogs/AutoChangeLog-pr-11395.yml
new file mode 100644
index 0000000000..df56407f2d
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11395.yml
@@ -0,0 +1,4 @@
+author: "Timberpoes"
+delete-after: True
+changes:
+ - bugfix: "Shuttle countdowns once again read like \"01:05\" instead of \"01: 5\"."
diff --git a/html/changelogs/AutoChangeLog-pr-11397.yml b/html/changelogs/AutoChangeLog-pr-11397.yml
new file mode 100644
index 0000000000..ef7b84b4ee
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11397.yml
@@ -0,0 +1,4 @@
+author: "zeroisthebiggay"
+delete-after: True
+changes:
+ - balance: "syndicate contractor helmets are no longer secretly lead"
diff --git a/html/changelogs/AutoChangeLog-pr-11398.yml b/html/changelogs/AutoChangeLog-pr-11398.yml
new file mode 100644
index 0000000000..a9c54e468a
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11398.yml
@@ -0,0 +1,4 @@
+author: "kevinz000"
+delete-after: True
+changes:
+ - bugfix: "hands free actions no longer check mobility and only consciousness."
diff --git a/html/changelogs/AutoChangeLog-pr-11399.yml b/html/changelogs/AutoChangeLog-pr-11399.yml
new file mode 100644
index 0000000000..7ad4dc0afa
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11399.yml
@@ -0,0 +1,4 @@
+author: "Seris02"
+delete-after: True
+changes:
+ - bugfix: "a very specific fix with tails and wagging"
diff --git a/html/changelogs/AutoChangeLog-pr-11401.yml b/html/changelogs/AutoChangeLog-pr-11401.yml
new file mode 100644
index 0000000000..6fbc3f771f
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11401.yml
@@ -0,0 +1,4 @@
+author: "InnocentFire made the sprites all thanks to them!"
+delete-after: True
+changes:
+ - imageadd: "All bows now have inhand sprites once again"
diff --git a/html/changelogs/AutoChangeLog-pr-11403.yml b/html/changelogs/AutoChangeLog-pr-11403.yml
new file mode 100644
index 0000000000..2f6835b46f
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11403.yml
@@ -0,0 +1,4 @@
+author: "Skoglol"
+delete-after: True
+changes:
+ - bugfix: "Fixed gibber exploit."
diff --git a/html/changelogs/AutoChangeLog-pr-11411.yml b/html/changelogs/AutoChangeLog-pr-11411.yml
new file mode 100644
index 0000000000..1bca49bb3b
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11411.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "The flying speed slowdown while hurt now actually affects flying mobs and not floating ones."
diff --git a/html/changelogs/AutoChangeLog-pr-11417.yml b/html/changelogs/AutoChangeLog-pr-11417.yml
new file mode 100644
index 0000000000..fd80d12e96
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11417.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Fixed dynamic voting."
diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi
index d3ffdb62e4..988ae1a30f 100644
Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ
diff --git a/icons/mob/head_muzzled.dmi b/icons/mob/head_muzzled.dmi
index 4b8263469f..f1fb09651f 100644
Binary files a/icons/mob/head_muzzled.dmi and b/icons/mob/head_muzzled.dmi differ
diff --git a/icons/mob/inhands/weapons/guns_lefthand.dmi b/icons/mob/inhands/weapons/guns_lefthand.dmi
index a166610826..2fdb9b88d2 100644
Binary files a/icons/mob/inhands/weapons/guns_lefthand.dmi and b/icons/mob/inhands/weapons/guns_lefthand.dmi differ
diff --git a/icons/mob/inhands/weapons/guns_righthand.dmi b/icons/mob/inhands/weapons/guns_righthand.dmi
index 47ed1adfee..dc8d8a4c3f 100644
Binary files a/icons/mob/inhands/weapons/guns_righthand.dmi and b/icons/mob/inhands/weapons/guns_righthand.dmi differ
diff --git a/icons/mob/mutant_bodyparts.dmi b/icons/mob/mutant_bodyparts.dmi
index 7886ca39fa..2f7f9b5be9 100644
Binary files a/icons/mob/mutant_bodyparts.dmi and b/icons/mob/mutant_bodyparts.dmi differ
diff --git a/icons/mob/suit_digi.dmi b/icons/mob/suit_digi.dmi
index 8bea32eca4..0d34d379a8 100644
Binary files a/icons/mob/suit_digi.dmi and b/icons/mob/suit_digi.dmi differ
diff --git a/icons/mob/taur_canine.dmi b/icons/mob/taur_canine.dmi
index d266d1f135..26e4d488cd 100644
Binary files a/icons/mob/taur_canine.dmi and b/icons/mob/taur_canine.dmi differ
diff --git a/icons/mob/taur_naga.dmi b/icons/mob/taur_naga.dmi
index 479fa5c83a..a4c3644003 100644
Binary files a/icons/mob/taur_naga.dmi and b/icons/mob/taur_naga.dmi differ
diff --git a/icons/obj/food/containers.dmi b/icons/obj/food/containers.dmi
index 2639d6860a..641715fd87 100644
Binary files a/icons/obj/food/containers.dmi and b/icons/obj/food/containers.dmi differ
diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi
index 670269da00..9518640416 100644
Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ
diff --git a/icons/obj/reagentfillings.dmi b/icons/obj/reagentfillings.dmi
index eb3ca4b2f7..3d5a825f27 100644
Binary files a/icons/obj/reagentfillings.dmi and b/icons/obj/reagentfillings.dmi differ
diff --git a/modular_citadel/code/modules/arousal/genitals.dm b/modular_citadel/code/modules/arousal/genitals.dm
index d5191b0532..7cf8fb8ff9 100644
--- a/modular_citadel/code/modules/arousal/genitals.dm
+++ b/modular_citadel/code/modules/arousal/genitals.dm
@@ -312,7 +312,7 @@
genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size][dna.species.use_skintones ? "_s" : ""]_[aroused_state]_[layertext]"
- if(layer == GENITALS_FRONT_LAYER && CHECK_BITFIELD(G.genital_flags, GENITAL_THROUGH_CLOTHES))
+ if(layers_num[layer] == GENITALS_FRONT_LAYER && CHECK_BITFIELD(G.genital_flags, GENITAL_THROUGH_CLOTHES))
genital_overlay.layer = -GENITALS_EXPOSED_LAYER
LAZYADD(fully_exposed, genital_overlay) // to be added to a layer with higher priority than clothes, hence the name of the bitflag.
else
diff --git a/modular_citadel/code/modules/client/preferences.dm b/modular_citadel/code/modules/client/preferences.dm
index 8b0ba2dd43..f1dbe31d02 100644
--- a/modular_citadel/code/modules/client/preferences.dm
+++ b/modular_citadel/code/modules/client/preferences.dm
@@ -49,6 +49,5 @@
/datum/preferences/copy_to(mob/living/carbon/human/character, icon_updates = 1)
..()
character.give_genitals(TRUE)
- character.flavor_text = features["flavor_text"] //Let's update their flavor_text at least initially
if(icon_updates)
character.update_genitals()
diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm
index a7dbe8d799..dac6d97eef 100644
--- a/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm
+++ b/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm
@@ -191,7 +191,7 @@
var/datum/component/nanites/N = C.GetComponent(/datum/component/nanites)
if(prob(5))
to_chat(C, "The residual voltage from the nanites causes you to seize up!")
- C.electrocute_act(10, (get_turf(C)), 1, FALSE, FALSE, FALSE, TRUE)
+ C.electrocute_act(10, (get_turf(C)), 1, SHOCK_ILLUSION)
if(prob(10))
var/atom/T = C
T.emp_act(EMP_HEAVY)
@@ -218,7 +218,7 @@ datum/reagent/fermi/nanite_b_gone/reaction_obj(obj/O, reac_volume)
/datum/reagent/fermi/nanite_b_goneTox/on_mob_life(mob/living/carbon/C)//Damages the taker if their purity is low. Extended use of impure chemicals will make the original die. (thus can't be spammed unless you've very good)
if(prob(15))
to_chat(C, "The residual voltage in your system causes you to seize up!")
- C.electrocute_act(10, (get_turf(C)), 1, FALSE, FALSE, FALSE, TRUE)
+ C.electrocute_act(10, (get_turf(C)), 1, SHOCK_ILLUSION)
if(prob(50))
var/atom/T = C
T.emp_act(EMP_HEAVY)
diff --git a/modular_citadel/icons/mob/mam_tails.dmi b/modular_citadel/icons/mob/mam_tails.dmi
index c2a89eab9a..d91f15a3f7 100644
Binary files a/modular_citadel/icons/mob/mam_tails.dmi and b/modular_citadel/icons/mob/mam_tails.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index 1fe4fe9ce1..9abd2527b8 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -498,6 +498,7 @@
#include "code\datums\elements\dusts_on_leaving_area.dm"
#include "code\datums\elements\earhealing.dm"
#include "code\datums\elements\firestacker.dm"
+#include "code\datums\elements\flavor_text.dm"
#include "code\datums\elements\ghost_role_eligibility.dm"
#include "code\datums\elements\mob_holder.dm"
#include "code\datums\elements\swimming.dm"
@@ -1300,6 +1301,22 @@
#include "code\modules\antagonists\blob\blob\blobs\node.dm"
#include "code\modules\antagonists\blob\blob\blobs\resource.dm"
#include "code\modules\antagonists\blob\blob\blobs\shield.dm"
+#include "code\modules\antagonists\blob\blob\blobstrains\_blobstrain.dm"
+#include "code\modules\antagonists\blob\blob\blobstrains\_reagent.dm"
+#include "code\modules\antagonists\blob\blob\blobstrains\blazing_oil.dm"
+#include "code\modules\antagonists\blob\blob\blobstrains\cryogenic_poison.dm"
+#include "code\modules\antagonists\blob\blob\blobstrains\electromagnetic_web.dm"
+#include "code\modules\antagonists\blob\blob\blobstrains\energized_jelly.dm"
+#include "code\modules\antagonists\blob\blob\blobstrains\explosive_lattice.dm"
+#include "code\modules\antagonists\blob\blob\blobstrains\multiplex.dm"
+#include "code\modules\antagonists\blob\blob\blobstrains\networked_fibers.dm"
+#include "code\modules\antagonists\blob\blob\blobstrains\pressurized_slime.dm"
+#include "code\modules\antagonists\blob\blob\blobstrains\reactive_spines.dm"
+#include "code\modules\antagonists\blob\blob\blobstrains\regenerative_materia.dm"
+#include "code\modules\antagonists\blob\blob\blobstrains\replicating_foam.dm"
+#include "code\modules\antagonists\blob\blob\blobstrains\shifting_fragments.dm"
+#include "code\modules\antagonists\blob\blob\blobstrains\synchronous_mesh.dm"
+#include "code\modules\antagonists\blob\blob\blobstrains\zombifying_pods.dm"
#include "code\modules\antagonists\blood_contract\blood_contract.dm"
#include "code\modules\antagonists\bloodsucker\bloodsucker_flaws.dm"
#include "code\modules\antagonists\bloodsucker\bloodsucker_integration.dm"
@@ -2759,7 +2776,6 @@
#include "code\modules\reagents\chemistry\machinery\reagentgrinder.dm"
#include "code\modules\reagents\chemistry\machinery\smoke_machine.dm"
#include "code\modules\reagents\chemistry\reagents\alcohol_reagents.dm"
-#include "code\modules\reagents\chemistry\reagents\blob_reagents.dm"
#include "code\modules\reagents\chemistry\reagents\drink_reagents.dm"
#include "code\modules\reagents\chemistry\reagents\drug_reagents.dm"
#include "code\modules\reagents\chemistry\reagents\food_reagents.dm"