mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-20 06:32:56 +00:00
* [no gbp] Golem mineral functionality tweaks/fixes (#75343) ## About The Pull Request Fixes a couple of things people have pointed out about golem transformations. - Diamond golems now stop being invisible when they attack or throw something, they also turn invisible a bit slower. - Using a bluespace knot takes 2 seconds instead of 3 seconds. - Bananium Golems only slip you if they are lying down. In order to achieve that last one I refactored the slipperiness component to take an optional extra callback, and then killed a subtype of it which could be replaced with passing in a callback. I tested it and it seems to work the same as it used to. These are largely how things were supposed to work and I just overlooked them. I am sure this won't be the last PR of a similar vein while people try these out, provided that I actually hear anything they are saying about it. ## Why It's Good For The Game Diamond golems shouldn't be able to attack you while remaining invisible and untargetable even if it is funny. Clown golems aren't supposed to be able to slip you by swapping places with you even if it is funny. The bluespace hand was basically just worse than using the crystal and not eating it, maybe still needs another buff after this one. ## Changelog 🆑 fix: Diamond Golems can no longer attack or throw things and remain invisible. fix: Bananium Golems are only slippery if you actually tread on them (aka: while they are resting). balance: Golem bluespace teleportation is slightly quicker. /🆑 --------- Co-authored-by: san7890 <the@ san7890.com> * [no gbp] Golem mineral functionality tweaks/fixes --------- Co-authored-by: Jacquerel <hnevard@gmail.com> Co-authored-by: san7890 <the@ san7890.com>
173 lines
6.0 KiB
Plaintext
173 lines
6.0 KiB
Plaintext
/// Slippery component, for making anything slippery. Of course.
|
|
/datum/component/slippery
|
|
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
|
|
/// If the slip forces you to drop held items.
|
|
var/force_drop_items = FALSE
|
|
/// How long the slip keeps you knocked down.
|
|
var/knockdown_time = 0
|
|
/// How long the slip paralyzes for.
|
|
var/paralyze_time = 0
|
|
/// Flags for how slippery the parent is. See [__DEFINES/mobs.dm]
|
|
var/lube_flags
|
|
/// Optional callback providing an additional chance to prevent slippage
|
|
var/datum/callback/can_slip_callback
|
|
/// A proc callback to call on slip.
|
|
var/datum/callback/on_slip_callback
|
|
/// If parent is an item, this is the person currently holding/wearing the parent (or the parent if no one is holding it)
|
|
var/mob/living/holder
|
|
/// Whitelist of item slots the parent can be equipped in that make the holder slippery. If null or empty, it will always make the holder slippery.
|
|
var/list/slot_whitelist = list(ITEM_SLOT_OCLOTHING, ITEM_SLOT_ICLOTHING, ITEM_SLOT_GLOVES, ITEM_SLOT_FEET, ITEM_SLOT_HEAD, ITEM_SLOT_MASK, ITEM_SLOT_BELT, ITEM_SLOT_NECK)
|
|
///what we give to connect_loc by default, makes slippable mobs moving over us slip
|
|
var/static/list/default_connections = list(
|
|
COMSIG_ATOM_ENTERED = PROC_REF(Slip),
|
|
)
|
|
|
|
///what we give to connect_loc if we're an item and get equipped by a mob. makes slippable mobs moving over our holder slip
|
|
var/static/list/holder_connections = list(
|
|
COMSIG_ATOM_ENTERED = PROC_REF(Slip_on_wearer),
|
|
)
|
|
|
|
/// The connect_loc_behalf component for the holder_connections list.
|
|
var/datum/weakref/holder_connect_loc_behalf
|
|
|
|
/datum/component/slippery/Initialize(
|
|
knockdown,
|
|
lube_flags = NONE,
|
|
datum/callback/on_slip_callback,
|
|
paralyze,
|
|
force_drop = FALSE,
|
|
slot_whitelist,
|
|
datum/callback/can_slip_callback,
|
|
)
|
|
src.knockdown_time = max(knockdown, 0)
|
|
src.paralyze_time = max(paralyze, 0)
|
|
src.force_drop_items = force_drop
|
|
src.lube_flags = lube_flags
|
|
src.can_slip_callback = can_slip_callback
|
|
src.on_slip_callback = on_slip_callback
|
|
if(slot_whitelist)
|
|
src.slot_whitelist = slot_whitelist
|
|
|
|
add_connect_loc_behalf_to_parent()
|
|
if(ismovable(parent))
|
|
if(isitem(parent))
|
|
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(on_equip))
|
|
RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(on_drop))
|
|
else
|
|
RegisterSignal(parent, COMSIG_ATOM_ENTERED, PROC_REF(Slip))
|
|
|
|
/datum/component/slippery/proc/add_connect_loc_behalf_to_parent()
|
|
if(ismovable(parent))
|
|
AddComponent(/datum/component/connect_loc_behalf, parent, default_connections)
|
|
|
|
/datum/component/slippery/InheritComponent(
|
|
datum/component/slippery/component,
|
|
i_am_original,
|
|
knockdown,
|
|
lube_flags = NONE,
|
|
datum/callback/on_slip_callback,
|
|
paralyze,
|
|
force_drop = FALSE,
|
|
slot_whitelist,
|
|
datum/callback/can_slip_callback,
|
|
)
|
|
if(component)
|
|
knockdown = component.knockdown_time
|
|
lube_flags = component.lube_flags
|
|
on_slip_callback = component.on_slip_callback
|
|
can_slip_callback = component.on_slip_callback
|
|
paralyze = component.paralyze_time
|
|
force_drop = component.force_drop_items
|
|
slot_whitelist = component.slot_whitelist
|
|
|
|
src.knockdown_time = max(knockdown, 0)
|
|
src.paralyze_time = max(paralyze, 0)
|
|
src.force_drop_items = force_drop
|
|
src.lube_flags = lube_flags
|
|
src.on_slip_callback = on_slip_callback
|
|
src.can_slip_callback = can_slip_callback
|
|
if(slot_whitelist)
|
|
src.slot_whitelist = slot_whitelist
|
|
/*
|
|
* The proc that does the sliping. Invokes the slip callback we have set.
|
|
*
|
|
* source - the source of the signal
|
|
* AM - the atom/movable that is being slipped.
|
|
*/
|
|
/datum/component/slippery/proc/Slip(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs)
|
|
SIGNAL_HANDLER
|
|
if(!isliving(arrived))
|
|
return
|
|
var/mob/living/victim = arrived
|
|
if((victim.movement_type & (FLYING | FLOATING)))
|
|
return
|
|
if(can_slip_callback && !can_slip_callback.Invoke(holder, victim))
|
|
return
|
|
if(victim.slip(knockdown_time, parent, lube_flags, paralyze_time, force_drop_items))
|
|
on_slip_callback?.Invoke(victim)
|
|
|
|
/*
|
|
* Gets called when COMSIG_ITEM_EQUIPPED is sent to parent.
|
|
* This proc register slip signals to the equipper.
|
|
* If we have a slot whitelist, we only register the signals if the slot is valid (ex: clown PDA only slips in ID or belt slot).
|
|
*
|
|
* source - the source of the signal
|
|
* equipper - the mob we're equipping the slippery thing to
|
|
* slot - the slot we're equipping the slippery thing to on the equipper.
|
|
*/
|
|
/datum/component/slippery/proc/on_equip(datum/source, mob/equipper, slot)
|
|
SIGNAL_HANDLER
|
|
|
|
if((!LAZYLEN(slot_whitelist) || (slot in slot_whitelist)) && isliving(equipper))
|
|
holder = equipper
|
|
qdel(GetComponent(/datum/component/connect_loc_behalf))
|
|
AddComponent(/datum/component/connect_loc_behalf, holder, holder_connections)
|
|
RegisterSignal(holder, COMSIG_PARENT_QDELETING, PROC_REF(holder_deleted))
|
|
|
|
/*
|
|
* Detects if the holder mob is deleted.
|
|
* If our holder mob is the holder set in this component, we null it.
|
|
*
|
|
* source - the source of the signal
|
|
* possible_holder - the mob being deleted.
|
|
*/
|
|
/datum/component/slippery/proc/holder_deleted(datum/source, datum/possible_holder)
|
|
SIGNAL_HANDLER
|
|
|
|
if(possible_holder == holder)
|
|
holder = null
|
|
|
|
/*
|
|
* Gets called when COMSIG_ITEM_DROPPED is sent to parent.
|
|
* Makes our holder mob un-slippery.
|
|
*
|
|
* source - the source of the signal
|
|
* user - the mob that was formerly wearing our slippery item.
|
|
*/
|
|
/datum/component/slippery/proc/on_drop(datum/source, mob/user)
|
|
SIGNAL_HANDLER
|
|
|
|
UnregisterSignal(user, COMSIG_PARENT_QDELETING)
|
|
|
|
qdel(GetComponent(/datum/component/connect_loc_behalf))
|
|
add_connect_loc_behalf_to_parent()
|
|
|
|
holder = null
|
|
|
|
/*
|
|
* The slip proc, but for equipped items.
|
|
* Slips the person who crossed us if we're lying down and unbuckled.
|
|
*
|
|
* source - the source of the signal
|
|
* AM - the atom/movable that slipped on us.
|
|
*/
|
|
/datum/component/slippery/proc/Slip_on_wearer(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs)
|
|
SIGNAL_HANDLER
|
|
|
|
if(holder.body_position == LYING_DOWN && !holder.buckled)
|
|
Slip(source, arrived)
|
|
|
|
/datum/component/slippery/UnregisterFromParent()
|
|
. = ..()
|
|
qdel(GetComponent(/datum/component/connect_loc_behalf))
|