This commit is contained in:
Fox-McCloud
2015-06-13 20:10:02 -04:00
parent b3a585172a
commit 09097b38ed
10 changed files with 430 additions and 3 deletions
+2 -1
View File
@@ -134,7 +134,8 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Vermin Infestation",/datum/event/infestation, 100, list(ASSIGNMENT_JANITOR = 100)),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Wallrot", /datum/event/wallrot, 0, list(ASSIGNMENT_ENGINEER = 30, ASSIGNMENT_GARDENER = 50)),
// NON-BAY EVENTS
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Cargo Bonus", /datum/event/cargo_bonus, 100)
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Cargo Bonus", /datum/event/cargo_bonus, 100),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Revenant", /datum/event/revenant, 50)
)
/datum/event_container/moderate
+1
View File
@@ -50,6 +50,7 @@ var/global/list/possibleEvents = list()
//possibleEvents[/datum/event/mundane_news] = 300
possibleEvents[/datum/event/cargo_bonus] = 150
possibleEvents[/datum/event/revenant] = 75
possibleEvents[/datum/event/pda_spam] = max(min(25, player_list.len) * 4, 200)
possibleEvents[/datum/event/money_lotto] = max(min(5, player_list.len), 50)
@@ -0,0 +1,199 @@
//Revenants: based off of wraiths from Goon
//"Ghosts" that are invisible and move like ghosts, cannot take damage while invsible
//Don't hear deadchat and are NOT normal ghosts
//Admin-spawn or random event
/mob/living/simple_animal/revenant
name = "revenant"
desc = "A malevolent spirit."
icon = 'icons/mob/mob.dmi'
icon_state = "revenant_idle"
incorporeal_move = 1
invisibility = INVISIBILITY_OBSERVER
health = 25
maxHealth = 25
see_in_dark = 255
see_invisible = SEE_INVISIBLE_OBSERVER
universal_understand = 1
response_help = "passes through"
response_disarm = "swings at"
response_harm = "punches"
minbodytemp = 0
maxbodytemp = INFINITY
harm_intent_damage = 5
speak_emote = list("hisses", "spits", "growls")
friendly = "touches"
status_flags = 0
wander = 0
density = 0
var/essence = 25 //The resource of revenants. Max health is equal to twice this amount
var/essence_regen_cap = 25 //The regeneration cap of essence (go figure); regenerates every Life() tick up to this amount.
var/essence_regen = 1 //If the revenant regenerates essence or not; 1 for yes, 0 for no
var/essence_min = 1 //The minimum amount of essence a revenant can have; by default, it never drops below one
var/strikes = 3 //How many times a revenant can die before dying for good
var/revealed = 0 //If the revenant can take damage from normal sources.
var/inhibited = 0 //If the revenant's abilities are blocked by a chaplain's power.
/mob/living/simple_animal/revenant/Life()
..()
if(essence < essence_min)
essence = essence_min
if(strikes > 0)
strikes--
src << "<span class='boldannounce'>Your essence has dropped below critical levels. You barely manage to save yourself - [strikes ? "you can't keep this up!" : "next time, it's death."]</span>"
else if(strikes <= 0)
src << "<span class='userdanger'><b>NO! No... it's too late, you can feel yourself fading...</b></span>"
src.notransform = 1
src.revealed = 1
src.invisibility = 0
playsound(src, 'sound/effects/screech.ogg', 100, 1)
src.visible_message("<b>The revenant</b> lets out a waning screech as violet mist swirls around its dissolving body!")
src.icon_state = "revenant_draining"
sleep(30)
src.death()
maxHealth = essence * 2
if(!revealed)
health = maxHealth //Heals to full when not revealed
if(essence_regen && !inhibited && essence < essence_regen_cap) //While inhibited, essence will not regenerate
essence++
/mob/living/simple_animal/revenant/Process_Spacemove(var/check_drift = 0)
return 1 //Mainly to prevent the no-grav effect
/mob/living/simple_animal/revenant/ex_act(severity)
return 1 //Immune to the effects of explosions.
/mob/living/simple_animal/revenant/ClickOn(var/atom/A, var/params) //Copypaste from ghost code - revenants can't interact with the world directly.
if(client.buildmode)
build_click(src, client.buildmode, params, A)
return
var/list/modifiers = params2list(params)
if(modifiers["middle"])
MiddleClickOn(A)
return
if(modifiers["shift"])
ShiftClickOn(A)
return
if(modifiers["alt"])
AltClickOn(A)
return
if(modifiers["ctrl"])
CtrlClickOn(A)
return
if(world.time <= next_move)
return
A.attack_ghost(src)
/mob/living/simple_animal/revenant/say(message)
return 0 //Revenants cannot speak out loud.
/mob/living/simple_animal/revenant/Stat()
..()
if(statpanel("Status"))
stat(null, "Current essence: [essence]E")
/mob/living/simple_animal/revenant/New()
..()
spawn(5)
if(src.mind)
src << 'sound/effects/ghost.ogg'
src.store_memory("<span class='deadsay'>I am a revenant. My spectral form has been empowered. My only goal is to gather essence from the humans of [world.name].</span>")
src << "<br>"
src << "<span class='deadsay'><font size=3><b>You are a revenant!</b></font></span>"
src << "<b>Your formerly mundane spirit has been infused with alien energies and empowered into a revenant.</b>"
src << "<b>You are not dead, not alive, but somewhere in between. You are capable of very limited interaction with both worlds.</b>"
src << "<b>You are invincible and invisible to everyone but other ghosts. Some abilities may change this.</b>"
src << "<b>Your goal is to gather essence from humans. Your essence passively regenerates up to 25E over time. You can use the Harvest abilities to gather more from corpses.</b>"
src << "<b>Be sure to read the wiki page at https://tgstation13.org/wiki/Revenant !</b>"
src << "<br>"
if(!src.giveSpells())
message_admins("Revenant was created but has no mind. Trying again in five seconds.")
spawn(50)
if(!src.giveSpells())
message_admins("Revenant still has no mind. Deleting...")
qdel(src)
/mob/living/simple_animal/revenant/proc/giveSpells()
if(src.mind)
src.mind.spell_list += new /obj/effect/proc_holder/spell/wizard/targeted/revenant_harvest
src.mind.spell_list += new /obj/effect/proc_holder/spell/wizard/targeted/revenant_transmit
src.mind.spell_list += new /obj/effect/proc_holder/spell/wizard/aoe_turf/revenant_light
return 1
return 0
/mob/living/simple_animal/revenant/death()
if(!strikes)
return 0 //Impossible to die with strikes still active
..(1)
reveal(10, 1)
visible_message("<span class='danger'>[src] pulses with an eldritch purple light as its form unwinds into smoke.</span>")
ghostize()
qdel(src)
return
/mob/living/simple_animal/revenant/attackby(obj/item/W, mob/living/user, params)
..()
if(istype(W, /obj/item/weapon/nullrod))
src.visible_message("<b>The revenant</b> screeches and flails!", \
"<span class='boldannounce'>The null rod invokes agony in you! You feel your essence draining away!</span>")
src.essence -= 25 //hella effective
src.inhibited = 1
spawn(30)
src.inhibited = 0
/obj/effect/proc_holder/spell/proc/essence_check(var/essence_cost, var/silent = 0)
var/mob/living/simple_animal/revenant/W = usr
if(!istype(usr) || !usr)
return
if(W.essence < essence_cost)
if(!silent)
W << "<span class='warning'>You need [essence_cost]E to use [name] but you only have [W.essence]E available. Harvest some more things.</span>"
return 0
W.essence -= essence_cost
return 1
/mob/living/simple_animal/revenant/proc/wallcheck()
var/turf/T = get_turf(usr)
if(!istype(T, /turf/simulated/wall))
return 1
usr << "<span class='warning'>You can't use abilities from a wall. What did you expect?</span>"
return 0
/mob/living/simple_animal/revenant/proc/change_essence_amount(var/essence_amt, var/silent = 0, var/source = null)
var/mob/living/simple_animal/revenant/user = usr
if(!istype(usr) || !usr)
return
if(!essence_amt)
return
user.essence += essence_amt
if(!silent)
if(essence_amt >= 0)
user << "<span class='info'>Gained [essence_amt]E from [source].</span>"
else
user << "<span class='info'>Lost [essence_amt]E from [source].</span>"
return 1
/mob/living/simple_animal/revenant/proc/reveal(var/time, var/stun)
var/mob/living/simple_animal/revenant/R = usr
if(!istype(usr) || !usr)
return
R.revealed = 1
R.invisibility = 0
if(stun)
R.notransform = 1
spawn(time)
R.revealed = 0
R.invisibility = INVISIBILITY_OBSERVER
if(stun)
R.notransform = 0
@@ -0,0 +1,167 @@
//Harvest Essence: The bread and butter of the revenant. The basic way of harvesting additional essence.
/obj/effect/proc_holder/spell/wizard/targeted/revenant_harvest
name = "Harvest (0E)"
desc = "Siphons the lingering spectral essence from a human, empowering yourself."
panel = "Revenant Abilities"
charge_max = 100 //Short cooldown
clothes_req = 0
range = 5
var/essence_drained = 0
var/draining
var/list/drained_mobs = list() //Cannot harvest the same mob twice
/obj/effect/proc_holder/spell/wizard/targeted/revenant_harvest/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
if(user.inhibited)
user << "<span class='warning'>Something is blocking the use of [src]!</span>"
charge_counter = charge_max
return
if(!user.wallcheck())
charge_counter = charge_max
return
for(var/mob/living/carbon/human/target in targets)
spawn(0)
if(draining)
user << "<span class='warning'>You are already siphoning the essence of a soul!</span>"
return
if(target in drained_mobs)
user << "<span class='warning'>[target]'s soul is dead and empty.</span>"
return
if(target.stat != DEAD)
user << "<span class='notice'>This being's soul is too strong to harvest.</span>"
if(prob(10))
target << "You feel as if you are being watched."
return
draining = 1
essence_drained = 1
user << "<span class='notice'>You search for the still-living soul of [target].</span>"
sleep(10)
if(target.ckey)
user << "<span class='notice'>Their soul burns with intelligence.</span>"
essence_drained += 3
sleep(20)
switch(essence_drained)
if(1 to 2)
user << "<span class='info'>[target] will not yield much essence. Still, every bit counts.</span>"
if(3 to 4)
user << "<span class='info'>[target] will yield an average amount of essence.</span>"
if(5 to INFINITY)
user << "<span class='info'>Such a feast! [target] will yield much essence to you.</span>"
sleep(30)
if(!in_range(user, target))
user << "<span class='warning'>You are not close enough to siphon [target]'s soul. The link has been broken.</span>"
draining = 0
return
if(!target.stat)
user << "<span class='warning'>They are now powerful enough to fight off your draining.</span>"
target << "<span class='boldannounce'>You feel something tugging across your body before subsiding.</span>"
user << "<span class='danger'>You begin siphoning essence from [target]'s soul. You can not move while this is happening.</span>"
if(target.stat != DEAD)
target << "<span class='warning'>You feel a horribly unpleasant draining sensation as your grip on life weakens...</span>"
user.icon_state = "revenant_draining"
user.notransform = 1
user.revealed = 1
user.invisibility = 0
target.visible_message("<span class='warning'>[target] suddenly rises slightly into the air, their skin turning an ashy gray.</span>")
target.Beam(user,icon_state="drain_life",icon='icons/effects/effects.dmi',time=80)
target.death(0)
target.visible_message("<span class='warning'>[target] gently slumps back onto the ground.</span>")
user.icon_state = "revenant_idle"
user.change_essence_amount(essence_drained * 5, 0, target)
user << "<span class='info'>[target]'s soul has been considerably weakened and will yield no more essence for the time being.</span>"
user.revealed = 0
user.notransform = 0
user.invisibility = INVISIBILITY_OBSERVER
drained_mobs.Add(target)
draining = 0
//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob for 5E.
/obj/effect/proc_holder/spell/wizard/targeted/revenant_transmit
name = "Transmit (5E)"
desc = "Telepathically transmits a message to the target."
panel = "Revenant Abilities (Locked)"
charge_max = 50
clothes_req = 0
range = -1
include_user = 1
var/locked = 1
/obj/effect/proc_holder/spell/wizard/targeted/revenant_transmit/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
if(user.inhibited)
user << "<span class='warning'>Something is blocking the use of [src]!</span>"
charge_counter = charge_max
return
if(locked && essence_check(5, 1))
usr << "<span class='info'>You have unlocked Transmit!</span>"
locked = 0
charge_counter = charge_max
panel = "Revenant Abilities"
range = 7
include_user = 0
return
if(locked)
charge_counter = charge_max
return
if(!user.wallcheck())
charge_counter = charge_max
return
if(!essence_check(5))
charge_counter = charge_max
return
for(var/mob/living/M in targets)
spawn(0)
var/msg = stripped_input(usr, "What do you wish to tell [M]?", null, "")
if(!msg)
charge_counter = charge_max
return
usr << "<span class='info'><b>You transmit to [M]:</b> [msg]</span>"
M << "<span class='deadsay'><b>A strange voice resonates in your head...</b></span><i> [msg]</I>"
//Overload Light: Breaks a light that's online and sends out lightning bolts to all nearby people.
/obj/effect/proc_holder/spell/wizard/aoe_turf/revenant_light
name = "Overload Light (25E)"
desc = "Directs a large amount of essence into an electrical light, causing an impressive light show."
panel = "Revenant Abilities (Locked)"
charge_max = 300
clothes_req = 0
range = 1
var/locked = 1
/obj/effect/proc_holder/spell/wizard/aoe_turf/revenant_light/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
if(user.inhibited)
user << "<span class='warning'>Something is blocking the use of [src]!</span>"
charge_counter = charge_max
return
if(locked && essence_check(25, 1))
user << "<span class='info'>You have unlocked Overload Light!</span>"
name = "Overload Light (25E)"
panel = "Revenant Abilities"
locked = 0
range = 5
charge_counter = charge_max
return
if(locked)
charge_counter = charge_max
return
if(!user.wallcheck())
charge_counter = charge_max
return
if(!essence_check(25))
charge_counter = charge_max
return
for(var/turf/T in targets)
spawn(0)
for(var/obj/machinery/light/L in T.contents)
spawn(0)
if(!L.on)
return
L.visible_message("<span class='warning'><b>\The [L] suddenly flares brightly and begins to spark!</span>")
sleep(20)
for(var/mob/living/M in orange(4, L))
if(M == user)
return
M.Beam(L,icon_state="lightning",icon='icons/effects/effects.dmi',time=5)
M.electrocute_act(25, "[L.name]")
playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1)
user.reveal(50, 1)
@@ -0,0 +1,54 @@
/datum/event/revenant
var/key_of_revenant
/datum/event/revenant/proc/get_revenant(var/end_if_fail = 0)
key_of_revenant = null
if(!key_of_revenant)
var/list/candidates = get_candidates(BE_REVENANT)
if(!candidates.len)
if(end_if_fail)
return 0
return find_revenant()
var/client/C = pick(candidates)
key_of_revenant = C.key
if(!key_of_revenant)
if(end_if_fail)
return 0
return find_revenant()
var/datum/mind/player_mind = new /datum/mind(key_of_revenant)
player_mind.active = 1
var/list/spawn_locs = list()
for(var/obj/effect/landmark/L in landmarks_list)
if(isturf(L.loc))
switch(L.name)
if("carpspawn")
spawn_locs += L.loc
if(!spawn_locs)
return find_revenant()
var/mob/living/simple_animal/revenant/revvie = new /mob/living/simple_animal/revenant/(pick(spawn_locs))
player_mind.transfer_to(revvie)
player_mind.assigned_role = "revenant"
player_mind.special_role = "Revenant"
ticker.mode.traitors |= player_mind
message_admins("[key_of_revenant] has been made into a Revenant by an event.")
log_game("[key_of_revenant] was spawned as a Revenant by an event.")
return 1
/datum/event/revenant/start()
get_revenant()
/datum/event/revenant/proc/find_revenant()
message_admins("Attempted to spawn a Revenant but there was no players available. Will try again momentarily, bear with me...")
spawn(50)
if(get_revenant(1))
message_admins("Hooray! Situation has been resolved, [key_of_revenant] has been spawned as a Revenant.")
log_game("[key_of_revenant] was spawned as a Revenant by an event.")
return 0
message_admins("Unfortunately, no candidates were available for becoming a Revenant. Shutting down. :(")
return kill()