diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm
index ab3ad39dfa3..35916bd5208 100644
--- a/code/datums/status_effects/buffs.dm
+++ b/code/datums/status_effects/buffs.dm
@@ -133,7 +133,7 @@
/datum/status_effect/cyborg_power_regen/tick()
var/mob/living/silicon/robot/cyborg = owner
if(!istype(cyborg) || !cyborg.cell)
- cancel_effect()
+ qdel(src)
return
playsound(cyborg, 'sound/effects/light_flicker.ogg', 50, 1)
cyborg.cell.give(power_to_give)
diff --git a/code/datums/status_effects/gas.dm b/code/datums/status_effects/gas.dm
index 763654605a9..53a8bb485f6 100644
--- a/code/datums/status_effects/gas.dm
+++ b/code/datums/status_effects/gas.dm
@@ -19,9 +19,8 @@
/datum/status_effect/freon/tick()
owner.update_canmove()
- if(owner)
- if(owner.bodytemperature >= 310.055)
- cancel_effect()
+ if(owner && owner.bodytemperature >= 310.055)
+ qdel(src)
/datum/status_effect/freon/on_remove()
if(!owner.stat)
diff --git a/code/datums/status_effects/status_effect.dm b/code/datums/status_effects/status_effect.dm
index 3bf25eb02a2..3eba8c3aff8 100644
--- a/code/datums/status_effects/status_effect.dm
+++ b/code/datums/status_effects/status_effect.dm
@@ -1,7 +1,9 @@
//Status effects are used to apply temporary or permanent effects to mobs. Mobs are aware of their status effects at all times.
//This file contains their code, plus code for applying and removing them.
//When making a new status effect, add a define to status_effects.dm in __DEFINES for ease of use!
-var/list/status_effects = list() //All status effects affecting literally anyone
+
+var/global/list/all_status_effects = list() //a list of all status effects, if for some reason you need to remove all of them
+
/datum/status_effect
var/id = "effect" //Used for screen alerts.
var/duration = -1 //How long the status effect lasts in SECONDS. Enter -1 for an effect that never ends unless removed through some means.
@@ -11,13 +13,21 @@ var/list/status_effects = list() //All status effects affecting literally anyone
var/unique = TRUE //If there can be multiple status effects of this type on one mob.
var/alert_type = /obj/screen/alert/status_effect //the alert thrown by the status effect, contains name and description
-/datum/status_effect/New()
- ..()
- status_effects += src
+/datum/status_effect/New(mob/living/new_owner)
+ if(new_owner)
+ owner = new_owner
+ if(owner)
+ LAZYADD(owner.status_effects, src)
+ all_status_effects += src
addtimer(src, "start_ticking", 1) //Give us time to set any variables
/datum/status_effect/Destroy()
- status_effects -= src
+ STOP_PROCESSING(SSprocessing, src)
+ if(owner)
+ owner.clear_alert(id)
+ on_remove()
+ LAZYREMOVE(owner.status_effects, src)
+ all_status_effects -= src
return ..()
/datum/status_effect/proc/start_ticking()
@@ -27,13 +37,14 @@ var/list/status_effects = list() //All status effects affecting literally anyone
qdel(src)
return
on_apply()
- var/obj/screen/alert/status_effect/A = owner.throw_alert(id, alert_type)
- A.attached_effect = src //so the alert can reference us, if it needs to
+ if(alert_type)
+ var/obj/screen/alert/status_effect/A = owner.throw_alert(id, alert_type)
+ A.attached_effect = src //so the alert can reference us, if it needs to
START_PROCESSING(SSprocessing, src)
/datum/status_effect/process()
if(!owner)
- cancel_effect()
+ qdel(src)
return
if(duration != -1)
duration--
@@ -42,14 +53,7 @@ var/list/status_effects = list() //All status effects affecting literally anyone
tick()
tick_interval = initial(tick_interval)
if(!duration)
- cancel_effect()
-
-/datum/status_effect/proc/cancel_effect()
- STOP_PROCESSING(SSprocessing, src)
- if(owner)
- owner.clear_alert(id)
- on_remove()
- qdel(src)
+ qdel(src)
/datum/status_effect/proc/on_apply() //Called whenever the buff is applied.
/datum/status_effect/proc/tick() //Called every tick.
@@ -69,24 +73,28 @@ var/list/status_effects = list() //All status effects affecting literally anyone
//////////////////
/mob/living/proc/apply_status_effect(effect) //applies a given status effect to this mob, returning the effect if it was successful
+ . = FALSE
var/datum/status_effect/S1 = effect
+ LAZYINITLIST(status_effects)
for(var/datum/status_effect/S in status_effects)
- if(initial(S1.unique) && S.id == initial(S1.id) && S.owner == src)
+ if(S.id == initial(S1.id) && initial(S1.unique))
return
- S1 = new effect
- S1.owner = src
+ S1 = new effect(src)
. = S1
/mob/living/proc/remove_status_effect(effect) //removes all of a given status effect from this mob, returning TRUE if at least one was removed
. = FALSE
- var/datum/status_effect/S1 = effect
- for(var/datum/status_effect/S in status_effects)
- if(initial(S1.id) == S.id && S.owner == src)
- S.cancel_effect()
- . = TRUE
+ if(status_effects)
+ var/datum/status_effect/S1 = effect
+ for(var/datum/status_effect/S in status_effects)
+ if(initial(S1.id) == S.id)
+ qdel(S)
+ . = TRUE
-/mob/living/proc/has_status_effect(effect) //returns TRUE if the mob calling the proc owns the given status effect
- var/datum/status_effect/S1 = effect
- for(var/datum/status_effect/S in status_effects)
- if(initial(S1.id) == S.id && S.owner == src)
- return TRUE
+/mob/living/proc/has_status_effect(effect) //returns the effect if the mob calling the proc owns the given status effect
+ . = FALSE
+ if(status_effects)
+ var/datum/status_effect/S1 = effect
+ for(var/datum/status_effect/S in status_effects)
+ if(initial(S1.id) == S.id)
+ return S
diff --git a/code/game/gamemodes/clock_cult/clock_items/wraith_spectacles.dm b/code/game/gamemodes/clock_cult/clock_items/wraith_spectacles.dm
index 50ed7d61c89..6f98cba7171 100644
--- a/code/game/gamemodes/clock_cult/clock_items/wraith_spectacles.dm
+++ b/code/game/gamemodes/clock_cult/clock_items/wraith_spectacles.dm
@@ -5,10 +5,12 @@
icon = 'icons/obj/clothing/clockwork_garb.dmi'
icon_state = "wraith_specs"
item_state = "glasses"
+ actions_types = list(/datum/action/item_action/toggle)
resistance_flags = FIRE_PROOF | ACID_PROOF
vision_flags = SEE_MOBS | SEE_TURFS | SEE_OBJS
invis_view = 2
darkness_view = 3
+ tint = 3 //this'll get reset, but it won't handle vision updates properly otherwise
/obj/item/clothing/glasses/wraith_spectacles/New()
..()
@@ -18,24 +20,65 @@
all_clockwork_objects -= src
return ..()
+/obj/item/clothing/glasses/wraith_spectacles/attack_self(mob/user)
+ weldingvisortoggle(user)
+
+/obj/item/clothing/glasses/wraith_spectacles/visor_toggling()
+ ..()
+ invis_view = SEE_INVISIBLE_LIVING
+ tint = 0
+ if(!up)
+ if(is_servant_of_ratvar(loc))
+ invis_view = SEE_INVISIBLE_NOLIGHTING
+ vision_flags = SEE_MOBS | SEE_TURFS | SEE_OBJS
+ else
+ tint = 3
+ vision_flags = NONE
+
+/obj/item/clothing/glasses/wraith_spectacles/weldingvisortoggle(mob/user)
+ . = ..()
+ if(ishuman(loc))
+ var/mob/living/carbon/human/H = loc
+ if(src == H.glasses && !up)
+ if(H.disabilities & BLIND)
+ H << "\"You're blind, idiot. Stop embarassing yourself.\""
+ return
+ if(blind_cultist(H))
+ return
+ if(is_servant_of_ratvar(H))
+ H << "You push the spectacles down, and all is revealed to you.[ratvar_awakens ? "" : " Your eyes begin to itch - you cannot do this for long."]"
+ var/datum/status_effect/wraith_spectacles/WS = H.has_status_effect(STATUS_EFFECT_WRAITHSPECS)
+ if(WS)
+ WS.apply_eye_damage(H)
+ H.apply_status_effect(STATUS_EFFECT_WRAITHSPECS)
+ else
+ H << "You push the spectacles down, but you can't see through the glass."
+
+/obj/item/clothing/glasses/wraith_spectacles/proc/blind_cultist(mob/living/victim)
+ if(iscultist(victim))
+ victim << "\"It looks like Nar-Sie's dogs really don't value their eyes.\""
+ victim << "Your eyes explode with horrific pain!"
+ victim.emote("scream")
+ victim.become_blind()
+ victim.adjust_blurriness(30)
+ victim.adjust_blindness(30)
+ return TRUE
+
/obj/item/clothing/glasses/wraith_spectacles/equipped(mob/living/user, slot)
..()
- if(slot != slot_glasses)
+ if(slot != slot_glasses || up)
return
if(user.disabilities & BLIND)
user << "\"You're blind, idiot. Stop embarassing yourself.\"" //Ratvar with the sick burns yo
return
- if(iscultist(user)) //Cultists instantly go blind
- user << "\"It looks like Nar-Sie's dogs really don't value their eyes.\""
- user << "Your eyes explode with horrific pain!"
- user.emote("scream")
- user.become_blind()
- user.adjust_blurriness(30)
- user.adjust_blindness(30)
+ if(blind_cultist(user)) //Cultists instantly go blind
return
if(is_servant_of_ratvar(user))
tint = 0
user << "As you put on the spectacles, all is revealed to you.[ratvar_awakens ? "" : " Your eyes begin to itch - you cannot do this for long."]"
+ var/datum/status_effect/wraith_spectacles/WS = user.has_status_effect(STATUS_EFFECT_WRAITHSPECS)
+ if(WS)
+ WS.apply_eye_damage(user)
user.apply_status_effect(STATUS_EFFECT_WRAITHSPECS)
else
tint = 3
@@ -62,38 +105,33 @@
if(istype(L)) //this is probably more safety than actually needed
var/datum/status_effect/wraith_spectacles/W = attached_effect
var/glasses_right = istype(L.glasses, /obj/item/clothing/glasses/wraith_spectacles)
- desc = "[glasses_right ? "":""]You are [glasses_right ? "":"not "]wearing wraith spectacles[glasses_right ? "!":"."]
\
+ var/obj/item/clothing/glasses/wraith_spectacles/WS = L.glasses
+ desc = "[glasses_right && !WS.up ? "":""]You are [glasses_right ? "":"not "]wearing wraith spectacles[glasses_right && !WS.up ? "!":"."]
\
You have taken [W.eye_damage_done] eye damage from them.
"
if(L.disabilities & NEARSIGHT)
desc += "You are nearsighted!
"
- else if(glasses_right)
+ else if(glasses_right && !WS.up)
desc += "You will become nearsighted at [W.nearsight_breakpoint] eye damage.
"
if(L.disabilities & BLIND)
desc += "You are blind!"
- else if(glasses_right)
+ else if(glasses_right && !WS.up)
desc += "You will become blind at [W.blind_breakpoint] eye damage."
..()
+/datum/status_effect/wraith_spectacles/on_apply()
+ if(ishuman(owner))
+ var/mob/living/carbon/human/H = owner
+ apply_eye_damage(H)
+
/datum/status_effect/wraith_spectacles/tick()
if(!ishuman(owner))
- cancel_effect()
+ qdel(src)
return
var/mob/living/carbon/human/H = owner
- if(istype(H.glasses, /obj/item/clothing/glasses/wraith_spectacles) && !ratvar_awakens)
- if(H.disabilities & BLIND)
- return
- H.adjust_eye_damage(1)
- eye_damage_done++
- if(eye_damage_done >= 20)
- H.adjust_blurriness(2)
- if(eye_damage_done >= nearsight_breakpoint)
- if(H.become_nearsighted())
- H << "Your vision doubles, then trebles. Darkness begins to close in. You can't keep this up!"
- if(eye_damage_done >= blind_breakpoint)
- if(H.become_blind())
- H << "A piercing white light floods your vision. Suddenly, all goes dark!"
- if(prob(min(20, 5 + eye_damage_done)))
- H << "Your eyes continue to burn."
+ var/glasses_right = istype(H.glasses, /obj/item/clothing/glasses/wraith_spectacles)
+ var/obj/item/clothing/glasses/wraith_spectacles/WS = H.glasses
+ if(glasses_right && !WS.up && !ratvar_awakens)
+ apply_eye_damage(H)
else
if(ratvar_awakens)
H.cure_nearsighted()
@@ -104,4 +142,20 @@
H.adjust_eye_damage(-1)
eye_damage_done--
if(!eye_damage_done)
- cancel_effect()
+ qdel(src)
+
+/datum/status_effect/wraith_spectacles/proc/apply_eye_damage(mob/living/carbon/human/H)
+ if(H.disabilities & BLIND)
+ return
+ H.adjust_eye_damage(1)
+ eye_damage_done++
+ if(eye_damage_done >= 20)
+ H.adjust_blurriness(2)
+ if(eye_damage_done >= nearsight_breakpoint)
+ if(H.become_nearsighted())
+ H << "Your vision doubles, then trebles. Darkness begins to close in. You can't keep this up!"
+ if(eye_damage_done >= blind_breakpoint)
+ if(H.become_blind())
+ H << "A piercing white light floods your vision. Suddenly, all goes dark!"
+ if(prob(min(20, 5 + eye_damage_done)))
+ H << "Your eyes continue to burn."
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index c5c2f56f33a..c6316509682 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -685,25 +685,31 @@ BLIND // can't see anything
body_parts_covered |= CHEST
return adjusted
-/obj/item/clothing/proc/weldingvisortoggle() //Malk: proc to toggle welding visors on helmets, masks, goggles, etc.
- if(!can_use(usr))
- return
+/obj/item/clothing/proc/weldingvisortoggle(mob/user) //proc to toggle welding visors on helmets, masks, goggles, etc.
+ if(!can_use(user))
+ return FALSE
- up ^= 1
- flags ^= visor_flags
- flags_inv ^= visor_flags_inv
- flags_cover ^= initial(flags_cover)
- icon_state = "[initial(icon_state)][up ? "up" : ""]"
- usr << "You adjust \the [src] [up ? "up" : "down"]."
- flash_protect ^= initial(flash_protect)
- tint ^= initial(tint)
+ visor_toggling()
- if(istype(usr, /mob/living/carbon))
- var/mob/living/carbon/C = usr
+ user << "You adjust \the [src] [up ? "up" : "down"]."
+
+ if(istype(user, /mob/living/carbon))
+ var/mob/living/carbon/C = user
C.head_update(src, forced = 1)
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
+ return TRUE
+
+/obj/item/clothing/proc/visor_toggling() //handles all the actual toggling of flags
+ up = !up
+ flags ^= visor_flags
+ flags_inv ^= visor_flags_inv
+ flags_cover ^= initial(flags_cover)
+ icon_state = "[initial(icon_state)][up ? "up" : ""]"
+ flash_protect ^= initial(flash_protect)
+ tint ^= initial(tint)
+
/obj/item/clothing/proc/can_use(mob/user)
if(user && ismob(user))
diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm
index e83e5c7338a..597876fb4ae 100644
--- a/code/modules/clothing/glasses/glasses.dm
+++ b/code/modules/clothing/glasses/glasses.dm
@@ -3,6 +3,17 @@
materials = list(MAT_GLASS = 250)
var/glass_colour_type = null //colors your vision when worn
+/obj/item/clothing/glasses/visor_toggling()
+ ..()
+ vision_flags ^= initial(vision_flags)
+ darkness_view ^= initial(darkness_view)
+ invis_view ^= initial(invis_view)
+
+/obj/item/clothing/glasses/weldingvisortoggle(mob/user)
+ . = ..()
+ if(. && user)
+ user.update_sight()
+
//called when thermal glasses are emped.
/obj/item/clothing/glasses/proc/thermal_overload()
if(ishuman(src.loc))
@@ -202,17 +213,8 @@
visor_flags_inv = HIDEEYES
glass_colour_type = /datum/client_colour/glass_colour/gray
-
-/obj/item/clothing/glasses/welding/attack_self()
- toggle()
-
-
-/obj/item/clothing/glasses/welding/verb/toggle()
- set category = "Object"
- set name = "Adjust welding goggles"
- set src in usr
-
- weldingvisortoggle()
+/obj/item/clothing/glasses/welding/attack_self(mob/user)
+ weldingvisortoggle(user)
/obj/item/clothing/glasses/sunglasses/blindfold
diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm
index 130aa815b7e..3978b6ac385 100644
--- a/code/modules/clothing/head/misc_special.dm
+++ b/code/modules/clothing/head/misc_special.dm
@@ -28,16 +28,8 @@
visor_flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
resistance_flags = FIRE_PROOF
-/obj/item/clothing/head/welding/attack_self()
- toggle()
-
-
-/obj/item/clothing/head/welding/verb/toggle()
- set category = "Object"
- set name = "Adjust welding helmet"
- set src in usr
-
- weldingvisortoggle()
+/obj/item/clothing/head/welding/attack_self(mob/user)
+ weldingvisortoggle(user)
/*
diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm
index 4a5569bd0f0..f3d548503f6 100644
--- a/code/modules/clothing/masks/gasmask.dm
+++ b/code/modules/clothing/masks/gasmask.dm
@@ -29,15 +29,9 @@
visor_flags_cover = MASKCOVERSEYES
resistance_flags = FIRE_PROOF
-/obj/item/clothing/mask/gas/welding/attack_self()
- toggle()
+/obj/item/clothing/mask/gas/welding/attack_self(mob/user)
+ weldingvisortoggle(user)
-/obj/item/clothing/mask/gas/welding/verb/toggle()
- set category = "Object"
- set name = "Adjust welding mask"
- set src in usr
-
- weldingvisortoggle()
// ********************************************************************
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index d33be72052d..1e31f0342af 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -72,4 +72,6 @@
var/blood_volume = 0 //how much blood the mob has
var/obj/effect/proc_holder/ranged_ability //Any ranged ability the mob has, as a click override
+ var/list/status_effects //a list of all status effects the mob has
+
var/slipping = FALSE
\ No newline at end of file
diff --git a/icons/mob/eyes.dmi b/icons/mob/eyes.dmi
index dfb09bf5908..740573b2a59 100644
Binary files a/icons/mob/eyes.dmi and b/icons/mob/eyes.dmi differ
diff --git a/icons/obj/clothing/clockwork_garb.dmi b/icons/obj/clothing/clockwork_garb.dmi
index 036a50cce3f..23e5b979e2c 100644
Binary files a/icons/obj/clothing/clockwork_garb.dmi and b/icons/obj/clothing/clockwork_garb.dmi differ