mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-21 03:55:05 +01:00
Merge pull request #1387 from Aurorablade/STILLALOTOFBLOOD
[Need Feedback] TG Slaughter Demon Port Remake, THE REGIBBINGING
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
|
||||
/datum/event/spawn_slaughter
|
||||
var/key_of_slaughter
|
||||
|
||||
|
||||
|
||||
/datum/event/spawn_slaughter/proc/get_slaughter(var/end_if_fail = 0)
|
||||
key_of_slaughter = null
|
||||
if(!key_of_slaughter)
|
||||
var/list/candidates = get_candidates(BE_ALIEN)
|
||||
if(!candidates.len)
|
||||
if(end_if_fail)
|
||||
return 0
|
||||
return find_slaughter()
|
||||
var/client/C = pick(candidates)
|
||||
key_of_slaughter = C.key
|
||||
if(!key_of_slaughter)
|
||||
if(end_if_fail)
|
||||
return 0
|
||||
return find_slaughter()
|
||||
var/datum/mind/player_mind = new /datum/mind(key_of_slaughter)
|
||||
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("revenantspawn")
|
||||
spawn_locs += L.loc
|
||||
if(!spawn_locs) //If we can't find any revenant spawns, try the carp spawns
|
||||
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) //If we can't find either, just spawn the revenant at the player's location
|
||||
spawn_locs += get_turf(player_mind.current)
|
||||
if(!spawn_locs) //If we can't find THAT, then just retry
|
||||
return find_slaughter()
|
||||
var /obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(pick(spawn_locs))
|
||||
var/mob/living/simple_animal/slaughter/S = new /mob/living/simple_animal/slaughter/(holder)
|
||||
S.holder = holder
|
||||
player_mind.transfer_to(S)
|
||||
player_mind.assigned_role = "Slaughter Demon"
|
||||
player_mind.special_role = "Slaughter Demon"
|
||||
message_admins("[key_of_slaughter] has been made into a Slaughter Demon by an event.")
|
||||
log_game("[key_of_slaughter] was spawned as a Slaughter Demon by an event.")
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/datum/event/spawn_slaughter/start()
|
||||
get_slaughter()
|
||||
|
||||
|
||||
|
||||
/datum/event/spawn_slaughter/proc/find_slaughter()
|
||||
message_admins("Attempted to spawn a Slaughter Demon but there was no players available. Will try again momentarily.")
|
||||
spawn(50)
|
||||
if(get_slaughter(1))
|
||||
message_admins("Situation has been resolved, [key_of_slaughter] has been spawned as a Slaughter Demon.")
|
||||
log_game("[key_of_slaughter] was spawned as a Slaughter Demon by an event.")
|
||||
return 0
|
||||
message_admins("Unfortunately, no candidates were available for becoming a Slaugter Demon. Shutting down.")
|
||||
kill()
|
||||
@@ -0,0 +1,152 @@
|
||||
//Travel through pools of blood. Slaughter Demon powers for everyone!
|
||||
#define BLOODCRAWL 1
|
||||
#define BLOODCRAWL_EAT 2
|
||||
|
||||
/mob/living/proc/phaseout(var/obj/effect/decal/cleanable/B)
|
||||
var/mob/living/kidnapped = null
|
||||
var/turf/mobloc = get_turf(src.loc)
|
||||
var/turf/bloodloc = get_turf(B.loc)
|
||||
if(Adjacent(bloodloc))
|
||||
src.notransform = TRUE
|
||||
spawn(0)
|
||||
src.visible_message("<span class='danger'>[src] sinks into [B].</span>")
|
||||
playsound(get_turf(src), 'sound/misc/enter_blood.ogg', 100, 1, -1)
|
||||
var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter( mobloc )
|
||||
var/atom/movable/overlay/animation = new /atom/movable/overlay( mobloc )
|
||||
animation.name = "odd blood"
|
||||
animation.density = 0
|
||||
animation.anchored = 1
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
animation.icon_state = "jaunt"
|
||||
animation.layer = 5
|
||||
animation.master = holder
|
||||
animation.dir = src.dir
|
||||
|
||||
src.ExtinguishMob()
|
||||
if(src.buckled)
|
||||
src.buckled.unbuckle()
|
||||
if(src.pulling && src.bloodcrawl == BLOODCRAWL_EAT)
|
||||
if(istype(src.pulling, /mob/living/))
|
||||
var/mob/living/victim = src.pulling
|
||||
if(victim.stat == CONSCIOUS)
|
||||
src.visible_message("[victim] kicks free of \the [src] at the last second!")
|
||||
else
|
||||
victim.loc = holder///holder
|
||||
src.visible_message("<span class='danger'><B>\The [src] drags [victim] into [B]!</B></span>")
|
||||
kidnapped = victim
|
||||
flick("jaunt",animation)
|
||||
src.loc = holder
|
||||
src.holder = holder
|
||||
|
||||
if(kidnapped)
|
||||
src << "<B>You begin to feast on [kidnapped]. You can not move while you are doing this.</B>"
|
||||
src.visible_message("<span class='warning'><B>Loud eating sounds come from the blood...</B></span>")
|
||||
sleep(6)
|
||||
if (animation)
|
||||
qdel(animation)
|
||||
playsound(get_turf(src),'sound/misc/Demon_consume.ogg', 100, 1)
|
||||
sleep(30)
|
||||
playsound(get_turf(src),'sound/misc/Demon_consume.ogg', 100, 1)
|
||||
sleep(30)
|
||||
playsound(get_turf(src),'sound/misc/Demon_consume.ogg', 100, 1)
|
||||
sleep(30)
|
||||
src << "<B>You devour [kidnapped]. Your health is fully restored.</B>"
|
||||
src.adjustBruteLoss(-1000)
|
||||
src.adjustFireLoss(-1000)
|
||||
src.adjustOxyLoss(-1000)
|
||||
src.adjustToxLoss(-1000)
|
||||
kidnapped.ghostize()
|
||||
qdel(kidnapped)
|
||||
if (istype(src, /mob/living/simple_animal/slaughter)) //rason, do not want humans to get this
|
||||
|
||||
var/mob/living/simple_animal/slaughter/demon = src
|
||||
demon.devoured++
|
||||
else
|
||||
sleep(6)
|
||||
if (animation)
|
||||
qdel(animation)
|
||||
src.notransform = 0
|
||||
|
||||
/mob/living/proc/phasein(var/obj/effect/decal/cleanable/B)
|
||||
if(src.notransform)
|
||||
src << "<B>Finish eating first!</B>"
|
||||
else
|
||||
var/atom/movable/overlay/animation = new /atom/movable/overlay( B.loc )
|
||||
animation.name = "odd blood"
|
||||
animation.density = 0
|
||||
animation.anchored = 1
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
animation.icon_state = "jauntup" //Paradise Port:I reversed the jaunt animation so it looks like its rising up
|
||||
animation.layer = 5
|
||||
animation.master = B.loc
|
||||
animation.dir = src.dir
|
||||
flick("jauntup",animation)
|
||||
src.loc = B.loc
|
||||
src.client.eye = src
|
||||
if (prob(25))
|
||||
var/list/voice = list('sound/hallucinations/behind_you1.ogg','sound/hallucinations/im_here1.ogg','sound/hallucinations/turn_around1.ogg','sound/hallucinations/i_see_you1.ogg')
|
||||
playsound(get_turf(src), pick(voice),50, 1, -1)
|
||||
src.visible_message("<span class='warning'><B>\The [src] rises out of \the [B]!</B>")
|
||||
playsound(get_turf(src), 'sound/misc/exit_blood.ogg', 100, 1, -1)
|
||||
qdel(src.holder)
|
||||
src.holder = null
|
||||
sleep(6)
|
||||
if(animation)
|
||||
qdel(animation)
|
||||
|
||||
/obj/effect/decal/cleanable/blood/CtrlClick(mob/living/user)
|
||||
..()
|
||||
if(user.bloodcrawl)
|
||||
if(user.holder)
|
||||
user.phasein(src)
|
||||
else
|
||||
user.phaseout(src)
|
||||
|
||||
|
||||
|
||||
/obj/effect/decal/cleanable/trail_holder/CtrlClick(mob/living/user)
|
||||
..()
|
||||
if(user.bloodcrawl)
|
||||
if(user.holder)
|
||||
user.phasein(src)
|
||||
else
|
||||
user.phaseout(src)
|
||||
|
||||
|
||||
|
||||
/turf/CtrlClick(var/mob/living/user)
|
||||
..()
|
||||
if(user.bloodcrawl)
|
||||
for(var/obj/effect/decal/cleanable/B in src.contents)
|
||||
if(istype(B, /obj/effect/decal/cleanable/blood) || istype(B, /obj/effect/decal/cleanable/trail_holder))
|
||||
if(user.holder)
|
||||
user.phasein(B)
|
||||
break
|
||||
else
|
||||
user.phaseout(B)
|
||||
break
|
||||
|
||||
/obj/effect/dummy/slaughter //Can't use the wizard one, blocked by jaunt/slow
|
||||
name = "odd blood"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "nothing"
|
||||
var/canmove = 1
|
||||
density = 0
|
||||
anchored = 1
|
||||
|
||||
/obj/effect/dummy/slaughter/relaymove(var/mob/user, direction)
|
||||
if (!src.canmove || !direction) return
|
||||
var/turf/newLoc = get_step(src,direction)
|
||||
loc = newLoc
|
||||
src.canmove = 0
|
||||
spawn(1)
|
||||
src.canmove = 1
|
||||
|
||||
/obj/effect/dummy/slaughter/ex_act(severity)
|
||||
return 1
|
||||
|
||||
/obj/effect/dummy/slaughter/bullet_act(blah)
|
||||
return
|
||||
|
||||
/obj/effect/dummy/slaughter/singularity_act(blah)
|
||||
return
|
||||
@@ -46,6 +46,9 @@
|
||||
var/floating = 0
|
||||
var/nightvision = 0
|
||||
|
||||
var/bloodcrawl = 0 //0 No blood crawling, 1 blood crawling, 2 blood crawling+mob devour
|
||||
var/holder = null //The holder for blood crawling
|
||||
|
||||
var/ventcrawler = 0 //0 No vent crawling, 1 vent crawling in the nude, 2 vent crawling always
|
||||
var/list/icon/pipes_shown = list()
|
||||
var/last_played_vent
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
//////////////////The Monster
|
||||
|
||||
/mob/living/simple_animal/slaughter
|
||||
name = "Slaughter Demon"
|
||||
real_name = "Slaughter Demon"
|
||||
desc = "You should run."
|
||||
speak_emote = list("gurgles")
|
||||
emote_hear = list("wails","screeches")
|
||||
response_help = "thinks better of touching"
|
||||
response_disarm = "flails at"
|
||||
response_harm = "punches"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "daemon"
|
||||
icon_living = "daemon"
|
||||
speed = 1
|
||||
a_intent = "harm"
|
||||
stop_automated_movement = 1
|
||||
status_flags = CANPUSH
|
||||
attack_sound = 'sound/misc/demon_attack1.ogg'
|
||||
min_oxy = 0
|
||||
max_oxy = INFINITY
|
||||
min_tox = 0
|
||||
max_tox = INFINITY
|
||||
min_co2 = 0
|
||||
max_co2 = INFINITY
|
||||
min_n2 = 0
|
||||
max_n2 = INFINITY
|
||||
minbodytemp = 0
|
||||
maxbodytemp = INFINITY
|
||||
faction = list("slaughter")
|
||||
attacktext = "wildly tears into"
|
||||
maxHealth = 200
|
||||
health = 200
|
||||
environment_smash = 1
|
||||
//universal_understand = 1
|
||||
melee_damage_lower = 30
|
||||
melee_damage_upper = 30
|
||||
see_in_dark = 8
|
||||
see_invisible = SEE_INVISIBLE_MINIMUM
|
||||
var/boost = 0
|
||||
bloodcrawl = BLOODCRAWL_EAT
|
||||
|
||||
|
||||
var/devoured = 0
|
||||
|
||||
var/list/nearby_mortals = list()
|
||||
var/cooldown = 0
|
||||
var/gorecooldown = 0
|
||||
var/vialspawned = FALSE
|
||||
var/playstyle_string = "<B>You are the Slaughter Demon, a terrible creature from another existence. You have a single desire: To kill. \
|
||||
You may Ctrl+Click on blood pools to travel through them, appearing and dissaapearing from the station at will. \
|
||||
Pulling a dead or critical mob while you enter a pool will pull them in with you, allowing you to feast. \
|
||||
You move quickly upon leaving a pool of blood, but the material world will soon sap your strength and leave you sluggish. </B>"
|
||||
|
||||
|
||||
/mob/living/simple_animal/slaughter/New()
|
||||
..()
|
||||
spawn()
|
||||
if(src.mind)
|
||||
src.mind.current.verbs += /mob/living/simple_animal/slaughter/proc/slaughterWhisper
|
||||
src << src.playstyle_string
|
||||
src << "<B><span class ='notice'>You are not currently in the same plane of existence as the station. Ctrl+Click a blood pool to manifest.</span></B>"
|
||||
if(!(vialspawned))
|
||||
var/datum/objective/slaughter/objective = new
|
||||
var/datum/objective/demonFluff/fluffObjective = new
|
||||
ticker.mode.traitors |= src.mind
|
||||
objective.owner = src.mind
|
||||
fluffObjective.owner = src.mind
|
||||
//Paradise Port:I added the objective for one spawned like this
|
||||
src.mind.objectives += objective
|
||||
src.mind.objectives += fluffObjective
|
||||
src << "<B>Objective #[1]</B>: [objective.explanation_text]"
|
||||
src << "<B>Objective #[2]</B>: [fluffObjective.explanation_text]"
|
||||
|
||||
|
||||
/mob/living/simple_animal/slaughter/Life()
|
||||
..()
|
||||
if(boost<world.time)
|
||||
speed = 1
|
||||
else
|
||||
speed = 0
|
||||
|
||||
/mob/living/simple_animal/slaughter/Die()
|
||||
..()
|
||||
new /obj/effect/decal/cleanable/blood (src.loc)
|
||||
new /obj/effect/gibspawner/generic(get_turf(src))
|
||||
new /obj/effect/gibspawner/generic(get_turf(src))
|
||||
playsound(get_turf(src),'sound/misc/demon_dies.ogg', 200, 1)
|
||||
new /obj/item/weapon/demonheart (src.loc)
|
||||
visible_message("<span class='danger'>The [src] screams in anger as its form collapes into a pool of viscera.</span>")
|
||||
ghostize()
|
||||
qdel(src)
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/slaughter/phasein()
|
||||
..()
|
||||
speed = 0
|
||||
boost = world.time + 30
|
||||
|
||||
/mob/living/simple_animal/slaughter/say(message)
|
||||
return 0
|
||||
////////////////////The Powers
|
||||
|
||||
//Paradise Port:I added this cuase..SPOOPY DEMON IN YOUR BRAIN
|
||||
|
||||
|
||||
/mob/living/simple_animal/slaughter/proc/slaughterWhisper()
|
||||
set name = "Whisper"
|
||||
set desc = "Whisper to a mortal"
|
||||
set category = "Daemon"
|
||||
|
||||
var/list/choices = list()
|
||||
for(var/mob/living/carbon/C in living_mob_list)
|
||||
if(C.stat != 2 && C.client && C.stat != DEAD)
|
||||
choices += C
|
||||
|
||||
var/mob/living/carbon/M = input(src,"Who do you wish to talk to?") in null|choices
|
||||
spawn(0)
|
||||
var/msg = stripped_input(usr, "What do you wish to tell [M]?", null, "")
|
||||
if(!(msg))
|
||||
return
|
||||
usr << "<span class='info'><b>You whisper to [M]:</b> [msg]</span>"
|
||||
M << "<span class='deadsay'><b>Suddenly a strange,demonic,voice resonates in your head...</b></span><i><span class='danger'> [msg]</span></I>"
|
||||
|
||||
//////////The Loot
|
||||
|
||||
/obj/item/weapon/demonheart
|
||||
name = "demon's heart"
|
||||
desc = "It's still faintly beating with rage"
|
||||
icon = 'icons/obj/surgery.dmi'
|
||||
icon_state = "heart-on"
|
||||
origin_tech = "combat=5;biotech=8"
|
||||
|
||||
|
||||
/obj/item/weapon/demonheart/attack_self(mob/living/user)
|
||||
visible_message("[user] feasts upon the [src].")
|
||||
if(user.bloodcrawl == 0)
|
||||
user << "You absorb some of the demon's power!"
|
||||
user.bloodcrawl = BLOODCRAWL
|
||||
else if(user.bloodcrawl == 1)
|
||||
user << "You absorb some of the demon's power!"
|
||||
user << "You feel diffr-<span class = 'danger'> CONSUME THEM! </span>"
|
||||
user.bloodcrawl = BLOODCRAWL_EAT
|
||||
qdel(src)
|
||||
|
||||
|
||||
//Objectives and helpers.
|
||||
|
||||
//Objective info, Based on Reverent mini Atang
|
||||
/datum/objective/slaughter
|
||||
var/targetKill = 10
|
||||
|
||||
/datum/objective/slaughter/New()
|
||||
targetKill = rand(10,20)
|
||||
explanation_text = "Devour [targetKill] mortals."
|
||||
..()
|
||||
|
||||
/datum/objective/slaughter/check_completion()
|
||||
if(!istype(owner.current, /mob/living/simple_animal/slaughter) || !owner.current)
|
||||
return 0
|
||||
var/mob/living/simple_animal/slaughter/R = owner.current
|
||||
if(!R || R.stat == DEAD)
|
||||
return 0
|
||||
var/deathCount = R.devoured
|
||||
if(deathCount < targetKill)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/datum/objective/demonFluff
|
||||
|
||||
|
||||
/datum/objective/demonFluff/New()
|
||||
find_target()
|
||||
var/targetname = "someone"
|
||||
if(target && target.current)
|
||||
targetname = target.current.real_name
|
||||
var/list/explanationTexts = list("Attempt to make your presence unknown to the crew.", \
|
||||
"Kill or Destroy all Janitors or Sanitation bots.", \
|
||||
"Drive [targetname] insane with demonic whispering."
|
||||
)
|
||||
|
||||
explanation_text = pick(explanationTexts)
|
||||
..()
|
||||
|
||||
/datum/objective/demonFluff/check_completion()
|
||||
return 1
|
||||
Reference in New Issue
Block a user