mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-25 14:08:31 +01:00
Fixes Knockdown signal being incorrect, making knock-off items (and others) trigger when they should again. Also cleans up the knockoff component and unit tests it. (#67720)
At some point, someone did a find and replace over this file, and completely screwed up the signal for Knockdown(). This caused components that relied on it, like the Knockoff component, to work way less often. This PR fixes that. It also goes through and cleans up the Knockoff component. More consistent style guide stuff, minor improvements, better documentation. It also unit tests it.
This commit is contained in:
@@ -1,71 +1,99 @@
|
||||
///Items with these will have a chance to get knocked off when disarming or being knocked down
|
||||
/// Items with this component will have a chance to get knocked off
|
||||
/// (unequipped and sent to the ground) when the wearer is disarmed or knocked down.
|
||||
/datum/component/knockoff
|
||||
///Chance to knockoff
|
||||
/// Chance to knockoff when a knockoff action occurs.
|
||||
var/knockoff_chance = 100
|
||||
///Aiming for these zones will cause the knockoff, null means all zones allowed
|
||||
/// Used in being disarmed.
|
||||
/// If set, we will only roll the knockoff chance if the disarmer is targeting one of these zones.
|
||||
/// If unset, any disarm act will cause the knock-off chance to be rolled, no matter the zone targeted.
|
||||
var/list/target_zones
|
||||
///Can be only knocked off from these slots, null means all slots allowed
|
||||
var/list/slots_knockoffable
|
||||
/// Bitflag used in equip to determine what slots we need to be in to be knocked off.
|
||||
/// If set, we must be equipped in one of the slots to have a chance of our item being knocked off.
|
||||
/// If unset / NONE, a disarm or knockdown will have a chance of our item being knocked off regardless of slot, INCLUDING hand slots.
|
||||
var/slots_knockoffable = NONE
|
||||
|
||||
/datum/component/knockoff/Initialize(knockoff_chance,zone_override,slots_knockoffable)
|
||||
/datum/component/knockoff/Initialize(knockoff_chance = 100, target_zones, slots_knockoffable = NONE)
|
||||
if(!isitem(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED,.proc/OnEquipped)
|
||||
RegisterSignal(parent, COMSIG_ITEM_DROPPED,.proc/OnDropped)
|
||||
|
||||
src.knockoff_chance = knockoff_chance
|
||||
src.target_zones = target_zones
|
||||
src.slots_knockoffable = slots_knockoffable
|
||||
|
||||
if(zone_override)
|
||||
target_zones = zone_override
|
||||
/datum/component/knockoff/RegisterWithParent()
|
||||
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equipped)
|
||||
RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_dropped)
|
||||
|
||||
if(slots_knockoffable)
|
||||
src.slots_knockoffable = slots_knockoffable
|
||||
/datum/component/knockoff/UnregisterFromParent()
|
||||
UnregisterSignal(parent, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED))
|
||||
|
||||
///Tries to knockoff the item when disarmed
|
||||
/datum/component/knockoff/proc/Knockoff(mob/living/carbon/human/wearer,mob/living/attacker,zone)
|
||||
var/obj/item/item_parent = parent
|
||||
if(ismob(item_parent.loc))
|
||||
UnregisterSignal(item_parent.loc, list(COMSIG_HUMAN_DISARM_HIT, COMSIG_LIVING_STATUS_KNOCKDOWN))
|
||||
|
||||
/// Signal proc for [COMSIG_HUMAN_DISARM_HIT] on the mob who's equipped our parent
|
||||
/// Rolls a chance for knockoff whenever we're disarmed
|
||||
/datum/component/knockoff/proc/on_equipped_mob_disarm(mob/living/carbon/human/source, mob/living/attacker, zone)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/obj/item/item = parent
|
||||
if(!istype(wearer))
|
||||
if(!istype(source))
|
||||
return
|
||||
|
||||
if(target_zones && !(zone in target_zones))
|
||||
return
|
||||
if(!prob(knockoff_chance))
|
||||
return
|
||||
if(!wearer.dropItemToGround(item))
|
||||
return
|
||||
wearer.visible_message(span_warning("[attacker] knocks off [wearer]'s [item.name]!"),span_userdanger("[attacker] knocks off your [item.name]!"))
|
||||
|
||||
///Tries to knockoff the item when user is knocked down
|
||||
/datum/component/knockoff/proc/Knockoff_knockdown(mob/living/carbon/human/wearer,amount)
|
||||
var/obj/item/item_parent = parent
|
||||
if(!source.dropItemToGround(item_parent))
|
||||
return
|
||||
|
||||
source.visible_message(
|
||||
span_warning("[attacker] knocks off [source]'s [item_parent.name]!"),
|
||||
span_userdanger("[attacker] knocks off your [item_parent.name]!"),
|
||||
)
|
||||
|
||||
/// Signal proc for [COMSIG_LIVING_STATUS_KNOCKDOWN] on the mob who's equipped our parent
|
||||
/// Rolls a chance for knockoff whenever we're knocked down
|
||||
/datum/component/knockoff/proc/on_equipped_mob_knockdown(mob/living/carbon/human/source, amount)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(amount <= 0)
|
||||
if(!istype(source))
|
||||
return
|
||||
|
||||
var/obj/item/item = parent
|
||||
if(!istype(wearer))
|
||||
// Healing knockdown or setting knockdown to zero or something? Don't knock off.
|
||||
if(amount <= 0)
|
||||
return
|
||||
if(!prob(knockoff_chance))
|
||||
return
|
||||
if(!wearer.dropItemToGround(item))
|
||||
return
|
||||
wearer.visible_message(span_warning("[wearer]'s [item.name] get[item.p_s()] knocked off!"),span_userdanger("Your [item.name] [item.p_were()] knocked off!"))
|
||||
|
||||
|
||||
/datum/component/knockoff/proc/OnEquipped(datum/source, mob/living/carbon/human/H,slot)
|
||||
SIGNAL_HANDLER
|
||||
if(!istype(H))
|
||||
var/obj/item/item_parent = parent
|
||||
if(!source.dropItemToGround(item_parent))
|
||||
return
|
||||
if(slots_knockoffable && !(slot in slots_knockoffable))
|
||||
UnregisterSignal(H, COMSIG_HUMAN_DISARM_HIT)
|
||||
UnregisterSignal(H, COMSIG_LIVING_STATUS_KNOCKDOWN)
|
||||
return
|
||||
RegisterSignal(H, COMSIG_HUMAN_DISARM_HIT, .proc/Knockoff, TRUE)
|
||||
RegisterSignal(H, COMSIG_LIVING_STATUS_KNOCKDOWN, .proc/Knockoff_knockdown, TRUE)
|
||||
|
||||
/datum/component/knockoff/proc/OnDropped(datum/source, mob/living/M)
|
||||
source.visible_message(
|
||||
span_warning("[source]'s [item_parent.name] get[item_parent.p_s()] knocked off!"),
|
||||
span_userdanger("Your [item_parent.name] [item_parent.p_were()] knocked off!"),
|
||||
)
|
||||
|
||||
/// Signal proc for [COMSIG_ITEM_EQUIPPED]
|
||||
/// Registers our signals which can cause a knockdown whenever we're equipped correctly
|
||||
/datum/component/knockoff/proc/on_equipped(datum/source, mob/living/carbon/human/equipper, slot)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
UnregisterSignal(M, COMSIG_HUMAN_DISARM_HIT)
|
||||
UnregisterSignal(M, COMSIG_LIVING_STATUS_KNOCKDOWN)
|
||||
if(!istype(equipper))
|
||||
return
|
||||
|
||||
if(slots_knockoffable && !(slot & slots_knockoffable))
|
||||
UnregisterSignal(equipper, list(COMSIG_HUMAN_DISARM_HIT, COMSIG_LIVING_STATUS_KNOCKDOWN))
|
||||
return
|
||||
|
||||
RegisterSignal(equipper, COMSIG_HUMAN_DISARM_HIT, .proc/on_equipped_mob_disarm, TRUE)
|
||||
RegisterSignal(equipper, COMSIG_LIVING_STATUS_KNOCKDOWN, .proc/on_equipped_mob_knockdown, TRUE)
|
||||
|
||||
/// Signal proc for [COMSIG_ITEM_DROPPED]
|
||||
/// Unregisters our signals which can cause a knockdown when we're unequipped (dropped)
|
||||
/datum/component/knockoff/proc/on_dropped(datum/source, mob/living/dropper)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
UnregisterSignal(dropper, list(COMSIG_HUMAN_DISARM_HIT, COMSIG_LIVING_STATUS_KNOCKDOWN))
|
||||
|
||||
Reference in New Issue
Block a user