mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 17:52:36 +00:00
* Refactors embedding to use datums instead of storing data in bespoke elements (#84599) ## About The Pull Request This refactors embedding elements to make them use singleton datums (similarly to armor) instead being bespoke and creating a new element every time armor values are supposed to be adjusted. Default values have been removed from defines due to now being declared in base class itself. Additionally fixes vending machines and tackling gloves setting generated shards (which they instantly embed into their victim) embed properties to null after running the embedding code, despite said shards having non-null embedding values by default, making them not be able to embed into anyone else, also potentially breaking the pain/jostling code if they somehow get updated. ## Why It's Good For The Game Current embedding system is an unnecessarily complicated mess as bespoke elements are hard to work with, and creating a new element every time you change values is hacky at best. This change should make it easier to read and work with. ## Changelog 🆑 fix: Fixed glass shards generated from falling vending machines or tackling windows not being able to embed into anyone. refactor: Refactored embedding code to use datums instead of bespoke elements and ugly associated lists. /🆑 * Refactors embedding to use datums instead of storing data in bespoke elements * modular fixes * fix c14 * paint -> pain ugggh --------- Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Co-authored-by: SpaceLoveSs13 <68121607+SpaceLoveSs13@users.noreply.github.com>
158 lines
7.6 KiB
Plaintext
158 lines
7.6 KiB
Plaintext
/**
|
|
* Component for allowing items to be inserted into foam darts.
|
|
* The parent can register signal handlers for `COMSIG_DART_INSERT_ADDED`,
|
|
* `COMSIG_DART_INSERT_REMOVED` to define custom behavior for when the item
|
|
* is added to/removed from a dart, and `COMSIG_DART_INSERT_GET_VAR_MODIFIERS`
|
|
* to define the modifications the item makes to the vars of the fired projectile.
|
|
*/
|
|
/datum/component/dart_insert
|
|
/// List for tracking the modifications this component has made to the vars of the containing projectile
|
|
var/list/var_modifiers
|
|
/// A reference to the ammo casing this component's parent was inserted into
|
|
var/obj/item/ammo_casing/holder_casing
|
|
/// A reference to the projectile this component's parent was inserted into
|
|
var/obj/projectile/holder_projectile
|
|
/// The icon file used for the overlay applied over the containing ammo casing
|
|
var/casing_overlay_icon
|
|
/// The icon state used for the overlay applied over the containing ammo casing
|
|
var/casing_overlay_icon_state
|
|
/// The icon file used for the overlay applied over the containing projectile
|
|
var/projectile_overlay_icon
|
|
/// The icon state used for the overlay applied over the containing projectile
|
|
var/projectile_overlay_icon_state
|
|
/// Optional callback to invoke when acquiring projectile var modifiers
|
|
var/datum/callback/modifier_getter
|
|
|
|
/datum/component/dart_insert/Initialize(_casing_overlay_icon, _casing_overlay_icon_state, _projectile_overlay_icon, _projectile_overlay_icon_state, datum/callback/_modifier_getter)
|
|
if(!isitem(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
casing_overlay_icon = _casing_overlay_icon
|
|
casing_overlay_icon_state = _casing_overlay_icon_state
|
|
projectile_overlay_icon = _projectile_overlay_icon
|
|
projectile_overlay_icon_state = _projectile_overlay_icon_state
|
|
modifier_getter = _modifier_getter
|
|
|
|
/datum/component/dart_insert/RegisterWithParent()
|
|
. = ..()
|
|
RegisterSignal(parent, COMSIG_ITEM_PRE_ATTACK, PROC_REF(on_preattack))
|
|
RegisterSignal(parent, COMSIG_OBJ_RESKIN, PROC_REF(on_reskin))
|
|
|
|
/datum/component/dart_insert/UnregisterFromParent()
|
|
. = ..()
|
|
var/obj/item/parent_item = parent
|
|
var/parent_loc = parent_item.loc
|
|
if(parent_loc && (parent_loc == holder_casing || parent_loc == holder_projectile))
|
|
parent_item.forceMove(get_turf(parent_item))
|
|
remove_from_dart(holder_casing, holder_projectile)
|
|
UnregisterSignal(parent, COMSIG_ITEM_PRE_ATTACK)
|
|
|
|
/datum/component/dart_insert/proc/on_preattack(datum/source, atom/target, mob/user, params)
|
|
SIGNAL_HANDLER
|
|
var/obj/item/ammo_casing/foam_dart/dart = target
|
|
if(!istype(dart))
|
|
return
|
|
if(!dart.modified)
|
|
to_chat(user, span_warning("The safety cap prevents you from inserting [parent] into [dart]."))
|
|
return COMPONENT_CANCEL_ATTACK_CHAIN
|
|
if(HAS_TRAIT(dart, TRAIT_DART_HAS_INSERT))
|
|
to_chat(user, span_warning("There's already something in [dart]."))
|
|
return COMPONENT_CANCEL_ATTACK_CHAIN
|
|
add_to_dart(dart, user)
|
|
return COMPONENT_CANCEL_ATTACK_CHAIN
|
|
|
|
/datum/component/dart_insert/proc/on_reskin(datum/source, mob/user, skin)
|
|
SIGNAL_HANDLER
|
|
SEND_SIGNAL(parent, COMSIG_DART_INSERT_PARENT_RESKINNED)
|
|
|
|
/datum/component/dart_insert/proc/add_to_dart(obj/item/ammo_casing/dart, mob/user)
|
|
var/obj/projectile/dart_projectile = dart.loaded_projectile
|
|
var/obj/item/parent_item = parent
|
|
if(user)
|
|
if(!user.transferItemToLoc(parent_item, dart_projectile))
|
|
return
|
|
to_chat(user, span_notice("You insert [parent_item] into [dart]."))
|
|
else
|
|
parent_item.forceMove(dart_projectile)
|
|
ADD_TRAIT(dart, TRAIT_DART_HAS_INSERT, REF(src))
|
|
RegisterSignal(dart, COMSIG_ITEM_ATTACK_SELF, PROC_REF(on_dart_attack_self))
|
|
RegisterSignal(dart, COMSIG_ATOM_EXAMINE_MORE, PROC_REF(on_dart_examine_more))
|
|
RegisterSignals(parent, list(COMSIG_QDELETING, COMSIG_MOVABLE_MOVED), PROC_REF(on_leave_dart))
|
|
RegisterSignal(dart, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_casing_update_overlays))
|
|
RegisterSignal(dart_projectile, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_projectile_update_overlays))
|
|
RegisterSignals(dart_projectile, list(COMSIG_PROJECTILE_ON_SPAWN_DROP, COMSIG_PROJECTILE_ON_SPAWN_EMBEDDED), PROC_REF(on_spawn_drop))
|
|
apply_var_modifiers(dart_projectile)
|
|
dart.harmful = dart_projectile.damage > 0 || dart_projectile.wound_bonus > 0 || dart_projectile.bare_wound_bonus > 0
|
|
SEND_SIGNAL(parent, COMSIG_DART_INSERT_ADDED, dart)
|
|
dart.update_appearance()
|
|
dart_projectile.update_appearance()
|
|
holder_casing = dart
|
|
holder_projectile = dart_projectile
|
|
|
|
/datum/component/dart_insert/proc/remove_from_dart(obj/item/ammo_casing/dart, obj/projectile/projectile, mob/user)
|
|
holder_casing = null
|
|
holder_projectile = null
|
|
if(istype(dart))
|
|
UnregisterSignal(dart, list(COMSIG_ITEM_ATTACK_SELF, COMSIG_ATOM_EXAMINE_MORE, COMSIG_ATOM_UPDATE_OVERLAYS))
|
|
REMOVE_TRAIT(dart, TRAIT_DART_HAS_INSERT, REF(src))
|
|
dart.update_appearance()
|
|
if(istype(projectile))
|
|
remove_var_modifiers(projectile)
|
|
UnregisterSignal(projectile, list(COMSIG_PROJECTILE_ON_SPAWN_DROP, COMSIG_PROJECTILE_ON_SPAWN_EMBEDDED, COMSIG_ATOM_UPDATE_OVERLAYS))
|
|
if(dart?.loaded_projectile == projectile)
|
|
dart.harmful = projectile.damage > 0 || projectile.wound_bonus > 0 || projectile.bare_wound_bonus > 0
|
|
projectile.update_appearance()
|
|
SEND_SIGNAL(parent, COMSIG_DART_INSERT_REMOVED, dart, projectile, user)
|
|
UnregisterSignal(parent, list(COMSIG_QDELETING, COMSIG_MOVABLE_MOVED))
|
|
if(user)
|
|
INVOKE_ASYNC(user, TYPE_PROC_REF(/mob, put_in_hands), parent)
|
|
to_chat(user, span_notice("You remove [parent] from [dart]."))
|
|
|
|
/datum/component/dart_insert/proc/on_dart_attack_self(datum/source, mob/user)
|
|
SIGNAL_HANDLER
|
|
remove_from_dart(holder_casing, holder_projectile, user)
|
|
|
|
/datum/component/dart_insert/proc/on_dart_examine_more(datum/source, mob/user, list/examine_list)
|
|
var/obj/item/parent_item = parent
|
|
examine_list += span_notice("You can see a [parent_item.name] inserted into it.")
|
|
|
|
/datum/component/dart_insert/proc/on_leave_dart()
|
|
SIGNAL_HANDLER
|
|
remove_from_dart(holder_casing, holder_projectile)
|
|
|
|
/datum/component/dart_insert/proc/on_spawn_drop(datum/source, obj/item/ammo_casing/new_casing)
|
|
SIGNAL_HANDLER
|
|
UnregisterSignal(parent, list(COMSIG_QDELETING, COMSIG_MOVABLE_MOVED))
|
|
add_to_dart(new_casing)
|
|
|
|
/datum/component/dart_insert/proc/on_casing_update_overlays(datum/source, list/new_overlays)
|
|
SIGNAL_HANDLER
|
|
new_overlays += mutable_appearance(casing_overlay_icon, casing_overlay_icon_state)
|
|
|
|
/datum/component/dart_insert/proc/on_projectile_update_overlays(datum/source, list/new_overlays)
|
|
SIGNAL_HANDLER
|
|
new_overlays += mutable_appearance(projectile_overlay_icon, projectile_overlay_icon_state)
|
|
|
|
/datum/component/dart_insert/proc/apply_var_modifiers(obj/projectile/projectile)
|
|
var_modifiers = istype(modifier_getter) ? modifier_getter.Invoke() : list()
|
|
projectile.damage += var_modifiers["damage"]
|
|
if(var_modifiers["speed"])
|
|
var_modifiers["speed"] = reciprocal_add(projectile.speed, var_modifiers["speed"]) - projectile.speed
|
|
projectile.speed += var_modifiers["speed"]
|
|
projectile.armour_penetration += var_modifiers["armour_penetration"]
|
|
projectile.wound_bonus += var_modifiers["wound_bonus"]
|
|
projectile.bare_wound_bonus += var_modifiers["bare_wound_bonus"]
|
|
projectile.demolition_mod += var_modifiers["demolition_mod"]
|
|
if(var_modifiers["embedding"])
|
|
projectile.set_embed(var_modifiers["embedding"])
|
|
|
|
/datum/component/dart_insert/proc/remove_var_modifiers(obj/projectile/projectile)
|
|
projectile.damage -= var_modifiers["damage"]
|
|
projectile.speed -= var_modifiers["speed"]
|
|
projectile.armour_penetration -= var_modifiers["armour_penetration"]
|
|
projectile.wound_bonus -= var_modifiers["wound_bonus"]
|
|
projectile.bare_wound_bonus -= var_modifiers["bare_wound_bonus"]
|
|
projectile.demolition_mod -= var_modifiers["demolition_mod"]
|
|
if(var_modifiers["embedding"])
|
|
projectile.set_embed(initial(projectile.embed_type))
|
|
var_modifiers.Cut()
|