Files
Bubberstation/code/datums/components/swarming.dm
Jacquerel 8db829ab93 Swarming mobs spread out immediately (#91499)
## About The Pull Request

Mobs will check for swarming when an atom inits on their tile as well as
when one enters it

## Why It's Good For The Game

I was fucking around with the Hive Head changeling power and noticed
that the bees it spawns tend to stack up instead of spread out nicely,
and I didn't like that.

![image](https://github.com/user-attachments/assets/0c42ffbb-0183-4d56-bcd7-2352c1e16efd)

## Changelog

🆑
fix: Small stacking mobs like mice and bees will attempt to spread out
visually within their tile as soon as they spawn rather than just when
moving
/🆑
2025-06-15 15:42:21 -04:00

65 lines
2.0 KiB
Plaintext

/datum/component/swarming
var/offset_x = 0
var/offset_y = 0
var/is_swarming = FALSE
var/list/swarm_members = list()
var/static/list/swarming_loc_connections = list(
COMSIG_ATOM_EXITED = PROC_REF(leave_swarm),
COMSIG_ATOM_ENTERED = PROC_REF(join_swarm),
COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZED_ON = PROC_REF(join_swarm)
)
/datum/component/swarming/Initialize(max_x = 24, max_y = 24)
if(!ismovable(parent))
return COMPONENT_INCOMPATIBLE
offset_x = rand(-max_x, max_x)
offset_y = rand(-max_y, max_y)
AddComponent(/datum/component/connect_loc_behalf, parent, swarming_loc_connections)
/datum/component/swarming/Destroy()
for(var/other in swarm_members)
var/datum/component/swarming/other_swarm = other
other_swarm.swarm_members -= src
if(!other_swarm.swarm_members.len)
other_swarm.unswarm()
swarm_members = null
return ..()
/datum/component/swarming/proc/join_swarm(datum/source, atom/movable/arrived)
SIGNAL_HANDLER
var/datum/component/swarming/other_swarm = arrived.GetComponent(/datum/component/swarming)
if(!other_swarm)
return
swarm()
swarm_members |= other_swarm
other_swarm.swarm()
other_swarm.swarm_members |= src
/datum/component/swarming/proc/leave_swarm(datum/source, atom/movable/gone, direction)
SIGNAL_HANDLER
var/datum/component/swarming/other_swarm = gone.GetComponent(/datum/component/swarming)
if(!other_swarm || !(other_swarm in swarm_members))
return
swarm_members -= other_swarm
if(!swarm_members.len)
unswarm()
other_swarm.swarm_members -= src
if(!other_swarm.swarm_members.len)
other_swarm.unswarm()
/datum/component/swarming/proc/swarm()
var/atom/movable/owner = parent
if(!is_swarming)
is_swarming = TRUE
animate(owner, pixel_x = owner.pixel_x + offset_x, pixel_y = owner.pixel_y + offset_y, time = 2)
/datum/component/swarming/proc/unswarm()
var/atom/movable/owner = parent
if(is_swarming)
animate(owner, pixel_x = owner.pixel_x - offset_x, pixel_y = owner.pixel_y - offset_y, time = 2)
is_swarming = FALSE