diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm
index 8e27f9315c3..ce46913c2d2 100644
--- a/code/__DEFINES/is_helpers.dm
+++ b/code/__DEFINES/is_helpers.dm
@@ -1,5 +1,25 @@
+// Atoms
#define isatom(A) istype(A, /atom)
#define ismovableatom(A) istype(A, /atom/movable)
-#define isclient(A) istype(A, /client)
+// Mobs
+#define ismegafauna(A) (istype(A, /mob/living/simple_animal/hostile/megafauna))
+
+//Turfs
+#define issimulatedturf(A) (istype(A, /turf/simulated))
+
+#define isspaceturf(A) (istype(A, /turf/space))
+
+#define isfloorturf(A) (istype(A, /turf/simulated/floor))
+
+#define isunsimulatedturf(A) (istype(A, /turf/unsimulated))
+
+#define iswallturf(A) (istype(A, /turf/simulated/wall))
+
+#define isreinforcedwallturf(A) (istype(A, /turf/simulated/wall/r_wall))
+
+#define ismineralturf(A) (istype(A, /turf/simulated/mineral))
+
+// Misc
+#define isclient(A) istype(A, /client)
#define isradio(A) istype(A, /obj/item/device/radio)
\ No newline at end of file
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 3735f31caf8..b9ee580896c 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1814,4 +1814,22 @@ var/global/list/g_fancy_list_of_types = null
namecounts[name] = 1
pois[name] = A
- return pois
\ No newline at end of file
+ return pois
+
+/proc/flash_color(mob_or_client, flash_color="#960000", flash_time=20)
+ var/client/C
+ if(istype(mob_or_client, /mob))
+ var/mob/M = mob_or_client
+ if(M.client)
+ C = M.client
+ else
+ return
+ else if(istype(mob_or_client, /client))
+ C = mob_or_client
+
+ if(!istype(C))
+ return
+
+ C.color = flash_color
+ spawn(0)
+ animate(C, color = initial(C.color), time = flash_time)
\ No newline at end of file
diff --git a/code/datums/action.dm b/code/datums/action.dm
index f1c197cdfe8..f1826c334c5 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -187,6 +187,40 @@
/datum/action/item_action/toggle_hardsuit_mode
name = "Toggle Hardsuit Mode"
+
+/datum/action/item_action/toggle_unfriendly_fire
+ name = "Toggle Friendly Fire \[ON\]"
+ desc = "Toggles if the staff causes friendly fire."
+ button_icon_state = "vortex_ff_on"
+
+/datum/action/item_action/toggle_unfriendly_fire/Trigger()
+ if(..())
+ UpdateButtonIcon()
+
+/datum/action/item_action/toggle_unfriendly_fire/UpdateButtonIcon()
+ if(istype(target, /obj/item/weapon/hierophant_staff))
+ var/obj/item/weapon/hierophant_staff/H = target
+ if(H.friendly_fire_check)
+ button_icon_state = "vortex_ff_off"
+ name = "Toggle Friendly Fire \[OFF\]"
+ button.name = name
+ else
+ button_icon_state = "vortex_ff_on"
+ name = "Toggle Friendly Fire \[ON\]"
+ button.name = name
+ ..()
+
+/datum/action/item_action/vortex_recall
+ name = "Vortex Recall"
+ desc = "Recall yourself, and anyone nearby, to an attuned hierophant rune at any time.
If no such rune exists, will produce a rune at your location."
+ button_icon_state = "vortex_recall"
+
+/datum/action/item_action/vortex_recall/IsAvailable()
+ if(istype(target, /obj/item/weapon/hierophant_staff))
+ var/obj/item/weapon/hierophant_staff/H = target
+ if(H.teleporting)
+ return 0
+ return ..()
/datum/action/item_action/toggle
diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm
index 260da98d221..46f7b3fb469 100644
--- a/code/game/objects/items/stacks/sheets/leather.dm
+++ b/code/game/objects/items/stacks/sheets/leather.dm
@@ -144,7 +144,7 @@ var/global/list/datum/stack_recipe/sinew_recipes = list ( \
if(W.sharp)
user.visible_message("[user] starts cutting hair off \the [src].", "You start cutting the hair off \the [src]...", "You hear the sound of a knife rubbing against flesh.")
if(do_after(user,50, target = src))
- user << "You cut the hair from this [src.singular_name]."
+ to_chat(user, "You cut the hair from this [src.singular_name].")
//Try locating an exisitng stack on the tile and add to there if possible
for(var/obj/item/stack/sheet/hairlesshide/HS in usr.loc)
if(HS.amount < 50)
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index 8af2f5cd948..a64486b440c 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -1506,8 +1506,8 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
var/datum/map_template/ruin/template = landmark.ruin_template
admin_forcemove(usr, get_turf(landmark))
- usr << "[template.name]"
- usr << "[template.description]"
+ to_chat(usr, "[template.name]")
+ to_chat(usr, "[template.description]")
log_admin("[key_name(usr)] jumped to ruin [ruinname]")
if(!isobserver(usr))
diff --git a/code/modules/mining/lavaland/ash_flora.dm b/code/modules/mining/lavaland/ash_flora.dm
index 22d1e4cca8d..b5bd3f83f6b 100644
--- a/code/modules/mining/lavaland/ash_flora.dm
+++ b/code/modules/mining/lavaland/ash_flora.dm
@@ -38,7 +38,7 @@
msg = harvest_message_low
else if(rand_harvested == harvest_amount_high)
msg = harvest_message_high
- user << "[msg]"
+ to_chat(user, "[msg]")
for(var/i in 1 to rand_harvested)
new harvest(get_turf(src))
icon_state = "[base_icon]p"
diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm
index c671763502d..6dfc5935b00 100644
--- a/code/modules/mining/lavaland/necropolis_chests.dm
+++ b/code/modules/mining/lavaland/necropolis_chests.dm
@@ -288,4 +288,252 @@
/obj/effect/overlay/temp/lavastaff
icon_state = "lavastaff_warn"
- duration = 50
\ No newline at end of file
+ duration = 50
+
+// Legion
+
+/obj/item/weapon/staff/storm
+ name = "staff of storms"
+ desc = "An ancient staff retrieved from the remains of Legion. The wind stirs as you move it."
+ icon_state = "staffofstorms"
+ item_state = "staffofstorms"
+ icon = 'icons/obj/guns/magic.dmi'
+ slot_flags = SLOT_BACK
+ item_state = "staffofstorms"
+ w_class = 4
+ force = 25
+ damtype = BURN
+ hitsound = 'sound/weapons/sear.ogg'
+ var/storm_type = /datum/weather/ash_storm
+ var/storm_cooldown = 0
+
+/obj/item/weapon/staff/storm/attack_self(mob/user)
+ if(storm_cooldown > world.time)
+ to_chat(user, "The staff is still recharging!")
+ return
+
+ var/area/user_area = get_area(user)
+ var/datum/weather/A
+ var/z_level_name = space_manager.levels_by_name[user.z]
+ for(var/V in weather_master.existing_weather)
+ var/datum/weather/W = V
+ if(W.target_z == z_level_name && W.area_type == user_area.type)
+ A = W
+ break
+ if(A)
+
+ if(A.stage != END_STAGE)
+ if(A.stage == WIND_DOWN_STAGE)
+ to_chat(user, "The storm is already ending! It would be a waste to use the staff now.")
+ return
+ user.visible_message("[user] holds [src] skywards as an orange beam travels into the sky!", \
+ "You hold [src] skyward, dispelling the storm!")
+ playsound(user, 'sound/magic/Staff_Change.ogg', 200, 0)
+ A.wind_down()
+ return
+ else
+ A = new storm_type
+ A.name = "staff storm"
+ A.area_type = user_area.type
+ A.target_z = z_level_name
+ A.telegraph_duration = 100
+ A.end_duration = 100
+
+ user.visible_message("[user] holds [src] skywards as red lightning crackles into the sky!", \
+ "You hold [src] skyward, calling down a terrible storm!")
+ playsound(user, 'sound/magic/Staff_Change.ogg', 200, 0)
+ A.telegraph()
+ storm_cooldown = world.time + 200
+
+// Hierophant
+
+//Hierophant
+
+/obj/item/weapon/hierophant_staff
+ name = "Hierophant's staff"
+ desc = "A large club with intense magic power infused into it."
+ icon_state = "hierophant_staff"
+ item_state = "hierophant_staff"
+ icon = 'icons/obj/guns/magic.dmi'
+ slot_flags = SLOT_BACK
+ w_class = 4
+ force = 20
+ hitsound = "swing_hit"
+ //hitsound = 'sound/weapons/sonic_jackhammer.ogg'
+ actions_types = list(/datum/action/item_action/vortex_recall, /datum/action/item_action/toggle_unfriendly_fire)
+ var/cooldown_time = 20 //how long the cooldown between non-melee ranged attacks is
+ var/chaser_cooldown = 101 //how long the cooldown between firing chasers at mobs is
+ var/chaser_timer = 0 //what our current chaser cooldown is
+ var/timer = 0 //what our current cooldown is
+ var/blast_range = 3 //how long the cardinal blast's walls are
+ var/obj/effect/hierophant/rune //the associated rune we teleport to
+ 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/weapon/hierophant_staff/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
+ ..()
+ var/turf/T = get_turf(target)
+ if(!T || timer > world.time)
+ return
+ timer = world.time + CLICK_CD_MELEE //by default, melee attacks only cause melee blasts, and have an accordingly short cooldown
+ if(proximity_flag)
+ spawn(0)
+ aoe_burst(T, user)
+ add_logs(user, target, "fired 3x3 blast at", src)
+ else
+ if(ismineralturf(target) && get_dist(user, target) < 6) //target is minerals, we can hit it(even if we can't see it)
+ spawn(0)
+ cardinal_blasts(T, user)
+ timer = world.time + cooldown_time
+ else if(target in view(5, get_turf(user))) //if the target is in view, hit it
+ timer = world.time + cooldown_time
+ if(isliving(target) && chaser_timer <= world.time) //living and chasers off cooldown? fire one!
+ chaser_timer = world.time + chaser_cooldown
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/chaser, list(get_turf(user), user, target, 1.5, friendly_fire_check))
+ add_logs(user, target, "fired a chaser at", src)
+ else
+ spawn(0)
+ cardinal_blasts(T, user) //otherwise, just do cardinal blast
+ add_logs(user, target, "fired cardinal blast at", src)
+ else
+ to_chat(user, "That target is out of range!") //too far away
+
+/obj/item/weapon/hierophant_staff/ui_action_click(mob/user, actiontype)
+ if(actiontype == /datum/action/item_action/toggle_unfriendly_fire) //toggle friendly fire...
+ friendly_fire_check = !friendly_fire_check
+ to_chat(user, "You toggle friendly fire [friendly_fire_check ? "off":"on"]!")
+ return
+ if(user.get_active_hand() != src && user.get_inactive_hand() != src) //you need to hold the staff to teleport
+ to_chat(user, "You need to hold the staff in your hands to [rune ? "teleport with it" : "create a rune"]!")
+ return
+ if(!rune)
+ if(isturf(user.loc))
+ user.visible_message("[user] holds [src] carefully in front of them, moving it in a strange pattern...", \
+ "You start creating a hierophant rune to teleport to...")
+ timer = world.time + 51
+ if(do_after(user, 50, target = user))
+ var/turf/T = get_turf(user)
+ playsound(T,'sound/magic/Blind.ogg', 200, 1, -4)
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/teleport, list(T, user))
+ var/obj/effect/hierophant/H = new/obj/effect/hierophant(T)
+ rune = H
+ user.update_action_buttons_icon()
+ user.visible_message("[user] creates a strange rune beneath them!", \
+ "You create a hierophant rune, which you can teleport yourself and any allies to at any time!\n\
+ You can remove the rune to place a new one by striking it with the staff.")
+ else
+ timer = world.time
+ else
+ to_chat(user, "You need to be on solid ground to produce a rune!")
+ return
+ if(get_dist(user, rune) <= 2) //rune too close abort
+ to_chat(user, "You are too close to the rune to teleport to it!")
+ return
+ if(is_blocked_turf(get_turf(rune)))
+ to_chat(user, "The rune is blocked by something, preventing teleportation!")
+ return
+ teleporting = TRUE //start channel
+ user.update_action_buttons_icon()
+ user.visible_message("[user] starts to glow faintly...")
+ timer = world.time + 50
+ if(do_after(user, 40, target = user) && rune)
+ var/turf/T = get_turf(rune)
+ var/turf/source = get_turf(user)
+ if(is_blocked_turf(T))
+ teleporting = FALSE
+ to_chat(user, "The rune is blocked by something, preventing teleportation!")
+ user.update_action_buttons_icon()
+ return
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(T, user))
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(source, user))
+ playsound(T,'sound/magic/blink.ogg', 200, 1)
+ //playsound(T,'sound/magic/Wand_Teleport.ogg', 200, 1)
+ playsound(source,'sound/magic/blink.ogg', 200, 1)
+ //playsound(source,'sound/machines/AirlockOpen.ogg', 200, 1)
+ if(!do_after(user, 3, target = user) || !rune) //no walking away shitlord
+ teleporting = FALSE
+ if(user)
+ user.update_action_buttons_icon()
+ return
+ if(is_blocked_turf(T))
+ teleporting = FALSE
+ to_chat(user, "The rune is blocked by something, preventing teleportation!")
+ user.update_action_buttons_icon()
+ return
+ add_logs(user, rune, "teleported self from ([source.x],[source.y],[source.z]) to")
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/teleport, list(T, user))
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/teleport, list(source, user))
+ for(var/t in RANGE_TURFS(1, T))
+ var/obj/effect/overlay/temp/hierophant/blast/B = PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(t, user, TRUE)) //blasts produced will not hurt allies
+ B.damage = 30
+ for(var/t in RANGE_TURFS(1, source))
+ var/obj/effect/overlay/temp/hierophant/blast/B = PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(t, user, TRUE)) //but absolutely will hurt enemies
+ B.damage = 30
+ for(var/mob/living/L in range(1, source))
+ spawn(0)
+ teleport_mob(source, L, T, user) //regardless, take all mobs near us along
+ sleep(6) //at this point the blasts detonate
+ else
+ timer = world.time
+ teleporting = FALSE
+ if(user)
+ user.update_action_buttons_icon()
+
+/obj/item/weapon/hierophant_staff/proc/teleport_mob(turf/source, mob/M, turf/target, mob/user)
+ var/turf/turf_to_teleport_to = get_step(target, get_dir(source, M)) //get position relative to caster
+ if(!turf_to_teleport_to || is_blocked_turf(turf_to_teleport_to))
+ return
+ animate(M, alpha = 0, time = 2, easing = EASE_OUT) //fade out
+ sleep(1)
+ if(!M)
+ return
+ M.visible_message("[M] fades out!")
+ sleep(2)
+ if(!M)
+ return
+ M.forceMove(turf_to_teleport_to)
+ sleep(1)
+ if(!M)
+ return
+ animate(M, alpha = 255, time = 2, easing = EASE_IN) //fade IN
+ sleep(1)
+ if(!M)
+ return
+ M.visible_message("[M] fades in!")
+ if(user != M)
+ add_logs(user, M, "teleported", null, "from ([source.x],[source.y],[source.z])")
+
+/obj/item/weapon/hierophant_staff/proc/cardinal_blasts(turf/T, mob/living/user) //fire cardinal cross blasts with a delay
+ if(!T)
+ return
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/cardinal, list(T, user))
+ playsound(T,'sound/magic/blink.ogg', 200, 1)
+ //playsound(T,'sound/effects/bin_close.ogg', 200, 1)
+ sleep(2)
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(T, user, friendly_fire_check))
+ for(var/d in cardinal)
+ spawn(0)
+ blast_wall(T, d, user)
+
+/obj/item/weapon/hierophant_staff/proc/blast_wall(turf/T, dir, mob/living/user) //make a wall of blasts blast_range tiles long
+ if(!T)
+ return
+ var/range = blast_range
+ var/turf/previousturf = T
+ var/turf/J = get_step(previousturf, dir)
+ for(var/i in 1 to range)
+ if(!J)
+ return
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(J, user, friendly_fire_check))
+ previousturf = J
+ J = get_step(previousturf, dir)
+
+/obj/item/weapon/hierophant_staff/proc/aoe_burst(turf/T, mob/living/user) //make a 3x3 blast around a target
+ if(!T)
+ return
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(T, user))
+ playsound(T,'sound/magic/blink.ogg', 200, 1)
+ //playsound(T,'sound/effects/bin_close.ogg', 200, 1)
+ sleep(2)
+ for(var/t in RANGE_TURFS(1, T))
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(t, user, friendly_fire_check))
\ No newline at end of file
diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm
index 9e4f7289532..06e47411001 100644
--- a/code/modules/mining/mine_items.dm
+++ b/code/modules/mining/mine_items.dm
@@ -2,10 +2,16 @@
//this item is intended to give the effect of entering the mine, so that light gradually fades
/obj/effect/light_emitter
- name = "Light-emtter"
+ name = "Light emtter"
anchored = 1
+ invisibility = 101
unacidable = 1
- light_range = 8
+ var/set_light = 8
+ var/set_cap = 0
+
+/obj/effect/light_emitter/New()
+ ..()
+ set_light(set_light, set_cap)
/**********************Miner Lockers**************************/
diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm
index 6c0b0430e57..62babcaa1bd 100644
--- a/code/modules/mob/living/simple_animal/hostile/hostile.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm
@@ -348,7 +348,7 @@
EscapeConfinement()
for(var/dir in cardinal)
var/turf/T = get_step(targets_from, dir)
- if(istype(T, /turf/simulated/wall) || istype(T, /turf/simulated/mineral))
+ if(iswallturf(T) || ismineralturf(T))
if(T.Adjacent(targets_from))
T.attack_animal(src)
for(var/a in T)
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
new file mode 100644
index 00000000000..88ef094d340
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
@@ -0,0 +1,611 @@
+#define MEDAL_PREFIX "Hierophant"
+/*
+
+The Hierophant
+
+The Hierophant spawns in its arena, an area designed to make it harder to fight than it would otherwise be.
+
+The text this boss speaks is ROT4, use ROT22 to decode
+
+The Hierophant's attacks are as follows, and INTENSIFY at a random chance based on Hierophant's health;
+- Creates a cardinal or diagonal blast(Cross Blast) under its target, exploding after a short time.
+ INTENSITY EFFECT: Creates one of the cross blast types under itself instead of under the target.
+ INTENSITY EFFECT: The created Cross Blast fires in all directions if below half health.
+- If no chasers exist, creates a chaser that will seek its target, leaving a trail of blasts.
+ INTENSITY EFFECT: Creates a second, slower chaser.
+- Creates an expanding AoE burst.
+- INTENSE ATTACKS:
+ If target is at least 2 tiles away; Blinks to the target after a very brief delay, damaging everything near the start and end points.
+ As above, but does so multiple times if below half health.
+ Rapidly creates Cross Blasts under a target.
+ If chasers are off cooldown, creates four high-speed chasers.
+- IF TARGET WAS STRUCK IN MELEE: Creates a 3x3 square of blasts under the target.
+
+Cross Blasts and the AoE burst gain additional range as the Hierophant loses health, while Chasers gain additional speed.
+
+When The Hierophant dies, it leaves behind its staff, which, while much weaker than when wielded by The Hierophant itself, is still quite effective.
+- The staff can place a teleport rune, allowing the user to teleport themself and their allies to the rune.
+
+Difficulty: Hard
+
+*/
+
+/mob/living/simple_animal/hostile/megafauna/hierophant
+ name = "Hierophant"
+ desc = "An ancient, powerful priest-like being wielding a mighty staff."
+ health = 2500
+ maxHealth = 2500
+ attacktext = "clubs"
+ //attack_sound = 'sound/weapons/sonic_jackhammer.ogg'
+ attack_sound = "swing_hit"
+ icon_state = "hierophant"
+ icon_living = "hierophant"
+ friendly = "stares down"
+ icon = 'icons/mob/lavaland/hierophant.dmi'
+ faction = list("boss") //asteroid mobs? get that shit out of my beautiful square house
+ speak_emote = list("preaches")
+ armour_penetration = 50
+ melee_damage_lower = 10
+ melee_damage_upper = 10
+ speed = 1
+ move_to_delay = 10
+ ranged = 1
+ pixel_x = -16
+ ranged_cooldown_time = 40
+ aggro_vision_range = 23
+ loot = list(/obj/item/weapon/hierophant_staff)
+ wander = FALSE
+ var/burst_range = 3 //range on burst aoe
+ var/beam_range = 5 //range on cross blast beams
+ var/chaser_speed = 3 //how fast chasers are currently
+ var/chaser_cooldown = 101 //base cooldown/cooldown var between spawning chasers
+ var/major_attack_cooldown = 60 //base cooldown for major attacks
+ var/blinking = FALSE //if we're doing something that requires us to stand still and not attack
+ var/obj/effect/hierophant/spawned_rune //the rune we teleport back to
+ var/timeout_time = 15 //after this many Life() ticks with no target, we return to our rune
+ var/did_reset = TRUE //if we timed out, returned to our rune, and healed some
+ //var/list/kill_phrases = list("Wsyvgi sj irivkc xettih. Vitemvmrk...", "Irivkc wsyvgi jsyrh. Vitemvmrk...", "Jyip jsyrh. Egxmzexmrk vitemv gcgpiw...")
+ //var/list/target_phrases = list("Xevkix psgexih.", "Iriqc jsyrh.", "Eguymvih xevkix.")
+ medal_type = MEDAL_PREFIX
+ score_type = BIRD_SCORE
+ del_on_death = TRUE
+ death_sound = 'sound/magic/Repulse.ogg'
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/New()
+ ..()
+ internal = new/obj/item/device/gps/internal/hierophant(src)
+ spawned_rune = new(loc)
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/Life()
+ . = ..()
+ if(. && spawned_rune && !client)
+ if(target || loc == spawned_rune.loc)
+ timeout_time = initial(timeout_time)
+ else
+ timeout_time--
+ if(timeout_time <= 0 && !did_reset)
+ did_reset = TRUE
+ //visible_message("\"Vixyvrmrk xs fewi...\"")
+ blink(spawned_rune)
+ adjustHealth(min((health - maxHealth) * 0.5, -50)) //heal for 50% of our missing health
+ wander = FALSE
+ /*if(health > maxHealth * 0.9)
+ visible_message("\"Vitemvw gsqtpixi. Stivexmrk ex qebmqyq ijjmgmirgc.\"")
+ else
+ visible_message("\"Vitemvw gsqtpixi. Stivexmsrep ijjmgmirgc gsqtvsqmwih.\"")*/
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/death()
+ if(health > 0 || stat == DEAD)
+ return
+ else
+ stat = DEAD
+ blinking = TRUE //we do a fancy animation, release a huge burst(), and leave our staff.
+ animate(src, alpha = 0, color = "660099", time = 20, easing = EASE_OUT)
+ burst_range = 10
+ //visible_message("\"Mrmxmexmrk wipj-hiwxvygx wiuyirgi...\"")
+ visible_message("[src] disappears in a massive burst of magic, leaving only its staff.")
+ burst(get_turf(src))
+ ..()
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/Destroy()
+ qdel(spawned_rune)
+ . = ..()
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/devour(mob/living/L)
+ for(var/obj/item/W in L)
+ if(!L.unEquip(W))
+ qdel(W)
+ /*visible_message(
+ "\"[pick(kill_phrases)]\"\n[src] annihilates [L]!",
+ "You annihilate [L], restoring your health!")*/
+ visible_message(
+ "\"Caw.\"\n[src] annihilates [L]!",
+ "You annihilate [L], restoring your health!")
+ adjustHealth(-L.maxHealth*0.5)
+ L.dust()
+
+/*/mob/living/simple_animal/hostile/megafauna/hierophant/GiveTarget(new_target)
+ var/targets_the_same = (new_target == target)
+ . = ..()
+ if(. && target && !targets_the_same)
+ visible_message("\"[pick(target_phrases)]\"")*/
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/adjustHealth(amount)
+ . = ..()
+ if(src && amount > 0 && !blinking)
+ wander = TRUE
+ did_reset = FALSE
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/AttackingTarget()
+ if(!blinking)
+ if(target && isliving(target))
+ spawn(0)
+ melee_blast(get_turf(target)) //melee attacks on living mobs produce a 3x3 blast
+ ..()
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/DestroySurroundings()
+ if(!blinking)
+ ..()
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/Move()
+ if(!blinking)
+ /*if(!stat)
+ playsound(loc, 'sound/mecha/mechmove04.ogg', 150, 1, -4)*/
+ ..()
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/Goto(target, delay, minimum_distance)
+ wander = TRUE
+ if(!blinking)
+ ..()
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/proc/calculate_rage() //how angry we are overall
+ did_reset = FALSE //oh hey we're doing SOMETHING, clearly we might need to heal if we recall
+ anger_modifier = Clamp(((maxHealth - health) / 42),0,50)
+ burst_range = initial(burst_range) + round(anger_modifier * 0.08)
+ beam_range = initial(beam_range) + round(anger_modifier * 0.12)
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/OpenFire()
+ calculate_rage()
+ var/target_is_slow = FALSE
+ if(isliving(target))
+ var/mob/living/L = target
+ if(!blinking && L.stat == DEAD && get_dist(src, L) > 2)
+ blink(L)
+ return
+ if(L.movement_delay() > 1.5)
+ target_is_slow = TRUE
+ chaser_speed = max(1, (3 - anger_modifier * 0.04) + target_is_slow * 0.5)
+ if(blinking)
+ return
+ ranged_cooldown = world.time + max(5, ranged_cooldown_time - anger_modifier * 0.75) //scale cooldown lower with high anger.
+
+ if(prob(anger_modifier * 0.75)) //major ranged attack
+ var/list/possibilities = list()
+ var/cross_counter = 1 + round(anger_modifier * 0.12)
+ if(cross_counter > 1)
+ possibilities += "cross_blast_spam"
+ if(get_dist(src, target) > 2)
+ possibilities += "blink_spam"
+ if(chaser_cooldown < world.time)
+ if(prob(anger_modifier * 2))
+ possibilities = list("chaser_swarm")
+ else
+ possibilities += "chaser_swarm"
+ if(possibilities.len)
+ ranged_cooldown = world.time + max(5, major_attack_cooldown - anger_modifier * 0.75) //we didn't cancel out of an attack, use the higher cooldown
+ var/blink_counter = 1 + round(anger_modifier * 0.08)
+ switch(pick(possibilities))
+ if("blink_spam") //blink either once or multiple times.
+ if(health < maxHealth * 0.5 && !target_is_slow && blink_counter > 1)
+ //visible_message("\"Mx ampp rsx iwgeti.\"")
+ animate(src, color = "#660099", time = 6)
+ while(health && target && blink_counter)
+ if(loc == target.loc || loc == target) //we're on the same tile as them after about a second we can stop now
+ break
+ blink_counter--
+ blinking = FALSE
+ blink(target)
+ blinking = TRUE
+ sleep(5)
+ animate(src, color = initial(color), time = 8)
+ sleep(8)
+ blinking = FALSE
+ else
+ blink(target)
+ if("cross_blast_spam") //fire a lot of cross blasts at a target.
+ //visible_message("\"Piezi mx rsalivi xs vyr.\"")
+ blinking = TRUE
+ animate(src, color = "#660099", time = 6)
+ while(health && target && cross_counter)
+ cross_counter--
+ var/delay = 6
+ if(prob(60))
+ spawn(0)
+ cardinal_blasts(target)
+ else
+ spawn(0)
+ diagonal_blasts(target)
+ delay = 5 //this one isn't so mean, so do the next one faster(if there is one)
+ sleep(delay)
+ animate(src, color = initial(color), time = 8)
+ sleep(8)
+ blinking = FALSE
+ if("chaser_swarm") //fire four fucking chasers at a target and their friends.
+ //visible_message("\"Mx gerrsx lmhi.\"")
+ blinking = TRUE
+ animate(src, color = "#660099", time = 10)
+ var/list/targets = ListTargets()
+ var/list/cardinal_copy = cardinal.Copy()
+ while(health && targets.len && cardinal_copy.len)
+ var/mob/living/pickedtarget = pick(targets)
+ if(targets.len > 4)
+ pickedtarget = pick_n_take(targets)
+ if(pickedtarget.stat == DEAD)
+ pickedtarget = target
+ var/obj/effect/overlay/temp/hierophant/chaser/C = PoolOrNew(/obj/effect/overlay/temp/hierophant/chaser, list(loc, src, pickedtarget, chaser_speed, FALSE))
+ C.moving = 3
+ C.moving_dir = pick_n_take(cardinal_copy)
+ sleep(10)
+ chaser_cooldown = world.time + initial(chaser_cooldown)
+ animate(src, color = initial(color), time = 8)
+ sleep(8)
+ blinking = FALSE
+ return
+
+ if(prob(10 + (anger_modifier * 0.5)) && get_dist(src, target) > 2)
+ blink(target)
+
+ else if(prob(70 - anger_modifier)) //a cross blast of some type
+ if(prob(anger_modifier)) //at us?
+ if(prob(anger_modifier * 2) && health < maxHealth * 0.5) //we're super angry do it at all dirs
+ spawn(0)
+ alldir_blasts(src)
+ else if(prob(60))
+ spawn(0)
+ cardinal_blasts(src)
+ else
+ spawn(0)
+ diagonal_blasts(src)
+ else //at them?
+ if(prob(anger_modifier * 2) && health < maxHealth * 0.5 && !target_is_slow) //we're super angry do it at all dirs
+ spawn(0)
+ alldir_blasts(target)
+ else if(prob(60))
+ spawn(0)
+ cardinal_blasts(target)
+ else
+ spawn(0)
+ diagonal_blasts(target)
+ else if(chaser_cooldown < world.time) //if chasers are off cooldown, fire some!
+ var/obj/effect/overlay/temp/hierophant/chaser/C = PoolOrNew(/obj/effect/overlay/temp/hierophant/chaser, list(loc, src, target, chaser_speed, FALSE))
+ chaser_cooldown = world.time + initial(chaser_cooldown)
+ if((prob(anger_modifier) || target.Adjacent(src)) && target != src)
+ var/obj/effect/overlay/temp/hierophant/chaser/OC = PoolOrNew(/obj/effect/overlay/temp/hierophant/chaser, list(loc, src, target, max(1.5, 5 - anger_modifier * 0.07), FALSE))
+ OC.moving = 4
+ OC.moving_dir = pick(cardinal - C.moving_dir)
+ else //just release a burst of power
+ spawn(0)
+ burst(get_turf(src))
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/proc/diagonal_blasts(mob/victim) //fire diagonal cross blasts with a delay
+ var/turf/T = get_turf(victim)
+ if(!T)
+ return
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/diagonal, list(T, src))
+ playsound(T,'sound/magic/blink.ogg', 200, 1)
+ //playsound(T,'sound/effects/bin_close.ogg', 200, 1)
+ sleep(2)
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(T, src, FALSE))
+ for(var/d in diagonals)
+ spawn(0)
+ blast_wall(T, d)
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/proc/cardinal_blasts(mob/victim) //fire cardinal cross blasts with a delay
+ var/turf/T = get_turf(victim)
+ if(!T)
+ return
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/cardinal, list(T, src))
+ playsound(T,'sound/magic/blink.ogg', 200, 1)
+ //playsound(T,'sound/effects/bin_close.ogg', 200, 1)
+ sleep(2)
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(T, src, FALSE))
+ for(var/d in cardinal)
+ spawn(0)
+ blast_wall(T, d)
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/proc/alldir_blasts(mob/victim) //fire alldir cross blasts with a delay
+ var/turf/T = get_turf(victim)
+ if(!T)
+ return
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(T, src))
+ playsound(T,'sound/magic/blink.ogg', 200, 1)
+ //playsound(T,'sound/effects/bin_close.ogg', 200, 1)
+ sleep(2)
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(T, src, FALSE))
+ for(var/d in alldirs)
+ spawn(0)
+ blast_wall(T, d)
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/proc/blast_wall(turf/T, dir) //make a wall of blasts beam_range tiles long
+ var/range = beam_range
+ var/turf/previousturf = T
+ var/turf/J = get_step(previousturf, dir)
+ for(var/i in 1 to range)
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(J, src, FALSE))
+ previousturf = J
+ J = get_step(previousturf, dir)
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/proc/blink(mob/victim) //blink to a target
+ if(blinking || !victim)
+ return
+ var/turf/T = get_turf(victim)
+ var/turf/source = get_turf(src)
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(T, src))
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(source, src))
+ playsound(T,'sound/magic/blink.ogg', 200, 1)
+ //playsound(T,'sound/magic/Wand_Teleport.ogg', 200, 1)
+ playsound(source,'sound/magic/blink.ogg', 200, 1)
+ //playsound(source,'sound/machines/AirlockOpen.ogg', 200, 1)
+ blinking = TRUE
+ sleep(2) //short delay before we start...
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/teleport, list(T, src))
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/teleport, list(source, src))
+ for(var/t in RANGE_TURFS(1, T))
+ var/obj/effect/overlay/temp/hierophant/blast/B = PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(t, src, FALSE))
+ B.damage = 30
+ for(var/t in RANGE_TURFS(1, source))
+ var/obj/effect/overlay/temp/hierophant/blast/B = PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(t, src, FALSE))
+ B.damage = 30
+ animate(src, alpha = 0, time = 2, easing = EASE_OUT) //fade out
+ sleep(1)
+ visible_message("[src] fades out!")
+ density = FALSE
+ sleep(2)
+ forceMove(T)
+ sleep(1)
+ animate(src, alpha = 255, time = 2, easing = EASE_IN) //fade IN
+ sleep(1)
+ density = TRUE
+ visible_message("[src] fades in!")
+ sleep(1) //at this point the blasts we made detonate
+ blinking = FALSE
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/proc/melee_blast(mob/victim) //make a 3x3 blast around a target
+ if(!victim)
+ return
+ var/turf/T = get_turf(victim)
+ if(!T)
+ return
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(T, src))
+ playsound(T,'sound/magic/blink.ogg', 200, 1)
+ //playsound(T,'sound/effects/bin_close.ogg', 200, 1)
+ sleep(2)
+ for(var/t in RANGE_TURFS(1, T))
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(t, src, FALSE))
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/proc/burst(turf/original) //release a wave of blasts
+ playsound(original,'sound/magic/blink.ogg', 200, 1)
+ //playsound(original,'sound/machines/AirlockOpen.ogg', 200, 1)
+ var/last_dist = 0
+ for(var/t in spiral_range_turfs(burst_range, original))
+ var/turf/T = t
+ if(!T)
+ continue
+ var/dist = get_dist(original, T)
+ if(dist > last_dist)
+ last_dist = dist
+ sleep(1 + (burst_range - last_dist) * 0.5) //gets faster as it gets further out
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(T, src, FALSE))
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/AltClickOn(atom/A) //player control handler(don't give this to a player holy fuck)
+ if(!istype(A) || get_dist(A, src) <= 2)
+ return
+ blink(A)
+
+//Hierophant overlays
+/obj/effect/overlay/temp/hierophant
+ layer = MOB_LAYER - 0.1
+ var/mob/living/caster //who made this, anyway
+
+/obj/effect/overlay/temp/hierophant/New(loc, new_caster)
+ ..()
+ if(new_caster)
+ caster = new_caster
+
+/obj/effect/overlay/temp/hierophant/chaser //a hierophant's chaser. follows target around, moving and producing a blast every speed deciseconds.
+ duration = 98
+ var/mob/living/target //what it's following
+ var/turf/targetturf //what turf the target is actually on
+ var/moving_dir //what dir it's moving in
+ var/previous_moving_dir //what dir it was moving in before that
+ var/more_previouser_moving_dir //what dir it was moving in before THAT
+ var/moving = 0 //how many steps to move before recalculating
+ var/standard_moving_before_recalc = 4 //how many times we step before recalculating normally
+ var/tiles_per_step = 1 //how many tiles we move each step
+ var/speed = 3 //how many deciseconds between each step
+ var/currently_seeking = FALSE
+ var/friendly_fire_check = FALSE //if blasts produced apply friendly fire
+
+/obj/effect/overlay/temp/hierophant/chaser/New(loc, new_caster, new_target, new_speed, is_friendly_fire)
+ ..()
+ target = new_target
+ friendly_fire_check = is_friendly_fire
+ if(new_speed)
+ speed = new_speed
+ spawn(0)
+ seek_target()
+
+/obj/effect/overlay/temp/hierophant/chaser/proc/get_target_dir()
+ . = get_cardinal_dir(src, targetturf)
+ if((. != previous_moving_dir && . == more_previouser_moving_dir) || . == 0) //we're alternating, recalculate
+ var/list/cardinal_copy = cardinal.Copy()
+ cardinal_copy -= more_previouser_moving_dir
+ . = pick(cardinal_copy)
+
+/obj/effect/overlay/temp/hierophant/chaser/proc/seek_target()
+ if(!currently_seeking)
+ currently_seeking = TRUE
+ targetturf = get_turf(target)
+ while(target && src && !qdeleted(src) && currently_seeking && x && y && targetturf) //can this target actually be sook out
+ if(!moving) //we're out of tiles to move, find more and where the target is!
+ more_previouser_moving_dir = previous_moving_dir
+ previous_moving_dir = moving_dir
+ moving_dir = get_target_dir()
+ var/standard_target_dir = get_cardinal_dir(src, targetturf)
+ if((standard_target_dir != previous_moving_dir && standard_target_dir == more_previouser_moving_dir) || standard_target_dir == 0)
+ moving = 1 //we would be repeating, only move a tile before checking
+ else
+ moving = standard_moving_before_recalc
+ if(moving) //move in the dir we're moving in right now
+ var/turf/T = get_turf(src)
+ for(var/i in 1 to tiles_per_step)
+ var/maybe_new_turf = get_step(T, moving_dir)
+ if(maybe_new_turf)
+ T = maybe_new_turf
+ else
+ break
+ forceMove(T)
+ make_blast() //make a blast, too
+ moving--
+ sleep(speed)
+ targetturf = get_turf(target)
+
+/obj/effect/overlay/temp/hierophant/chaser/proc/make_blast()
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(loc, caster, friendly_fire_check))
+
+/obj/effect/overlay/temp/hierophant/telegraph
+ icon = 'icons/effects/96x96.dmi'
+ icon_state = "hierophant_telegraph"
+ pixel_x = -32
+ pixel_y = -32
+ duration = 3
+
+/obj/effect/overlay/temp/hierophant/telegraph/diagonal
+ icon_state = "hierophant_telegraph_diagonal"
+
+/obj/effect/overlay/temp/hierophant/telegraph/cardinal
+ icon_state = "hierophant_telegraph_cardinal"
+
+/obj/effect/overlay/temp/hierophant/telegraph/teleport
+ icon_state = "hierophant_telegraph_teleport"
+ duration = 9
+
+/obj/effect/overlay/temp/hierophant/blast
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "hierophant_blast"
+ name = "vortex blast"
+ luminosity = 1
+ desc = "Get out of the way!"
+ duration = 9
+ var/damage = 10 //how much damage do we do?
+ var/list/hit_things = list() //we hit these already, ignore them
+ var/friendly_fire_check = FALSE
+ var/bursting = FALSE //if we're bursting and need to hit anyone crossing us
+
+/obj/effect/overlay/temp/hierophant/blast/New(loc, new_caster, friendly_fire)
+ ..()
+ friendly_fire_check = friendly_fire
+ if(new_caster)
+ hit_things += new_caster
+ if(ismineralturf(loc)) //drill mineral turfs
+ var/turf/simulated/mineral/M = loc
+ M.gets_drilled(caster)
+ spawn(0)
+ blast()
+
+/obj/effect/overlay/temp/hierophant/blast/proc/blast()
+ var/turf/T = get_turf(src)
+ if(!T)
+ return
+ playsound(T,'sound/magic/Blind.ogg', 125, 1, -5) //make a sound
+ sleep(6) //wait a little
+ bursting = TRUE
+ do_damage(T) //do damage and mark us as bursting
+ sleep(1.3) //slightly forgiving; the burst animation is 1.5 deciseconds
+ bursting = FALSE //we no longer damage crossers
+
+/obj/effect/overlay/temp/hierophant/blast/Crossed(atom/movable/AM)
+ ..()
+ if(bursting)
+ do_damage(get_turf(src))
+
+/obj/effect/overlay/temp/hierophant/blast/proc/do_damage(turf/T)
+ for(var/mob/living/L in T.contents - hit_things) //find and damage mobs...
+ hit_things += L
+ if((friendly_fire_check && caster && caster.faction_check(L)) || L.stat == DEAD)
+ continue
+ if(L.client)
+ flash_color(L.client, "#660099", 1)
+ playsound(L,'sound/weapons/sear.ogg', 50, 1, -4)
+ to_chat(L, "You're struck by a [name]!")
+ var/limb_to_hit = pick("head", "chest", "r_arm", "l_arm", "r_leg", "l_leg")
+ var/armor = L.run_armor_check(limb_to_hit, "melee", "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 50, "Your armor was penetrated by [src]!")
+ L.apply_damage(damage, BURN, limb_to_hit, armor)
+ if(ismegafauna(L) || istype(L, /mob/living/simple_animal/hostile/asteroid))
+ L.adjustBruteLoss(damage)
+ add_logs(caster, L, "struck with a [name]")
+ for(var/obj/mecha/M in T.contents - hit_things) //and mechs.
+ hit_things += M
+ if(M.occupant)
+ if(friendly_fire_check && caster && caster.faction_check(M.occupant))
+ continue
+ to_chat(M.occupant, "Your [M.name] is struck by a [name]!")
+ playsound(M,'sound/weapons/sear.ogg', 50, 1, -4)
+ M.take_damage(damage, BURN, 0, 0)
+
+/obj/effect/hierophant
+ name = "hierophant rune"
+ desc = "A powerful magic mark allowing whomever attunes themself to it to return to it at will."
+ icon = 'icons/obj/rune.dmi'
+ icon_state = "hierophant"
+ layer = 2.5
+ anchored = TRUE
+ color = "#CC00FF"
+
+/obj/effect/hierophant/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/weapon/hierophant_staff))
+ var/obj/item/weapon/hierophant_staff/H = I
+ if(H.rune == src)
+ to_chat(user, "You start removing your hierophant rune...")
+ H.timer = world.time + 51
+ if(do_after(user, 50, target = src))
+ playsound(src,'sound/magic/Blind.ogg', 200, 1, -4)
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/teleport, list(get_turf(src), user))
+ to_chat(user, "You touch the rune with the staff, dispelling it!")
+ H.rune = null
+ user.update_action_buttons_icon()
+ qdel(src)
+ else
+ H.timer = world.time
+ else
+ to_chat(user, "You touch the rune with the staff, but nothing happens.")
+
+ else
+ ..()
+
+/obj/item/device/gps/internal/hierophant
+ icon_state = null
+ gpstag = "Zealous Signal"
+ desc = "Heed its words."
+ invisibility = 100
+
+/turf/simulated/indestructible/hierophant
+ icon_state = "hierophant1"
+ oxygen = 14
+ nitrogen = 23
+ temperature = 300
+ desc = "A floor with a square pattern. It's faintly cool to the touch."
+
+/turf/simulated/indestructible/hierophant/New()
+ ..()
+ if(prob(50))
+ icon_state = "hierophant2"
+
+/turf/unsimulated/indestructible/riveted/hierophant
+ name = "wall"
+ desc = "A wall made out of smooth, cold stone."
+ icon = 'icons/turf/walls/hierophant_wall.dmi'
+ icon_state = "hierophant"
+ smooth = SMOOTH_TRUE
+
+#undef MEDAL_PREFIX
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
index 975f7f0b93c..89119952f60 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
@@ -79,7 +79,8 @@ Difficulty: Medium
minimum_distance = 0
speed = 0
charging = 1
- addtimer(src, "reset_charge", 50)
+ spawn(50)
+ reset_charge()
/mob/living/simple_animal/hostile/megafauna/legion/proc/reset_charge()
ranged = 1
@@ -138,60 +139,4 @@ Difficulty: Medium
desc = "The message repeats."
invisibility = 100
-
-//Loot
-
-/obj/item/weapon/staff/storm
- name = "staff of storms"
- desc = "An ancient staff retrieved from the remains of Legion. The wind stirs as you move it."
- icon_state = "staffofstorms"
- item_state = "staffofstorms"
- icon = 'icons/obj/guns/magic.dmi'
- slot_flags = SLOT_BACK
- item_state = "staffofstorms"
- w_class = 4
- force = 25
- damtype = BURN
- hitsound = 'sound/weapons/sear.ogg'
- var/storm_type = /datum/weather/ash_storm
- var/storm_cooldown = 0
-
-/obj/item/weapon/staff/storm/attack_self(mob/user)
- if(storm_cooldown > world.time)
- to_chat(user, "The staff is still recharging!")
- return
-
- var/area/user_area = get_area(user)
- var/datum/weather/A
- var/z_level_name = space_manager.levels_by_name[user.z]
- for(var/V in weather_master.existing_weather)
- var/datum/weather/W = V
- if(W.target_z == z_level_name && W.area_type == user_area.type)
- A = W
- break
- if(A)
-
- if(A.stage != END_STAGE)
- if(A.stage == WIND_DOWN_STAGE)
- to_chat(user, "The storm is already ending! It would be a waste to use the staff now.")
- return
- user.visible_message("[user] holds [src] skywards as an orange beam travels into the sky!", \
- "You hold [src] skyward, dispelling the storm!")
- playsound(user, 'sound/magic/Staff_Change.ogg', 200, 0)
- A.wind_down()
- return
- else
- A = new storm_type
- A.name = "staff storm"
- A.area_type = user_area.type
- A.target_z = z_level_name
- A.telegraph_duration = 100
- A.end_duration = 100
-
- user.visible_message("[user] holds [src] skywards as red lightning crackles into the sky!", \
- "You hold [src] skyward, calling down a terrible storm!")
- playsound(user, 'sound/magic/Staff_Change.ogg', 200, 0)
- A.telegraph()
- storm_cooldown = world.time + 200
-
#undef MEDAL_PREFIX
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
index c7dd1a24f33..c29a6e8a4f8 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
@@ -1,7 +1,7 @@
#define MEDAL_PREFIX "Boss"
/mob/living/simple_animal/hostile/megafauna
- name = "boss of this gym"
+ name = "megafauna"
desc = "Attack the weak point for massive damage."
health = 1000
maxHealth = 1000
diff --git a/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm
index 4f12bb92270..c50e2dd2944 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining/hivelord.dm
@@ -99,17 +99,17 @@
if(proximity_flag && ishuman(target))
var/mob/living/carbon/human/H = target
if(inert)
- user << "[src] has become inert, its healing properties are no more."
+ to_chat(user, "[src] has become inert, its healing properties are no more.")
return
else
if(H.stat == DEAD)
- user << "[src] are useless on the dead."
+ to_chat(user, "[src] are useless on the dead.")
return
if(H != user)
H.visible_message("[user] forces [H] to apply [src]... They quickly regenerate all injuries!")
feedback_add_details("hivelord_core","[src.type]|used|other")
else
- user << "You start to smear [src] on yourself. It feels and smells disgusting, but you feel amazingly refreshed in mere moments."
+ to_chat(user, "You start to smear [src] on yourself. It feels and smells disgusting, but you feel amazingly refreshed in mere moments.")
feedback_add_details("hivelord_core","[src.type]|used|self")
playsound(src.loc,'sound/items/eatfood.ogg', rand(10,50), 1)
H.revive()
diff --git a/goon/browserassets/css/browserOutput.css b/goon/browserassets/css/browserOutput.css
index dad1ab1a340..8d00fca2d54 100644
--- a/goon/browserassets/css/browserOutput.css
+++ b/goon/browserassets/css/browserOutput.css
@@ -362,3 +362,8 @@ h1.alert, h2.alert {color: #000000;}
/* HELPER CLASSES */
.text-normal {font-weight: normal; font-style: normal;}
.hidden {display: none; visibility: hidden;}
+
+/* MEGAFAUNA */
+.colossus {color: #7F282A; font-size: 5;}
+.hierophant {color: #660099; font-weight: bold; font-size: 4;}
+.hierophant_warning {color: #660099; font-weight: bold; font-style: italic;}
\ No newline at end of file
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index 725d97ce21b..6f8eb8a6f71 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi
index b13c88015cc..9da31cf8814 100644
Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ
diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi
index 4c7a3707efd..721f739ac96 100644
Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ
diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi
index fd5deb0da2c..72636e0a000 100644
Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ
diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi
index 5ff67d8002f..2cc920010f8 100644
Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ
diff --git a/icons/obj/rune.dmi b/icons/obj/rune.dmi
index 901b7466d57..5df6a842ad5 100644
Binary files a/icons/obj/rune.dmi and b/icons/obj/rune.dmi differ
diff --git a/icons/turf/floors.dmi b/icons/turf/floors.dmi
index 7b67484616a..661db4f09bb 100644
Binary files a/icons/turf/floors.dmi and b/icons/turf/floors.dmi differ
diff --git a/icons/turf/walls/hierophant_wall.dmi b/icons/turf/walls/hierophant_wall.dmi
new file mode 100644
index 00000000000..8482970eaf0
Binary files /dev/null and b/icons/turf/walls/hierophant_wall.dmi differ
diff --git a/paradise.dme b/paradise.dme
index b094b194f01..c55cff9a6d9 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -1656,6 +1656,7 @@
#include "code\modules\mob\living\simple_animal\hostile\tree.dm"
#include "code\modules\mob\living\simple_animal\hostile\winter_mobs.dm"
#include "code\modules\mob\living\simple_animal\hostile\megafauna\dragon.dm"
+#include "code\modules\mob\living\simple_animal\hostile\megafauna\hierophant.dm"
#include "code\modules\mob\living\simple_animal\hostile\megafauna\legion.dm"
#include "code\modules\mob\living\simple_animal\hostile\megafauna\megafauna.dm"
#include "code\modules\mob\living\simple_animal\hostile\mining\hivelord.dm"