Files
Bubberstation/code/datums/components/squashable.dm
SkyratBot 169c42a262 [MIRROR] Refactors connect_loc_behalf into a component (#7613)
* Refactors connect_loc_behalf into a component (#60678)

See title. Also refactors caltrops into a component because they use connect_loc_behalf which requires them to hold the state.

This also fixes COMPONENT_DUPE_SELECTIVE from just outright not working.

connect_loc_behalf doesn't make sense as an element because it tries to hold states. There is also no way to maintain current behaviour and not have the states that it needs.
Due to the fact that it tries to hold states, it means the code itself is a lot more buggy because it's a lot harder to successfully manage these states without runtimes or bugs. 

On metastation, there is only 2519 connect_loc_behalf components at roundstart. MrStonedOne has told me that datums take up this much space:
image

If we do the (oversimplified) math, there are only ever 5 variables that'll likely be changed on most connect_loc_behalf components at runtime:
connections,
tracked,
signal_atom,
parent,
signal_procs

This means that on metastation at roundstart, we take up this amount: (24 + 16 * 5) * 2519 = 261.97600 kilobytes
This is not really significant and the benefits of moving this to a component greatly outweighs the memory cost.

(Basically the memory cost is outweighed by the maint cost of tracking down issues with the thing. It's too buggy to be viable longterm basically)

* Update glass.dm

Co-authored-by: Watermelon914 <37270891+Watermelon914@users.noreply.github.com>
Co-authored-by: Gandalf <jzo123@hotmail.com>
2021-08-17 20:29:11 +01:00

76 lines
2.8 KiB
Plaintext

///This component allows something to be when crossed, for example for cockroaches.
/datum/component/squashable
///Chance on crossed to be squashed
var/squash_chance = 50
///How much brute is applied when mob is squashed
var/squash_damage = 1
///Squash flags, for extra checks etcetera.
var/squash_flags = NONE
///Special callback to call on squash instead, for things like hauberoach
var/datum/callback/on_squash_callback
///signal list given to connect_loc
var/static/list/loc_connections = list(
COMSIG_ATOM_ENTERED = .proc/on_entered,
)
/datum/component/squashable/Initialize(squash_chance, squash_damage, squash_flags, squash_callback)
. = ..()
if(!isliving(parent))
return COMPONENT_INCOMPATIBLE
if(squash_chance)
src.squash_chance = squash_chance
if(squash_damage)
src.squash_damage = squash_damage
if(squash_flags)
src.squash_flags = squash_flags
if(!src.on_squash_callback && squash_callback)
on_squash_callback = CALLBACK(parent, squash_callback)
AddComponent(/datum/component/connect_loc_behalf, parent, loc_connections)
///Handles the squashing of the mob
/datum/component/squashable/proc/on_entered(turf/source_turf, atom/movable/crossing_movable)
SIGNAL_HANDLER
if(parent == crossing_movable)
return
var/mob/living/parent_as_living = parent
if(squash_flags & SQUASHED_SHOULD_BE_DOWN && parent_as_living.body_position != LYING_DOWN)
return
var/should_squash = prob(squash_chance)
if(should_squash && on_squash_callback)
if(on_squash_callback.Invoke(parent_as_living, crossing_movable))
return //Everything worked, we're done!
if(isliving(crossing_movable))
var/mob/living/crossing_mob = crossing_movable
if(crossing_mob.mob_size > MOB_SIZE_SMALL && !(crossing_mob.movement_type & FLYING))
if(HAS_TRAIT(crossing_mob, TRAIT_PACIFISM))
crossing_mob.visible_message(span_notice("[crossing_mob] carefully steps over [parent_as_living]."), span_notice("You carefully step over [parent_as_living] to avoid hurting it."))
return
if(should_squash)
crossing_mob.visible_message(span_notice("[crossing_mob] squashed [parent_as_living]."), span_notice("You squashed [parent_as_living]."))
Squish(parent_as_living)
else
parent_as_living.visible_message(span_notice("[parent_as_living] avoids getting crushed."))
else if(isstructure(crossing_movable))
if(should_squash)
crossing_movable.visible_message(span_notice("[parent_as_living] is crushed under [crossing_movable]."))
Squish(parent_as_living)
else
parent_as_living.visible_message(span_notice("[parent_as_living] avoids getting crushed."))
/datum/component/squashable/proc/Squish(mob/living/target)
if(squash_flags & SQUASHED_SHOULD_BE_GIBBED)
target.gib()
else
target.adjustBruteLoss(squash_damage)
/datum/component/squashable/UnregisterFromParent()
. = ..()
qdel(GetComponent(/datum/component/connect_loc_behalf))