diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm
index d5ee23c63a0..86fbb2d25bd 100644
--- a/code/game/gamemodes/clock_cult/clock_cult.dm
+++ b/code/game/gamemodes/clock_cult/clock_cult.dm
@@ -120,7 +120,8 @@ This file's folder contains:
all_clockwork_mobs -= M
M.mind.memory = "" //Not sure if there's a better way to do this
M.mind.special_role = null
- M.verbs -= /mob/living/carbon/human/proc/function_call //Removes any bound Ratvarian spears
+ for(var/datum/action/innate/function_call/F in M.actions) //Removes any bound Ratvarian spears
+ qdel(F)
if(issilicon(M))
var/mob/living/silicon/S = M
if(isrobot(S))
diff --git a/code/game/gamemodes/clock_cult/clock_items.dm b/code/game/gamemodes/clock_cult/clock_items.dm
index 3ca7ca391a6..1b55258d122 100644
--- a/code/game/gamemodes/clock_cult/clock_items.dm
+++ b/code/game/gamemodes/clock_cult/clock_items.dm
@@ -754,43 +754,85 @@
item_state = "ratvarian_spear"
force = 17 //Extra damage is dealt to silicons in afterattack()
throwforce = 40
- attack_verb = list("stabbed", "poked", "slashed", "impaled")
+ attack_verb = list("stabbed", "poked", "slashed")
hitsound = 'sound/weapons/bladeslice.ogg'
w_class = 4
+ var/impale_cooldown = 30 //brief delay, in deciseconds, where you can't impale again if you're really fast
/obj/item/clockwork/ratvarian_spear/New()
..()
+ impale_cooldown = 0
+ SSobj.processing += src
spawn(1)
- if(ratvar_awakens) //If Ratvar is alive, the spear is extremely powerful
- force = 30
- throwforce = 50
if(isliving(loc))
var/mob/living/L = loc
L << "Your spear begins to break down in this plane of existence. You can't use it for long!"
- spawn(3000) //5 minutes
- if(src)
- var/turf/T = get_turf(src)
- T.visible_message("[src] cracks in two and fades away!")
- PoolOrNew(/obj/effect/overlay/temp/ratvar/spearbreak, T)
- qdel(src)
+ addtimer(src, "break_spear", 3000, FALSE) //5 minutes
-/obj/item/clockwork/ratvarian_spear/afterattack(atom/target, mob/living/user, flag, params)
- if(!target || !user)
- return 0
- if(!ismob(target))
- return ..()
- var/mob/living/L = target
- if(issilicon(L))
- var/mob/living/silicon/S = L
+/obj/item/clockwork/ratvarian_spear/Destroy()
+ SSobj.processing -= src
+ return ..()
+
+/obj/item/clockwork/ratvarian_spear/process()
+ if(ratvar_awakens) //If Ratvar is alive, the spear is extremely powerful
+ force = 30
+ throwforce = 50
+ else
+ force = initial(force)
+ throwforce = initial(throwforce)
+
+/obj/item/clockwork/ratvarian_spear/examine(mob/user)
+ ..()
+ if(is_servant_of_ratvar(user) || isobserver(user))
+ user << "Stabbing a human you are pulling or have grabbed with the spear will impale them, doing massive damage and breaking the spear if they remain conscious."
+ user << "Throwing the spear will do massive damage, break the spear, and stun the target if it's an enemy cultist or silicon."
+
+/obj/item/clockwork/ratvarian_spear/attack(mob/living/target, mob/living/carbon/human/user)
+ var/impaling = FALSE
+ if(user.pulling && ishuman(user.pulling) && user.pulling == target)
+ if(impale_cooldown > world.time)
+ user << "You can't impale [target] yet, wait [max(round((impale_cooldown - world.time)*0.1, 0.1), 0)] seconds!"
+ return
+ impaling = TRUE
+ attack_verb = list("impaled")
+ force += 23 //40 damage if ratvar isn't alive, 53 if he is
+ user.stop_pulling()
+ target.Stun(2)
+ PoolOrNew(/obj/effect/overlay/temp/bloodsplatter, list(get_turf(target), get_dir(user, target)))
+ impale_cooldown = world.time + initial(impale_cooldown)
+ ..()
+ if(issilicon(target))
+ var/mob/living/silicon/S = target
if(S.stat != DEAD)
S.visible_message("[S] shudders violently at [src]'s touch!", "ERROR: Temperature rising!")
S.adjustFireLoss(25)
- else if(iscultist(L)) //Cultists take extra fire damage
- var/mob/living/M = L
+ else if(iscultist(target) || isconstruct(target)) //Cultists take extra fire damage
+ var/mob/living/M = target
M << "Your body flares with agony at [src]'s touch!"
M.adjustFireLoss(10)
- else
- ..()
+ if(impaling)
+ attack_verb = list("stabbed", "poked", "slashed")
+ if(target)
+ user << "You prepare to remove your ratvarian spear from [target]..."
+ if(do_after(user, 5, 1, target))
+ var/turf/T = get_turf(target)
+ var/obj/effect/overlay/temp/bloodsplatter/B = PoolOrNew(/obj/effect/overlay/temp/bloodsplatter, list(T, get_dir(target, user)))
+ playsound(T, 'sound/misc/splort.ogg', 200, 1)
+ if(target.stat != CONSCIOUS)
+ var/remove_verb = pick("pull", "yank", "drag")
+ user.visible_message("[user] [remove_verb]s [src] out of [target]!", "You [remove_verb] your spear out of [target]!")
+ else
+ user.visible_message("[user] kicks [target] off of [src], breaking it!", "You kick [target] off of [src], breaking it!")
+ target << "[user] kicks you off of their ratvarian spear!"
+ break_spear(get_turf(T))
+ step(target, get_dir(user, target))
+ T = get_turf(target)
+ B.forceMove(T)
+ target.Weaken(2)
+ playsound(T, 'sound/weapons/thudswoosh.ogg', 50, 1)
+ else if(target) //it's a do_after, we gotta check again to make sure they didn't get deleted
+ user << "Your ratvarian spear breaks!"
+ break_spear(get_turf(target))
/obj/item/clockwork/ratvarian_spear/throw_impact(atom/target)
var/turf/T = get_turf(target)
@@ -800,9 +842,17 @@
if(issilicon(L) || iscultist(L))
L.Stun(3)
L.Weaken(3)
- T.visible_message("[src] snaps in two and dematerializes!")
- PoolOrNew(/obj/effect/overlay/temp/ratvar/spearbreak, get_turf(T))
- qdel(src)
+ break_spear(T)
+
+/obj/item/clockwork/ratvarian_spear/proc/break_spear(turf/T)
+ if(src)
+ if(!T)
+ T = get_turf(src)
+ if(T) //make sure we're not in null or something
+ T.visible_message("[pick("[src] cracks in two and fades away!", "[src] snaps in two and dematerializes!")]")
+ PoolOrNew(/obj/effect/overlay/temp/ratvar/spearbreak, T)
+ qdel(src)
+
/obj/item/device/mmi/posibrain/soul_vessel //Soul vessel: An ancient positronic brain with a lawset catered to serving Ratvar.
name = "soul vessel"
diff --git a/code/game/gamemodes/clock_cult/clock_scripture.dm b/code/game/gamemodes/clock_cult/clock_scripture.dm
index f50971dc89a..155d008f7c2 100644
--- a/code/game/gamemodes/clock_cult/clock_scripture.dm
+++ b/code/game/gamemodes/clock_cult/clock_scripture.dm
@@ -545,23 +545,23 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed
required_components = list("vanguard_cogwheel" = 1, "replicant_alloy" = 1)
consumed_components = list("vanguard_cogwheel" = 1, "replicant_alloy" = 1)
whispered = TRUE
- usage_tip = "The spear will snap in two when thrown but do massive damage."
+ usage_tip = "You can impale human targets with the spear by pulling them, then attacking. Throwing the spear at a mob will do massive damage. Both of these will break the spear, however."
tier = SCRIPTURE_SCRIPT
/datum/clockwork_scripture/function_call/check_special_requirements()
- if(invoker.verbs.Find(/mob/living/carbon/human/proc/function_call))
+ for(var/datum/action/innate/function_call/F in invoker.actions)
invoker << "You have already bound a Ratvarian spear to yourself!"
return 0
return ishuman(invoker)
/datum/clockwork_scripture/function_call/scripture_effects()
invoker.visible_message("A shimmer of yellow light infuses [invoker]!", \
- "You bind a Ratvarian spear to yourself. Use the \"Function Call\" verb in your Clockwork tab to call it forth.")
- invoker.verbs += /mob/living/carbon/human/proc/function_call
+ "You bind a Ratvarian spear to yourself. Use the \"Function Call\" action button to call it forth.")
+ var/datum/action/innate/function_call/F = new()
+ F.Grant(invoker)
return 1
-
/datum/clockwork_scripture/spatial_gateway
name = "Spatial Gateway"
desc = "Tears open a miniaturized gateway in spacetime to any conscious servant that can transport objects or creatures to its destination. \
diff --git a/code/game/gamemodes/clock_cult/clock_unsorted.dm b/code/game/gamemodes/clock_cult/clock_unsorted.dm
index c5e8bc42091..4db8c8f38e4 100644
--- a/code/game/gamemodes/clock_cult/clock_unsorted.dm
+++ b/code/game/gamemodes/clock_cult/clock_unsorted.dm
@@ -1,16 +1,23 @@
-//Function Call verb: Calls forth a Ratvarian spear.
-/mob/living/carbon/human/proc/function_call()
- set name = "Function Call"
- set desc = "Calls forth your Ratvarian spear."
- set category = "Clockwork"
+//Function Call action: Calls forth a Ratvarian spear.
+/datum/action/innate/function_call
+ name = "Function Call"
+ button_icon_state = "ratvarian_spear"
+ check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_CONSCIOUS
- if(usr.l_hand && usr.r_hand)
+/datum/action/innate/function_call/IsAvailable()
+ if(!is_servant_of_ratvar(owner))
+ return 0
+ return ..()
+
+/datum/action/innate/function_call/Activate()
+ if(owner.l_hand && owner.r_hand)
usr << "You need an empty to hand to call forth your spear!"
return 0
- usr.visible_message("A strange spear materializes in [usr]'s hands!", "You call forth your spear!")
+ owner.visible_message("A strange spear materializes in [usr]'s hands!", "You call forth your spear!")
var/obj/item/clockwork/ratvarian_spear/R = new(get_turf(usr))
- usr.put_in_hands(R)
- usr.verbs -= /mob/living/carbon/human/proc/function_call
+ owner.put_in_hands(R)
+ for(var/datum/action/innate/function_call/F in owner.actions) //Removes any bound Ratvarian spears
+ qdel(F)
return 1
//allows a mob to select a target to gate to
diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm
index b496bc01a08..7e17407317c 100644
--- a/code/game/objects/effects/overlays.dm
+++ b/code/game/objects/effects/overlays.dm
@@ -24,8 +24,8 @@
anchored = 1
layer = ABOVE_MOB_LAYER
mouse_opacity = 0
- var/duration = 10
- var/randomdir = 1
+ var/duration = 10 //in deciseconds
+ var/randomdir = TRUE
/obj/effect/overlay/temp/Destroy()
..()
@@ -38,6 +38,48 @@
spawn(duration)
qdel(src)
+/obj/effect/overlay/temp/bloodsplatter
+ icon = 'icons/effects/blood.dmi'
+ duration = 5
+ randomdir = FALSE
+ layer = BELOW_MOB_LAYER
+
+/obj/effect/overlay/temp/bloodsplatter/New(loc, set_dir)
+ if(set_dir in diagonals)
+ icon_state = "splatter[pick(1, 2, 6)]"
+ else
+ icon_state = "splatter[pick(3, 4, 5)]"
+ ..()
+ var/target_pixel_x = 0
+ var/target_pixel_y = 0
+ switch(set_dir)
+ if(NORTH)
+ target_pixel_y = 16
+ if(SOUTH)
+ target_pixel_y = -16
+ layer = ABOVE_MOB_LAYER
+ if(EAST)
+ target_pixel_x = 16
+ if(WEST)
+ target_pixel_x = -16
+ if(NORTHEAST)
+ target_pixel_x = 16
+ target_pixel_y = 16
+ if(NORTHWEST)
+ target_pixel_x = -16
+ target_pixel_y = 16
+ if(SOUTHEAST)
+ target_pixel_x = 16
+ target_pixel_y = -16
+ layer = ABOVE_MOB_LAYER
+ if(SOUTHWEST)
+ target_pixel_x = -16
+ target_pixel_y = -16
+ layer = ABOVE_MOB_LAYER
+ dir = set_dir
+ animate(src, pixel_x = target_pixel_x, pixel_y = target_pixel_y, alpha = 0, time = duration)
+
+
/obj/effect/overlay/temp/heal //color is white by default, set to whatever is needed
name = "healing glow"
icon_state = "heal"
diff --git a/icons/effects/blood.dmi b/icons/effects/blood.dmi
index afef911cbdd..fc0fbe751e8 100644
Binary files a/icons/effects/blood.dmi and b/icons/effects/blood.dmi differ
diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi
index 0887bdd92c5..9a5e6fa58eb 100644
Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ