Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions code/__DEFINES/particle.dm
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
// /obj/effect/abstract/particle_holder/var/particle_flags
// Flags that effect how a particle holder displays something

/// If we're inside something inside a mob, display off that mob too
#define PARTICLE_ATTACH_MOB (1<<0)

#define DEBRIS_SPARKS "spark"
#define DEBRIS_WOOD "wood"
#define DEBRIS_ROCK "rock"
Expand Down
2 changes: 0 additions & 2 deletions code/_globalvars/bitfields.dm
Original file line number Diff line number Diff line change
Expand Up @@ -684,5 +684,3 @@ DEFINE_BITFIELD(insert_flags, list(
"PLAY_INSERT_SYNTH" = PLAY_INSERT_SYNTH,
"PLAY_INSERT_CO" = PLAY_INSERT_CO
))

DEFINE_BITFIELD(particle_flags, list("PARTICLE_ATTACH_MOB" = PARTICLE_ATTACH_MOB))
103 changes: 51 additions & 52 deletions code/game/objects/effects/particle_holder.dm
Original file line number Diff line number Diff line change
@@ -1,75 +1,74 @@
///objects can only have one particle on them at a time, so we use these abstract effects to hold and display the effects. You know, so multiple particle effects can exist at once.
///also because some objects do not display particles due to how their visuals are built
/obj/effect/abstract/particle_holder
name = "particle holder"
desc = "How are you reading this? Please make a bug report :)"
appearance_flags = KEEP_APART|KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE|LONG_GLIDE|RESET_COLOR //movable appearance_flags plus KEEP_APART and KEEP_TOGETHER
vis_flags = VIS_INHERIT_PLANE
layer = ABOVE_FLY_LAYER
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
anchored = TRUE
/// Holds info about how this particle emitter works
/// See \code\__DEFINES\particles.dm
var/particle_flags = NONE

var/atom/parent
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
layer = FLY_LAYER
vis_flags = VIS_INHERIT_PLANE
appearance_flags = KEEP_APART|TILE_BOUND
///typepath of the last location we're in, if it's different when moved then we need to update vis contents
var/last_attached_location_type
///the main item we're attached to at the moment, particle holders hold particles for something
var/datum/weakref/weak_attached
///besides the item we're also sometimes attached to other stuff! (items held emitting particles on a mob)
var/datum/weakref/weak_additional

/obj/effect/abstract/particle_holder/Initialize(mapload, particle_path, particle_flags = NONE)
/obj/effect/abstract/particle_holder/Initialize(mapload, particle_path = null)
. = ..()
if(isnull(particle_path))
return INITIALIZE_HINT_QDEL
if(!loc)
stack_trace("particle holder was created with no loc!")
return INITIALIZE_HINT_QDEL

// We nullspace ourselves because some objects use their contents (e.g. storage) and some items may drop everything in their contents on deconstruct.
parent = loc
loc = null

// Mouse opacity can get set to opaque by some objects when placed into the object's contents (storage containers).
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
src.particle_flags = particle_flags
particles = new particle_path()
// /atom doesn't have vis_contents, /turf and /atom/movable do
var/atom/movable/lie_about_areas = parent
lie_about_areas.vis_contents += src
RegisterSignal(parent, COMSIG_PARENT_QDELETING, PROC_REF(parent_deleted))

if(particle_flags & PARTICLE_ATTACH_MOB)
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_move))
on_move(parent, null, NORTH)
if(ismovable(loc))
RegisterSignal(loc, COMSIG_MOVABLE_MOVED, PROC_REF(on_move))
RegisterSignal(loc, COMSIG_PARENT_QDELETING, PROC_REF(on_qdel))
weak_attached = WEAKREF(loc)
if(particle_path)
particles = new particle_path
update_visual_contents(loc)

/obj/effect/abstract/particle_holder/Destroy(force)
var/atom/movable/attached = weak_attached.resolve()
var/atom/movable/additional_attached
if(weak_additional)
additional_attached = weak_additional.resolve()
if(attached)
attached.vis_contents -= src
UnregisterSignal(loc, list(COMSIG_MOVABLE_MOVED, COMSIG_PARENT_QDELETING))
if(additional_attached)
additional_attached.vis_contents -= src
QDEL_NULL(particles)
parent = null
return ..()

/// Non movables don't delete contents on destroy, so we gotta do this
/obj/effect/abstract/particle_holder/proc/parent_deleted(datum/source)
SIGNAL_HANDLER
qdel(src)

/// signal called when a parent that's been hooked into this moves
/// does a variety of checks to ensure overrides work out properly
///signal called when parent is moved
/obj/effect/abstract/particle_holder/proc/on_move(atom/movable/attached, atom/oldloc, direction)
SIGNAL_HANDLER
if(attached.loc.type != last_attached_location_type)
update_visual_contents(attached)

if(!(particle_flags & PARTICLE_ATTACH_MOB))
return
///signal called when parent is deleted
/obj/effect/abstract/particle_holder/proc/on_qdel(atom/movable/attached, force)
SIGNAL_HANDLER
qdel(src)//our parent is gone and we need to be as well

///logic proc for particle holders, aka where they move.
///subtypes of particle holders can override this for particles that should always be turf level or do special things when repositioning.
///this base subtype has some logic for items, as the loc of items becomes mobs very often hiding the particles
/obj/effect/abstract/particle_holder/proc/update_visual_contents(atom/movable/attached_to)
//remove old
if(ismob(oldloc))
var/mob/particle_mob = oldloc
particle_mob.vis_contents -= src

// If we're sitting in a mob, we want to emit from it too, for vibes and shit
if(ismob(attached.loc))
var/mob/particle_mob = attached.loc
if(weak_additional)
var/atom/movable/resolved_location = weak_additional.resolve()
if(resolved_location)
resolved_location.vis_contents -= src
//add to new
if(isitem(attached_to) && ismob(attached_to.loc)) //special case we want to also be emitting from the mob
var/mob/particle_mob = attached_to.loc
last_attached_location_type = attached_to.loc
weak_additional = WEAKREF(particle_mob)
particle_mob.vis_contents += src
//readd to ourselves
attached_to.vis_contents |= src

/// Sets the particles position to the passed coordinates
/obj/effect/abstract/particle_holder/proc/set_particle_position(x = 0, y = 0, z = 0)
particles.position = list(x, y, z)

/* Uncomment the day we need it
/obj/effect/abstract/particle_holder/reset_transform
appearance_flags = KEEP_APART|TILE_BOUND|RESET_TRANSFORM
*/
Loading