diff --git a/code/modules/admin/verbs/deadsay.dm b/code/modules/admin/verbs/deadsay.dm
index 19cc6dd5667..00a51054c80 100644
--- a/code/modules/admin/verbs/deadsay.dm
+++ b/code/modules/admin/verbs/deadsay.dm
@@ -26,7 +26,7 @@
for (var/mob/M in player_list)
if (istype(M, /mob/new_player))
continue
- if (M.stat == DEAD || (M.client && M.client.holder && (M.client.prefs.chat_toggles & CHAT_DEAD))) //admins can toggle deadchat on and off. This is a proc in admin.dm and is only give to Administrators and above
+ if (M.stat == DEAD || istype(M, /mob/living/simple_animal/revenant) || (M.client && M.client.holder && (M.client.prefs.chat_toggles & CHAT_DEAD))) //admins can toggle deadchat on and off. This is a proc in admin.dm and is only give to Administrators and above
M.show_message(rendered, 2)
feedback_add_details("admin_verb","D") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/revenant/revenant.dm b/code/modules/mob/living/simple_animal/revenant/revenant.dm
index 1bb8c995e60..c90283d76ba 100644
--- a/code/modules/mob/living/simple_animal/revenant/revenant.dm
+++ b/code/modules/mob/living/simple_animal/revenant/revenant.dm
@@ -3,17 +3,19 @@
//Don't hear deadchat and are NOT normal ghosts
//Admin-spawn or random event
+#define INVISIBILITY_REVENANT 30
+
/mob/living/simple_animal/revenant
name = "revenant"
desc = "A malevolent spirit."
icon = 'icons/mob/mob.dmi'
icon_state = "revenant_idle"
incorporeal_move = 3
- invisibility = INVISIBILITY_OBSERVER
+ invisibility = INVISIBILITY_REVENANT
health = 25
maxHealth = 25
healable = 0
- see_invisible = SEE_INVISIBLE_OBSERVER
+ see_invisible = INVISIBILITY_REVENANT
languages = ALL
response_help = "passes through"
response_disarm = "swings at"
@@ -137,7 +139,8 @@
if(target) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining.
change_essence_amount(essence_drained * 5, 0, target)
src << "[target]'s soul has been considerably weakened and will yield no more essence for the time being."
- target.visible_message("[target] gently slumps back onto the ground.")
+ target.visible_message("[target] slumps onto the ground.", \
+ "Violets lights, dancing in your vision, getting clo--")
drained_mobs.Add(target)
target.death(0)
icon_state = "revenant_idle"
@@ -150,7 +153,10 @@
/mob/living/simple_animal/revenant/say(message)
- return 0 //Revenants cannot speak out loud.
+ for(var/mob/M in mob_list)
+ if(istype(M, /mob/living/simple_animal/revenant) || M.stat == DEAD)
+ M << "REVENANT: [src] says, \"[message]\"" //Can commune with the dead
+ return
/mob/living/simple_animal/revenant/Stat()
..()
@@ -182,14 +188,16 @@
src.mind.objectives += objective2
src << "Objective #2: [objective2.explanation_text]"
ticker.mode.traitors |= src.mind //Necessary for announcing
- mob_spell_list += new /obj/effect/proc_holder/spell/targeted/revenant_transmit
- mob_spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_light
- mob_spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_defile
- mob_spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_malf
+ AddSpell(new /obj/effect/proc_holder/spell/targeted/revenant_transmit(null))
+ AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant_light(null))
+ AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant_defile(null))
+ AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant_malf(null))
/mob/living/simple_animal/revenant/death()
+ if(!revealed) //Revenants cannot die if they aren't revealed
+ return 0
..(1)
- src << "NO! No... it's too late, you can feel yourself fading..."
+ src << "NO! No... it's too late, you can feel yourself fading..."
notransform = 1
revealed = 1
invisibility = 0
@@ -199,8 +207,9 @@
for(var/i = alpha, i > 0, i -= 10)
sleep(0.1)
alpha = i
- visible_message("[src]'s body breaks apart into blue dust.")
- new /obj/item/weapon/ectoplasm/revenant(get_turf(src))
+ visible_message("[src]'s body breaks apart into a fine pile of blue dust.")
+ var/obj/item/weapon/ectoplasm/revenant/R = new (get_turf(src))
+ R.client_to_revive = src.client //If the essence reforms, the old revenant is put back in the body
ghostize()
qdel(src)
return
@@ -209,7 +218,7 @@
/mob/living/simple_animal/revenant/attackby(obj/item/W, mob/living/user, params)
if(istype(W, /obj/item/weapon/nullrod))
visible_message("[src] violently flinches!", \
- "As the null rod passes through you, you feel your essence draining away!")
+ "As the null rod passes through you, you feel your essence draining away!")
essence -= 25 //hella effective
inhibited = 1
spawn(30)
@@ -263,7 +272,7 @@
src << "You have been revealed."
spawn(time)
revealed = 0
- invisibility = INVISIBILITY_OBSERVER
+ invisibility = INVISIBILITY_REVENANT
src << "You are once more concealed."
/mob/living/simple_animal/revenant/proc/stun(time)
@@ -323,7 +332,8 @@
icon_state = "revenantEctoplasm"
w_class = 2
var/reforming = 0
- var/reformed = 0
+ var/inert = 0
+ var/client/client_to_revive
/obj/item/weapon/ectoplasm/revenant/New()
..()
@@ -332,17 +342,12 @@
if(src && reforming)
return reform()
if(src && !reforming)
+ reforming = 1
visible_message("[src] settles down and seems lifeless.")
return
-/obj/item/weapon/ectoplasm/revenant/attack_hand(mob/user)
- if(reformed)
- user << "[src] keeps slipping out of your hands, you can't get a hold on it!"
- return
- ..()
-
/obj/item/weapon/ectoplasm/revenant/attack_self(mob/user)
- if(!reforming)
+ if(!reforming || inert)
return ..()
user.visible_message("[user] scatters [src] in all directions.", \
"You scatter [src] across the area. The particles slowly fade away.")
@@ -351,6 +356,8 @@
/obj/item/weapon/ectoplasm/revenant/throw_impact(atom/hit_atom)
..()
+ if(inert)
+ return
visible_message("[src] breaks into particles upon impact, which fade away to nothingness.")
qdel(src)
@@ -364,20 +371,29 @@
/obj/item/weapon/ectoplasm/revenant/proc/reform()
if(!reforming || !src)
return
+ var/key_of_revenant
message_admins("Revenant ectoplasm was left undestroyed for 1 minute and has reformed into a new revenant.")
loc = get_turf(src) //In case it's in a backpack or someone's hand
visible_message("[src] suddenly rises into the air before fading away.")
var/mob/living/simple_animal/revenant/R = new(get_turf(src))
- qdel(src)
- var/list/candidates = get_candidates(BE_REVENANT)
- if(!candidates.len)
- message_admins("No candidates were found for the new revenant. Oh well!")
- return 0
- var/client/C = pick(candidates)
- var/key_of_revenant = C.key
- if(!key_of_revenant)
- message_admins("No ckey was found for the new revenant. Oh well!")
- return 0
+ if(client_to_revive)
+ for(var/mob/M in mob_list)
+ if(M.client == client_to_revive && M.stat == DEAD) //Only recreates the mob if the mob the client is in is dead
+ message_admins("[R.client] was a revenant and died. Re-making them into the new revenant formed by ectoplasm.")
+ R.client = client_to_revive
+ key_of_revenant = client_to_revive.key
+ break
+ message_admins("The new revenant's old client either could not be found or is in a new, living mob - grabbing a random candidate instead...")
+ else
+ var/list/candidates = get_candidates(BE_REVENANT)
+ if(!candidates.len)
+ message_admins("No candidates were found for the new revenant. Oh well!")
+ return 0
+ var/client/C = pick(candidates)
+ key_of_revenant = C.key
+ if(!key_of_revenant)
+ message_admins("No ckey was found for the new revenant. Oh well!")
+ return 0
var/datum/mind/player_mind = new /datum/mind(key_of_revenant)
player_mind.active = 1
player_mind.transfer_to(R)
@@ -386,4 +402,7 @@
ticker.mode.traitors |= player_mind
message_admins("[key_of_revenant] has been made into a revenant by reforming ectoplasm.")
log_game("[key_of_revenant] was spawned as a revenant by reforming ectoplasm.")
+ qdel(src)
+ if(src) //Should never happen, but just in case
+ inert = 1
return 1
diff --git a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm
index 6de716e3180..e577c84c52f 100644
--- a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm
+++ b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm
@@ -7,6 +7,8 @@
clothes_req = 0
range = 7
include_user = 0
+ action_icon_state = "r_transmit"
+ action_background_icon_state = "bg_revenant"
/obj/effect/proc_holder/spell/targeted/revenant_transmit/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
for(var/mob/living/M in targets)
@@ -16,7 +18,7 @@
charge_counter = charge_max
return
usr << "You transmit to [M]: [msg]"
- M << "A strange voice resonates in your head... [msg]"
+ M << "An alien voice resonates from all around... [msg]"
//Overload Light: Breaks a light that's online and sends out lightning bolts to all nearby people.
@@ -30,6 +32,8 @@
var/reveal = 80
var/stun = 20
var/locked = 1
+ action_icon_state = "overload_lights"
+ action_background_icon_state = "bg_revenant"
/obj/effect/proc_holder/spell/aoe_turf/revenant_light/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
if(locked)
@@ -40,7 +44,7 @@
name = "Overload Lights (20E)"
panel = "Revenant Abilities"
locked = 0
- range = 6
+ range = 2
charge_counter = charge_max
return
if(!user.castcheck(-20))
@@ -58,7 +62,7 @@
s.set_up(4, 1, L)
s.start()
sleep(10)
- for(var/mob/living/M in orange(4, L))
+ for(var/mob/living/M in range(4, L))
if(M == user)
return
M.Beam(L,icon_state="lightning",icon='icons/effects/effects.dmi',time=5)
@@ -73,8 +77,8 @@
//Defile: Corrupts nearby stuff, unblesses floor tiles.
/obj/effect/proc_holder/spell/aoe_turf/revenant_defile
- name = "Defile (35E)"
- desc = "Twists and corrupts the nearby area. Also dispels holy auras on floors, but not salt lines."
+ name = "Defile (20E)"
+ desc = "Twists and corrupts the nearby area. Also dispels holy auras on floors."
panel = "Revenant Abilities (Locked)"
charge_max = 200
clothes_req = 0
@@ -82,6 +86,8 @@
var/reveal = 100
var/stun = 20
var/locked = 1
+ action_icon_state = "defile"
+ action_background_icon_state = "bg_revenant"
/obj/effect/proc_holder/spell/aoe_turf/revenant_defile/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
if(locked)
@@ -89,7 +95,7 @@
charge_counter = charge_max
return
user << "You have unlocked Defile!"
- name = "Defile (20E)"
+ name = "Defile (10E)"
panel = "Revenant Abilities"
locked = 0
range = 3
@@ -102,10 +108,6 @@
spawn(0)
if(T.flags & NOJAUNT)
T.flags -= NOJAUNT
- if(!istype(T, /turf/simulated/wall/cult) && istype(T, /turf/simulated/wall) && prob(40))
- T.ChangeTurf(/turf/simulated/wall/cult)
- if(!istype(T, /turf/simulated/floor/engine/cult) && istype(T, /turf/simulated/floor) && prob(40))
- T.ChangeTurf(/turf/simulated/floor/engine/cult)
for(var/mob/living/carbon/human/human in T.contents)
human << "You suddenly feel tired."
human.adjustStaminaLoss(35)
@@ -128,6 +130,8 @@
var/reveal = 60
var/stun = 30
var/locked = 1
+ action_icon_state = "malfunction"
+ action_background_icon_state = "bg_revenant"
/obj/effect/proc_holder/spell/aoe_turf/revenant_malf/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
if(locked)
@@ -152,8 +156,19 @@
bot.open = 1
bot.Emag(null)
for(var/obj/machinery/mach in T.contents)
+ if(istype(mach, /obj/machinery/dominator)) //Doesn't work on dominators, to prevent kekkery
+ continue
if(prob(10))
mach.emag_act(null)
- empulse(user.loc, 3, 5)
+ else
+ mach.emp_act(1)
+ for(var/mob/living/silicon/robot/S in T.contents) //Only works on cyborgs, not AI
+ S << "ERROR $!(@ ERROR )#^! SENSORY OVERLOAD \[$(!@#"
+ S << 'sound/misc/interference.ogg'
+ playsound(S, 'sound/machines/warning-buzzer.ogg', 50, 1)
+ var/datum/effect/effect/system/spark_spread/sp = new /datum/effect/effect/system/spark_spread
+ sp.set_up(5, 1, S)
+ sp.start()
+ S.Weaken(6)
user.reveal(reveal)
user.stun(stun)
\ No newline at end of file
diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi
index 0f816bf5e99..c1ffea30969 100644
Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ
diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi
index 76d807e61d8..fb295a1cf5d 100644
Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ