diff --git a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm
index 3cc3b48e50..e6ca95472e 100644
--- a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm
+++ b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm
@@ -22,11 +22,19 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
desc = "You aren't entirely sure what this does, but it's very beepy and boopy."
background_icon_state = "bg_tech_blue"
icon_icon = 'icons/mob/actions/actions_AI.dmi'
+ check_flags = AB_CHECK_CONSCIOUS //can't doomsday if dead.
var/mob/living/silicon/ai/owner_AI //The owner AI, so we don't have to typecast every time
var/uses //If we have multiple uses of the same power
var/auto_use_uses = TRUE //If we automatically use up uses on each activation
var/cooldown_period //If applicable, the time in deciseconds we have to wait before using any more modules
+
+/datum/action/innate/ai/New()
+ ..()
+ if(uses > 1)
+ desc = "[desc] It has [uses] use\s remaining."
+ button.desc = desc
+
/datum/action/innate/ai/Grant(mob/living/L)
. = ..()
if(!isAI(owner))
@@ -38,7 +46,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
/datum/action/innate/ai/IsAvailable()
. = ..()
if(owner_AI && owner_AI.malf_cooldown > world.time)
- return
+ return FALSE
/datum/action/innate/ai/Trigger()
. = ..()
@@ -49,12 +57,16 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
/datum/action/innate/ai/proc/adjust_uses(amt, silent)
uses += amt
- if(!silent && uses)
- to_chat(owner, "[name] now has [uses] use[uses > 1 ? "s" : ""] remaining.")
- if(!uses)
- if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway!
- to_chat(owner, "[name] has run out of uses!")
- qdel(src)
+ if(uses)
+ if(!silent)
+ to_chat(owner, "[name] now has [uses] use[uses > 1 ? "s" : ""] remaining.")
+ desc = "[initial(desc)] It has [uses] use\s remaining."
+ UpdateButtonIcon()
+ return
+ if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway!
+ to_chat(owner, "[name] has run out of uses!")
+ qdel(src)
+
//Framework for ranged abilities that can have different effects by left-clicking stuff.
/datum/action/innate/ai/ranged
@@ -74,13 +86,16 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
/datum/action/innate/ai/ranged/adjust_uses(amt, silent)
uses += amt
- if(!silent && uses)
- to_chat(owner, "[name] now has [uses] use[uses > 1 ? "s" : ""] remaining.")
- if(!uses)
- if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway!
- to_chat(owner, "[name] has run out of uses!")
- Remove(owner)
- QDEL_IN(src, 100) //let any active timers on us finish up
+ if(uses)
+ if(!silent)
+ to_chat(owner, "[name] now has [uses] use[uses > 1 ? "s" : ""] remaining.")
+ desc = "[initial(desc)] It has [uses] use\s remaining."
+ UpdateButtonIcon()
+ return
+ if(initial(uses) > 1) //no need to tell 'em if it was one-use anyway!
+ to_chat(owner, "[name] has run out of uses!")
+ Remove(owner)
+ QDEL_IN(src, 100) //let any active timers on us finish up
/datum/action/innate/ai/ranged/Destroy()
QDEL_NULL(linked_ability)
@@ -97,7 +112,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
var/datum/action/innate/ai/ranged/attached_action
/obj/effect/proc_holder/ranged_ai/Destroy()
- QDEL_NULL(attached_action)
+ attached_action = null
return ..()
/obj/effect/proc_holder/ranged_ai/proc/toggle(mob/user)
@@ -185,6 +200,8 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
A.playsound_local(A, AM.unlock_sound, 50, 0)
else //Adding uses to an existing module
action.uses += initial(action.uses)
+ action.desc = "[initial(action.desc)] It has [action.uses] use\s remaining."
+ action.UpdateButtonIcon()
temp = "Additional use[action.uses > 1 ? "s" : ""] added to [action.name]!"
processing_time -= AM.cost
@@ -238,6 +255,8 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
return
if(alert(owner, "Send arming signal? (true = arm, false = cancel)", "purge_all_life()", "confirm = TRUE;", "confirm = FALSE;") != "confirm = TRUE;")
return
+ if (active)
+ return //prevent the AI from activating an already active doomsday
active = TRUE
set_us_up_the_bomb(owner)
@@ -245,64 +264,64 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
set waitfor = FALSE
to_chat(owner, "run -o -a 'selfdestruct'")
sleep(5)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "Running executable 'selfdestruct'...")
sleep(rand(10, 30))
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
owner.playsound_local(owner, 'sound/misc/bloblarm.ogg', 50, 0)
to_chat(owner, "!!! UNAUTHORIZED SELF-DESTRUCT ACCESS !!!")
to_chat(owner, "This is a class-3 security violation. This incident will be reported to Central Command.")
for(var/i in 1 to 3)
sleep(20)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "Sending security report to Central Command.....[rand(0, 9) + (rand(20, 30) * i)]%")
sleep(3)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "auth 'akjv9c88asdf12nb' ******************")
owner.playsound_local(owner, 'sound/items/timer.ogg', 50, 0)
sleep(30)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "Credentials accepted. Welcome, akjv9c88asdf12nb.")
owner.playsound_local(owner, 'sound/misc/server-ready.ogg', 50, 0)
sleep(5)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "Arm self-destruct device? (Y/N)")
owner.playsound_local(owner, 'sound/misc/compiler-stage1.ogg', 50, 0)
sleep(20)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "Y")
sleep(15)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "Confirm arming of self-destruct device? (Y/N)")
owner.playsound_local(owner, 'sound/misc/compiler-stage2.ogg', 50, 0)
sleep(10)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "Y")
sleep(rand(15, 25))
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "Please repeat password to confirm.")
owner.playsound_local(owner, 'sound/misc/compiler-stage2.ogg', 50, 0)
sleep(14)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "******************")
sleep(40)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
to_chat(owner, "Credentials accepted. Transmitting arming signal...")
owner.playsound_local(owner, 'sound/misc/server-ready.ogg', 50, 0)
sleep(30)
- if(!owner || QDELETED(owner))
+ if(QDELETED(owner) || owner.stat == DEAD)
return
priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", "aimalf")
set_security_level("delta")
@@ -724,9 +743,10 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
/datum/action/innate/ai/blackout
name = "Blackout"
- desc = "Overloads lights across the station."
+ desc = "Overloads random lights across the station."
button_icon_state = "blackout"
uses = 3
+ auto_use_uses = FALSE
/datum/action/innate/ai/blackout/Activate()
for(var/obj/machinery/power/apc/apc in GLOB.apcs_list)
@@ -736,6 +756,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
apc.overload++
to_chat(owner, "Overcurrent applied to the powernet.")
owner.playsound_local(owner, "sparks", 50, 0)
+ adjust_uses(-1)
//Disable Emergency Lights
@@ -784,11 +805,6 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
auto_use_uses = FALSE
cooldown_period = 30
-/datum/action/innate/ai/reactivate_cameras/New()
- ..()
- desc = "[desc] There are 30 reactivations remaining."
- button.desc = desc
-
/datum/action/innate/ai/reactivate_cameras/Activate()
var/fixed_cameras = 0
for(var/V in GLOB.cameranet.cameras)
@@ -803,8 +819,6 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
to_chat(owner, "Diagnostic complete! Cameras reactivated: [fixed_cameras]. Reactivations remaining: [uses].")
owner.playsound_local(owner, 'sound/items/wirecutter.ogg', 50, 0)
adjust_uses(0, TRUE) //Checks the uses remaining
- if(src && uses) //Not sure if not having src here would cause a runtime, so it's here to be safe
- desc = "[initial(desc)] There are [uses] reactivations remaining."
//Upgrade Camera Network: EMP-proofs all cameras, in addition to giving them X-ray vision.