Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

twirl knife to flick off the blood #15554

Merged
merged 12 commits into from
Sep 13, 2023
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 @@ -1122,6 +1123,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 @@ -1707,6 +1712,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 @@ -190,6 +190,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