Skip to content

Commit

Permalink
Converts most common particle sources to use our new pooling system (t…
Browse files Browse the repository at this point in the history
…gstation#88048)

## About The Pull Request

Closes tgstation#83370
Converted most cases where we could benefit from using shared particles
(aka when there's probably more than 3 uses of that particle in a round)
to use the new shared particle system. Should provide significant
clientside performance in particle-heavy areas like botany (or sometimes
kitchen)

## Changelog
:cl:
refactor: Converted most common particle sources to use our new pooling
system.
/:cl:
  • Loading branch information
SmArtKar authored Nov 21, 2024
1 parent fac6f1c commit 742729f
Show file tree
Hide file tree
Showing 16 changed files with 124 additions and 100 deletions.
17 changes: 10 additions & 7 deletions code/datums/proximity_monitor/fields/gravity.dm
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
alpha = 200
/// our emissive appearance
var/mutable_appearance/emissive
var/particles/particle_type

/obj/gravity_fluff_field/Initialize(mapload, strength)
. = ..()
Expand All @@ -89,20 +90,22 @@
QUEUE_SMOOTH_NEIGHBORS(src)
switch(strength)
if(2 to INFINITY)
particles = new /particles/grav_field_down/strong()
particle_type = /particles/grav_field_down/strong
if(1 to 2)
particles = new /particles/grav_field_down()
particle_type = /particles/grav_field_down
if(0 to 1)
particles = new /particles/grav_field_float()
particle_type = /particles/grav_field_float
if(-INFINITY to -1)
particles = new /particles/grav_field_up()
color = particles.color
particle_type = /particles/grav_field_up
if (particle_type)
add_shared_particles(/particles/grav_field_down/strong)
color = particle_type::color
RegisterSignal(src, COMSIG_ATOM_SMOOTHED_ICON, PROC_REF(smoothed))

/obj/gravity_fluff_field/Destroy(force)
. = ..()
QDEL_NULL(particles)
remove_shared_particles(particle_type)
emissive = null
return ..()

/obj/gravity_fluff_field/proc/smoothed(datum/source)
SIGNAL_HANDLER
Expand Down
13 changes: 8 additions & 5 deletions code/game/objects/effects/shared_particle_holder.dm
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,19 @@ GLOBAL_LIST_EMPTY(shared_particles)
vis_contents += GLOB.shared_particles[particle_key][SHARED_PARTICLE_HOLDER_INDEX][1]
return GLOB.shared_particles[particle_key][SHARED_PARTICLE_HOLDER_INDEX][1]

if (length(GLOB.shared_particles[particle_key][SHARED_PARTICLE_HOLDER_INDEX]) < pool_size)
var/list/type_holders = GLOB.shared_particles[particle_key][SHARED_PARTICLE_HOLDER_INDEX]
for (var/obj/effect/abstract/shared_particle_holder/particle_holder as anything in type_holders)
if (particle_holder in vis_contents)
return particle_holder

if (length(type_holders) < pool_size)
var/obj/effect/abstract/shared_particle_holder/new_holder = new(null, particle_type, particle_flags)
GLOB.shared_particles[particle_key][SHARED_PARTICLE_HOLDER_INDEX] += new_holder
type_holders += new_holder
vis_contents += new_holder
GLOB.shared_particles[particle_key][SHARED_PARTICLE_USER_NUM_INDEX] += 1
return new_holder

var/obj/effect/abstract/shared_particle_holder/particle_holder = pick(GLOB.shared_particles[particle_key][SHARED_PARTICLE_HOLDER_INDEX])
if (particle_holder in vis_contents)
return particle_holder
var/obj/effect/abstract/shared_particle_holder/particle_holder = pick(type_holders)
vis_contents += particle_holder
GLOB.shared_particles[particle_key][SHARED_PARTICLE_USER_NUM_INDEX] += 1
return particle_holder
Expand Down
7 changes: 6 additions & 1 deletion code/game/objects/items/food/misc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,12 @@
. = ..()
RegisterSignal(src, COMSIG_ITEM_GRILL_PROCESS, PROC_REF(OnGrill))
if(stink_particles)
particles = new stink_particles
add_shared_particles(stink_particles)

/obj/item/food/badrecipe/Destroy(force)
if (stink_particles)
remove_shared_particles(stink_particles)
return ..()

// We override the parent procs here to prevent burned messes from cooking into burned messes.
/obj/item/food/badrecipe/make_grillable()
Expand Down
4 changes: 2 additions & 2 deletions code/game/objects/structures/fireplace.dm
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@
fuel_added = 0
update_appearance()
adjust_light()
particles = new /particles/smoke/burning()
add_shared_particles(/particles/smoke/burning)

switch(dir)
if(SOUTH)
Expand All @@ -185,7 +185,7 @@
update_appearance()
adjust_light()
desc = initial(desc)
QDEL_NULL(particles)
remove_shared_particles(/particles/smoke/burning)

#undef LOG_BURN_TIMER
#undef PAPER_BURN_TIMER
Expand Down
4 changes: 2 additions & 2 deletions code/game/objects/structures/lavaland/ore_vent.dm
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@
addtimer(CALLBACK(node, TYPE_PROC_REF(/atom, update_appearance)), wave_timer * 0.25)
addtimer(CALLBACK(node, TYPE_PROC_REF(/atom, update_appearance)), wave_timer * 0.5)
addtimer(CALLBACK(node, TYPE_PROC_REF(/atom, update_appearance)), wave_timer * 0.75)
particles = new /particles/smoke/ash()
add_shared_particles(/particles/smoke/ash)
for(var/i in 1 to 5) // Clears the surroundings of the ore vent before starting wave defense.
for(var/turf/closed/mineral/rock in oview(i))
if(istype(rock, /turf/open/misc/asteroid) && prob(35)) // so it's too common
Expand Down Expand Up @@ -272,7 +272,7 @@

SEND_SIGNAL(src, COMSIG_VENT_WAVE_CONCLUDED)
COOLDOWN_RESET(src, wave_cooldown)
particles = null
remove_shared_particles(/particles/smoke/ash)

if(force)
initiate_wave_win()
Expand Down
14 changes: 7 additions & 7 deletions code/modules/clothing/head/mind_monkey_helmet.dm
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
var/light_colors = 1 ///which icon state color this is (red, blue, yellow)
/// This chance is increased by 7 every time the helmet fails to get a host, to dissuade spam. starts negative to add 1 safe reuse
var/rage_chance = -7
/// Holds the steam effect at dangerous rage chance levels.
var/obj/effect/abstract/particle_holder/particle_effect
/// Currently used particle type
var/particle_path

/obj/item/clothing/head/helmet/monkey_sentience/Initialize(mapload)
. = ..()
Expand Down Expand Up @@ -60,7 +60,8 @@
UnregisterSignal(magnification, COMSIG_SPECIES_LOSS)
magnification = null
visible_message(span_notice("[src] falls silent and drops on the floor. Maybe you should try again later?"))
var/particle_path
if (particle_path)
remove_shared_particles(particle_path)
switch(rage_chance)
if(-7 to 0)
user.visible_message(span_notice("[src] falls silent and drops on the floor. Try again later?"))
Expand All @@ -83,11 +84,10 @@
playsound(src, 'sound/machines/buzz/buzz-two.ogg', 30, TRUE)
particle_path = /particles/smoke/steam
rage_chance += 7

QDEL_NULL(particle_effect)
if(particle_path)
particle_effect = new(src, particle_path)
QDEL_IN(particle_effect, 2 MINUTES)
add_shared_particles(particle_path)
addtimer(CALLBACK(src, TYPE_PROC_REF(/atom/movable, remove_shared_particles), particle_path), 2 MINUTES)
addtimer(VARSET_CALLBACK(src, particle_path, null), 2 MINUTES)

if((rage_chance > 0) && prob(rage_chance)) // too much spam means agnry gorilla running at you
malfunction(user)
Expand Down
13 changes: 5 additions & 8 deletions code/modules/food_and_drinks/machinery/coffeemaker.dm
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
/obj/machinery/coffeemaker/Destroy()
QDEL_NULL(coffeepot)
QDEL_NULL(cartridge)
remove_shared_particles(/particles/smoke)
return ..()

/obj/machinery/coffeemaker/Exited(atom/movable/gone, direction)
Expand Down Expand Up @@ -391,10 +392,8 @@

///Updates the smoke state to something else, setting particles if relevant
/obj/machinery/coffeemaker/proc/toggle_steam()
QDEL_NULL(particles)
if(brewing)
particles = new /particles/smoke/steam/mild()
particles.position = list(-6, 0, 0)
var/obj/effect/abstract/shared_particle_holder/smoke_particles = add_shared_particles(/particles/smoke/steam/mild, "smoke_coffeemaker")
smoke_particles.particles.position = list(-6, 0, 0)

/obj/machinery/coffeemaker/proc/operate_for(time, silent = FALSE)
brewing = TRUE
Expand Down Expand Up @@ -705,10 +704,8 @@
update_appearance(UPDATE_OVERLAYS)

/obj/machinery/coffeemaker/impressa/toggle_steam()
QDEL_NULL(particles)
if(brewing)
particles = new /particles/smoke/steam/mild()
particles.position = list(-2, 1, 0)
var/obj/effect/abstract/shared_particle_holder/smoke_particles = add_shared_particles(/particles/smoke/steam/mild, "smoke_impressa")
smoke_particles.particles.position = list(-2, 1, 0)

/obj/machinery/coffeemaker/impressa/brew()
power_change()
Expand Down
9 changes: 3 additions & 6 deletions code/modules/food_and_drinks/machinery/microwave.dm
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
/obj/machinery/microwave/Destroy()
QDEL_LIST(ingredients)
QDEL_NULL(soundloop)
QDEL_NULL(particles)
remove_shared_particles(/particles/smoke)
if(!isnull(cell))
QDEL_NULL(cell)
return ..()
Expand Down Expand Up @@ -707,17 +707,14 @@
if(HAS_TRAIT(smeller, TRAIT_ANOSMIA))
cant_smell += smeller
visible_message(span_danger("You smell a burnt smell coming from [src]!"), ignored_mobs = cant_smell)
particles = new /particles/smoke()
addtimer(CALLBACK(src, PROC_REF(remove_smoke)), 10 SECONDS)
add_shared_particles(/particles/smoke)
addtimer(CALLBACK(src, TYPE_PROC_REF(/atom/movable, remove_shared_particles), /particles/smoke), 10 SECONDS)
Shake(duration = 1 SECONDS)

cycles--
use_energy(active_power_usage)
addtimer(CALLBACK(src, PROC_REF(cook_loop), type, cycles, wait, cooker), wait)

/obj/machinery/microwave/proc/remove_smoke()
QDEL_NULL(particles)

/obj/machinery/microwave/power_change()
. = ..()
if(cell_powered)
Expand Down
19 changes: 14 additions & 5 deletions code/modules/food_and_drinks/machinery/oven.dm
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
var/datum/looping_sound/oven/oven_loop
///Current state of smoke coming from the oven
var/smoke_state = OVEN_SMOKE_STATE_NONE
///Currently used particle type, if any
var/particle_type

/obj/machinery/oven/Initialize(mapload)
. = ..()
Expand All @@ -40,7 +42,8 @@

/obj/machinery/oven/Destroy()
QDEL_NULL(oven_loop)
QDEL_NULL(particles)
if (particle_type)
remove_shared_particles(particle_type)
return ..()

/// Used to determine if the oven appears active and cooking, or offline.
Expand Down Expand Up @@ -210,16 +213,22 @@
/obj/machinery/oven/proc/set_smoke_state(new_state)
if(new_state == smoke_state)
return

smoke_state = new_state
if (particle_type)
remove_shared_particles(particle_type)
particle_type = null

QDEL_NULL(particles)
switch(smoke_state)
if(OVEN_SMOKE_STATE_BAD)
particles = new /particles/smoke()
particle_type = /particles/smoke
if(OVEN_SMOKE_STATE_NEUTRAL)
particles = new /particles/smoke/steam()
particle_type = /particles/smoke/steam
if(OVEN_SMOKE_STATE_GOOD)
particles = new /particles/smoke/steam/mild()
particle_type = /particles/smoke/steam/mild

if (particle_type)
add_shared_particles(particle_type)

/obj/machinery/oven/crowbar_act(mob/living/user, obj/item/tool)
return default_deconstruction_crowbar(tool, ignore_panel = TRUE)
Expand Down
39 changes: 21 additions & 18 deletions code/modules/food_and_drinks/machinery/stove_component.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
VAR_FINAL/on = FALSE
/// A reference to the current soup pot overtop
VAR_FINAL/obj/item/container
/// A particle holder for the smoke that comes out of the soup while a container is cooking.
VAR_FINAL/obj/effect/abstract/particle_holder/soup_smoke
/// Typepath of particles to use for the particle holder.
VAR_FINAL/particle_type = /particles/smoke/steam/mild
/// Ref to our looping sound played when cooking
Expand Down Expand Up @@ -60,11 +58,12 @@
real_parent.flags_1 |= HAS_CONTEXTUAL_SCREENTIPS_1

/datum/component/stove/UnregisterFromParent()
var/obj/machinery/real_parent = parent
if(!QDELING(parent))
var/obj/machinery/real_parent = parent
container.forceMove(real_parent.drop_location())

QDEL_NULL(soup_smoke)
if (particle_type)
real_parent.remove_shared_particles("[particle_type]_stove_[container_x]")

UnregisterSignal(parent, list(
COMSIG_ATOM_ATTACK_HAND_SECONDARY,
Expand Down Expand Up @@ -248,27 +247,31 @@
SIGNAL_HANDLER

var/existing_temp = container?.reagents.chem_temp || 0
var/old_type = particle_type
if(existing_temp >= SOUP_BURN_TEMP)
particle_type = /particles/smoke/steam/bad
else if(existing_temp >= WATER_BOILING_POINT)
particle_type = /particles/smoke/steam/mild
else
particle_type = null

update_smoke()
update_smoke(old_type)

/datum/component/stove/proc/update_smoke(old_type = null)
var/obj/obj_parent = parent

if (old_type)
obj_parent.remove_shared_particles("[old_type]_stove_[container_x]")

if(!on || !container?.reagents.total_volume)
soup_sound?.stop()
if (!isnull(particle_type))
obj_parent.remove_shared_particles("[particle_type]_stove_[container_x]")
return

/datum/component/stove/proc/update_smoke()
if(on && container?.reagents.total_volume > 0)
soup_sound.start()
// Don't override existing particles, wasteful
if(isnull(soup_smoke) || soup_smoke.particles.type != particle_type)
QDEL_NULL(soup_smoke)
if(isnull(particle_type))
return
// this gets badly murdered by sidemap
soup_smoke = new(parent, particle_type)
soup_smoke.set_particle_position(container_x, round(ICON_SIZE_Y * 0.66), 0)
soup_sound.start()
if(isnull(particle_type))
return
var/obj/effect/abstract/shared_particle_holder/soup_smoke = obj_parent.add_shared_particles(particle_type, "[particle_type]_stove_[container_x]")
soup_smoke.particles.position = list(container_x, round(ICON_SIZE_Y * 0.66), 0)

QDEL_NULL(soup_smoke)
soup_sound?.stop()
8 changes: 6 additions & 2 deletions code/modules/hydroponics/beekeeping/bee_smoker.dm
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
. = ..()
beesmoke_loop = new(src)

/obj/item/bee_smoker/Destroy(force)
remove_shared_particles(/particles/smoke/bee_smoke)
return ..()

/obj/item/bee_smoker/attack_self(mob/user)
. = ..()
if(.)
Expand Down Expand Up @@ -100,13 +104,13 @@

if(!activated)
beesmoke_loop.stop()
QDEL_NULL(particles)
remove_shared_particles(/particles/smoke/bee_smoke)
STOP_PROCESSING(SSobj, src)
return

beesmoke_loop.start()
START_PROCESSING(SSobj, src)
particles = new /particles/smoke/bee_smoke
add_shared_particles(/particles/smoke/bee_smoke)

/particles/smoke/bee_smoke
lifespan = 0.4 SECONDS
Expand Down
8 changes: 4 additions & 4 deletions code/modules/hydroponics/hydroponics.dm
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@
/obj/machinery/hydroponics/Destroy()
if(myseed)
QDEL_NULL(myseed)
remove_shared_particles(/particles/pollen)
return ..()

/obj/machinery/hydroponics/Exited(atom/movable/gone)
Expand Down Expand Up @@ -536,7 +537,7 @@
age = 0
update_appearance()
if(isnull(myseed))
particles = null
remove_shared_particles(/particles/pollen)

/*
* Setter proc to set a tray to a new self_sustaining state and update all values associated with it.
Expand Down Expand Up @@ -798,12 +799,11 @@
T.myseed.set_instability(round((T.myseed.instability+(1/10)*(myseed.instability-T.myseed.instability))))
T.myseed.set_yield(round((T.myseed.yield+(1/2)*(myseed.yield-T.myseed.yield))))
any_adjacent = TRUE
if(isnull(particles))
particles = new /particles/pollen()
add_shared_particles(/particles/pollen)
if(myseed.instability >= 20 && prob(70) && length(T.myseed.reagents_add))
myseed.perform_reagent_pollination(T.myseed)
if(!any_adjacent)
particles = null
remove_shared_particles(/particles/pollen)

/**
* Bee pollinate proc.
Expand Down
6 changes: 5 additions & 1 deletion code/modules/mining/lavaland/tendril_loot.dm
Original file line number Diff line number Diff line change
Expand Up @@ -817,7 +817,11 @@

/obj/item/drake_remains/Initialize(mapload)
. = ..()
particles = new /particles/bonfire()
add_shared_particles(/particles/bonfire)

/obj/item/drake_remains/Destroy(force)
remove_shared_particles(/particles/bonfire)
return ..()

/obj/item/clothing/glasses/godeye
name = "eye of god"
Expand Down
Loading

0 comments on commit 742729f

Please sign in to comment.