diff --git a/code/datums/action.dm b/code/datums/action.dm index 6a2f02c2562..043117efb84 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -212,7 +212,7 @@ /datum/action/item_action/toggle_unfriendly_fire name = "Toggle Friendly Fire \[ON\]" - desc = "Toggles if the staff causes friendly fire." + desc = "Toggles if the club's blasts cause friendly fire." button_icon_state = "vortex_ff_on" /datum/action/item_action/toggle_unfriendly_fire/Trigger() @@ -220,8 +220,8 @@ UpdateButtonIcon() /datum/action/item_action/toggle_unfriendly_fire/UpdateButtonIcon() - if(istype(target, /obj/item/hierophant_staff)) - var/obj/item/hierophant_staff/H = target + if(istype(target, /obj/item/hierophant_club)) + var/obj/item/hierophant_club/H = target if(H.friendly_fire_check) button_icon_state = "vortex_ff_off" name = "Toggle Friendly Fire \[OFF\]" @@ -247,12 +247,12 @@ /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." + desc = "Recall yourself, and anyone nearby, to an attuned hierophant beacon at any time.
If the beacon is still attached, will detach it." button_icon_state = "vortex_recall" /datum/action/item_action/vortex_recall/IsAvailable() - if(istype(target, /obj/item/hierophant_staff)) - var/obj/item/hierophant_staff/H = target + if(istype(target, /obj/item/hierophant_club)) + var/obj/item/hierophant_club/H = target if(H.teleporting) return 0 return ..() diff --git a/code/datums/ruins/lavaland.dm b/code/datums/ruins/lavaland.dm index 7fe8ad7248e..bb80fe84d01 100644 --- a/code/datums/ruins/lavaland.dm +++ b/code/datums/ruins/lavaland.dm @@ -124,8 +124,8 @@ datum/map_template/ruin/lavaland/ash_walker id = "hierophant" description = "A strange, square chunk of metal of massive size. Inside awaits only death and many, many squares." suffix = "lavaland_surface_hierophant.dmm" - allow_duplicates = FALSE always_place = TRUE + allow_duplicates = FALSE /datum/map_template/ruin/lavaland/blood_drunk_miner name = "Blood-Drunk Miner" diff --git a/code/game/turfs/simulated/floor/indestructible.dm b/code/game/turfs/simulated/floor/indestructible.dm index 3217a4c7996..adb41ac335e 100644 --- a/code/game/turfs/simulated/floor/indestructible.dm +++ b/code/game/turfs/simulated/floor/indestructible.dm @@ -74,15 +74,16 @@ temperature = T20C /turf/simulated/floor/indestructible/hierophant - icon_state = "hierophant1" + name = "floor" + icon = 'icons/turf/floors/hierophant_floor.dmi' + icon_state = "floor" oxygen = 14 nitrogen = 23 temperature = 300 planetary_atmos = TRUE - desc = "A floor with a square pattern. It's faintly cool to the touch." + smooth = SMOOTH_TRUE /turf/simulated/floor/indestructible/hierophant/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) return FALSE -/turf/simulated/floor/indestructible/hierophant/two - icon_state = "hierophant2" +/turf/simulated/floor/indestructible/hierophant/two \ No newline at end of file diff --git a/code/game/turfs/simulated/walls_indestructible.dm b/code/game/turfs/simulated/walls_indestructible.dm index e25992a2555..8850fbf24fa 100644 --- a/code/game/turfs/simulated/walls_indestructible.dm +++ b/code/game/turfs/simulated/walls_indestructible.dm @@ -29,17 +29,17 @@ return /turf/simulated/wall/indestructible/attackby(obj/item/I, mob/user, params) - return + return /turf/simulated/wall/indestructible/attack_hand(mob/user) - return + return /turf/simulated/wall/indestructible/attack_hulk(mob/user, does_attack_animation = FALSE) return /turf/simulated/wall/indestructible/attack_animal(mob/living/simple_animal/M) return - + /turf/simulated/wall/indestructible/mech_melee_attack(obj/mecha/M) return @@ -66,9 +66,9 @@ /turf/simulated/wall/indestructible/hierophant name = "wall" - desc = "A wall made out of smooth, cold stone." + desc = "A wall made out of a strange metal. The squares on it pulse in a predictable pattern." icon = 'icons/turf/walls/hierophant_wall.dmi' - icon_state = "hierophant" + icon_state = "wall" smooth = SMOOTH_TRUE /turf/simulated/wall/indestructible/uranium diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm index 720be7dda04..972ca9af868 100644 --- a/code/modules/mining/equipment/survival_pod.dm +++ b/code/modules/mining/equipment/survival_pod.dm @@ -341,7 +341,7 @@ /obj/item/shield/changeling, /obj/item/lava_staff, /obj/item/katana/energy, - /obj/item/hierophant_staff, + /obj/item/hierophant_club, /obj/item/storage/toolbox/green/memetic, /obj/item/gun/projectile/automatic/l6_saw, /obj/item/gun/magic/staff/chaos, diff --git a/code/modules/mining/lavaland/loot/hierophant_loot.dm b/code/modules/mining/lavaland/loot/hierophant_loot.dm index 23e894746d2..d7f47baed1d 100644 --- a/code/modules/mining/lavaland/loot/hierophant_loot.dm +++ b/code/modules/mining/lavaland/loot/hierophant_loot.dm @@ -1,115 +1,190 @@ -/obj/item/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' +#define HIEROPHANT_CLUB_CARDINAL_DAMAGE 30 + +/obj/item/hierophant_club + name = "hierophant club" + desc = "The strange technology of this large club allows various nigh-magical feats. It used to beat you, but now you can set the beat." + icon_state = "hierophant_club_ready_beacon" + item_state = "hierophant_club_ready_beacon" + icon = 'icons/obj/lavaland/artefacts.dmi' + lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi' + righthand_file = 'icons/mob/inhands/64x64_righthand.dmi' + inhand_x_dimension = 64 + inhand_y_dimension = 64 slot_flags = SLOT_BACK w_class = WEIGHT_CLASS_BULKY - force = 20 - hitsound = "swing_hit" - //hitsound = 'sound/weapons/sonic_jackhammer.ogg' + force = 15 + attack_verb = list("clubbed", "beat", "pummeled") + 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_cooldown = 81 //how long the cooldown between firing chasers at mobs is var/chaser_timer = 0 //what our current chaser cooldown is + var/chaser_speed = 0.8 //how fast our chasers are 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/blast_range = 13 //how long the cardinal blast's walls are + var/obj/effect/hierophant/beacon //the associated beacon 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/hierophant_staff/afterattack(atom/target, mob/user, proximity_flag, click_parameters) +/obj/item/hierophant_club/examine(mob/user) + ..() + to_chat(user, "The[beacon ? " beacon is not currently":"re is a beacon"] attached.") + +/obj/item/hierophant_club/suicide_act(mob/living/user) + atom_say("Xverwpsgexmrk...") + user.visible_message("[user] holds [src] into the air! It looks like [user.p_theyre()] trying to commit suicide!") + new/obj/effect/temp_visual/hierophant/telegraph(get_turf(user)) + playsound(user,'sound/machines/airlock_open.ogg', 75, TRUE) + user.visible_message("[user] fades out, leaving [user.p_their()] belongings behind!") + for(var/obj/item/I in user) + if(I != src) + user.unEquip(I) + for(var/turf/T in RANGE_TURFS(1, user)) + var/obj/effect/temp_visual/hierophant/blast/B = new(T, user, TRUE) + B.damage = 0 + user.unEquip(src) //Drop us last, so it goes on top of their stuff + qdel(user) + return OBLITERATION + + +/obj/item/hierophant_club/afterattack(atom/target, mob/user, proximity_flag, click_parameters) ..() var/turf/T = get_turf(target) if(!T || timer > world.time) return + calculate_anger_mod(user) 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) + INVOKE_ASYNC(src, .proc/aoe_burst, T, user) add_attack_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) + INVOKE_ASYNC(src, .proc/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 - new /obj/effect/temp_visual/hierophant/chaser(get_turf(user), user, target, 1.5, friendly_fire_check) + var/obj/effect/temp_visual/hierophant/chaser/C = new(get_turf(user), user, target, chaser_speed, friendly_fire_check) + C.damage = 30 + C.monster_damage_boost = FALSE add_attack_logs(user, target, "Fired a chaser at [src]") else - spawn(0) - cardinal_blasts(T, user) //otherwise, just do cardinal blast + INVOKE_ASYNC(src, .proc/cardinal_blasts, T, user) //otherwise, just do cardinal blast add_attack_logs(user, target, "Fired cardinal blast at [src]") else - to_chat(user, "That target is out of range!") //too far away + to_chat(user, "That target is out of range!" ) + timer = world.time + INVOKE_ASYNC(src, .proc/prepare_icon_update) -/obj/item/hierophant_staff/ui_action_click(mob/user, actiontype) +/obj/item/hierophant_club/proc/calculate_anger_mod(mob/user) //we get stronger as the user loses health + chaser_cooldown = initial(chaser_cooldown) + cooldown_time = initial(cooldown_time) + chaser_speed = initial(chaser_speed) + blast_range = initial(blast_range) + if(isliving(user)) + var/mob/living/L = user + var/health_percent = L.health / L.maxHealth + chaser_cooldown += round(health_percent * 20) //two tenths of a second for each missing 10% of health + cooldown_time += round(health_percent * 10) //one tenth of a second for each missing 10% of health + chaser_speed = max(chaser_speed + health_percent, 0.5) //one tenth of a second faster for each missing 10% of health + blast_range -= round(health_percent * 10) //one additional range for each missing 10% of health + +/obj/item/hierophant_club/update_icon() + icon_state = "hierophant_club[timer <= world.time ? "_ready":""][(beacon && !QDELETED(beacon)) ? "":"_beacon"]" + item_state = icon_state + if(ismob(loc)) + var/mob/M = loc + M.update_inv_l_hand() + M.update_inv_r_hand() + M.update_inv_back() + +/obj/item/hierophant_club/proc/prepare_icon_update() + update_icon() + sleep(timer - world.time) + update_icon() + +/obj/item/hierophant_club/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.is_in_active_hand(src) && user.is_in_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"]!") + if(timer > world.time) return - if(!rune) + if(user.is_in_active_hand(src) && user.is_in_inactive_hand(src)) //you need to hold the staff to teleport + to_chat(user, "You need to hold the club in your hands to [beacon ? "teleport with it":"detach the beacon"]!") + return + if(!beacon || QDELETED(beacon)) if(isturf(user.loc)) - user.visible_message("[user] holds [src] carefully in front of [user.p_them()], moving it in a strange pattern...", \ - "You start creating a hierophant rune to teleport to...") + user.visible_message("[user] starts fiddling with [src]'s pommel...", \ + "You start detaching the hierophant beacon...") timer = world.time + 51 - if(do_after(user, 50, target = user)) + INVOKE_ASYNC(src, .proc/prepare_icon_update) + if(do_after(user, 50, target = user) && !beacon) var/turf/T = get_turf(user) - playsound(T,'sound/magic/blind.ogg', 200, 1, -4) + playsound(T,'sound/magic/blind.ogg', 200, TRUE, -4) new /obj/effect/temp_visual/hierophant/telegraph/teleport(T, user) - var/obj/effect/hierophant/H = new/obj/effect/hierophant(T) - rune = H + beacon = new/obj/effect/hierophant(T) user.update_action_buttons_icon() - user.visible_message("[user] creates a strange rune beneath [user.p_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.") + user.visible_message("[user] places a strange machine beneath [user.p_their()] feet!", \ + "You detach the hierophant beacon, allowing you to teleport yourself and any allies to it at any time!\n\ + You can remove the beacon to place it again by striking it with the club.") else timer = world.time + INVOKE_ASYNC(src, .proc/prepare_icon_update) else - to_chat(user, "You need to be on solid ground to produce a rune!") + to_chat(user, "You need to be on solid ground to detach the beacon!") 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!") + if(get_dist(user, beacon) <= 2) //beacon too close abort + to_chat(user, "You are too close to the beacon to teleport to it!") return - if(is_blocked_turf(get_turf(rune))) - to_chat(user, "The rune is blocked by something, preventing teleportation!") + if(is_blocked_turf(get_turf(beacon), TRUE)) + to_chat(user, "The beacon is blocked by something, preventing teleportation!") + return + if(!isturf(user.loc)) + to_chat(user, "You don't have enough space to teleport from here!") 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) + INVOKE_ASYNC(src, .proc/prepare_icon_update) + beacon.icon_state = "hierophant_tele_on" + var/obj/effect/temp_visual/hierophant/telegraph/edge/TE1 = new /obj/effect/temp_visual/hierophant/telegraph/edge(user.loc) + var/obj/effect/temp_visual/hierophant/telegraph/edge/TE2 = new /obj/effect/temp_visual/hierophant/telegraph/edge(beacon.loc) + if(do_after(user, 40, target = user) && user && beacon) + var/turf/T = get_turf(beacon) var/turf/source = get_turf(user) - if(is_blocked_turf(T)) + if(is_blocked_turf(T, TRUE)) teleporting = FALSE - to_chat(user, "The rune is blocked by something, preventing teleportation!") + to_chat(user, "The beacon is blocked by something, preventing teleportation!") user.update_action_buttons_icon() + timer = world.time + INVOKE_ASYNC(src, .proc/prepare_icon_update) + beacon.icon_state = "hierophant_tele_off" return new /obj/effect/temp_visual/hierophant/telegraph(T, user) new /obj/effect/temp_visual/hierophant/telegraph(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 + playsound(T,'sound/magic/wand_teleport.ogg', 200, TRUE) + playsound(source,'sound/machines/airlock_open.ogg', 200, TRUE) + if(!do_after(user, 3, target = user) || !user || !beacon || QDELETED(beacon)) //no walking away shitlord teleporting = FALSE if(user) user.update_action_buttons_icon() + timer = world.time + INVOKE_ASYNC(src, .proc/prepare_icon_update) + if(beacon) + beacon.icon_state = "hierophant_tele_off" return - if(is_blocked_turf(T)) + if(is_blocked_turf(T, TRUE)) teleporting = FALSE - to_chat(user, "The rune is blocked by something, preventing teleportation!") + to_chat(user, "The beacon is blocked by something, preventing teleportation!") user.update_action_buttons_icon() + timer = world.time + INVOKE_ASYNC(src, .proc/prepare_icon_update) + beacon.icon_state = "hierophant_tele_off" return - add_attack_logs(user, rune, "Teleported self from ([source.x],[source.y],[source.z]) to ([T.x],[T.y],[T.z])") + add_attack_logs(user, beacon, "Teleported self from ([AREACOORD(source)]) to ([AREACOORD(beacon)])") new /obj/effect/temp_visual/hierophant/telegraph/teleport(T, user) new /obj/effect/temp_visual/hierophant/telegraph/teleport(source, user) for(var/t in RANGE_TURFS(1, T)) @@ -119,18 +194,24 @@ var/obj/effect/temp_visual/hierophant/blast/B = new /obj/effect/temp_visual/hierophant/blast(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 + INVOKE_ASYNC(src, .proc/teleport_mob, source, L, T, user) //regardless, take all mobs near us along sleep(6) //at this point the blasts detonate + if(beacon) + beacon.icon_state = "hierophant_tele_off" else + qdel(TE1) + qdel(TE2) timer = world.time + INVOKE_ASYNC(src, .proc/prepare_icon_update) + if(beacon) + beacon.icon_state = "hierophant_tele_off" teleporting = FALSE if(user) user.update_action_buttons_icon() -/obj/item/hierophant_staff/proc/teleport_mob(turf/source, mob/M, turf/target, mob/user) +/obj/item/hierophant_club/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)) + if(!turf_to_teleport_to || is_blocked_turf(turf_to_teleport_to, TRUE)) return animate(M, alpha = 0, time = 2, easing = EASE_OUT) //fade out sleep(1) @@ -152,19 +233,19 @@ if(user != M) add_attack_logs(user, M, "Teleported from ([source.x],[source.y],[source.z])") -/obj/item/hierophant_staff/proc/cardinal_blasts(turf/T, mob/living/user) //fire cardinal cross blasts with a delay +/obj/item/hierophant_club/proc/cardinal_blasts(turf/T, mob/living/user) //fire cardinal cross blasts with a delay if(!T) return new /obj/effect/temp_visual/hierophant/telegraph/cardinal(T, user) - playsound(T,'sound/magic/blink.ogg', 200, 1) - //playsound(T,'sound/effects/bin_close.ogg', 200, 1) + playsound(T,'sound/effects/bin_close.ogg', 200, TRUE) sleep(2) - new /obj/effect/temp_visual/hierophant/blast(T, user, friendly_fire_check) + var/obj/effect/temp_visual/hierophant/blast/B = new(T, user, friendly_fire_check) + B.damage = HIEROPHANT_CLUB_CARDINAL_DAMAGE + B.monster_damage_boost = FALSE for(var/d in cardinal) - spawn(0) - blast_wall(T, d, user) + INVOKE_ASYNC(src, .proc/blast_wall, T, d, user) -/obj/item/hierophant_staff/proc/blast_wall(turf/T, dir, mob/living/user) //make a wall of blasts blast_range tiles long +/obj/item/hierophant_club/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 @@ -173,16 +254,20 @@ for(var/i in 1 to range) if(!J) return - new /obj/effect/temp_visual/hierophant/blast(J, user, friendly_fire_check) + var/obj/effect/temp_visual/hierophant/blast/B = new(J, user, friendly_fire_check) + B.damage = HIEROPHANT_CLUB_CARDINAL_DAMAGE + B.monster_damage_boost = FALSE previousturf = J J = get_step(previousturf, dir) -/obj/item/hierophant_staff/proc/aoe_burst(turf/T, mob/living/user) //make a 3x3 blast around a target +/obj/item/hierophant_club/proc/aoe_burst(turf/T, mob/living/user) //make a 3x3 blast around a target if(!T) return new /obj/effect/temp_visual/hierophant/telegraph(T, user) - playsound(T,'sound/magic/blink.ogg', 200, 1) - //playsound(T,'sound/effects/bin_close.ogg', 200, 1) + playsound(T,'sound/effects/bin_close.ogg', 200, TRUE) sleep(2) for(var/t in RANGE_TURFS(1, T)) - new /obj/effect/temp_visual/hierophant/blast(t, user, friendly_fire_check) + var/obj/effect/temp_visual/hierophant/blast/B = new(t, user, friendly_fire_check) + B.damage = 15 //keeps monster damage boost due to lower damage + +#undef HIEROPHANT_CLUB_CARDINAL_DAMAGE \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm index 70c713b37eb..088d8631e77 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -2,124 +2,422 @@ The Hierophant -The Hierophant spawns in its arena, an area designed to make it harder to fight than it would otherwise be. +The Hierophant spawns in its arena, which makes fighting it challenging but not impossible. 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: +The Hierophant's attacks are as follows; +- These attacks happen at a random, increasing chance: 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. + Rapidly creates cardinal and diagonal Cross Blasts under a target. + If chasers are off cooldown, creates 4 chasers. -Cross Blasts and the AoE burst gain additional range as the Hierophant loses health, while Chasers gain additional speed. +- IF TARGET IS OUTSIDE THE ARENA: Creates an arena around the target for 10 seconds, blinking to the target if not in the created arena. + The arena has a 20 second cooldown, giving people a small window to get the fuck out. -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. +- If no chasers exist, creates a chaser that will seek its target, leaving a trail of blasts. + Is more likely to create a second, slower, chaser if hurt. +- If the target is at least 2 tiles away, may Blink to the target after a very brief delay, damaging everything near the start and end points. +- Creates a cardinal or diagonal blast(Cross Blast) under its target, exploding after a short time. + If below half health, the created Cross Blast may fire in all directions. +- Creates an expanding AoE burst. + +- IF ATTACKING IN MELEE: Creates an expanding AoE burst. + +Cross Blasts and the AoE burst gain additional range as Hierophant loses health, while Chasers gain additional speed. + +When Hierophant dies, it stops trying to murder you and shrinks into a small form, which, while much weaker, is still quite effective. +- The smaller club can place a teleport beacon, allowing the user to teleport themself and their allies to the beacon. Difficulty: Hard */ /mob/living/simple_animal/hostile/megafauna/hierophant - name = "Hierophant" - desc = "An ancient, powerful priest-like being wielding a mighty staff." + name = "hierophant" + desc = "A massive metal club that hangs in the air as though waiting. It'll make you dance to its beat." health = 2500 maxHealth = 2500 attacktext = "clubs" - //attack_sound = 'sound/weapons/sonic_jackhammer.ogg' - attack_sound = "swing_hit" + attack_sound = 'sound/weapons/sonic_jackhammer.ogg' icon_state = "hierophant" icon_living = "hierophant" friendly = "stares down" - icon = 'icons/mob/lavaland/hierophant.dmi' + icon = 'icons/mob/lavaland/hierophant_new.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 + melee_damage_lower = 15 + melee_damage_upper = 15 + speed = 10 move_to_delay = 10 - ranged = 1 - pixel_x = -16 + ranged = TRUE ranged_cooldown_time = 40 - aggro_vision_range = 23 - loot = list(/obj/item/hierophant_staff) - crusher_loot = list(/obj/item/hierophant_staff, /obj/item/crusher_trophy/vortex_talisman) + aggro_vision_range = 21 //so it can see to one side of the arena to the other + loot = list(/obj/item/hierophant_club) + crusher_loot = list(/obj/item/hierophant_club, /obj/item/crusher_trophy/vortex_talisman) 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.") internal_type = /obj/item/gps/internal/hierophant medal_type = BOSS_MEDAL_HIEROPHANT score_type = HIEROPHANT_SCORE del_on_death = TRUE death_sound = 'sound/magic/repulse.ogg' + attack_action_types = list(/datum/action/innate/megafauna_attack/blink, + /datum/action/innate/megafauna_attack/chaser_swarm, + /datum/action/innate/megafauna_attack/cross_blasts, + /datum/action/innate/megafauna_attack/blink_spam) + + 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/arena_cooldown = 200 //base cooldown/cooldown var for creating an arena + var/blinking = FALSE //if we're doing something that requires us to stand still and not attack + var/obj/effect/hierophant/spawned_beacon //the beacon we teleport back to + var/timeout_time = 15 //after this many Life() ticks with no target, we return to our beacon + var/did_reset = TRUE //if we timed out, returned to our beacon, and healed some + var/list/kill_phrases = list("Wsyvgi sj irivkc xettih. Vitemvmrk...", "Irivkc wsyvgi jsyrh. Vitemvmrk...", "Jyip jsyrh. Egxmzexmrk vitemv gcgpiw...", "Kix fiex. Liepmrk...") + var/list/target_phrases = list("Xevkix psgexih.", "Iriqc jsyrh.", "Eguymvih xevkix.") + var/list/stored_nearby = list() // stores people nearby the hierophant when it enters the death animation /mob/living/simple_animal/hostile/megafauna/hierophant/Initialize(mapload) . = ..() - spawned_rune = new(loc) + spawned_beacon = new(loc) -/mob/living/simple_animal/hostile/megafauna/hierophant/Life(seconds, times_fired) +/datum/action/innate/megafauna_attack/blink + name = "Blink To Target" + icon_icon = 'icons/mob/actions/actions.dmi' + button_icon_state = "sniper_zoom" + chosen_message = "You are now blinking to your target." + chosen_attack_num = 1 + +/datum/action/innate/megafauna_attack/chaser_swarm + name = "Chaser Swarm" + icon_icon = 'icons/effects/effects.dmi' + button_icon_state = "hierophant_squares_indefinite" + chosen_message = "You are firing a chaser swarm at your target." + chosen_attack_num = 2 + +/datum/action/innate/megafauna_attack/cross_blasts + name = "Cross Blasts" + icon_icon = 'icons/effects/effects.dmi' + button_icon_state = "hierophant_blast_indefinite" + chosen_message = "You are now firing cross blasts at your target." + chosen_attack_num = 3 + +/datum/action/innate/megafauna_attack/blink_spam + name = "Blink Chase" + icon_icon = 'icons/obj/lavaland/artefacts.dmi' + button_icon_state = "hierophant_club_ready_beacon" + chosen_message = "You are now repeatedly blinking at your target." + chosen_attack_num = 4 + +/mob/living/simple_animal/hostile/megafauna/hierophant/OpenFire() + if(blinking) + return + + calculate_rage() + var/blink_counter = 1 + round(anger_modifier * 0.08) + var/cross_counter = 1 + round(anger_modifier * 0.12) + + arena_trap(target) + ranged_cooldown = world.time + max(5, ranged_cooldown_time - anger_modifier * 0.75) //scale cooldown lower with high anger. + + var/target_slowness = 0 + var/mob/living/L + if(isliving(target)) + L = target + target_slowness += L.movement_delay() + if(client) + target_slowness += 1 + + target_slowness = max(target_slowness, 1) + chaser_speed = max(1, (3 - anger_modifier * 0.04) + ((target_slowness - 1) * 0.5)) + + if(client) + switch(chosen_attack) + if(1) + blink(target) + if(2) + chaser_swarm(blink_counter, target_slowness, cross_counter) + if(3) + cross_blast_spam(blink_counter, target_slowness, cross_counter) + if(4) + blink_spam(blink_counter, target_slowness, cross_counter) + return + + if(L?.stat == DEAD && !blinking && get_dist(src, L) > 2) + blink(L) + return + + if(prob(anger_modifier * 0.75)) //major ranged attack + var/list/possibilities = list() + 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) + switch(pick(possibilities)) + if("blink_spam") //blink either once or multiple times. + blink_spam(blink_counter, target_slowness, cross_counter) + if("cross_blast_spam") //fire a lot of cross blasts at a target. + cross_blast_spam(blink_counter, target_slowness, cross_counter) + if("chaser_swarm") //fire four fucking chasers at a target and their friends. + chaser_swarm(blink_counter, target_slowness, cross_counter) + return + + if(chaser_cooldown < world.time) //if chasers are off cooldown, fire some! + var/obj/effect/temp_visual/hierophant/chaser/C = new /obj/effect/temp_visual/hierophant/chaser(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/temp_visual/hierophant/chaser/OC = new(loc, src, target, chaser_speed * 1.5, FALSE) + OC.moving = 4 + OC.moving_dir = pick(cardinal - C.moving_dir) + + else 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 * (2 / target_slowness)) && health < maxHealth * 0.5) //we're super angry do it at all dirs + INVOKE_ASYNC(src, .proc/blasts, target, alldirs) + else if(prob(60)) + INVOKE_ASYNC(src, .proc/blasts, target, cardinal) + else + INVOKE_ASYNC(src, .proc/blasts, target, diagonals) + else //just release a burst of power + INVOKE_ASYNC(src, .proc/burst, get_turf(src)) + +/mob/living/simple_animal/hostile/megafauna/hierophant/proc/blink_spam(var/blink_counter, var/target_slowness, var/cross_counter) + ranged_cooldown = world.time + max(5, major_attack_cooldown - anger_modifier * 0.75) + if(health < maxHealth * 0.5 && blink_counter > 1) + visible_message("\"Mx ampp rsx iwgeti.\"") + var/oldcolor = color + animate(src, color = "#660099", time = 6) + SLEEP_CHECK_DEATH(6) + while(!QDELETED(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_CHECK_DEATH(4 + target_slowness) + animate(src, color = oldcolor, time = 8) + addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 8) + SLEEP_CHECK_DEATH(8) + blinking = FALSE + else + blink(target) + +/mob/living/simple_animal/hostile/megafauna/hierophant/proc/cross_blast_spam(var/blink_counter, var/target_slowness, var/cross_counter) + ranged_cooldown = world.time + max(5, major_attack_cooldown - anger_modifier * 0.75) + visible_message("\"Piezi mx rsalivi xs vyr.\"") + blinking = TRUE + var/oldcolor = color + animate(src, color = "#660099", time = 6) + SLEEP_CHECK_DEATH(6) + while(!QDELETED(target) && cross_counter) + cross_counter-- + if(prob(60)) + INVOKE_ASYNC(src, .proc/blasts, target, cardinal) + else + INVOKE_ASYNC(src, .proc/blasts, target, diagonals) + SLEEP_CHECK_DEATH(6 + target_slowness) + animate(src, color = oldcolor, time = 8) + addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 8) + SLEEP_CHECK_DEATH(8) + blinking = FALSE + + +/mob/living/simple_animal/hostile/megafauna/hierophant/proc/chaser_swarm(var/blink_counter, var/target_slowness, var/cross_counter) + ranged_cooldown = world.time + max(5, major_attack_cooldown - anger_modifier * 0.75) + visible_message("\"Mx gerrsx lmhi.\"") + blinking = TRUE + var/oldcolor = color + animate(src, color = "#660099", time = 6) + SLEEP_CHECK_DEATH(6) + var/list/targets = ListTargets() + var/list/cardinal_copy = cardinal.Copy() + while(targets.len && cardinal_copy.len) + var/mob/living/pickedtarget = pick(targets) + if(targets.len >= cardinal_copy.len) + pickedtarget = pick_n_take(targets) + if(!istype(pickedtarget) || pickedtarget.stat == DEAD) + pickedtarget = target + if(QDELETED(pickedtarget) || (istype(pickedtarget) && pickedtarget.stat == DEAD)) + break //main target is dead and we're out of living targets, cancel out + var/obj/effect/temp_visual/hierophant/chaser/C = new(loc, src, pickedtarget, chaser_speed, FALSE) + C.moving = 3 + C.moving_dir = pick_n_take(cardinal_copy) + SLEEP_CHECK_DEATH(8 + target_slowness) + chaser_cooldown = world.time + initial(chaser_cooldown) + animate(src, color = oldcolor, time = 8) + addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 8) + SLEEP_CHECK_DEATH(8) + blinking = FALSE + +/mob/living/simple_animal/hostile/megafauna/hierophant/proc/blasts(mob/victim, var/list/directions = cardinal) //fires cross blasts with a delay + var/turf/T = get_turf(victim) + if(!T) + return + if(directions == cardinal) + new /obj/effect/temp_visual/hierophant/telegraph/cardinal(T, src) + else if(directions == diagonals) + new /obj/effect/temp_visual/hierophant/telegraph/diagonal(T, src) + else + new /obj/effect/temp_visual/hierophant/telegraph(T, src) + playsound(T,'sound/effects/bin_close.ogg', 200, TRUE) + SLEEP_CHECK_DEATH(2) + new /obj/effect/temp_visual/hierophant/blast(T, src, FALSE) + for(var/d in directions) + INVOKE_ASYNC(src, .proc/blast_wall, T, d) + +/mob/living/simple_animal/hostile/megafauna/hierophant/proc/blast_wall(turf/T, set_dir) //make a wall of blasts beam_range tiles long + var/range = beam_range + var/turf/previousturf = T + var/turf/J = get_step(previousturf, set_dir) + for(var/i in 1 to range) + new /obj/effect/temp_visual/hierophant/blast(J, src, FALSE) + previousturf = J + J = get_step(previousturf, set_dir) + +/mob/living/simple_animal/hostile/megafauna/hierophant/proc/arena_trap(mob/victim) //trap a target in an arena + var/turf/T = get_turf(victim) + if(!istype(victim) || victim.stat == DEAD || !T || arena_cooldown > world.time) + return + if((istype(get_area(T), /area/ruin/unpowered/hierophant) || istype(get_area(src), /area/ruin/unpowered/hierophant)) && victim != src) + return + arena_cooldown = world.time + initial(arena_cooldown) + for(var/d in cardinal) + INVOKE_ASYNC(src, .proc/arena_squares, T, d) + for(var/t in RANGE_TURFS(11, T)) + if(t && get_dist(t, T) == 11) + new /obj/effect/temp_visual/hierophant/wall(t, src) + new /obj/effect/temp_visual/hierophant/blast(t, src, FALSE) + if(get_dist(src, T) >= 11) //hey you're out of range I need to get closer to you! + INVOKE_ASYNC(src, .proc/blink, T) + +/mob/living/simple_animal/hostile/megafauna/hierophant/proc/arena_squares(turf/T, set_dir) //make a fancy effect extending from the arena target + var/turf/previousturf = T + var/turf/J = get_step(previousturf, set_dir) + for(var/i in 1 to 10) + var/obj/effect/temp_visual/hierophant/squares/HS = new(J) + HS.setDir(set_dir) + previousturf = J + J = get_step(previousturf, set_dir) + SLEEP_CHECK_DEATH(0.5) + +/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) + new /obj/effect/temp_visual/hierophant/telegraph(T, src) + new /obj/effect/temp_visual/hierophant/telegraph(source, src) + playsound(T,'sound/magic/wand_teleport.ogg', 200, TRUE) + playsound(source,'sound/machines/airlock_open.ogg', 200, TRUE) + blinking = TRUE + SLEEP_CHECK_DEATH(2) //short delay before we start... + new /obj/effect/temp_visual/hierophant/telegraph/teleport(T, src) + new /obj/effect/temp_visual/hierophant/telegraph/teleport(source, src) + for(var/t in RANGE_TURFS(1, T)) + var/obj/effect/temp_visual/hierophant/blast/B = new(t, src, FALSE) + B.damage = 30 + for(var/t in RANGE_TURFS(1, source)) + var/obj/effect/temp_visual/hierophant/blast/B = new(t, src, FALSE) + B.damage = 30 + animate(src, alpha = 0, time = 2, easing = EASE_OUT) //fade out + SLEEP_CHECK_DEATH(1) + visible_message("[src] fades out!") + density = FALSE + SLEEP_CHECK_DEATH(2) + forceMove(T) + SLEEP_CHECK_DEATH(1) + animate(src, alpha = 255, time = 2, easing = EASE_IN) //fade IN + SLEEP_CHECK_DEATH(1) + density = TRUE + visible_message("[src] fades in!") + SLEEP_CHECK_DEATH(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 + new /obj/effect/temp_visual/hierophant/telegraph(T, src) + playsound(T,'sound/effects/bin_close.ogg', 200, TRUE) + SLEEP_CHECK_DEATH(2) + for(var/t in RANGE_TURFS(1, T)) + new /obj/effect/temp_visual/hierophant/blast(t, src, FALSE) + +//expanding square +/proc/hierophant_burst(mob/caster, turf/original, burst_range, spread_speed = 0.5) + playsound(original,'sound/machines/airlock_open.ogg', 200, TRUE) + 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 + min(burst_range - last_dist, 12) * spread_speed) //gets faster as it gets further out + new /obj/effect/temp_visual/hierophant/blast(T, caster, FALSE) + +/mob/living/simple_animal/hostile/megafauna/hierophant/proc/burst(turf/original, spread_speed) + hierophant_burst(src, original, burst_range, spread_speed) + +/mob/living/simple_animal/hostile/megafauna/hierophant/Life() . = ..() - if(. && spawned_rune && !client) - if(target || loc == spawned_rune.loc) + if(. && spawned_beacon && !QDELETED(spawned_beacon) && !client) + if(target || loc == spawned_beacon.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 + visible_message("\"Vixyvrmrk xs fewi...\"") + blink(spawned_beacon) + adjustHealth(min((health - maxHealth) * 0.5, -250)) //heal for 50% of our missing health, minimum 10% of maximum health wander = FALSE - /*if(health > maxHealth * 0.9) + if(health > maxHealth * 0.9) visible_message("\"Vitemvw gsqtpixi. Stivexmrk ex qebmqyq ijjmgmirgc.\"") else - visible_message("\"Vitemvw gsqtpixi. Stivexmsrep ijjmgmirgc gsqtvsqmwih.\"")*/ + visible_message("\"Vitemvw gsqtpixi. Stivexmsrep ijjmgmirgc gsqtvsqmwih.\"") /mob/living/simple_animal/hostile/megafauna/hierophant/death() - if(!can_die()) - return FALSE - 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)) - // Things are in this order due to `del_on_death` - return ..() + if(health > 0 || stat == DEAD) + return + else + stat = DEAD + blinking = TRUE //we do a fancy animation, release a huge burst(), and leave our staff. + visible_message("\"Mrmxmexmrk wipj-hiwxvygx wiuyirgi...\"") + visible_message("[src] shrinks, releasing a massive burst of energy!") + for(var/mob/living/L in view(7, src)) + stored_nearby += L // store the people to grant the achievements to once we die + hierophant_burst(null, get_turf(src), 10) + stat = CONSCIOUS // deathgasp wont run if dead, stupid + ..(/* force_grant = stored_nearby */) /mob/living/simple_animal/hostile/megafauna/hierophant/Destroy() - QDEL_NULL(spawned_rune) + QDEL_NULL(spawned_beacon) return ..() /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!") + visible_message("\"[pick(kill_phrases)]\"") + visible_message("[src] annihilates [L]!","You annihilate [L], restoring your health!") adjustHealth(-L.maxHealth*0.5) L.dust() @@ -128,24 +426,36 @@ Difficulty: Hard if(istype(the_target, /mob/living/simple_animal/hostile/asteroid/hivelordbrood)) //ignore temporary targets in favor of more permanent targets return FALSE -/*/mob/living/simple_animal/hostile/megafauna/hierophant/GiveTarget(new_target) +/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)]\"")*/ + visible_message("\"[pick(target_phrases)]\"") + if(spawned_beacon && loc == spawned_beacon.loc && did_reset) + arena_trap(src) /mob/living/simple_animal/hostile/megafauna/hierophant/adjustHealth(amount, updating_health = TRUE) . = ..() - if(src && amount > 0 && !blinking) + if(src && . && !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 - return ..() + var/mob/living/L = target + if(L.stat != DEAD) + if(ranged_cooldown <= world.time) + calculate_rage() + ranged_cooldown = world.time + max(5, ranged_cooldown_time - anger_modifier * 0.75) + INVOKE_ASYNC(src, .proc/burst, get_turf(src)) + else + burst_range = 3 + INVOKE_ASYNC(src, .proc/burst, get_turf(src), 0.25) //melee attacks on living mobs cause it to release a fast burst if on cooldown + else + devour(L) + else + return ..() /mob/living/simple_animal/hostile/megafauna/hierophant/DestroySurroundings() if(!blinking) @@ -153,9 +463,16 @@ Difficulty: Hard /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/Moved(oldLoc, movement_dir) + . = ..() + if(!stat && .) + var/obj/effect/temp_visual/hierophant/squares/HS = new(oldLoc) + HS.setDir(movement_dir) + playsound(src, 'sound/mecha/mechmove04.ogg', 150, TRUE, -4) + if(target) + arena_trap(target) /mob/living/simple_animal/hostile/megafauna/hierophant/Goto(target, delay, minimum_distance) wander = TRUE @@ -168,254 +485,59 @@ Difficulty: Hard 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/temp_visual/hierophant/chaser/C = new /obj/effect/temp_visual/hierophant/chaser(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/temp_visual/hierophant/chaser/C = new /obj/effect/temp_visual/hierophant/chaser(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/temp_visual/hierophant/chaser/OC = new /obj/effect/temp_visual/hierophant/chaser(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 - new /obj/effect/temp_visual/hierophant/telegraph/diagonal(T, src) - playsound(T,'sound/magic/blink.ogg', 200, 1) - //playsound(T,'sound/effects/bin_close.ogg', 200, 1) - sleep(2) - new /obj/effect/temp_visual/hierophant/blast(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 - new /obj/effect/temp_visual/hierophant/telegraph/cardinal(T, src) - playsound(T,'sound/magic/blink.ogg', 200, 1) - //playsound(T,'sound/effects/bin_close.ogg', 200, 1) - sleep(2) - new /obj/effect/temp_visual/hierophant/blast(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 - new /obj/effect/temp_visual/hierophant/telegraph(T, src) - playsound(T,'sound/magic/blink.ogg', 200, 1) - //playsound(T,'sound/effects/bin_close.ogg', 200, 1) - sleep(2) - new /obj/effect/temp_visual/hierophant/blast(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) - new /obj/effect/temp_visual/hierophant/blast(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) - new /obj/effect/temp_visual/hierophant/telegraph(T, src) - new /obj/effect/temp_visual/hierophant/telegraph(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... - new /obj/effect/temp_visual/hierophant/telegraph/teleport(T, src) - new /obj/effect/temp_visual/hierophant/telegraph/teleport(source, src) - for(var/t in RANGE_TURFS(1, T)) - var/obj/effect/temp_visual/hierophant/blast/B = new /obj/effect/temp_visual/hierophant/blast(t, src, FALSE) - B.damage = 30 - for(var/t in RANGE_TURFS(1, source)) - var/obj/effect/temp_visual/hierophant/blast/B = new /obj/effect/temp_visual/hierophant/blast(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 - new /obj/effect/temp_visual/hierophant/telegraph(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)) - new /obj/effect/temp_visual/hierophant/blast(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 - new /obj/effect/temp_visual/hierophant/blast(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/temp_visual/hierophant - layer = MOB_LAYER - 0.1 + name = "vortex energy" + layer = BELOW_MOB_LAYER var/mob/living/caster //who made this, anyway -/obj/effect/temp_visual/hierophant/New(loc, new_caster) - ..() +/obj/effect/temp_visual/hierophant/Initialize(mapload, new_caster) + . = ..() if(new_caster) caster = new_caster +/obj/effect/temp_visual/hierophant/squares + icon_state = "hierophant_squares" + duration = 3 + light_range = MINIMUM_USEFUL_LIGHT_RANGE + randomdir = FALSE + +/obj/effect/temp_visual/hierophant/squares/Initialize(mapload, new_caster) + . = ..() + if(ismineralturf(loc)) + var/turf/simulated/mineral/M = loc + M.gets_drilled(caster) + +/obj/effect/temp_visual/hierophant/wall //smoothing and pooling were not friends, but pooling is dead. + name = "vortex wall" + icon = 'icons/turf/walls/hierophant_wall_temp.dmi' + icon_state = "wall" + light_range = MINIMUM_USEFUL_LIGHT_RANGE + duration = 100 + smooth = SMOOTH_TRUE + +/obj/effect/temp_visual/hierophant/wall/Initialize(mapload, new_caster) + . = ..() + queue_smooth_neighbors(src) + queue_smooth(src) + +/obj/effect/temp_visual/hierophant/wall/Destroy() + queue_smooth_neighbors(src) + return ..() + +/obj/effect/temp_visual/hierophant/wall/CanPass(atom/movable/mover, turf/target) + if(QDELETED(caster)) + return FALSE + if(mover == caster.pulledby) + return TRUE + if(istype(mover, /obj/item/projectile)) + var/obj/item/projectile/P = mover + if(P.firer == caster) + return TRUE + if(mover == caster) + return TRUE + return FALSE + /obj/effect/temp_visual/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 @@ -429,15 +551,16 @@ Difficulty: Hard var/speed = 3 //how many deciseconds between each step var/currently_seeking = FALSE var/friendly_fire_check = FALSE //if blasts produced apply friendly fire + var/monster_damage_boost = TRUE + var/damage = 10 -/obj/effect/temp_visual/hierophant/chaser/New(loc, new_caster, new_target, new_speed, is_friendly_fire) - ..() +/obj/effect/temp_visual/hierophant/chaser/Initialize(mapload, 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() + addtimer(CALLBACK(src, .proc/seek_target), 1) /obj/effect/temp_visual/hierophant/chaser/proc/get_target_dir() . = get_cardinal_dir(src, targetturf) @@ -475,7 +598,9 @@ Difficulty: Hard targetturf = get_turf(target) /obj/effect/temp_visual/hierophant/chaser/proc/make_blast() - new /obj/effect/temp_visual/hierophant/blast(loc, caster, friendly_fire_check) + var/obj/effect/temp_visual/hierophant/blast/B = new(loc, caster, friendly_fire_check) + B.damage = damage + B.monster_damage_boost = monster_damage_boost /obj/effect/temp_visual/hierophant/telegraph icon = 'icons/effects/96x96.dmi' @@ -499,132 +624,117 @@ Difficulty: Hard duration = 40 /obj/effect/temp_visual/hierophant/blast - icon = 'icons/effects/effects.dmi' icon_state = "hierophant_blast" name = "vortex blast" - layer = 3.9 // between LYING_MOB_LAYER and ABOVE_MOB_LAYER - luminosity = 1 + light_range = 2 + light_power = 2 desc = "Get out of the way!" duration = 9 var/damage = 10 //how much damage do we do? + var/monster_damage_boost = TRUE //do we deal extra damage to monsters? Used by the boss 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/temp_visual/hierophant/blast/New(loc, new_caster, friendly_fire) - ..() +/obj/effect/temp_visual/hierophant/blast/Initialize(mapload, 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() + INVOKE_ASYNC(src, .proc/blast) /obj/effect/temp_visual/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 + playsound(T,'sound/magic/blind.ogg', 125, TRUE, -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/temp_visual/hierophant/blast/Crossed(atom/movable/AM, oldloc) +/obj/effect/temp_visual/hierophant/blast/Crossed(atom/movable/AM) ..() if(bursting) do_damage(get_turf(src)) /obj/effect/temp_visual/hierophant/blast/proc/do_damage(turf/T) + if(!damage) + return 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_mob(L)) || L.stat == DEAD) continue if(L.client) flash_color(L.client, "#660099", 1) - playsound(L,'sound/weapons/sear.ogg', 50, 1, -4) + playsound(L,'sound/weapons/sear.ogg', 50, TRUE, -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/limb_to_hit = L.get_organ(pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_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)) + if(ishostile(L)) + var/mob/living/simple_animal/hostile/H = L //mobs find and damage you... + if(H.stat == CONSCIOUS && !H.target && H.AIStatus != AI_OFF && !H.client) + if(!QDELETED(caster)) + if(get_dist(H, caster) <= H.aggro_vision_range) + H.FindTarget(list(caster), 1) + else + H.Goto(get_turf(caster), H.move_to_delay, 3) + if(monster_damage_boost && (ismegafauna(L) || istype(L, /mob/living/simple_animal/hostile/asteroid))) L.adjustBruteLoss(damage) - add_attack_logs(caster, L, "Struck with a [name]") - for(var/obj/mecha/M in T.contents - hit_things) //and mechs. + if(caster) + add_attack_logs(caster, L, "Struck with a [name]") + for(var/obj/mecha/M in T.contents - hit_things) //also damage mechs. hit_things += M if(M.occupant) if(friendly_fire_check && caster && caster.faction_check_mob(M.occupant)) continue to_chat(M.occupant, "Your [M.name] is struck by a [name]!") - playsound(M,'sound/weapons/sear.ogg', 50, 1, -4) + playsound(M,'sound/weapons/sear.ogg', 50, TRUE, -4) M.take_damage(damage, BURN, 0, 0) -/obj/effect/temp_visual/hierophant/wall //smoothing and pooling were not friends, but pooling is dead. - name = "vortex wall" - icon = 'icons/turf/walls/hierophant_wall_temp.dmi' - icon_state = "wall" - light_range = MINIMUM_USEFUL_LIGHT_RANGE - duration = 100 - smooth = SMOOTH_TRUE - -/obj/effect/temp_visual/hierophant/wall/New(loc, new_caster) - ..() - queue_smooth_neighbors(src) - queue_smooth(src) - -/obj/effect/temp_visual/hierophant/wall/Destroy() - queue_smooth_neighbors(src) - return ..() - -/obj/effect/temp_visual/hierophant/wall/CanPass(atom/movable/mover, turf/target) - if(QDELETED(caster)) - return FALSE - if(mover == caster.pulledby) - return TRUE - if(istype(mover, /obj/item/projectile)) - var/obj/item/projectile/P = mover - if(P.firer == caster) - return TRUE - if(mover == caster) - return TRUE - return FALSE - - /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 + name = "hierophant beacon" + desc = "A strange beacon, allowing mass teleportation for those able to use it." + icon = 'icons/obj/lavaland/artefacts.dmi' + icon_state = "hierophant_tele_off" + light_range = 2 + layer = LOW_OBJ_LAYER anchored = TRUE - color = "#CC00FF" + +/obj/effect/hierophant/ex_act() + return /obj/effect/hierophant/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/hierophant_staff)) - var/obj/item/hierophant_staff/H = I - if(H.rune == src) - to_chat(user, "You start removing your hierophant rune...") + if(istype(I, /obj/item/hierophant_club)) + var/obj/item/hierophant_club/H = I + if(H.timer > world.time) + return + if(H.beacon == src) + to_chat(user, "You start removing your hierophant beacon...") H.timer = world.time + 51 + INVOKE_ASYNC(H, /obj/item/hierophant_club.proc/prepare_icon_update) if(do_after(user, 50, target = src)) - playsound(src,'sound/magic/blind.ogg', 200, 1, -4) + playsound(src,'sound/magic/blind.ogg', 200, TRUE, -4) new /obj/effect/temp_visual/hierophant/telegraph/teleport(get_turf(src), user) - to_chat(user, "You touch the rune with the staff, dispelling it!") - H.rune = null + to_chat(user, "You collect [src], reattaching it to the club!") + H.beacon = null user.update_action_buttons_icon() qdel(src) else H.timer = world.time + INVOKE_ASYNC(H, /obj/item/hierophant_club.proc/prepare_icon_update) else - to_chat(user, "You touch the rune with the staff, but nothing happens.") - + to_chat(user, "You touch the beacon with the club, but nothing happens.") else - ..() + return ..() /obj/item/gps/internal/hierophant icon_state = null gpstag = "Zealous Signal" desc = "Heed its words." - invisibility = 100 + invisibility = 100 \ No newline at end of file diff --git a/goon/browserassets/css/browserOutput-dark.css b/goon/browserassets/css/browserOutput-dark.css index 426493dfc88..c3d7915c818 100644 --- a/goon/browserassets/css/browserOutput-dark.css +++ b/goon/browserassets/css/browserOutput-dark.css @@ -404,8 +404,8 @@ h1.alert, h2.alert {color: #FFF;} /* MEGAFAUNA */ .colossus {color: #7F282A; font-size: 175%;} -.hierophant {color: #660099; font-weight: bold; font-size: 150%;} -.hierophant_warning {color: #660099; font-weight: bold; font-style: italic;} +.hierophant {color: #660099; font-weight: bold; font-style: italic;} +.hierophant_warning {color: #660099; font-style: italic;} /* EMOJI STUFF */ .emoji {max-height: 16px; max-width: 16px} diff --git a/goon/browserassets/css/browserOutput.css b/goon/browserassets/css/browserOutput.css index 07ae914de62..62dd8b2714b 100644 --- a/goon/browserassets/css/browserOutput.css +++ b/goon/browserassets/css/browserOutput.css @@ -401,8 +401,8 @@ h1.alert, h2.alert {color: #000000;} /* MEGAFAUNA */ .colossus {color: #7F282A; font-size: 175%;} -.hierophant {color: #660099; font-weight: bold; font-size: 150%;} -.hierophant_warning {color: #660099; font-weight: bold; font-style: italic;} +.hierophant {color: #660099; font-weight: bold; font-style: italic;} +.hierophant_warning {color: #660099; font-style: italic;} /* EMOJI STUFF */ .emoji {max-height: 16px; max-width: 16px} diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index 89f57b2517d..7e1bb227ef3 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index 36025c083b4..2e3c9f7cae0 100644 Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ diff --git a/icons/mob/inhands/64x64_lefthand.dmi b/icons/mob/inhands/64x64_lefthand.dmi index 69b9922f140..f0b5ec6f0e7 100644 Binary files a/icons/mob/inhands/64x64_lefthand.dmi and b/icons/mob/inhands/64x64_lefthand.dmi differ diff --git a/icons/mob/inhands/64x64_righthand.dmi b/icons/mob/inhands/64x64_righthand.dmi index 09cef64e2b0..36f930193d2 100644 Binary files a/icons/mob/inhands/64x64_righthand.dmi and b/icons/mob/inhands/64x64_righthand.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index 7d0961fc449..3a0c32e68b4 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 5850e4d8d8c..6cf43537d88 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/mob/lavaland/hierophant_new.dmi b/icons/mob/lavaland/hierophant_new.dmi new file mode 100644 index 00000000000..84348700324 Binary files /dev/null and b/icons/mob/lavaland/hierophant_new.dmi differ diff --git a/icons/obj/lavaland/artefacts.dmi b/icons/obj/lavaland/artefacts.dmi index 8e91b20368f..bc95bbc1fe3 100644 Binary files a/icons/obj/lavaland/artefacts.dmi and b/icons/obj/lavaland/artefacts.dmi differ diff --git a/icons/turf/floors/hierophant_floor.dmi b/icons/turf/floors/hierophant_floor.dmi new file mode 100644 index 00000000000..365f887bfa4 Binary files /dev/null and b/icons/turf/floors/hierophant_floor.dmi differ diff --git a/icons/turf/walls/hierophant_wall.dmi b/icons/turf/walls/hierophant_wall.dmi index c51880ddef2..8963db4e996 100644 Binary files a/icons/turf/walls/hierophant_wall.dmi and b/icons/turf/walls/hierophant_wall.dmi differ