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