diff --git a/code/datums/spells/bloodcrawl.dm b/code/datums/spells/bloodcrawl.dm
new file mode 100644
index 00000000000..8af7ee8dfb3
--- /dev/null
+++ b/code/datums/spells/bloodcrawl.dm
@@ -0,0 +1,34 @@
+/obj/effect/proc_holder/spell/bloodcrawl
+ name = "Blood Crawl"
+ desc = "Use pools of blood to phase out of existence."
+ charge_max = 0
+ clothes_req = 0
+ selection_type = "range"
+ range = 1
+ cooldown_min = 0
+ overlay = null
+ action_icon_state = "bloodcrawl"
+ action_background_icon_state = "bg_demon"
+ panel = "Demon"
+ var/phased = 0
+
+/obj/effect/proc_holder/spell/bloodcrawl/choose_targets(mob/user = usr)
+ for(var/obj/effect/decal/cleanable/target in range(range, get_turf(user)))
+ if(istype(target,/obj/effect/decal/cleanable/blood) && !(istype(target,/obj/effect/decal/cleanable/blood/oil) || istype(target,/obj/effect/decal/cleanable/blood/gibs/robot)))
+ perform(target)
+ return
+ revert_cast()
+ user << "There must be a nearby source of blood!"
+
+/obj/effect/proc_holder/spell/bloodcrawl/perform(obj/effect/decal/cleanable/target, recharge = 1, mob/living/user = usr)
+ if(istype(user))
+ if(phased == 1)
+ if(user.phasein(target))
+ phased = 0
+ else
+ if(user.phaseout(target))
+ phased = 1
+ start_recharge()
+ return
+ revert_cast()
+ user << "You are unable to blood crawl!"
\ No newline at end of file
diff --git a/code/game/gamemodes/miniantags/slaughter/bloodcrawl.dm b/code/game/gamemodes/miniantags/slaughter/bloodcrawl.dm
index 2ee52db528c..a057a696422 100644
--- a/code/game/gamemodes/miniantags/slaughter/bloodcrawl.dm
+++ b/code/game/gamemodes/miniantags/slaughter/bloodcrawl.dm
@@ -18,85 +18,85 @@
C.regenerate_icons()
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("[src] sinks into [B].")
- 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
+ var/turf/mobloc = get_turf(loc)
+ notransform = TRUE
+ spawn(0)
+ visible_message("[src] sinks into [B].")
+ 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 = dir
- src.ExtinguishMob()
- if(src.buckled)
- src.buckled.unbuckle_mob()
- 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 [B] just before entering it!")
- else
- victim.loc = holder///holder
- victim.emote("scream")
- src.visible_message("[src] drags [victim] into [B]!")
- kidnapped = victim
- flick("jaunt",animation)
- src.loc = holder
- src.holder = holder
-
- if(kidnapped)
- src << "You begin to feast on [kidnapped]. You can not move while you are doing this."
- src.visible_message("Loud eating sounds come from the blood...")
- sleep(6)
- if (animation)
- qdel(animation)
- for(var/i = 3; i > 0; i--)
- playsound(get_turf(src),'sound/misc/Demon_consume.ogg', 100, 1)
- sleep(30)
- if (kidnapped)
- src << "You devour [kidnapped]. Your health is fully restored."
- src.adjustBruteLoss(-1000)
- src.adjustFireLoss(-1000)
- src.adjustOxyLoss(-1000)
- src.adjustToxLoss(-1000)
-
- 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++
- kidnapped << "You feel teeth sink into your flesh, and the--"
- kidnapped.adjustBruteLoss(1000)
- kidnapped.forceMove(src)
- demon.consumed_mobs.Add(kidnapped)
- else
- kidnapped.ghostize()
- qdel(kidnapped)
+ ExtinguishMob()
+ if(buckled)
+ buckled.unbuckle_mob()
+ if(pulling && bloodcrawl == BLOODCRAWL_EAT)
+ if(istype(pulling, /mob/living/))
+ var/mob/living/victim = pulling
+ if(victim.stat == CONSCIOUS)
+ visible_message("[victim] kicks free of [B] just before entering it!")
else
- src << "You happily devour... nothing? Your meal vanished at some point!"
+ victim.forceMove(holder)//holder
+ victim.emote("scream")
+ visible_message("[src] drags [victim] into [B]!")
+ kidnapped = victim
+ flick("jaunt",animation)
+ loc = holder
+ holder = holder
+
+ if(kidnapped)
+ src << "You begin to feast on [kidnapped]. You can not move while you are doing this."
+ visible_message("Loud eating sounds come from the blood...")
+ sleep(6)
+ if(animation)
+ qdel(animation)
+ for(var/i = 3; i > 0; i--)
+ playsound(get_turf(src),'sound/misc/Demon_consume.ogg', 100, 1)
+ sleep(30)
+ if(kidnapped)
+ src << "You devour [kidnapped]. Your health is fully restored."
+ adjustBruteLoss(-1000)
+ adjustFireLoss(-1000)
+ adjustOxyLoss(-1000)
+ adjustToxLoss(-1000)
+
+ 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++
+ kidnapped << "You feel teeth sink into your flesh, and the--"
+ kidnapped.adjustBruteLoss(1000)
+ kidnapped.forceMove(src)
+ demon.consumed_mobs.Add(kidnapped)
+ else
+ kidnapped.ghostize()
+ qdel(kidnapped)
else
- sleep(6)
- if (animation)
- qdel(animation)
- src.notransform = 0
+ src << "You happily devour... nothing? Your meal vanished at some point!"
+ else
+ sleep(6)
+ if (animation)
+ qdel(animation)
+ notransform = 0
+ return 1
/obj/item/weapon/bloodcrawl
name = "blood crawl"
desc = "You are unable to hold anything while in this form."
icon = 'icons/effects/blood.dmi'
- flags = NODROP
+ flags = NODROP|ABSTRACT
/mob/living/proc/phasein(var/obj/effect/decal/cleanable/B)
- if(src.notransform)
+ if(notransform)
src << "Finish eating first!"
+ return 0
else
var/atom/movable/overlay/animation = new /atom/movable/overlay( B.loc )
animation.name = "odd blood"
@@ -106,67 +106,36 @@
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
+ animation.dir = dir
B.visible_message("[B] starts to bubble...")
if(!do_after(src, 20, target = B))
return
if(!B)
return
- src.forceMove(B.loc)
- src.client.eye = src
+ forceMove(B.loc)
+ client.eye = src
if (prob(25) && istype(src, /mob/living/simple_animal/slaughter))
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("\The [src] rises out of \the [B]!")
+ visible_message("\The [src] rises out of \the [B]!")
playsound(get_turf(src), 'sound/misc/exit_blood.ogg', 100, 1, -1)
flick("jauntup",animation)
- qdel(src.holder)
- src.holder = null
+ qdel(holder)
+ holder = null
if(iscarbon(src))
var/mob/living/carbon/C = src
for(var/obj/item/weapon/bloodcrawl/BC in C)
C.flags = null
C.unEquip(BC)
qdel(BC)
- var/oldcolor = src.color
- src.color = B.color
+ var/oldcolor = color
+ color = B.color
sleep(6)//wait for animation to finish
if(animation)
qdel(animation)
spawn(30)
- src.color = oldcolor
-
-/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
+ color = oldcolor
+ return 1
/obj/effect/dummy/slaughter //Can't use the wizard one, blocked by jaunt/slow
name = "odd blood"
@@ -175,20 +144,16 @@
var/canmove = 1
density = 0
anchored = 1
+ invisibility = 60
-/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/relaymove(mob/user, direction)
+ forceMove(get_step(src,direction))
-/obj/effect/dummy/slaughter/ex_act(severity)
- return 1
-
-/obj/effect/dummy/slaughter/bullet_act(blah)
+/obj/effect/dummy/slaughter/ex_act()
return
-/obj/effect/dummy/slaughter/singularity_act(blah)
+/obj/effect/dummy/slaughter/bullet_act()
+ return
+
+/obj/effect/dummy/slaughter/singularity_act()
return
\ No newline at end of file
diff --git a/code/game/gamemodes/miniantags/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm
index 5f9b320a2a5..ae9879ca8c3 100644
--- a/code/game/gamemodes/miniantags/slaughter/slaughter.dm
+++ b/code/game/gamemodes/miniantags/slaughter/slaughter.dm
@@ -57,23 +57,26 @@
/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 << "You are not currently in the same plane of existence as the station. Ctrl+Click a blood pool to manifest."
- src << 'sound/misc/demon_dies.ogg'
- 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 << "Objective #[1]: [objective.explanation_text]"
- src << "Objective #[2]: [fluffObjective.explanation_text]"
+ var/obj/effect/proc_holder/spell/bloodcrawl/bloodspell = new
+ AddSpell(bloodspell)
+ if(istype(loc, /obj/effect/dummy/slaughter))
+ bloodspell.phased = 1
+ if(mind)
+ src << src.playstyle_string
+ src << "You are not currently in the same plane of existence as the station. Ctrl+Click a blood pool to manifest."
+ src << 'sound/misc/demon_dies.ogg'
+ mind.current.verbs += /mob/living/simple_animal/slaughter/proc/slaughterWhisper
+ if(!(vialspawned))
+ var/datum/objective/slaughter/objective = new
+ var/datum/objective/demonFluff/fluffObjective = new
+ ticker.mode.traitors |= mind
+ objective.owner = mind
+ fluffObjective.owner = mind
+ //Paradise Port:I added the objective for one spawned like this
+ mind.objectives += objective
+ mind.objectives += fluffObjective
+ src << "Objective #[1]: [objective.explanation_text]"
+ src << "Objective #[2]: [fluffObjective.explanation_text]"
/mob/living/simple_animal/slaughter/Life()
@@ -90,10 +93,10 @@
innards.icon_state = "innards"
innards.name = "pile of viscera"
innards.desc = "A repulsive pile of guts and gore."
- new /obj/effect/decal/cleanable/blood (src.loc)
+ new /obj/effect/decal/cleanable/blood(loc)
new /obj/effect/gibspawner/generic(get_turf(src))
new /obj/effect/gibspawner/generic(get_turf(src))
- new /obj/item/organ/internal/heart/demonheart(src.loc)
+ new /obj/item/organ/internal/heart/demonheart(loc)
playsound(get_turf(src),'sound/misc/demon_dies.ogg', 200, 1)
visible_message("[src] screams in anger as it collapses into a puddle of viscera, its most recent meals spilling out of it.")
for(var/mob/living/M in consumed_mobs)
@@ -145,16 +148,23 @@
icon_state = "demon_heart"
origin_tech = "combat=5;biotech=8"
+/obj/item/organ/internal/heart/demon/update_icon()
+ return //always beating visually
/obj/item/organ/internal/heart/demonheart/attack_self(mob/living/user)
user.visible_message("[user] raises [src] to their mouth and tears into it with their teeth!", \
"An unnatural hunger consumes you. You raise [src] to your mouth and devour it!")
playsound(user, 'sound/misc/Demon_consume.ogg', 50, 1)
+ for(var/obj/effect/proc_holder/spell/knownspell in user.mind.spell_list)
+ if(knownspell.type == /obj/effect/proc_holder/spell/bloodcrawl)
+ qdel(src)
+ return
+
if(user.bloodcrawl == 0)
user.visible_message("[user]'s eyes flare a deep crimson!", \
"You feel a strange power seep into your body... you have absorbed the demon's blood-travelling powers!")
user.bloodcrawl = BLOODCRAWL
- else if(user.bloodcrawl == 1)
+ else if(user.bloodcrawl == BLOODCRAWL)
user << "You feel diffr- CONSUME THEM! "
user.bloodcrawl = BLOODCRAWL_EAT
else
@@ -163,10 +173,16 @@
user.drop_item()
insert(user) //Consuming the heart literally replaces your heart with a demon heart. H A R D C O R E
+/obj/item/organ/internal/heart/demon/insert(mob/living/carbon/M, special = 0)
+ ..()
+ if(M.mind)
+ M.mind.AddSpell(new /obj/effect/proc_holder/spell/bloodcrawl(null))
+
/obj/item/organ/internal/heart/demonheart/remove(mob/living/carbon/M, special = 0)
..()
if(M.mind)
M.bloodcrawl = 0
+ M.mind.remove_spell(/obj/effect/proc_holder/spell/bloodcrawl)
//Objectives and helpers.
diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi
index 22d7d9cd166..5e7b65eb543 100644
Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ
diff --git a/paradise.dme b/paradise.dme
index dd87fb61193..5aacb4a45d5 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -208,6 +208,7 @@
#include "code\datums\helper_datums\teleport.dm"
#include "code\datums\helper_datums\topic_input.dm"
#include "code\datums\spells\area_teleport.dm"
+#include "code\datums\spells\bloodcrawl.dm"
#include "code\datums\spells\charge.dm"
#include "code\datums\spells\conjure.dm"
#include "code\datums\spells\construct_spells.dm"