diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index 6bc79fb7d5..2df42fbb51 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -6,6 +6,7 @@
)
#define Z_TURFS(ZLEVEL) block(locate(1,1,ZLEVEL), locate(world.maxx, world.maxy, ZLEVEL))
+#define CULT_POLL_WAIT 2400
/proc/get_area(atom/A)
if (!istype(A))
@@ -485,6 +486,69 @@
++i
return L
+/proc/pollCultists(var/mob/living/Nominee) // Cult Master Poll
+ var/time_passed = world.time
+ var/list/yes_voters = new
+ var/list/cult_total = new
+ if(world.time<1)
+ Nominee << "It would be premature to select a leader while everyone is still settling in, try again in [round((1800-world.time)/10)] seconds"
+ return
+ for(var/datum/mind/B in SSticker.mode.cult)
+ if(!isliving(B.current))
+ continue
+ var/mob/living/M = B.current
+ if(isliving(M))
+ M << 'sound/hallucinations/im_here1.ogg'
+ M.verbs -= /mob/living/proc/cult_master
+ to_chat(M, "Acolyte [Nominee] has asserted that they are worthy of leading the cult. A vote will be called shortly.")
+ sleep(250)
+ for(var/datum/mind/B in SSticker.mode.cult)
+ if(!isliving(B.current))
+ continue
+ var/mob/living/M = B.current
+ M << 'sound/magic/exit_blood.ogg'
+ switch(askuser(M,"[Nominee] seeks to lead your cult, do you support them?","Please answer in 20 seconds!","Yes","No","Abstain", StealFocus=0, Timeout=200))
+ if(1)
+ if((world.time-time_passed)>500)
+ M << "Sorry, your vote came too late!"
+ M << 'sound/machines/buzz-sigh.ogg'
+ else
+ M << "Choice registered: Yes."
+ yes_voters += M
+ cult_total += M
+ if(2)
+ if((world.time-time_passed)>500)
+ M << "Sorry, your vote came too late!"
+ M << 'sound/machines/buzz-sigh.ogg'
+ else
+ M << "Choice registered: No."
+ cult_total += M
+ if(3)
+ M << "Choice registered: Abstain."
+ sleep(300)
+ if(yes_voters.len > (cult_total.len/2))
+ var/datum/action/innate/cultmast/finalreck/FinalReckoning = new()
+ var/datum/action/innate/cultmast/cultmark/Mark = new()
+ FinalReckoning.Grant(Nominee)
+ Mark.Grant(Nominee)
+ Nominee.mind.special_role = "Cult Master"
+ Nominee.update_action_buttons_icon()
+ Nominee.apply_status_effect(/datum/status_effect/cult_master)
+ SSticker.mode.set_antag_hud(Nominee,"cultmaster")
+ GLOB.cult_mastered = TRUE
+ for(var/datum/mind/B in SSticker.mode.cult)
+ if(!B.current.incapacitated())
+ to_chat(B.current,"[Nominee] has the cult's support and is now their master. Follow their orders to the best of your ability!")
+ return TRUE
+ else
+ for(var/datum/mind/B in SSticker.mode.cult)
+ if(!B.current.incapacitated())
+ to_chat(B.current, "[Nominee] could not win the cult's support and shall continue to serve as an acolyte.")
+ B.current.verbs += /mob/living/proc/cult_master
+ return FALSE
+
+/proc/poll_helper(var/mob/living/M)
+
/proc/makeBody(mob/dead/observer/G_found) // Uses stripped down and bastardized code from respawn character
if(!G_found || !G_found.key)
return
diff --git a/code/__HELPERS/game.dm.rej b/code/__HELPERS/game.dm.rej
new file mode 100644
index 0000000000..d64ec0418b
--- /dev/null
+++ b/code/__HELPERS/game.dm.rej
@@ -0,0 +1,66 @@
+diff a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm (rejected hunks)
+@@ -489,41 +490,38 @@
+ var/time_passed = world.time
+ var/list/yes_voters = new
+ var/list/cult_total = new
+- if(world.time<1800)
+- Nominee << "It would be premature to select a leader while everyone is still settling in, try again in [round((1800-world.time)/10)] seconds"
++ if(world.time < CULT_POLL_WAIT)
++ Nominee << "It would be premature to select a leader while everyone is still settling in, try again in [round((CULT_POLL_WAIT-world.time)/10)] seconds"
+ return
+ for(var/datum/mind/B in SSticker.mode.cult)
+- if(!isliving(B.current))
+- continue
+ var/mob/living/M = B.current
+- if(isliving(M))
++ if(!M.incapacitated())
+ M << 'sound/hallucinations/im_here1.ogg'
+ M.verbs -= /mob/living/proc/cult_master
+ to_chat(M, "Acolyte [Nominee] has asserted that they are worthy of leading the cult. A vote will be called shortly.")
+ sleep(250)
+ for(var/datum/mind/B in SSticker.mode.cult)
+- if(!isliving(B.current))
+- continue
+ var/mob/living/M = B.current
+- M << 'sound/magic/exit_blood.ogg'
+- switch(askuser(M,"[Nominee] seeks to lead your cult, do you support them?","Please answer in 20 seconds!","Yes","No","Abstain", StealFocus=0, Timeout=200))
+- if(1)
+- if((world.time-time_passed)>500)
+- M << "Sorry, your vote came too late!"
+- M << 'sound/machines/buzz-sigh.ogg'
+- else
+- M << "Choice registered: Yes."
+- yes_voters += M
+- cult_total += M
+- if(2)
+- if((world.time-time_passed)>500)
+- M << "Sorry, your vote came too late!"
+- M << 'sound/machines/buzz-sigh.ogg'
+- else
+- M << "Choice registered: No."
+- cult_total += M
+- if(3)
+- M << "Choice registered: Abstain."
++ if(!M.incapacitated())
++ M << 'sound/magic/exit_blood.ogg'
++ switch(askuser(M,"[Nominee] seeks to lead your cult, do you support them?","Please answer in 20 seconds!","Yes","No","Abstain", StealFocus=0, Timeout=200))
++ if(1)
++ if((world.time-time_passed)>500)
++ to_chat(M, "Sorry, your vote came too late!")
++ M << 'sound/machines/buzz-sigh.ogg'
++ else
++ M << "Choice registered: Yes."
++ yes_voters += M
++ cult_total += M
++ if(2)
++ if((world.time-time_passed)>500)
++ to_chat(M, "Sorry, your vote came too late!")
++ M << 'sound/machines/buzz-sigh.ogg'
++ else
++ to_chat(M, "Choice registered: No.")
++ cult_total += M
++ if(3)
++ to_chat(M, "Choice registered: Abstain.")
+ sleep(300)
+ if(yes_voters.len > (cult_total.len/2))
+ var/datum/action/innate/cultmast/finalreck/FinalReckoning = new()
diff --git a/code/__HELPERS/matrices.dm b/code/__HELPERS/matrices.dm
index 2e34624df5..8b77b170e0 100644
--- a/code/__HELPERS/matrices.dm
+++ b/code/__HELPERS/matrices.dm
@@ -24,7 +24,6 @@
//doesn't have an object argument because this is "Stacking" with the animate call above
//3 billion% intentional
-
//Dumps the matrix data in format a-f
/matrix/proc/tolist()
. = list()
diff --git a/code/_globalvars/game_modes.dm b/code/_globalvars/game_modes.dm
index 153ebbf089..912ae78a04 100644
--- a/code/_globalvars/game_modes.dm
+++ b/code/_globalvars/game_modes.dm
@@ -3,3 +3,10 @@ GLOBAL_VAR_INIT(secret_force_mode, "secret") // if this is anything but "secret"
GLOBAL_VAR_INIT(wavesecret, 0) // meteor mode, delays wave progression, terrible name
GLOBAL_DATUM(start_state, /datum/station_state) // Used in round-end report
+
+// Cult, needs to be global so admin cultists are functional
+GLOBAL_VAR_INIT(blood_target, null) // Cult Master's target or Construct's Master
+GLOBAL_DATUM(sac_mind, /datum/mind)
+GLOBAL_VAR_INIT(sac_image, null)
+GLOBAL_VAR_INIT(cult_mastered, FALSE)
+GLOBAL_VAR_INIT(sac_complete, FALSE)
\ No newline at end of file
diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
index 9c8fe9750a..8e3de4c374 100644
--- a/code/_onclick/hud/alert.dm
+++ b/code/_onclick/hud/alert.dm
@@ -42,6 +42,7 @@
thealert.override_alerts = override
if(override)
thealert.timeout = null
+ thealert.mob_viewer = src
if(new_master)
var/old_layer = new_master.layer
@@ -96,6 +97,7 @@
var/severity = 0
var/alerttooltipstyle = ""
var/override_alerts = FALSE //If it is overriding other alerts of the same type
+ var/mob/mob_viewer //the mob viewing this alert
/obj/screen/alert/MouseEntered(location,control,params)
@@ -256,6 +258,103 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
icon_state = "blobbernaut_nofactory"
alerttooltipstyle = "blob"
+// BLOODCULT
+
+/obj/screen/alert/bloodsense
+ name = "Blood Sense"
+ desc = "Allows you to sense blood that is manipulated by dark magicks."
+ icon_state = "cult_sense"
+ alerttooltipstyle = "cult"
+ var/image/sacimage
+ var/angle = 0
+ var/mob/living/simple_animal/hostile/construct/Cviewer = null
+
+/obj/screen/alert/bloodsense/Initialize()
+ ..()
+ sacimage = GLOB.sac_image
+ START_PROCESSING(SSprocessing, src)
+
+/obj/screen/alert/bloodsense/Destroy()
+ sacimage = null
+ Cviewer = null
+ STOP_PROCESSING(SSprocessing, src)
+ return ..()
+
+/obj/screen/alert/bloodsense/process()
+ var/atom/blood_target
+ if(GLOB.blood_target)
+ if(!get_turf(GLOB.blood_target))
+ GLOB.blood_target = null
+ else
+ blood_target = GLOB.blood_target
+ if(Cviewer)
+ if(Cviewer.seeking && Cviewer.master)
+ blood_target = Cviewer.master
+ if(!blood_target && !GLOB.sac_complete)
+ if(icon_state == "runed_sense0")
+ return
+ animate(src, transform = null, time = 1, loop = 0)
+ angle = 0
+ cut_overlays()
+ icon_state = "runed_sense0"
+ desc = "Nar-Sie demands that [GLOB.sac_mind] be sacrificed before the summoning ritual can begin."
+ add_overlay(sacimage)
+ return
+ if(!blood_target && GLOB.sac_complete)
+ if(icon_state == "runed_sense1")
+ return
+ animate(src, transform = null, time = 1, loop = 0)
+ angle = 0
+ cut_overlays()
+ icon_state = "runed_sense1"
+ var/image/narnar = new('icons/mob/screen_alert.dmi', "mini_nar")
+ desc = "The sacrifice is complete, prepare to summon Nar-Sie!"
+ add_overlay(narnar)
+ return
+ if(!blood_target)
+ return
+ var/turf/P = get_turf(blood_target)
+ var/turf/Q = get_turf(mob_viewer)
+ var/area/A = get_area(P)
+ if(P.z != Q.z) //The target is on a different Z level, we cannot sense that far.
+ return
+ desc = "You are currently tracking [blood_target] in [A.name]"
+ var/target_angle = Get_Angle(mob_viewer, blood_target)
+ var/target_dist = get_dist(P, Q)
+ cut_overlays()
+ switch(target_dist)
+ if(0 to 1)
+ icon_state = "runed_sense2"
+ if(2 to 8)
+ icon_state = "arrow8"
+ if(9 to 15)
+ icon_state = "arrow7"
+ if(16 to 22)
+ icon_state = "arrow6"
+ if(23 to 29)
+ icon_state = "arrow5"
+ if(30 to 36)
+ icon_state = "arrow4"
+ if(37 to 43)
+ icon_state = "arrow3"
+ if(44 to 50)
+ icon_state = "arrow2"
+ if(51 to 57)
+ icon_state = "arrow1"
+ if(58 to 64)
+ icon_state = "arrow0"
+ if(65 to 400)
+ icon_state = "arrow"
+ var/difference = target_angle - angle
+ angle = target_angle
+ if(!difference)
+ return
+ var/matrix/final = matrix(transform)
+ final.Turn(difference)
+ animate(src, transform = final, time = 5, loop = 0)
+
+
+
// CLOCKCULT
/obj/screen/alert/clockwork
alerttooltipstyle = "clockcult"
diff --git a/code/datums/antagonists/datum_cult.dm.rej b/code/datums/antagonists/datum_cult.dm.rej
new file mode 100644
index 0000000000..137565bd5f
--- /dev/null
+++ b/code/datums/antagonists/datum_cult.dm.rej
@@ -0,0 +1,9 @@
+diff a/code/datums/antagonists/datum_cult.dm b/code/datums/antagonists/datum_cult.dm (rejected hunks)
+@@ -65,6 +65,7 @@
+ cult_memorization(owner)
+ if(jobban_isbanned(current, ROLE_CULTIST))
+ addtimer(CALLBACK(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, current, ROLE_CULTIST, ROLE_CULTIST), 0)
++ SSticker.mode.update_cult_icons_added(owner)
+ current.throw_alert("bloodsense", /obj/screen/alert/bloodsense)
+ current.log_message("Has been converted to the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG)
+
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index e99d5bb59a..f4a535e4c4 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -1438,14 +1438,7 @@
to_chat(current, "You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie.")
to_chat(current, "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back.")
var/datum/game_mode/cult/cult = SSticker.mode
-
- if (istype(cult))
- cult.memorize_cult_objectives(src)
- else
- var/explanation = "Summon Nar-Sie via the use of the appropriate rune (Hell join self). It will only work if nine cultists stand on and around it."
- to_chat(current, "Objective #1: [explanation]")
- memory += "Objective #1: [explanation]
"
-
+ cult.memorize_cult_objectives(src)
var/mob/living/carbon/human/H = current
if (!SSticker.mode.equip_cultist(current))
to_chat(H, "Spawning an amulet from your Master failed.")
diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm
index 3f261c7991..043b1c3df6 100644
--- a/code/datums/status_effects/buffs.dm
+++ b/code/datums/status_effects/buffs.dm
@@ -223,3 +223,32 @@
name = "Wish Granter's Immortality"
desc = "You are being resurrected!"
icon_state = "wish_granter"
+
+/datum/status_effect/cult_master
+ id = "The Cult Master"
+ duration = -1
+ tick_interval = 100
+ alert_type = null
+ var/alive = TRUE
+
+/datum/status_effect/cult_master/proc/deathrattle()
+ var/area/A = get_area(owner)
+ for(var/datum/mind/B in SSticker.mode.cult)
+ if(isliving(B.current))
+ var/mob/living/M = B.current
+ M << 'sound/hallucinations/veryfar_noise.ogg'
+ to_chat(M, "The Cult's Master, [owner], has fallen in the [A]!")
+
+
+/datum/status_effect/cult_master/tick()
+ if(owner.stat != DEAD && !alive)
+ alive = TRUE
+ return
+ if(owner.stat == DEAD && alive)
+ alive = FALSE
+ deathrattle()
+
+/datum/status_effect/cult_master/on_remove()
+ deathrattle()
+ . = ..()
+
diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm
index 7780ae5db9..b67ad1f74b 100644
--- a/code/game/gamemodes/cult/cult.dm
+++ b/code/game/gamemodes/cult/cult.dm
@@ -1,5 +1,3 @@
-
-
/datum/game_mode
var/list/datum/mind/cult = list()
var/list/cult_objectives = list()
@@ -36,10 +34,10 @@
antag_flag = ROLE_CULTIST
restricted_jobs = list("Chaplain","AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel")
protected_jobs = list()
- required_players = 24
- required_enemies = 4
- recommended_enemies = 4
- enemy_minimum_age = 14
+ required_players = 1
+ required_enemies = 1
+ recommended_enemies = 1
+ enemy_minimum_age = 0
announce_span = "cult"
announce_text = "Some crew members are trying to start a cult to Nar-Sie!\n\
@@ -47,14 +45,13 @@
Crew: Prevent the cult from expanding and drive it out."
var/finished = 0
- var/eldergod = 1 //for the summon god objective
var/acolytes_needed = 10 //for the survive objective
var/acolytes_survived = 0
- var/datum/mind/sacrifice_target = null//The target to be sacrificed
var/list/cultists_to_cult = list() //the cultists we'll convert
+
/datum/game_mode/cult/pre_setup()
cult_objectives += "sacrifice"
cult_objectives += "eldergod"
@@ -89,10 +86,11 @@
if("survive")
explanation = "Our knowledge must live on. Make sure at least [acolytes_needed] acolytes escape on the shuttle to spread their work on an another station."
if("sacrifice")
- if(sacrifice_target)
- explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role] via invoking a Sacrifice rune with them on it and three acolytes around it."
+ if(GLOB.sac_mind)
+ explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role] via invoking a Sacrifice rune with them on it and three acolytes around it."
else
- explanation = "Free objective."
+ explanation = "The veil has already been weakened here, proceed to the next objective."
+ GLOB.sac_complete = TRUE
if("eldergod")
explanation = "Summon Nar-Sie by invoking the rune 'Summon Nar-Sie' with nine acolytes on it. You must do this after sacrificing your target."
to_chat(cult_mind.current, "Objective #[obj_count]: [explanation]")
@@ -108,9 +106,17 @@
if(player.mind && !(player.mind in cultists_to_cult))
possible_targets += player.mind
if(possible_targets.len > 0)
- sacrifice_target = pick(possible_targets)
- if(!sacrifice_target)
+ GLOB.sac_mind = pick(possible_targets)
+ if(!GLOB.sac_mind)
message_admins("Cult Sacrifice: ERROR - Null target chosen!")
+ else
+ var/datum/job/sacjob = SSjob.GetJob(GLOB.sac_mind.assigned_role)
+ var/icon/reshape = get_flat_human_icon(null, sacjob, GLOB.sac_mind.current.client.prefs)
+ reshape.Shift(SOUTH, 4)
+ reshape.Shift(EAST, 1)
+ reshape.Crop(7,4,26,31)
+ reshape.Crop(-5,-3,26,30)
+ GLOB.sac_image = reshape
else
message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!")
for(var/datum/mind/cult_mind in cultists_to_cult)
@@ -198,7 +204,7 @@
if(cult_objectives.Find("eldergod"))
cult_fail += eldergod //1 by default, 0 if the elder god has been summoned at least once
if(cult_objectives.Find("sacrifice"))
- if(sacrifice_target && !GLOB.sacrificed.Find(sacrifice_target)) //if the target has been GLOB.sacrificed, ignore this step. otherwise, add 1 to cult_fail
+ if(GLOB.sac_mind && GLOB.sac_complete) //if the target has been GLOB.sacrificed, ignore this step. otherwise, add 1 to cult_fail
cult_fail++
return cult_fail //if any objectives aren't met, failure
@@ -269,12 +275,45 @@
return 1
-/datum/game_mode/proc/auto_declare_completion_cult()
- if( cult.len || (SSticker && istype(SSticker.mode,/datum/game_mode/cult)) )
- var/text = "
The cultists were:"
- for(var/datum/mind/cultist in cult)
- text += printplayer(cultist)
-
- text += "
"
-
- to_chat(world, text)
+/datum/game_mode/proc/datum_cult_completion()
+ var/text = ""
+ var/acolytes_survived = 0
+ for(var/datum/mind/cult_mind in cult)
+ if (cult_mind.current && cult_mind.current.stat != DEAD)
+ if(cult_mind.current.onCentcom() || cult_mind.current.onSyndieBase())
+ acolytes_survived++
+ var/cult_fail = 0
+ cult_fail += eldergod
+ if(!GLOB.sac_complete)
+ cult_fail++
+ if(!cult_fail)
+ SSblackbox.set_details("round_end_result","win - cult win")
+ SSblackbox.set_val("round_end_result",acolytes_survived)
+ to_chat(world, "The cult has succeeded! Nar-sie has snuffed out another torch in the void!")
+ else
+ SSblackbox.set_details("round_end_result","loss - staff stopped the cult")
+ SSblackbox.set_val("round_end_result",acolytes_survived)
+ to_chat(world, "The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!")
+ if(cult_objectives.len)
+ text += "
The cultists' objectives were:"
+ for(var/obj_count in 1 to 2)
+ var/explanation
+ switch(cult_objectives[obj_count])
+ if("sacrifice")
+ if(GLOB.sac_complete)
+ explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. Success!"
+ SSblackbox.add_details("cult_objective","cult_sacrifice|SUCCESS")
+ else
+ explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. Fail."
+ SSblackbox.add_details("cult_objective","cult_sacrifice|FAIL")
+ if("eldergod")
+ if(!eldergod)
+ explanation = "Summon Nar-Sie. Success!"
+ SSblackbox.add_details("cult_objective","cult_narsie|SUCCESS")
+ SSticker.news_report = CULT_SUMMON
+ else
+ explanation = "Summon Nar-Sie. Fail."
+ SSblackbox.add_details("cult_objective","cult_narsie|FAIL")
+ SSticker.news_report = CULT_FAILURE
+ text += "
Objective #[obj_count]: [explanation]"
+ to_chat(world, text)
diff --git a/code/game/gamemodes/cult/cult.dm.rej b/code/game/gamemodes/cult/cult.dm.rej
new file mode 100644
index 0000000000..fb9b30c910
--- /dev/null
+++ b/code/game/gamemodes/cult/cult.dm.rej
@@ -0,0 +1,33 @@
+diff a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm (rejected hunks)
+@@ -4,7 +4,7 @@
+ var/eldergod = 1 //for the summon god objective
+
+ /proc/iscultist(mob/living/M)
+- return istype(M) && M.has_antag_datum(/datum/antagonist/cultist, TRUE)
++ return istype(M) && M.mind && M.mind.has_antag_datum(ANTAG_DATUM_CULT)
+
+ /proc/is_sacrifice_target(datum/mind/mind)
+ if(mind == GLOB.sac_mind)
+@@ -163,18 +163,18 @@
+ /datum/game_mode/proc/add_cultist(datum/mind/cult_mind, stun) //BASE
+ if (!istype(cult_mind))
+ return 0
+- if(cult_mind.current.gain_antag_datum(/datum/antagonist/cultist))
++ if(cult_mind.add_antag_datum(ANTAG_DATUM_CULT))
+ if(stun)
+ cult_mind.current.Paralyse(5)
+ return 1
+
+ /datum/game_mode/proc/remove_cultist(datum/mind/cult_mind, show_message = 1, stun)
+ if(cult_mind.current)
+- var/datum/antagonist/cultist/cult_datum = cult_mind.current.has_antag_datum(/datum/antagonist/cultist, TRUE)
++ var/datum/antagonist/cult/cult_datum = cult_mind.has_antag_datum(ANTAG_DATUM_CULT)
+ if(!cult_datum)
+ return FALSE
+- cult_datum.silent_update = show_message
+- cult_datum.on_remove()
++ cult_datum.silent = show_message
++ cult_datum.on_removal()
+ if(stun)
+ cult_mind.current.Paralyse(5)
+ return TRUE
diff --git a/code/game/gamemodes/cult/cult_comms.dm b/code/game/gamemodes/cult/cult_comms.dm
index 40c7bbece8..ff8ee97de7 100644
--- a/code/game/gamemodes/cult/cult_comms.dm
+++ b/code/game/gamemodes/cult/cult_comms.dm
@@ -1,3 +1,5 @@
+// Contains cult communion, guide, and cult master abilities
+#define MARK_COOLDOWN
/datum/action/innate/cultcomm
name = "Communion"
@@ -19,11 +21,15 @@
cultist_commune(usr, input)
/proc/cultist_commune(mob/living/user, message)
+ var/my_message
if(!message)
return
user.whisper("O bidai nabora se[pick("'","`")]sma!")
user.whisper(html_decode(message))
- var/my_message = "[(ishuman(user) ? "Acolyte" : "Construct")] [findtextEx(user.name, user.real_name) ? user.name : "[user.real_name] (as [user.name])"]: [message]"
+ if (user.mind.special_role == "Cult Master")
+ my_message = "[(ishuman(user) ? "Master" : "Lord")] [findtextEx(user.name, user.real_name) ? user.name : "[user.real_name] (as [user.name])"]: [message]"
+ else
+ my_message = "[(ishuman(user) ? "Acolyte" : "Construct")] [findtextEx(user.name, user.real_name) ? user.name : "[user.real_name] (as [user.name])"]: [message]"
for(var/mob/M in GLOB.mob_list)
if(iscultist(M))
to_chat(M, my_message)
@@ -65,3 +71,149 @@
popup.set_content(text)
popup.open()
return 1
+
+/mob/living/proc/cult_master()
+ set category = "Cultist"
+ set name = "Assert Leadership"
+ pollCultists(src) // This proc handles the distribution of cult master actions
+
+/datum/action/innate/cultmast
+ background_icon_state = "bg_demon"
+ buttontooltipstyle = "cult"
+ check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_CONSCIOUS
+
+/datum/action/innate/cultmast/IsAvailable()
+ if(owner.mind.special_role != "Cult Master")
+ return 0
+ return ..()
+
+/datum/action/innate/cultmast/finalreck
+ name = "Final Reckoning"
+ desc = "A single-use spell that brings the entire cult to the master's location"
+ button_icon_state = "sintouch"
+
+/datum/action/innate/cultmast/finalreck/Activate()
+ var/list/destinations = list()
+ for(var/turf/T in orange(1,owner))
+ if(istype(T, /turf/open))
+ destinations += T
+ for(var/i in 1 to 4)
+ owner.chant(i)
+ if(do_after(owner, 30, target = owner))
+ for(var/datum/mind/B in SSticker.mode.cult)
+ var/mob/living/M = B.current
+ if(isliving(M) && M.stat != DEAD)
+ var/turf/mobloc = get_turf(M)
+ switch(i)
+ if (1)
+ new /obj/effect/overlay/temp/cult/sparks(mobloc, M.dir)
+ playsound(mobloc, "sparks", 50, 1)
+ if (2)
+ new /obj/effect/overlay/temp/dir_setting/cult/phase/out(mobloc, M.dir)
+ playsound(mobloc, "sparks", 75, 1)
+ if (3)
+ new /obj/effect/overlay/temp/dir_setting/cult/phase(mobloc, M.dir)
+ playsound(mobloc, "sparks", 100, 1)
+ if (4)
+ playsound(mobloc, 'sound/magic/exit_blood.ogg', 100, 1)
+ if(M != owner)
+ var/turf/final = pick(destinations)
+ new /obj/effect/overlay/temp/cult/blood(final)
+ addtimer(CALLBACK(M, /mob/.proc/reckon, final), 10)
+ else
+ for(var/datum/action/innate/cultmast/finalreck/H in owner.actions)
+ qdel(H)
+ else
+ return
+
+/mob/proc/reckon(var/turf/final)
+ new /obj/effect/overlay/temp/cult/blood/out(get_turf(src))
+ forceMove(final)
+
+/mob/proc/chant(var/i)
+ switch(i)
+ if (1)
+ say("C'arta Forbici!")
+ if (2)
+ say("Pleggh E'ntrath!")
+ playsound(get_turf(src),'sound/magic/clockwork/narsie_attack.ogg', 50, 1)
+ if (3)
+ say("Barhah hra Zar'garis!")
+ playsound(get_turf(src),'sound/magic/clockwork/narsie_attack.ogg', 75, 1)
+ if (4)
+ say("N'ath reth Sh'yro eth D'rekkathnor!!!")
+ playsound(get_turf(src),'sound/magic/clockwork/narsie_attack.ogg', 100, 1)
+
+/datum/action/innate/cultmast/cultmark
+ name = "Mark Target"
+ desc = "Marks a target for the cult"
+ button_icon_state = "cult_mark"
+ var/obj/effect/proc_holder/cultmark/CM
+ var/time = 0
+
+/datum/action/innate/cultmast/cultmark/New()
+ CM = new()
+ ..()
+
+/datum/action/innate/cultmast/cultmark/IsAvailable()
+ if(owner.mind.special_role != "Cult Master")
+ return 0
+ if((world.time - time)<1200 && !CM.active)
+ owner << "You need to wait [round((1200-(world.time-time))/10)] seconds before you can mark another target!"
+ return 0
+ return ..()
+
+/datum/action/innate/cultmast/cultmark/Destroy()
+ QDEL_NULL(CM)
+ return ..()
+
+/datum/action/innate/cultmast/cultmark/Activate()
+ CM.toggle(owner) //the important bit
+ if(!active)
+ time = world.time
+ else
+ time = 0
+ return TRUE
+
+/obj/effect/proc_holder/cultmark
+ active = FALSE
+ ranged_mousepointer = 'icons/effects/cult_target.dmi'
+
+
+/obj/effect/proc_holder/cultmark/proc/toggle(mob/user)
+ if(active)
+ remove_ranged_ability("You cease the marking ritual...")
+ else
+ add_ranged_ability(user, "You prepare to mark a target for your cult...")
+
+/obj/effect/proc_holder/cultmark/InterceptClickOn(mob/living/caller, params, atom/target)
+ if(..())
+ return
+ if(ranged_ability_user.incapacitated())
+ remove_ranged_ability()
+ return
+ var/turf/T = get_turf(ranged_ability_user)
+ if(!isturf(T))
+ return FALSE
+ if(target in view(7, get_turf(ranged_ability_user)))
+ remove_ranged_ability(caller, "The marking rite is complete! It will last for 90 seconds.")
+ GLOB.blood_target = target
+ var/area/A = get_area(target)
+ for(var/datum/mind/B in SSticker.mode.cult)
+ var/mob/living/M = B.current
+ if(M.stat != DEAD)
+ to_chat(M, "Master [ranged_ability_user] has marked [GLOB.blood_target] in the [A.name] as the cult's top priority, get there immediately!")
+ M << pick(sound('sound/hallucinations/over_here2.ogg',0,1,75), sound('sound/hallucinations/over_here3.ogg',0,1,75))
+ var/image/cult_marker = image('icons/effects/cult_target.dmi', target, "glow", ABOVE_MOB_LAYER)
+ M.client.images |= cult_marker
+ addtimer(CALLBACK(M, /mob/living/proc/reset_blood_image, cult_marker), 900, TIMER_OVERRIDE)
+ return TRUE
+ return FALSE
+
+/mob/living/proc/reset_blood_image(var/image/cult_marker)
+ if(GLOB.blood_target && src.stat!=DEAD)
+ to_chat(src,"The blood mark has expired!")
+ if(client)
+ client.images.Remove(cult_marker)
+ QDEL_NULL(cult_marker)
+ GLOB.blood_target = null
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm
index a90aeb78bc..6058e8f605 100644
--- a/code/game/gamemodes/cult/cult_items.dm
+++ b/code/game/gamemodes/cult/cult_items.dm
@@ -213,7 +213,7 @@
flags_inv = HIDEJUMPSUIT
allowed = list(/obj/item/weapon/tome,/obj/item/weapon/melee/cultblade)
body_parts_covered = CHEST|GROIN|LEGS|ARMS
- armor = list(melee = -50, bullet = -50, laser = -100,energy = -50, bomb = -50, bio = -50, rad = -50, fire = 0, acid = 0)
+ armor = list(melee = -50, bullet = -50, laser = -50,energy = -50, bomb = -50, bio = -50, rad = -50, fire = 0, acid = 0)
slowdown = -1
hoodtype = /obj/item/clothing/head/hooded/berserkerhood
diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm
index ce4abced72..f393929463 100644
--- a/code/game/gamemodes/cult/ritual.dm
+++ b/code/game/gamemodes/cult/ritual.dm
@@ -197,35 +197,30 @@ This file contains the arcane tome files.
if(!src || QDELETED(src) || !Adjacent(user) || user.incapacitated() || !check_rune_turf(Turf, user))
return
if(ispath(rune_to_scribe, /obj/effect/rune/narsie))
- if(SSticker.mode.name == "cult")
- var/datum/game_mode/cult/cult_mode = SSticker.mode
- if(!("eldergod" in cult_mode.cult_objectives))
- to_chat(user, "Nar-Sie does not wish to be summoned!")
- return
- if(cult_mode.sacrifice_target && !(cult_mode.sacrifice_target in GLOB.sacrificed))
- to_chat(user, "The sacrifice is not complete. The portal would lack the power to open if you tried!")
- return
- if(!cult_mode.eldergod)
- to_chat(user, "\"I am already here. There is no need to try to summon me now.\"")
- return
- if((loc.z && loc.z != ZLEVEL_STATION) || !A.blob_allowed)
- to_chat(user, "The Geometer is not interested in lesser locations; the station is the prize!")
- return
- var/confirm_final = alert(user, "This is the FINAL step to summon Nar-Sie, it is a long, painful ritual and the crew will be alerted to your presence", "Are you prepared for the final battle?", "My life for Nar-Sie!", "No")
- if(confirm_final == "No")
- to_chat(user, "You decide to prepare further before scribing the rune.")
- return
- Turf = get_turf(user)
- A = get_area(src)
- if(!check_rune_turf(Turf, user) || (loc.z && loc.z != ZLEVEL_STATION)|| !A.blob_allowed)
- return
- priority_announce("Figments from an eldritch god are being summoned by [user] into [A.map_name] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensionsal Affairs", 'sound/AI/spanomalies.ogg')
- for(var/B in spiral_range_turfs(1, user, 1))
- var/obj/structure/emergency_shield/sanguine/N = new(B)
- shields += N
- else
+ if(!("eldergod" in SSticker.mode.cult_objectives))
to_chat(user, "Nar-Sie does not wish to be summoned!")
return
+ if(GLOB.sac_complete)
+ to_chat(user, "The sacrifice is not complete. The portal would lack the power to open if you tried!")
+ return
+ if(!SSticker.mode.eldergod)
+ to_chat(user, "\"I am already here. There is no need to try to summon me now.\"")
+ return
+ if((loc.z && loc.z != ZLEVEL_STATION) || !A.blob_allowed)
+ to_chat(user, "The Geometer is not interested in lesser locations; the station is the prize!")
+ return
+ var/confirm_final = alert(user, "This is the FINAL step to summon Nar-Sie, it is a long, painful ritual and the crew will be alerted to your presence", "Are you prepared for the final battle?", "My life for Nar-Sie!", "No")
+ if(confirm_final == "No")
+ to_chat(user, "You decide to prepare further before scribing the rune.")
+ return
+ Turf = get_turf(user)
+ A = get_area(src)
+ if(!check_rune_turf(Turf, user) || (loc.z && loc.z != ZLEVEL_STATION)|| !A.blob_allowed)
+ return
+ priority_announce("Figments from an eldritch god are being summoned by [user] into [A.map_name] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensional Affairs", 'sound/AI/spanomalies.ogg')
+ for(var/B in spiral_range_turfs(1, user, 1))
+ var/obj/structure/emergency_shield/sanguine/N = new(B)
+ shields += N
user.visible_message("[user] [user.blood_volume ? "cuts open their arm and begins writing in their own blood":"begins sketching out a strange design"]!", \
"You [user.blood_volume ? "slice open your arm and ":""]begin drawing a sigil of the Geometer.")
if(user.blood_volume)
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index 3a80ed54b3..4b9dd1a6c7 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -398,23 +398,23 @@ structure_check() searches for nearby cultist structures required for the invoca
return 1
/obj/effect/rune/convert/proc/do_sacrifice(mob/living/sacrificial, list/invokers)
+ var/big_sac = FALSE
if((((ishuman(sacrificial) || iscyborg(sacrificial)) && sacrificial.stat != DEAD) || is_sacrifice_target(sacrificial.mind)) && invokers.len < 3)
for(var/M in invokers)
to_chat(M, "[sacrificial] is too greatly linked to the world! You need three acolytes!")
log_game("Offer rune failed - not enough acolytes and target is living or sac target")
return FALSE
- var/sacrifice_fulfilled = FALSE
-
if(sacrificial.mind)
GLOB.sacrificed += sacrificial.mind
if(is_sacrifice_target(sacrificial.mind))
- sacrifice_fulfilled = TRUE
+ GLOB.sac_complete = TRUE
+ big_sac = TRUE
else
GLOB.sacrificed += sacrificial
new /obj/effect/overlay/temp/cult/sac(get_turf(src))
for(var/M in invokers)
- if(sacrifice_fulfilled)
+ if(big_sac)
to_chat(M, "\"Yes! This is the one I desire! You have done well.\"")
else
if(ishuman(sacrificial) || iscyborg(sacrificial))
@@ -451,7 +451,7 @@ structure_check() searches for nearby cultist structures required for the invoca
scribe_delay = 450 //how long the rune takes to create
scribe_damage = 40.1 //how much damage you take doing it
var/used
- var/ignore_gamemode = FALSE
+ var/ignore_gamemode = TRUE
/obj/effect/rune/narsie/Initialize(mapload, set_keyword)
. = ..()
@@ -490,7 +490,7 @@ structure_check() searches for nearby cultist structures required for the invoca
//BEGIN THE SUMMONING
used = 1
..()
- send_to_playing_players('sound/effects/dimensional_rend.ogg') //There used to be a message for this but every time it was changed it got edgier so I removed it
+ send_to_playing_players('sound/effects/dimensional_rend.ogg')
var/turf/T = get_turf(src)
sleep(40)
if(src)
diff --git a/code/game/gamemodes/game_mode.dm.rej b/code/game/gamemodes/game_mode.dm.rej
new file mode 100644
index 0000000000..a8a4a7ca6c
--- /dev/null
+++ b/code/game/gamemodes/game_mode.dm.rej
@@ -0,0 +1,10 @@
+diff a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm (rejected hunks)
+@@ -258,6 +258,8 @@
+ if(escaped_total > 0)
+ feedback_set("escaped_total",escaped_total)
+ send2irc("Server", "Round just ended.")
++ if(cult.len && !istype(SSticker.mode,/datum/game_mode/cult))
++ datum_cult_completion()
+ return 0
+
+
diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm
index 7ccf7a6b7e..b840b64c93 100644
--- a/code/game/gamemodes/wizard/soulstone.dm
+++ b/code/game/gamemodes/wizard/soulstone.dm
@@ -54,7 +54,7 @@
if(!ishuman(M))//If target is not a human.
return ..()
if(iscultist(M))
- to_chat(user, "\"Come now, do not capture your fellow's soul.\"")
+ to_chat(user, "\"Come now, do not capture your bretheren's soul.\"")
return
add_logs(user, M, "captured [M.name]'s soul", src)
@@ -132,11 +132,11 @@
if("VICTIM")
var/mob/living/carbon/human/T = target
- if(SSticker.mode.name == "cult" && T.mind == SSticker.mode:sacrifice_target)
+ if(is_sacrifice_target(T.mind))
if(iscultist(user))
to_chat(user, "\"This soul is mine. SACRIFICE THEM!\"")
else
- to_chat(user, "The soulstone doesn't work for no apparent reason.")
+ to_chat(user, "The soulstone seems to reject this soul.")
return 0
if(contents.len)
to_chat(user, "Capture failed!: The soulstone is full! Free an existing soul to make room.")
@@ -188,7 +188,10 @@
else
makeNewConstruct(/mob/living/simple_animal/hostile/construct/builder/noncult, A, user, 0, T.loc)
-
+ for(var/datum/mind/B in SSticker.mode.cult)
+ if(B == A.mind)
+ SSticker.mode.cult -= A.mind
+ SSticker.mode.update_cult_icons_removed(A.mind)
qdel(T)
user.drop_item()
qdel(src)
@@ -200,6 +203,9 @@
var/mob/living/simple_animal/hostile/construct/newstruct = new ctype((loc_override) ? (loc_override) : (get_turf(target)))
if(stoner)
newstruct.faction |= "\ref[stoner]"
+ newstruct.master = stoner
+ var/datum/action/innate/seek_master/SM = new()
+ SM.Grant(newstruct)
newstruct.key = target.key
if(newstruct.mind && ((stoner && iscultist(stoner)) || cultoverride) && SSticker && SSticker.mode)
SSticker.mode.add_cultist(newstruct.mind, 0)
@@ -207,6 +213,9 @@
to_chat(newstruct, "You are still bound to serve the cult[stoner ? " and [stoner]":""], follow their orders and help them complete their goals at all costs.")
else if(stoner)
to_chat(newstruct, "You are still bound to serve your creator, [stoner], follow their orders and help them complete their goals at all costs.")
+ newstruct.throw_alert("bloodsense", /obj/screen/alert/bloodsense)
+ var/obj/screen/alert/bloodsense/BS = newstruct.alerts["bloodsense"]
+ BS.Cviewer = newstruct
newstruct.cancel_camera()
diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm
index 3935b86c92..2a5dff0fd6 100644
--- a/code/game/objects/effects/overlays.dm
+++ b/code/game/objects/effects/overlays.dm
@@ -230,7 +230,15 @@
name = "blood sparks"
icon_state = "bloodsparkles"
-/obj/effect/overlay/temp/dir_setting/cult/phase
+/obj/effect/overlay/temp/cult/blood // The traditional teleport
+ name = "blood jaunt"
+ duration = 12
+ icon_state = "bloodin"
+
+/obj/effect/overlay/temp/cult/blood/out
+ icon_state = "bloodout"
+
+/obj/effect/overlay/temp/dir_setting/cult/phase // The veil shifter teleport
name = "phase glow"
duration = 7
icon_state = "cultin"
diff --git a/code/game/objects/effects/overlays.dm.rej b/code/game/objects/effects/overlays.dm.rej
new file mode 100644
index 0000000000..7bfce2cb62
--- /dev/null
+++ b/code/game/objects/effects/overlays.dm.rej
@@ -0,0 +1,10 @@
+diff a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm (rejected hunks)
+@@ -214,7 +214,7 @@
+ icon = 'icons/effects/fire.dmi'
+ icon_state = "3"
+ duration = 20
+-
++
+ /obj/effect/overlay/temp/cult
+ randomdir = 0
+ duration = 10
diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm
index 0734670468..d908ed547d 100644
--- a/code/modules/mob/living/death.dm
+++ b/code/modules/mob/living/death.dm
@@ -49,8 +49,8 @@
timeofdeath = world.time
tod = worldtime2text()
var/turf/T = get_turf(src)
+ var/area/A = get_area(T)
if(mind && mind.name && mind.active && (!(T.flags & NO_DEATHRATTLE)))
- var/area/A = get_area(T)
var/rendered = "[mind.name] has died at [A.name]."
deadchat_broadcast(rendered, follow_target = src, turf_target = T, message_type=DEADCHAT_DEATHRATTLE)
if(mind)
diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm
index b879f1baf6..37ef42291d 100644
--- a/code/modules/mob/living/simple_animal/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs.dm
@@ -31,12 +31,20 @@
deathmessage = "collapses in a shattered heap."
var/list/construct_spells = list()
var/playstyle_string = "You are a generic construct! Your job is to not exist, and you should probably adminhelp this."
+ var/master = null
+ var/seeking = FALSE
/mob/living/simple_animal/hostile/construct/Initialize()
. = ..()
for(var/spell in construct_spells)
AddSpell(new spell(null))
+/mob/living/simple_animal/hostile/construct/Destroy()
+ for(var/X in actions)
+ var/datum/action/A = X
+ qdel(A)
+ ..()
+
/mob/living/simple_animal/hostile/construct/Login()
..()
to_chat(src, playstyle_string)
diff --git a/code/modules/mob/living/simple_animal/constructs.dm.rej b/code/modules/mob/living/simple_animal/constructs.dm.rej
new file mode 100644
index 0000000000..b730acfbe9
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/constructs.dm.rej
@@ -0,0 +1,40 @@
+diff a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm (rejected hunks)
+@@ -41,14 +41,11 @@
+ for(var/spell in construct_spells)
+ AddSpell(new spell(null))
+
+-<<<<<<< HEAD
+ /mob/living/simple_animal/hostile/construct/Destroy()
+ for(var/X in actions)
+ var/datum/action/A = X
+ qdel(A)
+ ..()
+-=======
+->>>>>>> a7603e4aba50d410795d5207e6d5e929b2401cb9
+
+ /mob/living/simple_animal/hostile/construct/Login()
+ ..()
+@@ -288,8 +285,6 @@
+ environment_smash = 1 //only token destruction, don't smash the cult wall NO STOP
+
+
+-
+-<<<<<<< HEAD
+ ///////////////////////Master-Tracker///////////////////////
+
+ /datum/action/innate/seek_master
+@@ -320,7 +315,7 @@
+ the_construct.seeking = TRUE
+ to_chat(the_construct, "You are now tracking your master.")
+
+-=======
++
+ /////////////////////////////ui stuff/////////////////////////////
+
+ /mob/living/simple_animal/hostile/construct/update_health_hud()
+@@ -337,4 +332,4 @@
+ hud_used.healths.icon_state = "[icon_state]_health5"
+ else
+ hud_used.healths.icon_state = "[icon_state]_health6"
+->>>>>>> a7603e4aba50d410795d5207e6d5e929b2401cb9
++
diff --git a/config/game_options.txt b/config/game_options.txt
index 356dc1acab..dce0b57d42 100644
--- a/config/game_options.txt
+++ b/config/game_options.txt
@@ -166,7 +166,7 @@ MIDROUND_ANTAG ABDUCTION
#MIN_POP GANG 20
#MAX_POP GANG -1
-#MIN_POP CULT 24
+#MIN_POP CULT 0
#MAX_POP CULT -1
#MIN_POP CLOCKWORK_CULT 24
diff --git a/icons/effects/64x64.dmi b/icons/effects/64x64.dmi
index 347bccc942..361cfff40c 100644
Binary files a/icons/effects/64x64.dmi and b/icons/effects/64x64.dmi differ
diff --git a/icons/effects/cult_target.dmi b/icons/effects/cult_target.dmi
new file mode 100644
index 0000000000..650feb3361
Binary files /dev/null and b/icons/effects/cult_target.dmi differ
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index d684794ee8..fe537a8e73 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi
index 29c527b123..6d05b89039 100644
Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ
diff --git a/icons/mob/screen_alert.dmi b/icons/mob/screen_alert.dmi
index 5858925d86..162f5308e8 100644
Binary files a/icons/mob/screen_alert.dmi and b/icons/mob/screen_alert.dmi differ