From 315943b725bcaa6a39c7e7f26dcdfaa07ebd65b0 Mon Sep 17 00:00:00 2001 From: juxjux9930 <68120725+juxjux9930@users.noreply.github.com> Date: Tue, 19 Sep 2023 19:35:57 +0300 Subject: [PATCH] [MIRROR] Particles stuff --- code/__defines/_renderer.dm | 16 +- code/_helpers/global_lists.dm | 8 +- code/_helpers/maths.dm | 17 ++ code/game/atoms_movable.dm | 2 + code/game/machinery/bluespace_drive.dm | 18 +- .../objects/effects/particles/particles.dm | 182 ++++++++++++++---- code/modules/power/fusion/core/_core.dm | 4 +- code/modules/power/fusion/core/core_field.dm | 29 ++- .../power/fusion/fusion_particle_catcher.dm | 4 +- .../particle_accelerator/particle.dm | 4 +- 10 files changed, 199 insertions(+), 85 deletions(-) diff --git a/code/__defines/_renderer.dm b/code/__defines/_renderer.dm index e8f04987068af..90ff79719959c 100644 --- a/code/__defines/_renderer.dm +++ b/code/__defines/_renderer.dm @@ -299,22 +299,18 @@ GLOBAL_LIST_EMPTY(zmimic_renderers) vis_contents -= gas_heat_object if (quality == GLOB.PREF_LOW) - if(!istype(gas_heat_object, /obj/effect/heat)) - QDEL_NULL(gas_heat_object) - gas_heat_object = new /obj/effect/heat(null) + QDEL_NULL(gas_heat_object) + gas_heat_object = new /obj/effect/heat(null) else - if(!istype(gas_heat_object, /obj/particle_emitter/heat)) - QDEL_NULL(gas_heat_object) - gas_heat_object = new /obj/particle_emitter/heat(null, -1) + QDEL_NULL(gas_heat_object) if (quality == GLOB.PREF_MED) - gas_heat_object.particles?.count = 250 - gas_heat_object.particles?.spawning = 15 + gas_heat_object = new /obj/particle_emitter/heat(null) else if (quality == GLOB.PREF_HIGH) - gas_heat_object.particles?.count = 600 - gas_heat_object.particles?.spawning = 35 + gas_heat_object = new /obj/particle_emitter/heat/high(null) vis_contents += gas_heat_object + /atom/movable/renderer/heat/Initialize() . = ..() Setup() diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm index 2455fb039f32f..0b480b8131fb7 100644 --- a/code/_helpers/global_lists.dm +++ b/code/_helpers/global_lists.dm @@ -22,6 +22,7 @@ var/global/list/language_keys[0] // Table of say codes for all languages var/global/list/playable_species = list(SPECIES_HUMAN) // A list of ALL playable species, whitelisted, latejoin or otherwise. +GLOBAL_LIST_EMPTY(all_particles) // Grabs var/global/list/all_grabstates[0] @@ -165,7 +166,12 @@ var/global/list/string_slot_flags = list( var/datum/grab/G = all_grabstates[grabstate_name] G.refresh_updown() - return 1 + paths = typesof(/particles) + for (var/path in paths) + var/particles/P = new path() + GLOB.all_particles[P.name] = P + + return TRUE //*** params cache var/global/list/paramslist_cache = list() diff --git a/code/_helpers/maths.dm b/code/_helpers/maths.dm index a45f28553cc06..c0a102af8f91c 100644 --- a/code/_helpers/maths.dm +++ b/code/_helpers/maths.dm @@ -236,3 +236,20 @@ var/d = max - min var/t = round((val - min) / d) return val - (t * d) + + +/proc/MakeGenerator(g_type, g_min, g_max, g_rand = UNIFORM_RAND) + switch (g_rand) + if (1) + g_rand = NORMAL_RAND + if (2) + g_rand = LINEAR_RAND + if (3) + g_rand = SQUARE_RAND + else + g_rand = UNIFORM_RAND + + if (!isnum(g_min) || !isnum(g_max)) + return null + + return generator(g_type, g_min, g_max, g_rand) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index ed0a282712098..86cf810c8b69c 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -155,6 +155,8 @@ virtual_mob = null if (em_block) QDEL_NULL(em_block) + if (particles) + particles = null return ..() /atom/movable/Bump(atom/A, yes) diff --git a/code/game/machinery/bluespace_drive.dm b/code/game/machinery/bluespace_drive.dm index 1a547e7d7cb18..1e84f0d607d94 100644 --- a/code/game/machinery/bluespace_drive.dm +++ b/code/game/machinery/bluespace_drive.dm @@ -37,7 +37,7 @@ /obj/machinery/bluespacedrive/Initialize() . = ..() drive_sound = GLOB.sound_player.PlayLoopingSound(src, "\ref[src]", 'sound/machines/BSD_idle.ogg', 50, 7) - particles = new /particles/bluespace_torus + AddParticles(/particles/torus/bluespace) set_light(1, 5, 15, 10, COLOR_CYAN) update_icon() @@ -165,22 +165,6 @@ floor.ChangeTurf(/turf/simulated/floor/bluespace) - - -/particles/bluespace_torus - width = 700 - height = 700 - count = 2700 - spawning = 260 - lifespan = 0.75 SECONDS - fade = 0.95 SECONDS - position = generator("circle", 16, 24, NORMAL_RAND) - velocity = generator("circle", -6, 6, NORMAL_RAND) - friction = 0.15 - gradient = list(0, COLOR_WHITE, 0.75, COLOR_BLUE_LIGHT) - color_change = 0.125 - drift = generator("vector", list(-0.2, -0.2), list(0.2, 0.2)) - /datum/bubble_effect/bluespace_pulse ///List of mobs that can be swapped around when the pulse hits var/list/mob/living/mobs_to_switch = list() diff --git a/code/game/objects/effects/particles/particles.dm b/code/game/objects/effects/particles/particles.dm index 9e984f6ca78c8..948f921173732 100644 --- a/code/game/objects/effects/particles/particles.dm +++ b/code/game/objects/effects/particles/particles.dm @@ -1,7 +1,63 @@ -/* A series of particle systems. Some are based on F0lak's particle systems -*/ +/atom/movable/proc/AddParticles(type, create_new = FALSE) + if (ispath(type)) + if (create_new) + particles = new type() + GLOB.all_particles[src.name] = particles + else + var/particles/P = type + var/index = initial(P.name) + particles = GLOB.all_particles[index] + else + if (GLOB.all_particles[type]) + particles = GLOB.all_particles[type] + return + + +/atom/movable/proc/MakeParticleEmitter(type, create_new = FALSE) + var/obj/particle_emitter/pe + pe = new /obj/particle_emitter(loc) + pe.AddParticles(type, create_new) + + +/atom/movable/proc/RemoveParticles(delete = FALSE) + if (delete) + QDEL_NULL(particles) + particles = null + if (/obj/particle_emitter in vis_contents) + vis_contents -= /obj/particle_emitter + + +/atom/movable/proc/ModParticles(target, min, max, type = "circle", random = 1) + if (particles) + particles.ModParticles(target, min, max, type = "circle", random = 1) + + +/particles + var/name = "particles" + + +/particles/proc/ModParticles(target, min, max, type = "circle", random = 1) + if (!(type in list("vector", "box", "circle", "sphere", "square", "cube"))) // Valid types for generator(), sans color + return + + if (target in list("width", "height", "count", "spawning", "bound1", "bound2", "gravity", "gradient", "transform")) // These vars cannot be generators, per reference doc, and changing some breaks things anyways + return + + if (target in vars) + vars[target] = MakeGenerator(type, min, max, random) + + +/particles/proc/SetGradient(...) + var/counter = 0 + var/list/new_gradient = list() + for (var/i in args) + new_gradient += counter + counter += 1/length(args) + new_gradient += i + gradient = new_gradient /particles/fire + name = "fire" width = 500 height = 500 count = 3000 @@ -12,10 +68,11 @@ position = generator("circle", 0, 8, NORMAL_RAND) drift = generator("vector", list(0, -0.2), list(0, 0.2)) gravity = list(0, 0.65) - color = "white" + /particles/smoke + name = "smoke" width = 500 height = 1000 count = 3000 @@ -24,12 +81,13 @@ fade = 40 velocity = generator("box", list(-1, 2), list(1, 2), NORMAL_RAND) gravity = list(0, 1) - friction = 0.1 drift = generator("vector", list(-0.2, -0.3), list(0.2, 0.3)) color = "white" + /particles/fire_sparks + name = "fire sparks" width = 500 height = 500 count = 3000 @@ -44,7 +102,9 @@ gradient = list(0, "yellow", 1, "red") color = "yellow" + /particles/drill_sparks + name = "drill sparks" width = 124 height = 124 count = 1600 @@ -60,7 +120,9 @@ color = 0 transform = list(1,0,0,0, 0,1,0,0, 0,0,1,1/5, 0,0,0,1) + /particles/flare_sparks + name = "flare sparks" width = 500 height = 500 count = 2000 @@ -73,11 +135,13 @@ gradient = list(0, COLOR_WHITE, 0.4, COLOR_RED) color_change = 0.125 + /particles/dust + name = "dust" width = 124 height = 124 count = 256 - spawning = 999999 //spawn all instantly + spawning = 256 lifespan = 0.75 SECONDS fade = 0.35 SECONDS position = generator("box", list(-16, -16), list(16, 16), NORMAL_RAND) @@ -85,11 +149,13 @@ friction = 0.125 color = COLOR_OFF_WHITE + /particles/debris + name = "debris" width = 124 height = 124 count = 16 - spawning = 999999 //spawn all instantly + spawning = 16 lifespan = 0.75 SECONDS fade = 0.35 SECONDS position = generator("box", list(-10, -10), list(10, 10), NORMAL_RAND) @@ -98,9 +164,11 @@ gravity = list(0, -1) icon = 'icons/effects/particles.dmi' icon_state = list("rock1", "rock2", "rock3", "rock4", "rock5") - rotation = generator("num", 0, 360, NORMAL_RAND) + rotation = generator("num", 0, 360) + /particles/drill_sparks/debris + name = "drill debris" friction = 0.25 gradient = null color = COLOR_WHITE @@ -108,26 +176,46 @@ icon = 'icons/effects/particles.dmi' icon_state = list("rock1", "rock2", "rock3", "rock4", "rock5") -/particles/fusion - width = 500 - height = 500 - count = 4000 - spawning = 260 - lifespan = 0.85 SECONDS - fade = 0.95 SECONDS - position = generator("circle", 2.5 * 32 - 5, 2.5 * 32 + 5, NORMAL_RAND) - velocity = generator("circle", 0, 3, NORMAL_RAND) + +/particles/torus + name = "torus" + width = 800 + height = 800 + count = 900 + spawning = 45 + lifespan = 1 SECONDS + fade = 0.5 SECONDS + position = generator("circle", 8, 16, NORMAL_RAND) + velocity = generator("circle", -2, 2, NORMAL_RAND) friction = 0.15 - gradient = list(0, COLOR_WHITE, 0.75, COLOR_BLUE_LIGHT) + gradient = list(0, COLOR_WHITE, 1, COLOR_BLUE_LIGHT) color_change = 0.1 color = 0 - drift = generator("circle", 0.2, NORMAL_RAND) + drift = generator("sphere", -1, 1, NORMAL_RAND) + + +/particles/torus/fusion + name = "fusion torus" + count = 3600 + spawning = 180 + position = generator("circle", 2.5 * 32 - 5, 2.5 * 32 + 5, NORMAL_RAND) + velocity = generator("circle", -6, 6, NORMAL_RAND) + + +/particles/torus/bluespace + name = "bluespace torus" + count = 1800 + spawning = 90 + position = generator("circle", 16, 24, NORMAL_RAND) + velocity = generator("circle", -4, 4, NORMAL_RAND) + /particles/heat + name = "heat" width = 500 height = 500 - count = 600 - spawning = 35 + count = 250 + spawning = 15 lifespan = 1.85 SECONDS fade = 1.25 SECONDS position = generator("box", list(-16, -16), list(16, 0), NORMAL_RAND) @@ -139,30 +227,39 @@ drift = generator("circle", 0.4, NORMAL_RAND) velocity = generator("circle", 0, 3, NORMAL_RAND) + +/particles/heat/high + name = "high heat" + count = 600 + spawning = 35 + + //Spawner object //Maybe we could pool them in and out + /obj/particle_emitter name = "" anchored = TRUE mouse_opacity = 0 appearance_flags = PIXEL_SCALE + var/particle_type = null + /obj/particle_emitter/Initialize(mapload, time, _color) . = ..() - if(time > 0) + if (particle_type) + particles = GLOB.all_particles[particle_type] + + if (time > 0) QDEL_IN(src, time) color = _color -/obj/particle_emitter/proc/enable(on) - if(on) - particles.spawning = initial(particles.spawning) - else - particles.spawning = 0 /obj/particle_emitter/sparks - particles = new/particles/drill_sparks + particle_type = "drill sparks" plane = EFFECTS_ABOVE_LIGHTING_PLANE + /obj/particle_emitter/sparks/set_dir(dir) ..() var/list/min @@ -180,43 +277,58 @@ min = list(-1, 3, 0) max = list(-6, 12, 0) - particles.velocity = generator("box", min, max, NORMAL_RAND) + particles.velocity = generator("box", min, max) + /obj/particle_emitter/sparks/debris - particles = new/particles/drill_sparks/debris + particle_type = "drill debris" plane = DEFAULT_PLANE + /obj/particle_emitter/burst/Initialize(mapload, time) . = ..() //Burst emitters turn off after 1 tick - addtimer(new Callback(src, .proc/enable, FALSE), 1) + QDEL_IN(src, time) + + /obj/particle_emitter/burst/rocks - particles = new/particles/debris + particle_type = "debris" + /obj/particle_emitter/burst/dust - particles = new/particles/dust + particle_type = "dust" + /obj/particle_emitter/smoke layer = FIRE_LAYER - particles = new/particles/smoke + particle_type = "smoke" + /obj/particle_emitter/smoke/Initialize(mapload, time, _color) . = ..() filters = filter(type="blur", size=1.5) + /obj/particle_emitter/sparks_flare plane = EFFECTS_ABOVE_LIGHTING_PLANE - particles = new/particles/flare_sparks + particle_type = "flare" mouse_opacity = 1 + /obj/particle_emitter/sparks_flare/Initialize(mapload, time, _color) . = ..() filters = filter(type="bloom", size=3, offset = 0.5, alpha = 220) + /obj/particle_emitter/heat - particles = new/particles/heat + particle_type = "heat low" render_target = HEAT_EFFECT_TARGET + /obj/particle_emitter/heat/Initialize() . = ..() filters += filter(type = "blur", size = 1) + + +/obj/particle_emitter/heat/high + particle_type = "heat high" diff --git a/code/modules/power/fusion/core/_core.dm b/code/modules/power/fusion/core/_core.dm index 9d615ee6561e6..93ffe06fd1574 100644 --- a/code/modules/power/fusion/core/_core.dm +++ b/code/modules/power/fusion/core/_core.dm @@ -66,9 +66,9 @@ owned_field = null update_use_power(POWER_USE_IDLE) -/obj/machinery/power/fusion_core/proc/AddParticles(name, quantity = 1) +/obj/machinery/power/fusion_core/proc/AddReactants(name, quantity = 1) if(owned_field) - owned_field.AddParticles(name, quantity) + owned_field.AddReactants(name, quantity) . = 1 /obj/machinery/power/fusion_core/bullet_act(obj/item/projectile/Proj) diff --git a/code/modules/power/fusion/core/core_field.dm b/code/modules/power/fusion/core/core_field.dm index 2dcf68fa381af..b280a56e904cf 100644 --- a/code/modules/power/fusion/core/core_field.dm +++ b/code/modules/power/fusion/core/core_field.dm @@ -42,21 +42,16 @@ var/last_reactants = 0 - particles = new/particles/fusion - var/animating_ripple = FALSE /obj/effect/fusion_em_field/proc/UpdateVisuals() - //Take the particle system and edit it - - //size var/radius = ((size-1) / 2) * WORLD_ICON_SIZE particles.position = generator("circle", radius - size, radius + size, NORMAL_RAND) //Radiation affects drift - var/radiationfactor = clamp((radiation * 0.001), 0, 0.5) - particles.drift = generator("circle", (0.2 + radiationfactor), NORMAL_RAND) + var/radiationfactor = clamp((radiation * 0.001), 0, 0.5) + 0.2 + particles.drift = generator("circle", -radiationfactor, radiationfactor, , NORMAL_RAND) particles.spawning = last_reactants * 0.9 + Interpolate(0, 200, clamp(plasma_temperature / 70000, 0, 1)) @@ -64,6 +59,11 @@ /obj/effect/fusion_em_field/New(loc, obj/machinery/power/fusion_core/new_owned_core) ..() + owned_core = new_owned_core + if (!owned_core) + qdel(src) + return + filters = list(filter(type = "ripple", size = 4, "radius" = 1, "falloff" = 1) , filter(type="outline", size = 2, color = COLOR_RED) , filter(type="bloom", size=3, offset = 0.5, alpha = 235)) @@ -72,10 +72,7 @@ last_range = light_min_range last_power = light_min_power - owned_core = new_owned_core - if(!owned_core) - qdel(src) - return + AddParticles(/particles/torus/fusion, TRUE) particles.spawning = 0 //Turn off particles until something calls for it @@ -154,7 +151,7 @@ last_range = use_range last_power = use_power //Temperature based color - particles.gradient = list(0, COLOR_WHITE, 0.85, light_color) + particles.gradient = list(0, COLOR_WHITE, 1, light_color) UNLINT(var/dm_filter/outline = filters[2]) UNLINT(outline.color = light_color) UNLINT(var/dm_filter/bloom = filters[3]) @@ -174,7 +171,7 @@ if(uptake_gas && uptake_gas.total_moles) for(var/gasname in uptake_gas.gas) if(uptake_gas.gas[gasname]*10 > reactants[gasname]) - AddParticles(gasname, uptake_gas.gas[gasname]*10) + AddReactants(gasname, uptake_gas.gas[gasname]*10) uptake_gas.adjust_gas(gasname, -(uptake_gas.gas[gasname]), update=FALSE) added_particles = TRUE if(added_particles) @@ -327,7 +324,7 @@ plasma_temperature += 1 UpdateVisuals() -/obj/effect/fusion_em_field/proc/AddParticles(name, quantity = 1) +/obj/effect/fusion_em_field/proc/AddReactants(name, quantity = 1) if(name in reactants) reactants[name] += quantity else if(name != "proton" && name != "electron" && name != "neutron") @@ -513,11 +510,11 @@ // Loop through the newly produced reactants and add them to the pool. for(var/reactant in produced_reactants) - AddParticles(reactant, produced_reactants[reactant]) + AddReactants(reactant, produced_reactants[reactant]) // Check whether there are reactants left, and add them back to the pool. for(var/reactant in react_pool) - AddParticles(reactant, react_pool[reactant]) + AddReactants(reactant, react_pool[reactant]) UpdateVisuals() diff --git a/code/modules/power/fusion/fusion_particle_catcher.dm b/code/modules/power/fusion/fusion_particle_catcher.dm index de6a9bdd36c07..ad40db433b6bd 100644 --- a/code/modules/power/fusion/fusion_particle_catcher.dm +++ b/code/modules/power/fusion/fusion_particle_catcher.dm @@ -17,9 +17,9 @@ mysize = newsize UpdateSize() -/obj/effect/fusion_particle_catcher/proc/AddParticles(name, quantity = 1) +/obj/effect/fusion_particle_catcher/proc/AddReactants(name, quantity = 1) if(parent && parent.size >= mysize) - parent.AddParticles(name, quantity) + parent.AddReactants(name, quantity) return 1 return 0 diff --git a/code/modules/power/singularity/particle_accelerator/particle.dm b/code/modules/power/singularity/particle_accelerator/particle.dm index 24e0c41e0f2f3..86b0191f00231 100644 --- a/code/modules/power/singularity/particle_accelerator/particle.dm +++ b/code/modules/power/singularity/particle_accelerator/particle.dm @@ -34,14 +34,14 @@ else if(istype(A,/obj/machinery/power/fusion_core)) var/obj/machinery/power/fusion_core/collided_core = A if(particle_type && particle_type != "neutron") - if(collided_core.AddParticles(particle_type, 1 + additional_particles)) + if (collided_core.AddReactants(particle_type, 1 + additional_particles)) collided_core.owned_field.plasma_temperature += mega_energy collided_core.owned_field.energy += energy qdel(src) else if(istype(A, /obj/effect/fusion_particle_catcher)) var/obj/effect/fusion_particle_catcher/PC = A if(particle_type && particle_type != "neutron") - if(PC.parent.owned_core.AddParticles(particle_type, 1 + additional_particles)) + if (PC.parent.owned_core.AddReactants(particle_type, 1 + additional_particles)) PC.parent.plasma_temperature += mega_energy PC.parent.energy += energy qdel(src)