Skip to content

Commit

Permalink
twirl knife to flick off the blood (#15554)
Browse files Browse the repository at this point in the history
Co-authored-by: aloe <frawhstdev@gmail.com>
  • Loading branch information
TheTyrant25 and frawhst committed Sep 13, 2023
1 parent 88b0e9e commit 78cd1bf
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 0 deletions.
4 changes: 4 additions & 0 deletions _std/defines/component_defines/component_defines_atom.dm
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
#define COMSIG_ATOM_SET_OPACITY "atom_set_opacity"
/// get radioactivity level of atom (0 if signal not registered - ie, has no radioactive component) (return_val as a list)
#define COMSIG_ATOM_RADIOACTIVITY "atom_get_radioactivity"
/// when this atom has clean_forensic called, send this signal.
#define COMSIG_ATOM_CLEANED "atom_cleaned"

// ---- minimap ----

Expand Down Expand Up @@ -151,6 +153,8 @@
#define COMSIG_ITEM_PROCESS "itm_process"
/// After attacking any atom (not just mob) with this item (item, atom/target, mob/user, reach, params)
#define COMSIG_ITEM_AFTERATTACK "itm_afterattack"
/// When the item in hand is twirl emoted and spun in hand. (user, item)
#define COMSIG_ITEM_TWIRLED "itm_twirled"

// ---- bomb assembly signals ----

Expand Down
74 changes: 74 additions & 0 deletions code/datums/components/bloodflick.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
TYPEINFO(/datum/component/bloodflick)
initialization_args = list()

/// a component that makes items flick blood off them and onto the ground when twirled.
/datum/component/bloodflick
/// is the blood on the parent dried? if so, can't be cleaned by flicking.
var/hasdry = FALSE
/// Can blood be flicked off?
var/haswet = FALSE
/// a counter. represents how many sets of wet blood are on the parent
var/iswet = 0
/// how long the blood takes to dry.
var/drytime = 30 SECONDS
/// typecasted parent
var/obj/item/weapon

/datum/component/bloodflick/Initialize()
if (!isitem(src.parent))
return COMPONENT_INCOMPATIBLE
src.weapon = src.parent
RegisterSignal(parent, COMSIG_ITEM_TWIRLED, PROC_REF(flickblood))
RegisterSignal(parent, COMSIG_ITEM_ATTACK_POST, PROC_REF(wetten))
RegisterSignal(parent, COMSIG_ATOM_CLEANED, PROC_REF(clean))
..()

/datum/component/bloodflick/UnregisterFromParent()
UnregisterSignal(parent, COMSIG_ITEM_TWIRLED)
UnregisterSignal(parent, COMSIG_ITEM_ATTACK_POST)
UnregisterSignal(parent, COMSIG_ATOM_CLEANED)
..()

/datum/component/bloodflick/proc/flickblood()
if (!src.weapon.blood_DNA)
return
// if all the blood is wet, flicking it off cleans it.
if (!src.hasdry)
src.weapon.clean_forensic()
// if there's wet blood on it, flick it off
if (src.haswet)
src.haswet = FALSE
make_cleanable(/obj/decal/cleanable/blood, get_turf(src.parent))
playsound(src.weapon.loc, 'sound/impact_sounds/Slimy_Splat_1.ogg', 40, 1)
SPAWN(1 DECI SECOND) // so that the twirl emote message appears first (in theory)
boutput("<span class='notice'>Blood splatters onto the floor!</span>")

/// applies wet blood to the knife and starts the blood drying countdown
/datum/component/bloodflick/proc/wetten()
var/obj/item/dummy = src.parent
if (!dummy.blood_DNA) // not all attacks leave blood on the parent
return
if (!src.haswet)
src.haswet = TRUE
src.iswet += 1
SPAWN(drytime)
// it could get cleaned while it's drying
if (!dummy.blood_DNA)
src.hasdry = FALSE
src.haswet = FALSE
src.iswet = 0
// just in case
return
// if the parent is wet, dry it
if (src.haswet)
src.hasdry = TRUE
src.iswet -= 1
// if there's no more lingering sets of wet blood waiting to dry, dry the parent
if (!src.iswet)
src.haswet = FALSE

/// resets the variables
/datum/component/bloodflick/proc/clean()
src.hasdry = FALSE
src.haswet = FALSE
src.iswet = 0
1 change: 1 addition & 0 deletions code/mob/living/carbon/human/procs/emote.dm
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,7 @@
else if (src.r_hand)
thing = src.r_hand
if (thing)
SEND_SIGNAL(thing, COMSIG_ITEM_TWIRLED, src, thing)
message = thing.on_spin_emote(src)
maptext_out = "<I>twirls [thing]</I>"
animate_spin(thing, prob(50) ? "L" : "R", 1, 0)
Expand Down
1 change: 1 addition & 0 deletions code/modules/forensics/atom_forensic.dm
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@
L.forensics_blood_color = null
L.tracked_blood = null
L.set_clothing_icon_dirty()
SEND_SIGNAL(src, COMSIG_ATOM_CLEANED)

/atom/movable/proc/track_blood()
return
Expand Down
1 change: 1 addition & 0 deletions code/obj/item/kitchen.dm
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ TRAYS

New()
..()
src.AddComponent(/datum/component/bloodflick)
src.setItemSpecial(/datum/item_special/double)

attack(mob/living/carbon/M, mob/living/carbon/user)
Expand Down
6 changes: 6 additions & 0 deletions code/obj/item/misc_weapons.dm
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,7 @@ TYPEINFO(/obj/item/sword/pink/angel)

/obj/item/knife/butcher/New()
..()
src.AddComponent(/datum/component/bloodflick)
BLOCK_SETUP(BLOCK_KNIFE)

/obj/item/knife/butcher/throw_impact(atom/A, datum/thrown_thing/thr)
Expand Down Expand Up @@ -1123,6 +1124,10 @@ TYPEINFO(/obj/item/bat)
var/midair_fruit_slice_stamina_cost = 7 //! The amount of stamina it costs to slice food midair
custom_suicide = 1

/obj/item/swords/New()
src.AddComponent(/datum/component/bloodflick)
..()

/obj/item/swords/proc/handle_parry(mob/target, mob/user)
if (target != user && ishuman(target))
var/mob/living/carbon/human/H = target
Expand Down Expand Up @@ -1708,6 +1713,7 @@ obj/item/whetstone
New()
..()
START_TRACKING_CAT(TR_CAT_NUKE_OP_STYLE)
src.AddComponent(/datum/component/bloodflick)
src.setItemSpecial(/datum/item_special/swipe)
src.update_special_color()
AddComponent(/datum/component/itemblock/saberblock, null, PROC_REF(get_reflect_color))
Expand Down
1 change: 1 addition & 0 deletions goonstation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ var/datum/preMapLoad/preMapLoad = new
#include "code\datums\components\baseball_bat_reflect.dm"
#include "code\datums\components\battleroyale_death.dm"
#include "code\datums\components\biodegradable.dm"
#include "code\datums\components\bloodflick.dm"
#include "code\datums\components\buildableturf.dm"
#include "code\datums\components\bullet_holes.dm"
#include "code\datums\components\cell_holder.dm"
Expand Down

0 comments on commit 78cd1bf

Please sign in to comment.