From 963ca5b1ee5f04c71e2cdd2d1e9908ef2beb5266 Mon Sep 17 00:00:00 2001
From: SmArtKar <44720187+SmArtKar@users.noreply.github.com>
Date: Sun, 4 May 2025 16:30:34 +0200
Subject: [PATCH] Cult Master title is now granted to the most experienced cult
player, improvements and fixes (#90824)
## About The Pull Request
When the cult roundstart ruleset is picked, the most experienced cult
player is granted the cult Master title instead of it being determined
by voting. They can pass the role onto another willing cultist by using
an action once. Fixed cult masters not receiving their large speech
(instead not having any text spans whatsoever) and the Eldritch Pulse
spell being not usable whatsoever. Mark Target now displays an arrow
similar to heretic's living hearbeat to all cultists upon being cast.
This is a commission by Improvedname, but I do stand by the ideas
myself.
## Why It's Good For The Game
Cult Master, since its very inception, has been used for one thing and
one thing only - casting Final Reckoning on the summon rune by whoever
got to the area first and quickly used the vote that the cult reserved
for the finale. This results in other spells almost never being used, as
can be seen by the fact that one of them has been broken for the past 2
years. This change should make cult master more of a commander role akin
to how nuclear operative leader works, and make them a valuable target
for non-cultists to hunt down as they'll be present since roundstart.
## Changelog
:cl:
add: Cult Master is now assigned to the player with most hours as a
cultist upon roundstart, instead of being votable.
add: Cult Masters can transfer their role once.
balance: Mark Target now gives all cultists a noticable directional
indicator, similar to heretics' living hearbeat
fix: Fixed cult master's broken speech spans
fix: Fixed Eldritch Pulse not working
/:cl:
---
code/__HELPERS/game.dm | 3 -
.../dynamic/dynamic_rulesets_roundstart.dm | 5 +
code/modules/antagonists/cult/cult_comms.dm | 197 +++++++-----------
.../antagonists/cult/datums/cult_team.dm | 7 +-
.../antagonists/cult/datums/cultist.dm | 31 +--
.../heretic/heretic_living_heart.dm | 52 ++---
icons/effects/96x96.dmi | Bin 2013594 -> 2013595 bytes
7 files changed, 120 insertions(+), 175 deletions(-)
diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index d510078414b..4cb444fb21f 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -1,6 +1,3 @@
-///Time before being allowed to select a new cult leader again
-#define CULT_POLL_WAIT (240 SECONDS)
-
/// Returns either the error landmark or the location of the room. Needless to say, if this is used, it means things have gone awry.
#define GET_ERROR_ROOM ((locate(/obj/effect/landmark/error) in GLOB.landmarks_list) || locate(4,4,1))
diff --git a/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm b/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm
index 862b3307b4f..f560b07e149 100644
--- a/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm
+++ b/code/controllers/subsystem/dynamic/dynamic_rulesets_roundstart.dm
@@ -364,6 +364,11 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE)
M.add_antag_datum(new_cultist)
GLOB.pre_setup_antags -= M
main_cult.setup_objectives()
+ var/datum/mind/most_experienced = get_most_experienced(assigned, antag_flag)
+ if(!most_experienced)
+ most_experienced = assigned[1]
+ var/datum/antagonist/cult/leader = most_experienced.has_antag_datum(/datum/antagonist/cult)
+ leader.make_cult_leader()
return TRUE
/datum/dynamic_ruleset/roundstart/bloodcult/round_result()
diff --git a/code/modules/antagonists/cult/cult_comms.dm b/code/modules/antagonists/cult/cult_comms.dm
index 2dd0191d0ee..cf81acfcf10 100644
--- a/code/modules/antagonists/cult/cult_comms.dm
+++ b/code/modules/antagonists/cult/cult_comms.dm
@@ -54,7 +54,7 @@
var/span = "cult italic"
var/datum/antagonist/cult/cult_datum = user.mind.has_antag_datum(/datum/antagonist/cult)
if(cult_datum.is_cult_leader())
- span = "cultlarge"
+ span = "cult_large"
title = "Master"
else if(!ishuman(user))
title = "Construct"
@@ -89,115 +89,6 @@
var/link = FOLLOW_LINK(player_list, user)
to_chat(player_list, "[link] [my_message]")
-/datum/action/innate/cult/mastervote
- name = "Assert Leadership"
- button_icon_state = "cultvote"
- // So you can use it while your hands are cuffed or you are bucked
- // If you want to assert your leadership while handcuffed to a chair, be my guest
- check_flags = AB_CHECK_INCAPACITATED|AB_CHECK_CONSCIOUS|AB_CHECK_HANDS_BLOCKED
-
-/datum/action/innate/cult/mastervote/IsAvailable(feedback = FALSE)
- if(!owner || !owner.mind)
- return FALSE
- var/datum/antagonist/cult/mind_cult_datum = owner.mind.has_antag_datum(/datum/antagonist/cult)
- if(!mind_cult_datum || mind_cult_datum.cult_team.cult_leader_datum || mind_cult_datum.cult_team.cult_vote_called || !ishuman(owner))
- return FALSE
- return ..()
-
-/datum/action/innate/cult/mastervote/Activate()
- var/choice = tgui_alert(owner, "The mantle of leadership is heavy. Success in this role requires an expert level of communication and experience. Are you sure?",, list("Yes", "No"))
- if(choice == "Yes" && IsAvailable())
- var/datum/antagonist/cult/mind_cult_datum = owner.mind.has_antag_datum(/datum/antagonist/cult)
- start_poll_cultists_for_leader(owner, mind_cult_datum.cult_team)
-
-///Start the poll for Cult Leaeder.
-/proc/start_poll_cultists_for_leader(mob/living/nominee, datum/team/cult/team)
- if(world.time < CULT_POLL_WAIT)
- to_chat(nominee, "It would be premature to select a leader while everyone is still settling in, try again in [DisplayTimeText(CULT_POLL_WAIT-world.time)].")
- return
- team.cult_vote_called = TRUE
- for(var/datum/mind/team_member as anything in team.members)
- if(!team_member.current)
- continue
- team_member.current.update_mob_action_buttons()
- if(team_member.current.incapacitated)
- continue
- SEND_SOUND(team_member.current, 'sound/effects/hallucinations/im_here1.ogg')
- to_chat(team_member.current, span_cult_large("Acolyte [nominee] has asserted that [nominee.p_theyre()] worthy of leading the cult. A vote will be called shortly."))
-
- addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(poll_cultists_for_leader), nominee, team), 10 SECONDS)
-
-///Polls all Cultists on whether the person putting themselves forward should be made the Cult Leader, if they can actually be such.
-/proc/poll_cultists_for_leader(mob/living/nominee, datum/team/cult/team)
- if(QDELETED(nominee) || nominee.incapacitated)
- team.cult_vote_called = FALSE
- for(var/datum/mind/team_member as anything in team.members)
- if(!team_member.current)
- continue
- team_member.current.update_mob_action_buttons()
- if(team_member.current.incapacitated)
- continue
- to_chat(team_member.current,span_cult_large("[nominee] has died in the process of attempting to start a vote!"))
- return FALSE
- var/list/mob/living/asked_cultists = list()
- for(var/datum/mind/team_member as anything in team.members)
- if(!team_member.current || team_member.current == nominee || team_member.current.incapacitated)
- continue
- SEND_SOUND(team_member.current, 'sound/effects/magic/exit_blood.ogg')
- asked_cultists += team_member.current
-
- var/list/yes_voters = SSpolling.poll_candidates(
- question = "[span_notice(nominee.name)] seeks to lead your cult, do you support [nominee.p_them()]?",
- poll_time = 30 SECONDS,
- group = asked_cultists,
- alert_pic = nominee,
- role_name_text = "cult master nomination",
- custom_response_messages = list(
- POLL_RESPONSE_SIGNUP = "You have pledged your allegience to [nominee].",
- POLL_RESPONSE_ALREADY_SIGNED = "You have already pledged your allegience!",
- POLL_RESPONSE_NOT_SIGNED = "You aren't nominated for this.",
- POLL_RESPONSE_TOO_LATE_TO_UNREGISTER = "It's too late to unregister yourself, voting has already begun!",
- POLL_RESPONSE_UNREGISTERED = "You have been removed your pledge to [nominee].",
- chat_text_border_icon = mutable_appearance('icons/effects/effects.dmi', "cult_master_logo")
- )
- )
- if(QDELETED(nominee) || nominee.incapacitated)
- team.cult_vote_called = FALSE
- for(var/datum/mind/team_member as anything in team.members)
- if(!team_member.current)
- continue
- team_member.current.update_mob_action_buttons()
- if(team_member.current.incapacitated)
- continue
- to_chat(team_member.current,span_cult_large("[nominee] has died in the process of attempting to win the cult's support!"))
- return FALSE
- if(!nominee.mind)
- team.cult_vote_called = FALSE
- for(var/datum/mind/team_member as anything in team.members)
- if(!team_member.current)
- continue
- team_member.current.update_mob_action_buttons()
- if(team_member.current.incapacitated)
- continue
- to_chat(team_member.current,span_cult_large("[nominee] has gone catatonic in the process of attempting to win the cult's support!"))
- return FALSE
- if(LAZYLEN(yes_voters) <= LAZYLEN(asked_cultists) * 0.5)
- team.cult_vote_called = FALSE
- for(var/datum/mind/team_member as anything in team.members)
- if(!team_member.current)
- continue
- team_member.current.update_mob_action_buttons()
- if(team_member.current.incapacitated)
- continue
- to_chat(team_member.current, span_cult_large("[nominee] could not win the cult's support and shall continue to serve as an acolyte."))
- return FALSE
-
- team.cult_vote_called = FALSE
- var/datum/antagonist/cult/cult_datum = nominee.mind.has_antag_datum(/datum/antagonist/cult)
- if(!cult_datum.make_cult_leader())
- CRASH("[cult_datum.owner.current] was supposed to turn into the leader, but they didn't for some reason. This isn't supposed to happen unless an Admin messed with it.")
- return TRUE
-
/datum/action/innate/cult/master/IsAvailable(feedback = FALSE)
if(!owner.mind || GLOB.cult_narsie)
return FALSE
@@ -206,6 +97,63 @@
return FALSE
return ..()
+/datum/action/innate/cult/master/pass_role
+ name = "Pass the Mantle"
+ desc = "Pass the Master role onto another willing cultist. This can only be done once!"
+ button_icon_state = "cultvote"
+ check_flags = AB_CHECK_INCAPACITATED|AB_CHECK_CONSCIOUS|AB_CHECK_HANDS_BLOCKED
+
+/datum/action/innate/cult/master/pass_role/IsAvailable(feedback = FALSE)
+ . = ..()
+ if (!.)
+ return
+ var/datum/antagonist/cult/mind_cult_datum = owner.mind.has_antag_datum(/datum/antagonist/cult)
+ if(!mind_cult_datum || mind_cult_datum.cult_team.leader_passed_on)
+ return FALSE
+
+/datum/action/innate/cult/master/pass_role/Activate()
+ var/list/choices = list()
+ var/datum/antagonist/cult/owner_datum = owner.mind.has_antag_datum(/datum/antagonist/cult)
+ for(var/datum/mind/team_member as anything in owner_datum.cult_team.members)
+ if(!team_member.current || !ishuman(team_member.current) || team_member.current == owner || team_member.current.stat == DEAD)
+ continue
+
+ choices[team_member.current.real_name] = team_member
+
+ var/new_master = tgui_input_list(owner, "Select another cult member to pass the cult's Master role onto.", "Pass the Mantle", choices)
+ if (!new_master || !IsAvailable())
+ return
+
+ var/confirmation = tgui_alert(owner, "Are you sure that you want to make [new_master] the new Master? This can only be done once!", "Pass the Mantle", list("Yes", "No"))
+ if (confirmation != "Yes" || !IsAvailable())
+ return
+
+ var/datum/mind/master_mind = choices[new_master]
+ var/mob/living/carbon/human/master = master_mind.current
+ if (!master || master.stat == DEAD || !master.client)
+ to_chat(owner, span_cult("[new_master] can no longer take on the role of a Master."))
+ return
+
+ var/datum/antagonist/cult/target_datum = master_mind.has_antag_datum(/datum/antagonist/cult)
+ if(!target_datum || owner_datum.cult_team != target_datum?.cult_team)
+ to_chat(owner, span_cult("[new_master] can no longer take on the role of a Master."))
+ return
+
+ SEND_SOUND(master, sound('sound/effects/magic.ogg', volume = 33))
+ confirmation = tgui_alert(master, "[owner.real_name] is offering their role as the cult's Master to you! Do you wish to accept it?", "Take the Mantle", list("Yes", "No"))
+
+ if (confirmation != "Yes")
+ to_chat(owner, span_cult("[new_master] has declined your offer."))
+ return
+
+ if (!IsAvailable() || !master_mind.has_antag_datum(/datum/antagonist/cult) || !master.client)
+ to_chat(owner, span_cult("[new_master] can no longer take on the role of a Master."))
+ return
+
+ target_datum.cult_team.leader_passed_on = TRUE
+ owner_datum.demote_from_leader()
+ target_datum.make_cult_leader()
+
/datum/action/innate/cult/master/finalreck
name = "Final Reckoning"
desc = "A single-use spell that brings the entire cult to the master's location."
@@ -438,8 +386,7 @@
/datum/action/innate/cult/master/pulse/do_ability(mob/living/clicker, atom/clicked_on)
var/atom/throwee = throwee_ref?.resolve()
-
- if(QDELETED(throwee))
+ if(throwee && QDELING(throwee))
to_chat(clicker, span_cult("You lost your target!"))
throwee = null
throwee_ref = null
@@ -483,19 +430,17 @@
return TRUE
- else
- if(isliving(clicked_on))
- var/mob/living/living_clicked = clicked_on
- if(!IS_CULTIST(living_clicked))
- return FALSE
- SEND_SOUND(clicker, sound('sound/items/weapons/thudswoosh.ogg'))
- to_chat(clicker, span_cult_bold("You reach through the veil with your mind's eye and seize [clicked_on]! Click anywhere nearby to teleport [clicked_on.p_them()]!"))
- throwee_ref = WEAKREF(clicked_on)
- return TRUE
-
- if(istype(clicked_on, /obj/structure/destructible/cult))
- to_chat(clicker, span_cult_bold("You reach through the veil with your mind's eye and lift [clicked_on]! Click anywhere nearby to teleport it!"))
- throwee_ref = WEAKREF(clicked_on)
- return TRUE
+ if(isliving(clicked_on))
+ var/mob/living/living_clicked = clicked_on
+ if(!IS_CULTIST(living_clicked))
+ return FALSE
+ SEND_SOUND(clicker, sound('sound/items/weapons/thudswoosh.ogg'))
+ to_chat(clicker, span_cult_bold("You reach through the veil with your mind's eye and seize [clicked_on]! Click anywhere nearby to teleport [clicked_on.p_them()]!"))
+ throwee_ref = WEAKREF(clicked_on)
+ return TRUE
+ if(istype(clicked_on, /obj/structure/destructible/cult))
+ to_chat(clicker, span_cult_bold("You reach through the veil with your mind's eye and lift [clicked_on]! Click anywhere nearby to teleport it!"))
+ throwee_ref = WEAKREF(clicked_on)
+ return TRUE
return FALSE
diff --git a/code/modules/antagonists/cult/datums/cult_team.dm b/code/modules/antagonists/cult/datums/cult_team.dm
index 8606a6f82d9..130683a9046 100644
--- a/code/modules/antagonists/cult/datums/cult_team.dm
+++ b/code/modules/antagonists/cult/datums/cult_team.dm
@@ -8,8 +8,8 @@
///Timer for the blood mark expiration
var/blood_target_reset_timer
- ///Has a vote been called for a leader?
- var/cult_vote_called = FALSE
+ ///Has the cult leader passed on their responsibilities to someone else?
+ var/leader_passed_on = FALSE
///The cult leader
var/datum/antagonist/cult/cult_leader_datum
///Has the mass teleport been used yet?
@@ -161,12 +161,15 @@
for(var/datum/mind/cultist as anything in members)
if(!cultist.current)
continue
+
if(cultist.current.stat == DEAD || !cultist.current.client)
continue
to_chat(cultist.current, span_bold(span_cult_large("[marker] has marked [blood_target] in \the [target_area] as the cult's top priority, get there immediately!")))
SEND_SOUND(cultist.current, sound(SFX_HALLUCINATION_OVER_HERE, 0, 1, 75))
cultist.current.client.images += blood_target_image
+ if (cultist.current.hud_used)
+ new /atom/movable/screen/navigate_arrow(null, cultist.current.hud_used, get_turf(new_target), COLOR_CULT_RED)
if(duration != INFINITY)
blood_target_reset_timer = addtimer(CALLBACK(src, PROC_REF(unset_blood_target)), duration, TIMER_STOPPABLE)
diff --git a/code/modules/antagonists/cult/datums/cultist.dm b/code/modules/antagonists/cult/datums/cultist.dm
index 433c9ebedbe..eaa5150808c 100644
--- a/code/modules/antagonists/cult/datums/cultist.dm
+++ b/code/modules/antagonists/cult/datums/cultist.dm
@@ -9,9 +9,6 @@
antag_hud_name = "cult"
stinger_sound = 'sound/music/antag/bloodcult/bloodcult_gain.ogg'
- ///The vote ability Cultists have to elect someone to be the leader.
- var/datum/action/innate/cult/mastervote/vote_ability
-
///Boolean on whether the starting equipment should be given to their inventory.
var/give_equipment = FALSE
///Reference to the Blood cult team they are part of.
@@ -35,9 +32,6 @@
var/datum/action/innate/cult/comm/communion = new(owner)
communion.Grant(current)
- if(isnull(cult_team.cult_leader_datum))
- vote_ability = new(owner)
- vote_ability.Grant(current)
if(ishuman(current))
var/datum/action/innate/cult/blood_magic/magic = new(owner)
magic.Grant(current)
@@ -50,8 +44,6 @@
to_chat(owner.current, span_userdanger("An unfamiliar white light flashes through your mind, cleansing the taint of the Geometer and all your memories as her servant."))
owner.current.log_message("has renounced the cult of Nar'Sie!", LOG_ATTACK, color=COLOR_CULT_RED)
- if(vote_ability)
- QDEL_NULL(vote_ability)
for(var/datum/action/innate/cult/cult_buttons in owner.current.actions)
qdel(cult_buttons)
@@ -185,8 +177,8 @@
/datum/antagonist/cult/proc/make_cult_leader()
if(cult_team.cult_leader_datum)
return FALSE
- cult_team.cult_leader_datum = src
+ cult_team.cult_leader_datum = src
antag_hud_name = "cultmaster"
add_team_hud(owner.current)
RegisterSignal(owner.current, COMSIG_MOB_STATCHANGE, PROC_REF(deathrattle))
@@ -198,13 +190,15 @@
var/datum/action/innate/cult/master/pulse/throwing = new
bloodmark.Grant(owner.current)
throwing.Grant(owner.current)
+ if(!cult_team.leader_passed_on)
+ var/datum/action/innate/cult/master/pass_role/pass_role = new
+ pass_role.Grant(owner.current)
owner.current.update_mob_action_buttons()
for(var/datum/mind/cult_mind as anything in cult_team.members)
- var/datum/antagonist/cult/cult_datum = cult_mind.has_antag_datum(/datum/antagonist/cult)
- cult_datum.vote_ability.Remove(cult_mind.current)
- to_chat(cult_mind.current, span_cult_large("[owner.current] has won the cult's support and is now their master. \
- Follow [owner.current.p_their()] orders to the best of your ability!"))
+ if (cult_mind != owner)
+ to_chat(cult_mind.current, span_cult_large("[owner.current] is your cult's Master! \
+ Follow [owner.current.p_their()] orders to the best of your ability!"))
to_chat(owner.current, span_cult_large("You are the cult's Master. \
As the cult's Master, you have a unique title and loud voice when communicating, are capable of marking \
@@ -215,7 +209,6 @@
return TRUE
///Admin-only helper to demote someone from Cult leader, taking away their HUD, abilities, and deathrattle
-///And gives all cultists from their team back their ability to vote for a new leader.
/datum/antagonist/cult/proc/demote_from_leader()
if(!cult_team.cult_leader_datum)
return FALSE
@@ -234,13 +227,11 @@
var/datum/action/innate/cult/master/pulse/throwing = locate() in owner.current.actions
if(throwing)
throwing.Remove(owner.current)
+ var/datum/action/innate/cult/master/pass_role/pass_role = locate() in owner.current.actions
+ if(pass_role)
+ pass_role.Remove(owner.current)
owner.current.update_mob_action_buttons()
- for(var/datum/mind/cult_mind as anything in cult_team.members)
- var/datum/antagonist/cult/cult_datum = cult_mind.has_antag_datum(/datum/antagonist/cult)
- cult_datum.vote_ability.Grant(cult_mind.current)
-
- to_chat(owner.current, span_cult_large("You have been demoted from being the cult's Master, you are now an acolyte once more!"))
-
+ to_chat(owner.current, span_cult_large("You have been demoted from being the cult's Master, you are now a mere acolyte!"))
return TRUE
///If dead (and Narsie isn't summoned), will alert all Cultists of their death, sending their location out.
diff --git a/code/modules/antagonists/heretic/heretic_living_heart.dm b/code/modules/antagonists/heretic/heretic_living_heart.dm
index a79831d9dc6..443ea0603fd 100644
--- a/code/modules/antagonists/heretic/heretic_living_heart.dm
+++ b/code/modules/antagonists/heretic/heretic_living_heart.dm
@@ -180,26 +180,6 @@
StartCooldown()
return TRUE
-/datum/action/cooldown/track_target/proc/make_navigate_arrow(turf/tracked_turf, arrow_color)
- var/datum/hud/user_hud = owner.hud_used
- if(!user_hud)
- return
- var/atom/movable/screen/heretic_arrow/arrow = new /atom/movable/screen/heretic_arrow(null, user_hud)
- animate(arrow, transform = matrix(dir2angle(get_dir(owner, tracked_turf)), MATRIX_ROTATE), 0.2 SECONDS)
- arrow.screen_loc = around_player
- arrow.color = arrow_color
- user_hud.infodisplay += arrow
- user_hud.show_hud(user_hud.hud_version)
- addtimer(CALLBACK(src, PROC_REF(end_effect), user_hud, arrow), 1.6 SECONDS)
-
-/datum/action/cooldown/track_target/proc/end_effect(datum/hud/user_hud, atom/movable/screen/heretic_arrow/arrow)
- arrow.icon_state = "heretic_arrow_disappear"
- addtimer(CALLBACK(src, PROC_REF(null_arrow), user_hud, arrow), 0.4 SECONDS)
-
-/datum/action/cooldown/track_target/proc/null_arrow(datum/hud/user_hud, atom/movable/screen/heretic_arrow/arrow)
- user_hud.infodisplay -= arrow
- user_hud.show_hud(user_hud.hud_version)
-
/// Callback for the radial to ensure it's closed when not allowed.
/datum/action/cooldown/track_target/proc/check_menu()
if(QDELETED(src))
@@ -268,7 +248,8 @@
balloon_message = "very far!"
arrow_color = COLOR_RED
- make_navigate_arrow(their_turf, arrow_color)
+ if(owner.hud_used)
+ new /atom/movable/screen/navigate_arrow(null, owner.hud_used, their_turf, arrow_color)
if(ismob(tracked_thing))
var/mob/tracked_mob = tracked_thing
@@ -277,9 +258,32 @@
return balloon_message
-/atom/movable/screen/heretic_arrow
+/atom/movable/screen/navigate_arrow
icon = 'icons/effects/96x96.dmi'
- name = "heretic arrow"
- icon_state = "heretic_arrow_appear"
+ name = "farsight arrow"
+ icon_state = "navigate_arrow_appear"
pixel_x = -32
pixel_y = -32
+ mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+
+/atom/movable/screen/navigate_arrow/Initialize(mapload, datum/hud/hud_owner, turf/tracked_turf, arrow_color)
+ . = ..()
+ var/mob/owner = get_mob()
+ if (owner)
+ animate(src, transform = matrix(get_angle(owner, tracked_turf), MATRIX_ROTATE), 0.2 SECONDS)
+ screen_loc = around_player
+ color = arrow_color
+ if (hud)
+ hud.infodisplay += src
+ hud.show_hud(hud.hud_version)
+ addtimer(CALLBACK(src, PROC_REF(end_effect)), 1.6 SECONDS)
+
+/atom/movable/screen/navigate_arrow/proc/end_effect()
+ icon_state = "navigate_arrow_disappear"
+ addtimer(CALLBACK(src, PROC_REF(null_arrow)), 0.4 SECONDS)
+
+/atom/movable/screen/navigate_arrow/proc/null_arrow()
+ if (hud)
+ hud.infodisplay -= src
+ hud.show_hud(hud.hud_version)
+ qdel(src)
diff --git a/icons/effects/96x96.dmi b/icons/effects/96x96.dmi
index 9942d0a539859d944cb0e9e695611d1ade36abc0..ed4a5b64d3caa77f5ac0f35fd801a7c20e6a85db 100644
GIT binary patch
delta 1157
zcmWm1dpr|(003~bV;F57GtcX&IG4<`VnQDKursVYMre!S$ZC&h()8vkiCxFG!WQxt
z=~x~Srzmgoh1MAa&mDGmxW{v$TsRZ2B|hfP^^6iFJ{$JG$w153wf4+>vf?q(s(^*|kSEn2*)y
zW>OqH1ES6>a3$el>f`dE5!g9=(+9!|I}v527_2GeG^1V|mMmZUGm_k~juvF-*<Ft;h^1C(3t=%Dhp)q})fb8kAmeEc
zUy}y?v{pEtJ>Od9bb|0^H&>ai@s)2I#i&8Gb1It_bHsK!w|6VUCJ~=qG0jfjnl+-G
zTGG-azkGts{nYvcCmf}`{
zDOmD*O~wxTK96?sOu9c&bX%=f66BY9pQgAuj~m$&GNy#9Q`La7yITluk;q-ON}qHY
zz54CG*%Dqx2$Dvp*pbn=N$F*`JNcc`s_N7LIAp%&Jl+v;;d7R4(a7Bx7Z)iHJ-?Wz
zf_KRdI@skINjEf|oVe@JAheXDgk_@kCcBJ@{iHD^xp#9$dPFIKKEbCY)@l2UyV
zl2Q{=U#58Q*wW;irNw^jnjTwA8)a13oB21v{SP8iUkCSHMV5<2OQOHy&Zfong}sWk
zG8pD&mbWarqLPja3~|m(b?5q-J;$BMV%lC@CH6pzDx>=XNpfi4#2=3bEw2s{HZf-#
zCt+jJgY$TI<9K4`+YP1I89`lEvA0~se6f{68^}Dw9{i!FW91TObAM10vxP})stSLH
zrhc40@a#AK_b0N5HIa?{=cgFq8Lf*PIMsA^^(&%>OtIQFX@zab^^UNii==}CX@0@B
zzWnERN23DWp{+LxEh@WM1GXIsZXG=pHcRIHHU9E#M4RGVL3ZSJ{~fx5Ndw)-)BRWq
ze_ItL=jK|b^!nXCqNlc0ib{?pa!S|FhB#)1a<;&00C$L+JFwA3m^eK00rm+
R27n=81Q`Eg2r*$d{0B$X7SI3y
delta 1157
zcmWm1X;cz+003}PNW~*C@Wv)-J#sOfdCYXn6!92ZzUII)%(8lnU>(W
znKG|rsYOpLHJzYjtb
zTym0*P6qE4c{Yjbj1+~|V$LTYhd|0T@fO@j;;o+0X(N*9C8kAwnajAKdEUkF`flo1
zWcM_|k5u|*O&n*}Lf*PkyCGR!P_9Zo7K_UZbJi(l#4l@SB?ZBhbZqBFxpvm^Vt_hhM{C7DHL;o^ce{)B*Q+0xbPqHM27PSho64Eh
z75AN|_qiXszxNsEj|Tk<-sP#1lz3lHU4Pu=NIxeX$s}r|oR2<`*cV(oHReh)sI;k|
zG_|BEysbS&9b`ETE$cE@wxSPCPes&^Jm_FUG&Zqqpe4!KSS`3qu>lq_N}2z
z@<~I~k4L(7kn{>{Q^(gf
zw~xYEyF|iKo)vw{tr9G-vbPRt#ocPK_TH`y`gQc6dcqs4=bC(XdrT1xN
z?U^2z&3mhgmU?@8s@gn?82rqUtVkhJ<-D-nQMWZr>&v^KrcQTHMlVLI>b*MHB1Ykv
zN%m6P(;Qi2SNmTr)2s6Q#bHOG%N##y=8hUCe}S;6awQ-25h{uGQ5vHI&nTm^db|@S
zgz$D_N`C$@=_bDOFqHV~X-E395ij?K)Qe;7X3Kl-#p^pXB!Ctl8!7MC-7`%_6w?Q;h_3Cp9x%~Q7#V#=Al+wb~~uc<8tXa?`{
zJSTFA5rY1?V?n48cx5;hfrBNs+jUbXN(iJ(w}meYS~Y*mL*da>UsCWUR+pq>*G&)d
z_dSupQ{^i2(GWHovIEcs^nm{l1$F}ZfB|3#zyKq_7%%}$fn5L`KmcaIZU70O0CT_s
Uumr3CYrqDu1<<`{h+SUye^eP9ng9R*