From 8167cd2f8c3b14eb410eba3584dcd131e430c635 Mon Sep 17 00:00:00 2001 From: AnturK Date: Sat, 16 Dec 2017 17:00:02 +0100 Subject: [PATCH] Knockoff component --- code/__DEFINES/components.dm | 1 + code/datums/components/knockoff.dm | 46 +++++++++++++++++++ code/game/objects/items.dm | 2 + .../mob/living/carbon/human/species.dm | 6 ++- tgstation.dme | 1 + 5 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 code/datums/components/knockoff.dm diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index b6b2c4cc774..7618aca8d07 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -74,6 +74,7 @@ // /mob/living/carbon/human signals #define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target) #define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker) +#define COMSIG_HUMAN_DISARM_HIT "human_disarm_hit" //Hit by successful disarm attack (mob/living/carbon/human/attacker,zone_targeted) #define CALTROP_BYPASS_SHOES 1 #define CALTROP_IGNORE_WALKERS 2 diff --git a/code/datums/components/knockoff.dm b/code/datums/components/knockoff.dm new file mode 100644 index 00000000000..f00e5c21fba --- /dev/null +++ b/code/datums/components/knockoff.dm @@ -0,0 +1,46 @@ +//Items with these will have a chance to get knocked off when disarming +/datum/component/knockoff + var/knockoff_chance = 100 //Chance to knockoff + var/list/target_zones //Aiming for these zones will cause the knockoff, null means all zones allowed + var/list/slots_knockoffable //Can be only knocked off from these slots, null means all slots allowed + var/datum/component/redirect/disarm_redirect + +/datum/component/knockoff/Initialize(knockoff_chance,zone_override,slots_knockoffable) + if(!isitem(parent)) + CRASH("Knockoff component misuse") + RegisterSignal(COMSIG_ITEM_EQUIPPED,.proc/OnEquipped) + RegisterSignal(COMSIG_ITEM_DROPPED,.proc/OnDropped) + + src.knockoff_chance = knockoff_chance + + if(zone_override) + target_zones = zone_override + + if(slots_knockoffable) + src.slots_knockoffable = slots_knockoffable + +/datum/component/knockoff/proc/Knockoff(mob/living/attacker,zone) + var/obj/item/I = parent + var/mob/living/carbon/human/wearer = I.loc + if(!istype(wearer)) + return + if(target_zones && !(zone in target_zones)) + return + if(prob(knockoff_chance)) + if(wearer.dropItemToGround(I)) + wearer.visible_message("[attacker] knocks off [wearer] [I.name]!","[attacker] knocks off your [I.name]!") + +/datum/component/knockoff/proc/OnEquipped(mob/living/carbon/human/H,slot) + if(!istype(H)) + return + if(slots_knockoffable && !(slot in slots_knockoffable)) + if(disarm_redirect) + QDEL_NULL(disarm_redirect) + return + if(!disarm_redirect) + disarm_redirect = H.AddComponent(/datum/component/redirect,list(COMSIG_HUMAN_DISARM_HIT),CALLBACK(src,.proc/Knockoff)) + +/datum/component/knockoff/proc/OnDropped(mob/living/M) + if(disarm_redirect) + QDEL_NULL(disarm_redirect) + diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index c7c3d7280b6..9c6d24142f7 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -412,6 +412,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) if(DROPDEL_1 & flags_1) qdel(src) in_inventory = FALSE + SendSignal(COMSIG_ITEM_DROPPED,user) // called just as an item is picked up (loc is not yet changed) /obj/item/proc/pickup(mob/user) @@ -442,6 +443,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/datum/action/A = X if(item_action_slot_check(slot, user)) //some items only give their actions buttons when in a specific slot. A.Grant(user) + SendSignal(COMSIG_ITEM_EQUIPPED,user,slot) in_inventory = TRUE //sometimes we only want to grant the item's action if it's equipped in a specific slot. diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 8c7a59a77d3..a85639faa09 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1216,10 +1216,12 @@ GLOBAL_LIST_EMPTY(roundstart_races) return 1 else user.do_attack_animation(target, ATTACK_EFFECT_DISARM) - + if(target.w_uniform) target.w_uniform.add_fingerprint(user) - var/obj/item/bodypart/affecting = target.get_bodypart(ran_zone(user.zone_selected)) + var/randomized_zone = ran_zone(user.zone_selected) + target.SendSignal(COMSIG_HUMAN_DISARM_HIT, user, user.zone_selected) + var/obj/item/bodypart/affecting = target.get_bodypart(randomized_zone) var/randn = rand(1, 100) if(randn <= 25) playsound(target, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) diff --git a/tgstation.dme b/tgstation.dme index cce449562f6..edc541587b3 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -307,6 +307,7 @@ #include "code\datums\components\caltrop.dm" #include "code\datums\components\chasm.dm" #include "code\datums\components\decal.dm" +#include "code\datums\components\knockoff.dm" #include "code\datums\components\infective.dm" #include "code\datums\components\jousting.dm" #include "code\datums\components\material_container.dm"