diff --git a/code/__DEFINES/particle_defines.dm b/code/__DEFINES/particle_defines.dm index b261cd4f98d..e4c0b381bbc 100644 --- a/code/__DEFINES/particle_defines.dm +++ b/code/__DEFINES/particle_defines.dm @@ -5,3 +5,16 @@ #define DEBRIS_GLASS "glass" #define DEBRIS_LEAF "leaf" #define DEBRIS_SNOW "snow" + +/* + * Generator defines + */ + +#define GEN_NUM "num" +#define GEN_VECTOR "vector" +#define GEN_BOX "box" +#define GEN_COLOR "color" +#define GEN_CIRCLE "circle" +#define GEN_SPHERE "sphere" +#define GEN_SQUARE "square" +#define GEN_CUBE "cube" diff --git a/code/datums/components/debris.dm b/code/datums/components/debris.dm index fd1f058fa79..57bd8c8e32f 100644 --- a/code/datums/components/debris.dm +++ b/code/datums/components/debris.dm @@ -3,35 +3,6 @@ * Originally from https://github.com/tgstation/TerraGov-Marine-Corps/pull/12752 */ -/particles/debris - icon = 'icons/effects/particles/generic_particles.dmi' - width = 500 - height = 500 - count = 10 - spawning = 10 - lifespan = 0.5 SECONDS - fade = 0.3 SECONDS - drift = generator("circle", 0, 7) - scale = 0.3 - velocity = list(50, 0) - friction = generator("num", 0.1, 0.15) - spin = generator("num", -20, 20) - -/particles/impact_smoke - icon = 'icons/effects/effects.dmi' - icon_state = "smoke" - width = 500 - height = 500 - count = 20 - spawning = 20 - lifespan = 0.8 SECONDS - fade = 10 SECONDS - grow = 0.1 - scale = 0.2 - spin = generator("num", -20, 20) - velocity = list(50, 0) - friction = generator("num", 0.1, 0.5) - /datum/component/debris /// Icon state of debris when impacted by a projectile var/debris @@ -76,7 +47,7 @@ if(debris && P.damage_type == BRUTE) debris_visuals = new(parent, /particles/debris) - debris_visuals.particles.position = generator("circle", position_offset, position_offset) + debris_visuals.particles.position = generator(GEN_CIRCLE, position_offset, position_offset) debris_visuals.particles.velocity = list(x_component, y_component) debris_visuals.layer = ABOVE_OBJ_LAYER + 0.02 debris_visuals.particles.icon_state = debris diff --git a/code/datums/elements/shatters_when_thrown.dm b/code/datums/elements/shatters_when_thrown.dm index 441d365e58c..d8e3aec4273 100644 --- a/code/datums/elements/shatters_when_thrown.dm +++ b/code/datums/elements/shatters_when_thrown.dm @@ -35,7 +35,7 @@ /// Handles the actual shattering part, throwing shards of whatever is defined on the component everywhere /datum/element/shatters_when_thrown/proc/shatter(atom/movable/source, atom/hit_atom) - var/generator/scatter_gen = generator("circle", 0, 48, NORMAL_RAND) + var/generator/scatter_gen = generator(GEN_CIRCLE, 0, 48, NORMAL_RAND) var/scatter_turf = get_turf(hit_atom) for(var/obj/item/scattered_item as anything in source.contents) diff --git a/code/datums/particles.dm b/code/datums/particles.dm new file mode 100644 index 00000000000..2162198a05c --- /dev/null +++ b/code/datums/particles.dm @@ -0,0 +1,105 @@ +/* + MARK: Impact debris + smoke +*/ + +/particles/debris + icon = 'icons/effects/particles/generic_particles.dmi' + width = 500 + height = 500 + count = 10 + spawning = 10 + lifespan = 0.5 SECONDS + fade = 0.3 SECONDS + drift = generator(GEN_CIRCLE, 0, 7) + scale = 0.3 + velocity = list(50, 0) + friction = generator(GEN_NUM, 0.1, 0.15) + spin = generator(GEN_NUM, -20, 20) + +/particles/impact_smoke + icon = 'icons/effects/effects.dmi' + icon_state = "smoke" + width = 500 + height = 500 + count = 20 + spawning = 20 + lifespan = 0.8 SECONDS + fade = 10 SECONDS + grow = 0.1 + scale = 0.2 + spin = generator(GEN_NUM, -20, 20) + velocity = list(50, 0) + friction = generator(GEN_NUM, 0.1, 0.5) + +/* + MARK: Explosion smoke +*/ + +/particles/explosion_smoke + icon = 'icons/effects/96x96.dmi' + icon_state = "smoke3" + width = 1000 + height = 1000 + count = 45 + spawning = 45 + gradient = list("#FA9632", "#C3630C", "#333333", "#808080", "#FFFFFF") + lifespan = 2.5 SECONDS + fade = 2 SECONDS + color = generator(GEN_NUM, 0, 0.25) + color_change = generator(GEN_NUM, 0.04, 0.05) + velocity = generator(GEN_CIRCLE, 15, 15) + drift = generator(GEN_CIRCLE, 0, 1, NORMAL_RAND) + spin = generator(GEN_NUM, -20, 20) + friction = generator(GEN_NUM, 0.1, 0.5) + gravity = list(1, 2) + scale = 0.25 + grow = 0.05 + +/particles/explosion_smoke/deva + scale = 0.5 + velocity = generator(GEN_CIRCLE, 23, 23) + +/particles/explosion_smoke/small + count = 15 + spawning = 15 + scale = 0.25 + velocity = generator(GEN_CIRCLE, 10, 10) + +/particles/smoke_wave + icon = 'icons/effects/96x96.dmi' + icon_state = "smoke3" + width = 750 + height = 750 + count = 75 + spawning = 75 + lifespan = 3 SECONDS + fade = 6 SECONDS + gradient = list("#BA9F6D", "#808080", "#FFFFFF") + color = generator(GEN_NUM, 0, 0.25) + color_change = generator(GEN_NUM, 0.08, 0.07) + velocity = generator(GEN_CIRCLE, 15, 15) + rotation = generator(GEN_NUM, -45, 45) + scale = 0.15 + grow = 0.05 + friction = 0.1 + +/particles/smoke_wave/small + count = 45 + spawning = 45 + scale = 0.05 + lifespan = 2 SECONDS + fade = 5 SECONDS + +/particles/sparks_outwards + icon = 'icons/effects/64x64.dmi' + icon_state = "flare" + width = 750 + height = 750 + count = 40 + spawning = 20 + lifespan = 5 SECONDS + fade = 2 SECONDS + position = generator(GEN_SPHERE, 8, 8) + velocity = generator(GEN_CIRCLE, 30, 30) + scale = 0.1 + friction = 0.1 diff --git a/code/game/objects/effects/effect_system/effects_explosion.dm b/code/game/objects/effects/effect_system/effects_explosion.dm index a3b15f322a5..3247946bb39 100644 --- a/code/game/objects/effects/effect_system/effects_explosion.dm +++ b/code/game/objects/effects/effect_system/effects_explosion.dm @@ -19,41 +19,3 @@ for(var/j in 1 to steps_amt) sleep(1) step(expl,direct) - -/obj/effect/explosion - name = "explosive particles" - icon = 'icons/effects/96x96.dmi' - icon_state = "explosion" - opacity = TRUE - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - pixel_x = -32 - pixel_y = -32 - -/obj/effect/explosion/New() - ..() - QDEL_IN(src, 10) - -/datum/effect_system/explosion - -/datum/effect_system/explosion/set_up(loca) - if(isturf(loca)) - location = loca - else - location = get_turf(loca) - -/datum/effect_system/explosion/start() - new/obj/effect/explosion(location) - var/datum/effect_system/expl_particles/P = new/datum/effect_system/expl_particles() - P.set_up(10, 0, location) - P.start() - -/datum/effect_system/explosion/smoke - -/datum/effect_system/explosion/smoke/proc/create_smoke() - var/datum/effect_system/smoke_spread/S = new - S.set_up(5, FALSE, location, null) - S.start() - -/datum/effect_system/explosion/smoke/start() - ..() - addtimer(CALLBACK(src, PROC_REF(create_smoke)), 5) diff --git a/code/game/objects/effects/temporary_visuals/explosion_temp_visuals.dm b/code/game/objects/effects/temporary_visuals/explosion_temp_visuals.dm new file mode 100644 index 00000000000..9b6b318758a --- /dev/null +++ b/code/game/objects/effects/temporary_visuals/explosion_temp_visuals.dm @@ -0,0 +1,64 @@ +/obj/effect/temp_visual/explosion + name = "boom" + icon = 'icons/effects/96x96.dmi' + icon_state = "explosion2" + duration = 6 SECONDS + /// Smoke wave particle holder + var/obj/effect/abstract/particle_holder/smoke_wave + /// Explosion smoke particle holder + var/obj/effect/abstract/particle_holder/explosion_smoke + /// Sparks particle holder + var/obj/effect/abstract/particle_holder/sparks + +/obj/effect/temp_visual/explosion/Initialize(mapload, radius, color, small = FALSE, large = FALSE) + . = ..() + set_light(radius, radius, LIGHT_COLOR_ORANGE) + generate_particles(radius, small, large) + var/image/I = image(icon, src, icon_state, 10, -32, -32) + var/matrix/rotate = matrix() + rotate.Turn(rand(0, 359)) + I.transform = rotate + overlays += I // We use an overlay so the explosion and light source are both in the correct location plus so the particles don't rotate with the explosion + icon_state = null + +/// Generate the particles +/obj/effect/temp_visual/explosion/proc/generate_particles(radius, small = FALSE, large = FALSE) + if(small) + smoke_wave = new(src, /particles/smoke_wave/small) + else + smoke_wave = new(src, /particles/smoke_wave) + + if(large) + explosion_smoke = new(src, /particles/explosion_smoke/deva) + else if(small) + explosion_smoke = new(src, /particles/explosion_smoke/small) + else + explosion_smoke = new(src, /particles/explosion_smoke) + + sparks = new(src, /particles/sparks_outwards) + + if(large) + smoke_wave.particles.velocity = generator(GEN_CIRCLE, 6 * radius, 6 * radius) + else if(small) + smoke_wave.particles.velocity = generator(GEN_CIRCLE, 3 * radius, 3 * radius) + else + smoke_wave.particles.velocity = generator(GEN_CIRCLE, 5 * radius, 5 * radius) + + explosion_smoke.layer = layer + 0.1 + sparks.particles.velocity = generator(GEN_CIRCLE, 8 * radius, 8 * radius) + + // The reason for these timers is to set the count to 0 + // This causes any particle systems to not spawn in new particles, but not delete the currently existing ones + addtimer(CALLBACK(src, PROC_REF(set_count_short)), 1 SECONDS) + +/obj/effect/temp_visual/explosion/proc/set_count_short() + remove_light() + explosion_smoke.particles.count = 0 + sparks.particles.count = 0 + smoke_wave.particles.count = 0 + +/obj/effect/temp_visual/explosion/Destroy() + QDEL_NULL(smoke_wave) + QDEL_NULL(explosion_smoke) + QDEL_NULL(sparks) + return ..() diff --git a/code/game/objects/effects/temporary_visuals/misc_visuals.dm b/code/game/objects/effects/temporary_visuals/misc_visuals.dm index 1a8a23ee937..77cdaa73bf4 100644 --- a/code/game/objects/effects/temporary_visuals/misc_visuals.dm +++ b/code/game/objects/effects/temporary_visuals/misc_visuals.dm @@ -231,16 +231,12 @@ layer = ABOVE_MOB_LAYER duration = 4 -/obj/effect/temp_visual/explosion +/obj/effect/temp_visual/pka_explosion name = "explosion" icon = 'icons/effects/96x96.dmi' - icon_state = "explosion" + icon_state = "explosionfast" pixel_x = -32 pixel_y = -32 - duration = 8 - -/obj/effect/temp_visual/explosion/fast - icon_state = "explosionfast" duration = 4 /obj/effect/temp_visual/heart diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm index 3720150cd1d..1c6b50e64fe 100644 --- a/code/game/objects/explosion.dm +++ b/code/game/objects/explosion.dm @@ -109,14 +109,12 @@ if(creaking_explosion) // 5 seconds after the bang, the station begins to creak addtimer(CALLBACK(M, TYPE_PROC_REF(/mob, playsound_local), epicenter, null, rand(FREQ_LOWER, FREQ_UPPER), 1, frequency, null, null, FALSE, hull_creaking_sound, 0), CREAK_DELAY) - if(heavy_impact_range > 1) - var/datum/effect_system/explosion/E - if(smoke) - E = new /datum/effect_system/explosion/smoke - else - E = new - E.set_up(epicenter) - E.start() + if(devastation_range > 0) + new /obj/effect/temp_visual/explosion(epicenter, max_range, FALSE, TRUE) + else if(heavy_impact_range > 0) + new /obj/effect/temp_visual/explosion(epicenter, max_range, FALSE, FALSE) + else if(light_impact_range > 0) + new /obj/effect/temp_visual/explosion(epicenter, max_range, TRUE, FALSE) var/list/affected_turfs = spiral_range_turfs(max_range, epicenter) diff --git a/code/game/objects/structures/depot_structures.dm b/code/game/objects/structures/depot_structures.dm index 42ace74d7f0..4d3a1919a49 100644 --- a/code/game/objects/structures/depot_structures.dm +++ b/code/game/objects/structures/depot_structures.dm @@ -113,7 +113,7 @@ M.gib() for(var/obj/mecha/E in range(30, T)) E.take_damage(E.max_integrity) - explosion(get_turf(src), 25, 35, 45, 55, 1, 1, 60, 0, 0) + explosion(get_turf(src), 25, 35, 45, 55, 1, 1, 60, 0) STOP_PROCESSING(SSobj, src) qdel(src) diff --git a/code/game/turfs/simulated/minerals.dm b/code/game/turfs/simulated/minerals.dm index 9ce9abd5050..9116c66a534 100644 --- a/code/game/turfs/simulated/minerals.dm +++ b/code/game/turfs/simulated/minerals.dm @@ -570,7 +570,7 @@ var/turf/bombturf = get_turf(src) mineralAmt = 0 stage = GIBTONITE_DETONATE - explosion(bombturf,1,3,5, adminlog = notify_admins) + explosion(bombturf, 1, 3, 5, adminlog = notify_admins) /turf/simulated/mineral/gibtonite/proc/defuse() if(stage == GIBTONITE_ACTIVE) diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index 8d1bfef8a8c..f2a6374bc3d 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -317,11 +317,11 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ spawn(det_time) if(primed) if(quality == GIBTONITE_QUALITY_HIGH) - explosion(src.loc,2,4,9,adminlog = notify_admins) + explosion(loc, 2, 4, 9, adminlog = notify_admins) if(quality == GIBTONITE_QUALITY_MEDIUM) - explosion(src.loc,1,2,5,adminlog = notify_admins) + explosion(loc, 1, 2, 5, adminlog = notify_admins) if(quality == GIBTONITE_QUALITY_LOW) - explosion(src.loc,-1,1,3,adminlog = notify_admins) + explosion(loc, -1, 1, 3, adminlog = notify_admins) qdel(src) diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index 114fa03cfb6..4c2220793e6 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -439,7 +439,7 @@ /obj/item/borg/upgrade/modkit/aoe/projectile_strike(obj/item/projectile/kinetic/K, turf/target_turf, atom/target, obj/item/gun/energy/kinetic_accelerator/KA) if(stats_stolen) return - new /obj/effect/temp_visual/explosion/fast(target_turf) + new /obj/effect/temp_visual/pka_explosion(target_turf) if(turf_aoe) for(var/T in RANGE_TURFS(1, target_turf) - target_turf) if(ismineralturf(T) && !is_ancient_rock(T)) diff --git a/icons/effects/96x96.dmi b/icons/effects/96x96.dmi index 7746a3d06d0..ca835f75288 100644 Binary files a/icons/effects/96x96.dmi and b/icons/effects/96x96.dmi differ diff --git a/paradise.dme b/paradise.dme index 749b72d925f..8f0b4deab90 100644 --- a/paradise.dme +++ b/paradise.dme @@ -372,6 +372,7 @@ #include "code\datums\mixed.dm" #include "code\datums\movement_detector.dm" #include "code\datums\mutable_appearance.dm" +#include "code\datums\particles.dm" #include "code\datums\pathfinding_mover.dm" #include "code\datums\periodic_news.dm" #include "code\datums\pipe_datums.dm" @@ -990,6 +991,7 @@ #include "code\game\objects\effects\spawners\windowspawner.dm" #include "code\game\objects\effects\temporary_visuals\clockcult.dm" #include "code\game\objects\effects\temporary_visuals\cult_visuals.dm" +#include "code\game\objects\effects\temporary_visuals\explosion_temp_visuals.dm" #include "code\game\objects\effects\temporary_visuals\misc_visuals.dm" #include "code\game\objects\effects\temporary_visuals\muzzle_flashes.dm" #include "code\game\objects\effects\temporary_visuals\temporary_visual.dm"