diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index ea3811085b..28a0dc7889 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1079,18 +1079,17 @@ B --><-- A return L //similar function to RANGE_TURFS(), but will search spiralling outwards from the center (like the above, but only turfs) -/proc/spiral_range_turfs(dist=0, center=usr, orange=0) +/proc/spiral_range_turfs(dist=0, center=usr, orange=0, list/outlist = list(), tick_checked) + outlist.Cut() if(!dist) - if(!orange) - return list(center) - else - return list() + outlist += center + return outlist var/turf/t_center = get_turf(center) if(!t_center) - return list() + return outlist - var/list/L = list() + var/list/L = outlist var/turf/T var/y var/x @@ -1128,6 +1127,8 @@ B --><-- A if(T) L += T c_dist++ + if(tick_checked) + CHECK_TICK return L diff --git a/code/_globalvars/configuration.dm b/code/_globalvars/configuration.dm index 23bfdd3987..b001b84255 100644 --- a/code/_globalvars/configuration.dm +++ b/code/_globalvars/configuration.dm @@ -22,12 +22,12 @@ GLOBAL_VAR_INIT(tinted_weldhelh, TRUE) // Debug2 is used in conjunction with a lot of admin verbs and therefore is actually legit. GLOBAL_VAR_INIT(Debug, FALSE) // global debug switch GLOBAL_VAR_INIT(Debug2, FALSE) - -//This was a define, but I changed it to a variable so it can be changed in-game.(kept the all-caps definition because... code...) -Errorage -GLOBAL_VAR_INIT(MAX_EX_DEVESTATION_RANGE, 3) -GLOBAL_VAR_INIT(MAX_EX_HEAVY_RANGE, 7) -GLOBAL_VAR_INIT(MAX_EX_LIGHT_RANGE, 14) -GLOBAL_VAR_INIT(MAX_EX_FLASH_RANGE, 14) -GLOBAL_VAR_INIT(MAX_EX_FLAME_RANGE, 14) -GLOBAL_VAR_INIT(DYN_EX_SCALE, 0.5) - + +//This was a define, but I changed it to a variable so it can be changed in-game.(kept the all-caps definition because... code...) -Errorage +GLOBAL_VAR_INIT(MAX_EX_DEVESTATION_RANGE, 3) +GLOBAL_VAR_INIT(MAX_EX_HEAVY_RANGE, 7) +GLOBAL_VAR_INIT(MAX_EX_LIGHT_RANGE, 14) +GLOBAL_VAR_INIT(MAX_EX_FLASH_RANGE, 14) +GLOBAL_VAR_INIT(MAX_EX_FLAME_RANGE, 14) +GLOBAL_VAR_INIT(DYN_EX_SCALE, 0.5) + diff --git a/code/controllers/subsystem/explosion.dm b/code/controllers/subsystem/explosion.dm new file mode 100644 index 0000000000..fe6657644f --- /dev/null +++ b/code/controllers/subsystem/explosion.dm @@ -0,0 +1,510 @@ +SUBSYSTEM_DEF(explosion) + priority = 99 + wait = 1 + flags = SS_TICKER|SS_NO_INIT + + var/list/explosions + + var/rebuild_tick_split_count = FALSE + var/tick_portions_required = 0 + + var/list/logs + + var/list/zlevels_that_ignore_bombcap + var/list/doppler_arrays + + //legacy caps, set by config + var/devastation_cap = 3 + var/heavy_cap = 7 + var/light_cap = 14 + var/flash_cap = 14 + var/flame_cap = 14 + var/dyn_ex_scale = 0.5 + + var/id_counter = 0 + +/datum/controller/subsystem/explosion/PreInit() + doppler_arrays = list() + logs = list() + explosions = list() + zlevels_that_ignore_bombcap = list("[ZLEVEL_MINING]") + +/datum/controller/subsystem/explosion/Shutdown() + QDEL_LIST(explosions) + QDEL_LIST(logs) + zlevels_that_ignore_bombcap.Cut() + +/datum/controller/subsystem/explosion/Recover() + explosions = SSexplosion.explosions + logs = SSexplosion.logs + id_counter = SSexplosion.id_counter + rebuild_tick_split_count = TRUE + zlevels_that_ignore_bombcap = SSexplosion.zlevels_that_ignore_bombcap + doppler_arrays = SSexplosion.doppler_arrays + + devastation_cap = SSexplosion.devastation_cap + heavy_cap = SSexplosion.heavy_cap + light_cap = SSexplosion.light_cap + flash_cap = SSexplosion.flash_cap + flame_cap = SSexplosion.flame_cap + dyn_ex_scale = SSexplosion.dyn_ex_scale + +/datum/controller/subsystem/explosion/fire() + var/list/cached_explosions = explosions + var/num_explosions = cached_explosions.len + if(!num_explosions) + return + + //figure exactly how many tick splits are required + var/num_splits + if(rebuild_tick_split_count) + var/reactionary = config.reactionary_explosions + num_splits = num_explosions + for(var/I in cached_explosions) + var/datum/explosion/E = I + if(!E.turfs_processed) + ++num_splits + if(reactionary && !E.densities_processed) + ++num_splits + tick_portions_required = num_splits + else + num_splits = tick_portions_required + + MC_SPLIT_TICK_INIT(num_splits) + + for(var/I in cached_explosions) + var/datum/explosion/E = I + + var/etp = E.turfs_processed + if(!etp) + if(GatherTurfs(E)) + --tick_portions_required + etp = TRUE + MC_SPLIT_TICK + + var/edp = E.densities_processed + if(!edp) + if(DensityCalculate(E, etp)) + --tick_portions_required + edp = TRUE + MC_SPLIT_TICK + + if(ProcessExplosion(E, edp)) //splits the tick + --tick_portions_required + explosions -= E + logs += E + NotifyDopplers(E) + MC_SPLIT_TICK + +/datum/controller/subsystem/explosion/proc/NotifyDopplers(datum/explosion/E) + for(var/array in doppler_arrays) + var/obj/machinery/doppler_array/A = array + A.sense_explosion(E.epicenter, E.devastation, E.heavy, E.light, E.finished_at - E.started_at, E.orig_dev_range, E.orig_heavy_range, E.orig_light_range) + +/datum/controller/subsystem/explosion/proc/Create(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = TRUE, ignorecap = FALSE, flame_range = 0 , silent = FALSE, smoke = FALSE) + epicenter = get_turf(epicenter) + if(!epicenter) + return + + if(adminlog) + message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area: [get_area(epicenter)] [ADMIN_COORDJMP(epicenter)]") + log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z])") + + var/datum/explosion/E = new(++id_counter, epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, flame_range, silent, smoke, ignorecap) + + if(heavy_impact_range > 1) + var/datum/effect_system/explosion/Eff + if(smoke) + Eff = new /datum/effect_system/explosion/smoke + else + Eff = new + Eff.set_up(epicenter) + Eff.start() + + //flash mobs + if(flash_range) + for(var/mob/living/L in viewers(flash_range, epicenter)) + L.flash_act() + + if(!silent) + ExplosionSound(epicenter, devastation_range, heavy_impact_range, E.extent) + + //add to SS + if(E.extent) + tick_portions_required += 2 + (config.reactionary_explosions ? 1 : 0) + explosions += E + else + logs += E //Already done processing + +/datum/controller/subsystem/explosion/proc/CreateDynamic(atom/epicenter, power, flash_range, adminlog = TRUE, ignorecap = TRUE, flame_range = 0 , silent = FALSE, smoke = TRUE) + if(!power) + return + var/range = round((2 * power) ** dyn_ex_scale) + Create(epicenter, round(range * 0.25), round(range * 0.5), round(range), flash_range*range, adminlog, ignorecap, flame_range*range, silent, smoke) + +// Using default dyn_ex scale: +// 100 explosion power is a (5, 10, 20) explosion. +// 75 explosion power is a (4, 8, 17) explosion. +// 50 explosion power is a (3, 7, 14) explosion. +// 25 explosion power is a (2, 5, 10) explosion. +// 10 explosion power is a (1, 3, 6) explosion. +// 5 explosion power is a (0, 1, 3) explosion. +// 1 explosion power is a (0, 0, 1) explosion. + +/datum/explosion + var/explosion_id + var/turf/epicenter + + var/started_at + var/finished_at + var/tick_started + var/tick_finished + + var/turfs_processed = FALSE + var/densities_processed = FALSE + + var/orig_dev_range + var/orig_heavy_range + var/orig_light_range + var/orig_flash_range + var/orig_flame_range + + var/devastation + var/heavy + var/light + var/extent + + var/flash + var/flame + + var/gather_dist = 0 + + var/list/gathered_turfs + var/list/calculated_turfs + + var/list/unsafe_turfs + +/datum/explosion/New(id, turf/epi, devastation_range, heavy_impact_range, light_impact_range, flash_range, flame_range, silent, smoke, ignorecap) + explosion_id = id + epicenter = epi + + densities_processed = !config.reactionary_explosions + + orig_dev_range = devastation_range + orig_heavy_range = heavy_impact_range + orig_light_range = light_impact_range + orig_flash_range = flash_range + orig_flame_range = flame_range + + if(!ignorecap && !("[epicenter.z]" in SSexplosion.zlevels_that_ignore_bombcap)) + //Clamp all values + devastation_range = min(SSexplosion.devastation_cap, devastation_range) + heavy_impact_range = min(SSexplosion.heavy_cap, heavy_impact_range) + light_impact_range = min(SSexplosion.light_cap, light_impact_range) + flash_range = min(SSexplosion.flash_cap, flash_range) + flame_range = min(SSexplosion.flame_cap, flame_range) + + //store this + devastation = devastation_range + heavy = heavy_impact_range + light = light_impact_range + + extent = max(devastation_range, heavy_impact_range, light_impact_range, flame_range) + + flash = flash_range + flame = flame_range + + started_at = REALTIMEOFDAY + tick_started = world.time + + gathered_turfs = list() + calculated_turfs = list() + unsafe_turfs = list() + +// Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves. +// Stereo users will also hear the direction of the explosion! + +// Calculate far explosion sound range. Only allow the sound effect for heavy/devastating explosions. +// 3/7/14 will calculate to 80 + 35 +/proc/ExplosionSound(turf/epicenter, devastation_range, heavy_impact_range, extent) + var/far_dist = 0 + far_dist += heavy_impact_range * 5 + far_dist += devastation_range * 20 + + var/z0 = epicenter.z + + var/frequency = get_rand_frequency() + var/ex_sound = get_sfx("explosion") + for(var/mob/M in GLOB.player_list) + // Double check for client + var/turf/M_turf = get_turf(M) + if(M_turf && M_turf.z == z0) + var/dist = get_dist(M_turf, epicenter) + // If inside the blast radius + world.view - 2 + if(dist <= round(extent + world.view - 2, 1)) + M.playsound_local(epicenter, ex_sound, 100, 1, frequency, falloff = 5) + // You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station. + else if(dist <= far_dist) + var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist + far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion + M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5) + +/datum/explosion/Destroy() + SSexplosion.explosions -= src + SSexplosion.logs -= src + LAZYCLEARLIST(gathered_turfs) + LAZYCLEARLIST(calculated_turfs) + LAZYCLEARLIST(unsafe_turfs) + return ..() + +/datum/controller/subsystem/explosion/proc/GatherTurfs(datum/explosion/E) + var/turf/epicenter = E.epicenter + + var/x0 = epicenter.x + var/y0 = epicenter.y + var/z0 = epicenter.z + + var/c_dist = E.gather_dist + var/dist = E.extent + + var/list/L = E.gathered_turfs + + if(!c_dist) + L += epicenter + ++c_dist + + while( c_dist <= dist ) + var/y = y0 + c_dist + var/x = x0 - c_dist + 1 + for(x in x to x0 + c_dist) + var/turf/T = locate(x, y, z0) + if(T) + L += T + + y = y0 + c_dist - 1 + x = x0 + c_dist + for(y in y0 - c_dist to y) + var/turf/T = locate(x, y, z0) + if(T) + L += T + + y = y0 - c_dist + x = x0 + c_dist - 1 + for(x in x0 - c_dist to x) + var/turf/T = locate(x, y, z0) + if(T) + L += T + + y = y0 - c_dist + 1 + x = x0 - c_dist + for(y in y to y0 + c_dist) + var/turf/T = locate(x, y, z0) + if(T) + L += T + ++c_dist + + if(MC_TICK_CHECK) + break + + if(c_dist > dist) + E.turfs_processed = TRUE + return TRUE + else + E.gather_dist = c_dist + return FALSE + +/datum/controller/subsystem/explosion/proc/DensityCalculate(datum/explosion/E, done_gathering_turfs) + var/list/L = E.calculated_turfs + var/cut_to = 1 + for(var/I in E.gathered_turfs) // we cache the explosion block rating of every turf in the explosion area + var/turf/T = I + ++cut_to + + var/current_exp_block = T.density ? T.explosion_block : 0 + + for(var/obj/machinery/door/D in T) + if(D.density) + current_exp_block += D.explosion_block + + for(var/obj/structure/window/W in T) + if(W.reinf && W.fulltile) + current_exp_block += W.explosion_block + + for(var/obj/structure/blob/B in T) + current_exp_block += B.explosion_block + + L[T] = current_exp_block + + if(MC_TICK_CHECK) + E.gathered_turfs.Cut(1, cut_to) + return FALSE + + E.gathered_turfs.Cut() + return done_gathering_turfs + +/datum/controller/subsystem/explosion/proc/ProcessExplosion(datum/explosion/E, done_calculating_turfs) + //cache shit for speed + var/id = E.explosion_id + + var/list/cached_unsafe = E.unsafe_turfs + var/list/cached_exp_block = E.calculated_turfs + var/list/affected_turfs = cached_exp_block ? cached_exp_block : E.gathered_turfs + + var/devastation_range = E.devastation + var/heavy_impact_range = E.heavy + var/light_impact_range = E.light + + var/flame_range = E.flame + var/throw_range_max = E.extent + + var/turf/epi = E.epicenter + + var/x0 = epi.x + var/y0 = epi.y + + var/cut_to = 1 + for(var/TI in affected_turfs) + var/turf/T = TI + ++cut_to + + var/init_dist = cheap_hypotenuse(T.x, T.y, x0, y0) + var/dist = init_dist + + if(cached_exp_block) + var/turf/Trajectory = T + while(Trajectory != epi) + Trajectory = get_step_towards(Trajectory, epi) + dist += cached_exp_block[Trajectory] + + var/flame_dist = dist < flame_range + var/throw_dist = dist + + if(dist < devastation_range) + dist = 1 + else if(dist < heavy_impact_range) + dist = 2 + else if(dist < light_impact_range) + dist = 3 + else + dist = 0 + + //------- EX_ACT AND TURF FIRES ------- + + if(flame_dist && prob(40) && !isspaceturf(T) && !T.density) + new /obj/effect/hotspot(T) //Mostly for ambience! + + if(dist > 0) + T.explosion_level = max(T.explosion_level, dist) //let the bigger one have it + T.explosion_id = id + T.ex_act(dist) + cached_unsafe += T + + //--- THROW ITEMS AROUND --- + + var/throw_dir = get_dir(epi, T) + for(var/obj/item/I in T) + if(!I.anchored) + var/throw_range = rand(throw_dist, throw_range_max) + var/turf/throw_at = get_ranged_target_turf(I, throw_dir, throw_range) + I.throw_speed = 4 //Temporarily change their throw_speed for embedding purposes (Resets when it finishes throwing, regardless of hitting anything) + I.throw_at(throw_at, throw_range, 4) + + if(MC_TICK_CHECK) + var/circumference = (PI * (init_dist + 4) * 2) //+4 to radius to prevent shit gaps + if(cached_unsafe.len > circumference) //only do this every revolution + for(var/Unexplode in cached_unsafe) + var/turf/UnexplodeT = Unexplode + UnexplodeT.explosion_level = 0 + cached_unsafe.Cut() + done_calculating_turfs = FALSE + break + + affected_turfs.Cut(1, cut_to) + + if(!done_calculating_turfs) + return FALSE + + //unfuck the shit + for(var/Unexplode in cached_unsafe) + var/turf/UnexplodeT = Unexplode + UnexplodeT.explosion_level = 0 + cached_unsafe.Cut() + + E.finished_at = REALTIMEOFDAY + E.tick_finished = world.time + + return TRUE + +/client/proc/check_bomb_impacts() + set name = "Check Bomb Impact" + set category = "Debug" + + var/newmode = alert("Use reactionary explosions?","Check Bomb Impact", "Yes", "No") + var/turf/epicenter = get_turf(mob) + if(!epicenter) + return + + var/x0 = epicenter.x + var/y0 = epicenter.y + + var/dev = 0 + var/heavy = 0 + var/light = 0 + var/list/choices = list("Small Bomb","Medium Bomb","Big Bomb","Custom Bomb") + var/choice = input("Bomb Size?") in choices + switch(choice) + if(null) + return 0 + if("Small Bomb") + dev = 1 + heavy = 2 + light = 3 + if("Medium Bomb") + dev = 2 + heavy = 3 + light = 4 + if("Big Bomb") + dev = 3 + heavy = 5 + light = 7 + if("Custom Bomb") + dev = input("Devestation range (Tiles):") as num + heavy = input("Heavy impact range (Tiles):") as num + light = input("Light impact range (Tiles):") as num + else + return + + var/datum/explosion/E = new(null, epicenter, dev, heavy, light, ignorecap = TRUE) + + while(!SSexplosion.GatherTurfs(E)) + stoplag() + var/list/turfs + if(newmode) + while(!SSexplosion.DensityCalculate(E, TRUE)) + stoplag() + turfs = E.calculated_turfs.Copy() + else + turfs = E.gathered_turfs.Copy() + + qdel(E) + + for(var/I in turfs) + var/turf/T = I + var/dist = cheap_hypotenuse(T.x, T.y, x0, y0) + turfs[T] + + if(dist < dev) + T.color = "red" + T.maptext = "Dev" + else if (dist < heavy) + T.color = "yellow" + T.maptext = "Heavy" + else if (dist < light) + T.color = "blue" + T.maptext = "Light" + CHECK_TICK + + sleep(100) + for(var/I in turfs) + var/turf/T = I + T.color = null + T.maptext = null diff --git a/code/game/objects/explosion.dm b/code/datums/explosion.dm similarity index 52% rename from code/game/objects/explosion.dm rename to code/datums/explosion.dm index 11079bf847..86ab021191 100644 --- a/code/game/objects/explosion.dm +++ b/code/datums/explosion.dm @@ -1,10 +1,48 @@ -/proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, ignorecap = 0, flame_range, silent = 0, smoke = 1) - set waitfor = 0 - src = null //so we don't abort once src is deleted +#define EXPLOSION_THROW_SPEED 4 + +GLOBAL_LIST_EMPTY(explosions) +//Against my better judgement, I will return the explosion datum +//If I see any GC errors for it I will find you +//and I will gib you +/proc/explosion(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = TRUE, ignorecap = FALSE, flame_range = 0 , silent = FALSE, smoke = FALSE) + return new /datum/explosion(epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog, ignorecap, flame_range, silent, smoke) + +//This datum creates 3 async tasks +//1 GatherSpiralTurfsProc runs spiral_range_turfs(tick_checked = TRUE) to populate the affected_turfs list +//2 CaculateExplosionBlock adds the blockings to the cached_exp_block list +//3 The main thread explodes the prepared turfs + +/datum/explosion + var/explosion_id + var/started_at + var/running = TRUE + var/stopped = 0 //This is the number of threads stopped !DOESN'T COUNT THREAD 2! + var/static/id_counter = 0 + +#define EX_PREPROCESS_EXIT_CHECK \ + if(!running) {\ + stopped = 2;\ + qdel(src);\ + return;\ + } + +#define EX_PREPROCESS_CHECK_TICK \ + if(TICK_CHECK) {\ + stoplag();\ + EX_PREPROCESS_EXIT_CHECK\ + } + +/datum/explosion/New(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog, ignorecap, flame_range, silent, smoke) + set waitfor = FALSE + + var/id = ++id_counter + explosion_id = id + epicenter = get_turf(epicenter) if(!epicenter) return + GLOB.explosions += src if(isnull(flame_range)) flame_range = light_impact_range if(isnull(flash_range)) @@ -30,14 +68,13 @@ //I would make this not ex_act the thing that triggered the explosion, //but everything that explodes gives us their loc or a get_turf() //and somethings expect us to ex_act them so they can qdel() - sleep(1) //tldr, let the calling proc call qdel(src) before we explode + stoplag() //tldr, let the calling proc call qdel(src) before we explode - var/static/explosionid = 1 - var/id = explosionid++ - var/start = world.timeofday + EX_PREPROCESS_EXIT_CHECK + + started_at = REALTIMEOFDAY var/max_range = max(devastation_range, heavy_impact_range, light_impact_range, flame_range) - var/list/cached_exp_block = list() if(adminlog) message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area: [get_area(epicenter)] [ADMIN_COORDJMP(epicenter)]") @@ -53,23 +90,27 @@ far_dist += heavy_impact_range * 5 far_dist += devastation_range * 20 + var/x0 = epicenter.x + var/y0 = epicenter.y + var/z0 = epicenter.z + if(!silent) var/frequency = get_rand_frequency() var/ex_sound = get_sfx("explosion") for(var/mob/M in GLOB.player_list) // Double check for client - if(M && M.client) - var/turf/M_turf = get_turf(M) - if(M_turf && M_turf.z == epicenter.z) - var/dist = get_dist(M_turf, epicenter) - // If inside the blast radius + world.view - 2 - if(dist <= round(max_range + world.view - 2, 1)) - M.playsound_local(epicenter, ex_sound, 100, 1, frequency, falloff = 5) - // You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station. - else if(dist <= far_dist) - var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist - far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion - M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5) + var/turf/M_turf = get_turf(M) + if(M_turf && M_turf.z == z0) + var/dist = get_dist(M_turf, epicenter) + // If inside the blast radius + world.view - 2 + if(dist <= round(max_range + world.view - 2, 1)) + M.playsound_local(epicenter, ex_sound, 100, 1, frequency, falloff = 5) + // You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station. + else if(dist <= far_dist) + var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist + far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion + M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5) + EX_PREPROCESS_CHECK_TICK //postpone processing for a bit var/postponeCycles = max(round(devastation_range/8),1) @@ -77,66 +118,52 @@ SSmachines.postpone(postponeCycles) if(heavy_impact_range > 1) + var/datum/effect_system/explosion/E if(smoke) - var/datum/effect_system/explosion/smoke/E = new/datum/effect_system/explosion/smoke() - E.set_up(epicenter) - E.start() + E = new /datum/effect_system/explosion/smoke else - var/datum/effect_system/explosion/E = new/datum/effect_system/explosion() - E.set_up(epicenter) - E.start() + E = new + E.set_up(epicenter) + E.start() - var/x0 = epicenter.x - var/y0 = epicenter.y - var/z0 = epicenter.z - - var/list/affected_turfs = spiral_range_turfs(max_range, epicenter) - - if(config.reactionary_explosions) - for(var/turf/T in affected_turfs) // we cache the explosion block rating of every turf in the explosion area - cached_exp_block[T] = 0 - if(T.density && T.explosion_block) - cached_exp_block[T] += T.explosion_block - - for(var/obj/machinery/door/D in T) - if(D.density && D.explosion_block) - cached_exp_block[T] += D.explosion_block - - for(var/obj/structure/window/W in T) - if(W.reinf && W.fulltile) - cached_exp_block[T] += W.explosion_block - - for(var/obj/structure/blob/B in T) - cached_exp_block[T] += B.explosion_block - CHECK_TICK + EX_PREPROCESS_CHECK_TICK //flash mobs if(flash_range) for(var/mob/living/L in viewers(flash_range, epicenter)) L.flash_act() - CHECK_TICK + EX_PREPROCESS_CHECK_TICK var/list/exploded_this_tick = list() //open turfs that need to be blocked off while we sleep - for(var/turf/T in affected_turfs) + var/list/affected_turfs = GatherSpiralTurfs(max_range, epicenter) - if (!T) - continue + var/reactionary = config.reactionary_explosions + var/list/cached_exp_block + + if(reactionary) + cached_exp_block = CaculateExplosionBlock(affected_turfs) + + //lists are guaranteed to contain at least 1 turf at this point + + var/iteration = 0 + var/affTurfLen = affected_turfs.len + var/expBlockLen = cached_exp_block.len + for(var/TI in affected_turfs) + var/turf/T = TI + ++iteration var/init_dist = cheap_hypotenuse(T.x, T.y, x0, y0) var/dist = init_dist - if(config.reactionary_explosions) + if(reactionary) var/turf/Trajectory = T while(Trajectory != epicenter) Trajectory = get_step_towards(Trajectory, epicenter) dist += cached_exp_block[Trajectory] - var/flame_dist = 0 + var/flame_dist = dist < flame_range var/throw_dist = dist - if(dist < flame_range) - flame_dist = 1 - if(dist < devastation_range) dist = 1 else if(dist < heavy_impact_range) @@ -148,27 +175,61 @@ //------- EX_ACT AND TURF FIRES ------- - if(T) - if(flame_dist && prob(40) && !isspaceturf(T) && !T.density) - new /obj/effect/hotspot(T) //Mostly for ambience! - if(dist > 0) - T.explosion_level = max(T.explosion_level, dist) //let the bigger one have it - T.explosion_id = id - T.ex_act(dist) - exploded_this_tick += T + if(flame_dist && prob(40) && !isspaceturf(T) && !T.density) + new /obj/effect/hotspot(T) //Mostly for ambience! + + if(dist > 0) + T.explosion_level = max(T.explosion_level, dist) //let the bigger one have it + T.explosion_id = id + T.ex_act(dist) + exploded_this_tick += T //--- THROW ITEMS AROUND --- var/throw_dir = get_dir(epicenter,T) for(var/obj/item/I in T) - if(I && !I.anchored) + if(!I.anchored) var/throw_range = rand(throw_dist, max_range) var/turf/throw_at = get_ranged_target_turf(I, throw_dir, throw_range) - I.throw_speed = 4 //Temporarily change their throw_speed for embedding purposes (Reset when it finishes throwing, regardless of hitting anything) - I.throw_at(throw_at, throw_range, I.throw_speed) + I.throw_speed = EXPLOSION_THROW_SPEED //Temporarily change their throw_speed for embedding purposes (Reset when it finishes throwing, regardless of hitting anything) + I.throw_at(throw_at, throw_range, EXPLOSION_THROW_SPEED) - if(TICK_CHECK) + //wait for the lists to repop + var/break_condition + if(reactionary) + //If we've caught up to the density checker thread and there are no more turfs to process + break_condition = iteration == expBlockLen && iteration < affTurfLen + else + //If we've caught up to the turf gathering thread and it's still running + break_condition = iteration == affTurfLen && !stopped + + if(break_condition || TICK_CHECK) stoplag() + + if(!running) + break + + //update the trackers + affTurfLen = affected_turfs.len + expBlockLen = cached_exp_block.len + + if(break_condition) + if(reactionary) + //until there are more block checked turfs than what we are currently at + //or the explosion has stopped + UNTIL(iteration < affTurfLen || !running) + else + //until there are more gathered turfs than what we are currently at + //or there are no more turfs to gather/the explosion has stopped + UNTIL(iteration < expBlockLen || stopped) + + if(!running) + break + + //update the trackers + affTurfLen = affected_turfs.len + expBlockLen = cached_exp_block.len + var/circumference = (PI * (init_dist + 4) * 2) //+4 to radius to prevent shit gaps if(exploded_this_tick.len > circumference) //only do this every revolution for(var/Unexplode in exploded_this_tick) @@ -182,24 +243,67 @@ UnexplodeT.explosion_level = 0 exploded_this_tick.Cut() - var/took = (world.timeofday-start)/10 - //You need to press the DebugGame verb to see these now....they were getting annoying and we've collected a fair bit of data. Just -test- changes to explosion code using this please so we can compare + var/took = (REALTIMEOFDAY - started_at) / 10 + + //You need to press the DebugGame verb to see these now....they were getting annoying and we've collected a fair bit of data. Just -test- changes to explosion code using this please so we can compare if(GLOB.Debug2) log_world("## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [took] seconds.") - //Machines which report explosions. - for(var/array in GLOB.doppler_arrays) - var/obj/machinery/doppler_array/A = array - A.sense_explosion(epicenter,devastation_range,heavy_impact_range,light_impact_range,took,orig_dev_range,orig_heavy_range,orig_light_range) + if(!stopped) //if we aren't in a hurry + //Machines which report explosions. + for(var/array in GLOB.doppler_arrays) + var/obj/machinery/doppler_array/A = array + A.sense_explosion(epicenter, devastation_range, heavy_impact_range, light_impact_range, took,orig_dev_range, orig_heavy_range, orig_light_range) - return 1 + ++stopped + qdel(src) +#undef EX_PREPROCESS_EXIT_CHECK +#undef EX_PREPROCESS_CHECK_TICK +//asyncly populate the affected_turfs list +/datum/explosion/proc/GatherSpiralTurfs(range, turf/epicenter) + set waitfor = FALSE + . = list() + spiral_range_turfs(range, epicenter, outlist = ., tick_checked = TRUE) + ++stopped -/proc/secondaryexplosion(turf/epicenter, range) - for(var/turf/tile in spiral_range_turfs(range, epicenter)) - tile.ex_act(2) +/datum/explosion/proc/CaculateExplosionBlock(list/affected_turfs) + set waitfor = FALSE + . = list() + var/processed = 0 + while(!stopped && running) + var/I + for(I in (processed + 1) to affected_turfs.len) // we cache the explosion block rating of every turf in the explosion area + var/turf/T = affected_turfs[I] + var/current_exp_block = T.density ? T.explosion_block : 0 + + for(var/obj/machinery/door/D in T) + if(D.density) + current_exp_block += D.explosion_block + + for(var/obj/structure/window/W in T) + if(W.reinf && W.fulltile) + current_exp_block += W.explosion_block + + for(var/obj/structure/blob/B in T) + current_exp_block += B.explosion_block + + .[T] = current_exp_block + + if(TICK_CHECK) + break + + processed = I + stoplag() + +/datum/explosion/Destroy() + running = FALSE + if(stopped < 2) //wait for main thread and spiral_range thread + return QDEL_HINT_IWILLGC + GLOB.explosions -= src + return ..() /client/proc/check_bomb_impacts() set name = "Check Bomb Impact" diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 65d4cf1449..d7422429ff 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -28,8 +28,8 @@ var/list/our_overlays //our local copy of (non-priority) overlays without byond magic. Use procs in SSoverlays to manipulate var/list/priority_overlays //overlays that should remain on top and not normally removed when using cut_overlay functions, like c4. - var/datum/proximity_monitor/proximity_monitor - + var/datum/proximity_monitor/proximity_monitor + /atom/New(loc, ...) //atom creation method that preloads variables at creation if(GLOB.use_preloader && (src.type == GLOB._preloader.target_path))//in case the instanciated atom is creating other atoms in New() @@ -39,21 +39,21 @@ var/do_initialize = SSatoms.initialized if(do_initialize > INITIALIZATION_INSSATOMS) - args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD - if(SSatoms.InitAtom(src, args)) - //we were deleted - return - - var/list/created = SSatoms.created_atoms - if(created) - created += src + args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD + if(SSatoms.InitAtom(src, args)) + //we were deleted + return + + var/list/created = SSatoms.created_atoms + if(created) + created += src //Called after New if the map is being loaded. mapload = TRUE //Called from base of New if the map is being loaded. mapload = FALSE -//This base must be called or derivatives must set initialized to TRUE -//must not sleep +//This base must be called or derivatives must set initialized to TRUE +//must not sleep //Other parameters are passed from New (excluding loc), this does not happen if mapload is TRUE -//Must return an Initialize hint. Defined in __DEFINES/subsystems.dm +//Must return an Initialize hint. Defined in __DEFINES/subsystems.dm //Note: the following functions don't call the base for optimization and must copypasta: // /turf/Initialize @@ -76,23 +76,23 @@ if (opacity && isturf(loc)) var/turf/T = loc T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guaranteed to be on afterwards anyways. - return INITIALIZE_HINT_NORMAL + return INITIALIZE_HINT_NORMAL -//called if Initialize returns INITIALIZE_HINT_LATELOAD -//This version shouldn't be called -/atom/proc/LateInitialize() - var/static/list/warned_types = list() - if(!warned_types[type]) - WARNING("Old style LateInitialize behaviour detected in [type]!") - warned_types[type] = TRUE - Initialize(FALSE) +//called if Initialize returns INITIALIZE_HINT_LATELOAD +//This version shouldn't be called +/atom/proc/LateInitialize() + var/static/list/warned_types = list() + if(!warned_types[type]) + WARNING("Old style LateInitialize behaviour detected in [type]!") + warned_types[type] = TRUE + Initialize(FALSE) /atom/Destroy() if(alternate_appearances) - for(var/K in alternate_appearances) - var/datum/atom_hud/alternate_appearance/AA = alternate_appearances[K] - AA.remove_from_hud(src) - + for(var/K in alternate_appearances) + var/datum/atom_hud/alternate_appearance/AA = alternate_appearances[K] + AA.remove_from_hud(src) + if(reagents) qdel(reagents) @@ -100,8 +100,8 @@ LAZYCLEARLIST(priority_overlays) //SSoverlays.processing -= src //we COULD do this, but it's better to just let it fall out of the processing queue - QDEL_NULL(light) - + QDEL_NULL(light) + return ..() /atom/proc/handle_ricochet(obj/item/projectile/P) @@ -277,7 +277,6 @@ return /atom/proc/ex_act(severity, target) - set waitfor = FALSE contents_explosion(severity, target) /atom/proc/blob_act(obj/structure/blob/B) @@ -509,10 +508,10 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons) /atom/proc/mech_melee_attack(obj/mecha/M) return -//If a mob logouts/logins in side of an object you can use this proc -/atom/proc/on_log(login) - if(loc) - loc.on_log(login) +//If a mob logouts/logins in side of an object you can use this proc +/atom/proc/on_log(login) + if(loc) + loc.on_log(login) /* diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm index 48dc35da4b..4053e9755c 100644 --- a/code/game/machinery/doppler_array.dm +++ b/code/game/machinery/doppler_array.dm @@ -1,5 +1,5 @@ -GLOBAL_LIST_EMPTY(doppler_arrays) - +GLOBAL_LIST_EMPTY(doppler_arrays) + /obj/machinery/doppler_array name = "tachyon-doppler array" desc = "A highly precise directional sensor array which measures the release of quants from decaying tachyons. The doppler shifting of the mirror-image formed by these quants can reveal the size, location and temporal affects of energetic disturbances within a large radius ahead of the array.\nAlt-click to rotate it clockwise." @@ -13,10 +13,10 @@ GLOBAL_LIST_EMPTY(doppler_arrays) /obj/machinery/doppler_array/New() ..() - GLOB.doppler_arrays += src + GLOB.doppler_arrays += src /obj/machinery/doppler_array/Destroy() - GLOB.doppler_arrays -= src + GLOB.doppler_arrays -= src return ..() /obj/machinery/doppler_array/process() diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 66cc6be38a..1e6fd57b1d 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -154,7 +154,7 @@ M.forceMove(loc) if(prob(30)) - explosion(get_turf(loc), 0, 0, 1, 3) + explosion(get_turf(loc), 0, 0, 1, 3) if(wreckage) var/obj/structure/mecha_wreckage/WR = new wreckage(loc, AI) diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm index 46c2306a79..74459cc85d 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -39,7 +39,7 @@ var/range_flash = 3 /obj/effect/mine/explosive/mineEffect(mob/victim) - explosion(loc, range_devastation, range_heavy, range_light, range_flash) + explosion(loc, range_devastation, range_heavy, range_light, range_flash) /obj/effect/mine/stun diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index f3c32d3d68..c86d0dff85 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -897,9 +897,9 @@ GLOBAL_LIST_EMPTY(PDAs) if(T) T.hotspot_expose(700,125) if(istype(cartridge, /obj/item/weapon/cartridge/syndicate)) - explosion(T, -1, 1, 3, 4) + explosion(T, -1, 1, 3, 4) else - explosion(T, -1, -1, 2, 3) + explosion(T, -1, -1, 2, 3) qdel(src) return diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index e03c85c09a..a4e1a45814 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -141,5 +141,5 @@ if(power_drained >= max_power) STOP_PROCESSING(SSobj, src) - explosion(src.loc, 4,8,16,32) + explosion(src.loc, 4,8,16,32) qdel(src) diff --git a/code/game/objects/items/weapons/grenades/ghettobomb.dm b/code/game/objects/items/weapons/grenades/ghettobomb.dm index f4d573e3ba..76f3c8ac73 100644 --- a/code/game/objects/items/weapons/grenades/ghettobomb.dm +++ b/code/game/objects/items/weapons/grenades/ghettobomb.dm @@ -59,7 +59,7 @@ /obj/item/weapon/grenade/iedcasing/prime() //Blowing that can up update_mob() - explosion(src.loc,-1,-1,2, flame_range = 4) // small explosion, plus a very large fireball. + explosion(src.loc,-1,-1,2, flame_range = 4) // small explosion, plus a very large fireball. qdel(src) /obj/item/weapon/grenade/iedcasing/examine(mob/user) diff --git a/code/game/objects/items/weapons/grenades/syndieminibomb.dm b/code/game/objects/items/weapons/grenades/syndieminibomb.dm index 67b0dcddeb..6b260d366a 100644 --- a/code/game/objects/items/weapons/grenades/syndieminibomb.dm +++ b/code/game/objects/items/weapons/grenades/syndieminibomb.dm @@ -9,7 +9,7 @@ /obj/item/weapon/grenade/syndieminibomb/prime() update_mob() - explosion(src.loc,1,2,4,flame_range = 2) + explosion(src.loc,1,2,4,flame_range = 2) qdel(src) /obj/item/weapon/grenade/syndieminibomb/concussion @@ -20,7 +20,7 @@ /obj/item/weapon/grenade/syndieminibomb/concussion/prime() update_mob() - explosion(src.loc,0,2,3,flame_range = 3) + explosion(src.loc,0,2,3,flame_range = 3) qdel(src) /obj/item/weapon/grenade/syndieminibomb/concussion/frag diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 0fd70e7ac3..ed502e17cd 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -83,7 +83,7 @@ /obj/item/weapon/storage/backpack/holding/singularity_act(current_size) var/dist = max((current_size - 2),1) - explosion(src.loc,(dist),(dist*2),(dist*4)) + explosion(src.loc,(dist),(dist*2),(dist*4)) return diff --git a/code/game/objects/structures/crates_lockers/crates/secure.dm b/code/game/objects/structures/crates_lockers/crates/secure.dm index 603dce4358..75096209f5 100644 --- a/code/game/objects/structures/crates_lockers/crates/secure.dm +++ b/code/game/objects/structures/crates_lockers/crates/secure.dm @@ -38,7 +38,7 @@ log_game("[key_name(user)] has detonated [src.name].") for(var/atom/movable/AM in src) qdel(AM) - explosion(get_turf(src), 0, 1, 5, 5) + explosion(get_turf(src), 0, 1, 5, 5) qdel(src) /obj/structure/closet/crate/secure/weapon diff --git a/code/modules/awaymissions/bluespaceartillery.dm b/code/modules/awaymissions/bluespaceartillery.dm index e3aeec62cd..2e7ce98510 100644 --- a/code/modules/awaymissions/bluespaceartillery.dm +++ b/code/modules/awaymissions/bluespaceartillery.dm @@ -53,7 +53,7 @@ for(var/turf/T in get_area_turfs(thearea.type)) L+=T var/loc = pick(L) - explosion(loc,explosiondev,explosionmed,explosionlight) + explosion(loc,explosiondev,explosionmed,explosionlight) reload = 0 /*/mob/proc/openfire() diff --git a/code/modules/awaymissions/mission_code/wildwest.dm b/code/modules/awaymissions/mission_code/wildwest.dm index 5847b8de8e..395344ce4c 100644 --- a/code/modules/awaymissions/mission_code/wildwest.dm +++ b/code/modules/awaymissions/mission_code/wildwest.dm @@ -107,7 +107,7 @@ var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread s.set_up(3, 1, src) s.start() - explosion(M, 1, 0, 0, 0) + explosion(M, 1, 0, 0, 0) qdel(src) /////For the Wishgranter/////////// diff --git a/code/modules/events/brand_intelligence.dm b/code/modules/events/brand_intelligence.dm index cf7b12b139..cb07cdfd9e 100644 --- a/code/modules/events/brand_intelligence.dm +++ b/code/modules/events/brand_intelligence.dm @@ -57,7 +57,7 @@ M.speak = rampant_speeches.Copy() M.speak_chance = 7 else - explosion(upriser.loc, -1, 1, 2, 4, 0) + explosion(upriser.loc, -1, 1, 2, 4, 0) qdel(upriser) kill() diff --git a/code/modules/events/processor_overload.dm b/code/modules/events/processor_overload.dm index e0673cb741..329e887379 100644 --- a/code/modules/events/processor_overload.dm +++ b/code/modules/events/processor_overload.dm @@ -32,7 +32,7 @@ var/obj/machinery/telecomms/processor/P = T if(prob(10)) // Damage the surrounding area to indicate that it popped - explosion(get_turf(P), 0, 0, 2) + explosion(get_turf(P), 0, 0, 2) // Only a level 1 explosion actually damages the machine // at all P.ex_act(1) diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index b1ba6680c2..9a9fefac03 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -263,11 +263,11 @@ spawn(det_time) if(primed) if(quality == 3) - explosion(src.loc,2,4,9,adminlog = notify_admins) + explosion(src.loc,2,4,9,adminlog = notify_admins) if(quality == 2) - explosion(src.loc,1,2,5,adminlog = notify_admins) + explosion(src.loc,1,2,5,adminlog = notify_admins) if(quality == 1) - explosion(src.loc,-1,1,3,adminlog = notify_admins) + explosion(src.loc,-1,1,3,adminlog = notify_admins) qdel(src) /obj/item/weapon/ore/Initialize() diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm index c78084335f..d21f0a221c 100644 --- a/code/modules/mob/living/silicon/ai/death.dm +++ b/code/modules/mob/living/silicon/ai/death.dm @@ -23,7 +23,7 @@ if(explosive) spawn(10) - explosion(src.loc, 3, 6, 12, 15) + explosion(src.loc, 3, 6, 12, 15) for(var/obj/machinery/ai_status_display/O in world) //change status if(src.key) diff --git a/code/modules/power/antimatter/containment_jar.dm b/code/modules/power/antimatter/containment_jar.dm index 0d2be23114..73fd2af580 100644 --- a/code/modules/power/antimatter/containment_jar.dm +++ b/code/modules/power/antimatter/containment_jar.dm @@ -18,12 +18,12 @@ /obj/item/weapon/am_containment/ex_act(severity, target) switch(severity) if(1) - explosion(get_turf(src), 1, 2, 3, 5)//Should likely be larger but this works fine for now I guess + explosion(get_turf(src), 1, 2, 3, 5)//Should likely be larger but this works fine for now I guess if(src) qdel(src) if(2) if(prob((fuel/10)-stability)) - explosion(get_turf(src), 1, 2, 3, 5) + explosion(get_turf(src), 1, 2, 3, 5) if(src) qdel(src) return diff --git a/code/modules/power/antimatter/control.dm b/code/modules/power/antimatter/control.dm index 647f838311..a1e448d282 100644 --- a/code/modules/power/antimatter/control.dm +++ b/code/modules/power/antimatter/control.dm @@ -46,7 +46,7 @@ /obj/machinery/power/am_control_unit/process() if(exploding) - explosion(get_turf(src),8,12,18,12) + explosion(get_turf(src),8,12,18,12) if(src) qdel(src) diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 64d4077a12..a4b994e0cf 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -123,7 +123,7 @@ corrupt() return //explosion(T, 0, 1, 2, 2) - explosion(T, devastation_range, heavy_impact_range, light_impact_range, flash_range) + explosion(T, devastation_range, heavy_impact_range, light_impact_range, flash_range) qdel(src) /obj/item/weapon/stock_parts/cell/proc/corrupt() diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index c02c13caf1..f1f251338e 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -167,7 +167,7 @@ src.updateDialog() /obj/machinery/power/port_gen/pacman/proc/overheat() - explosion(src.loc, 2, 5, 2, -1) + explosion(src.loc, 2, 5, 2, -1) /obj/machinery/power/port_gen/pacman/attackby(obj/item/O, mob/user, params) if(istype(O, sheet_path)) @@ -294,7 +294,7 @@ board_path = /obj/item/weapon/circuitboard/machine/pacman/super /obj/machinery/power/port_gen/pacman/super/overheat() - explosion(src.loc, 3, 3, 3, -1) + explosion(src.loc, 3, 3, 3, -1) /obj/machinery/power/port_gen/pacman/mrs name = "\improper M.R.S.P.A.C.M.A.N.-type portable generator" @@ -305,4 +305,4 @@ board_path = /obj/item/weapon/circuitboard/machine/pacman/mrs /obj/machinery/power/port_gen/pacman/mrs/overheat() - explosion(src.loc, 4, 4, 4, -1) + explosion(src.loc, 4, 4, 4, -1) diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm index 247273e3f4..dfc6351c3c 100644 --- a/code/modules/projectiles/guns/magic/wand.dm +++ b/code/modules/projectiles/guns/magic/wand.dm @@ -166,5 +166,5 @@ /obj/item/weapon/gun/magic/wand/fireball/zap_self(mob/living/user) ..() - explosion(user.loc, -1, 0, 2, 3, 0, flame_range = 2) + explosion(user.loc, -1, 0, 2, 3, 0, flame_range = 2) charges-- \ No newline at end of file diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 0594c17469..5ffebf33b3 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -61,10 +61,10 @@ /obj/item/projectile/bullet/pellet/overload/on_hit(atom/target, blocked = 0) ..() - explosion(target, 0, 0, 2) + explosion(target, 0, 0, 2) /obj/item/projectile/bullet/pellet/overload/on_range() - explosion(src, 0, 0, 2) + explosion(src, 0, 0, 2) do_sparks(3, TRUE, src) ..() diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 1844dc53ab..be13516d3c 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -66,7 +66,7 @@ reagent_id = "welding_fuel" /obj/structure/reagent_dispensers/fueltank/boom() - explosion(get_turf(src), 0, 1, 5, flame_range = 5) + explosion(get_turf(src), 0, 1, 5, flame_range = 5) qdel(src) /obj/structure/reagent_dispensers/fueltank/blob_act(obj/structure/blob/B) @@ -165,7 +165,7 @@ reagent_id = "beer" /obj/structure/reagent_dispensers/beerkeg/blob_act(obj/structure/blob/B) - explosion(src.loc,0,3,5,7,10) + explosion(src.loc,0,3,5,7,10) if(!QDELETED(src)) qdel(src) diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index 8db05a0c4f..fa58de0964 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -683,7 +683,7 @@ spawn(rand(35,100)) if(src.loc == user) visible_message("The [src]'s top opens, releasing a powerful blast!") - explosion(user.loc, -1, rand(1,5), rand(1,5), rand(1,5), rand(1,5), flame_range = 2) + explosion(user.loc, -1, rand(1,5), rand(1,5), rand(1,5), rand(1,5), flame_range = 2) warn_admins(user, "Explosion") qdel(src) //Comment this line to produce a light grenade (the bomb that keeps on exploding when used)!! diff --git a/code/modules/spells/spell_types/explosion.dm b/code/modules/spells/spell_types/explosion.dm index a19a9582ba..443546d12f 100644 --- a/code/modules/spells/spell_types/explosion.dm +++ b/code/modules/spells/spell_types/explosion.dm @@ -10,6 +10,6 @@ /obj/effect/proc_holder/spell/targeted/explosion/cast(list/targets,mob/user = usr) for(var/mob/living/target in targets) - explosion(target.loc,ex_severe,ex_heavy,ex_light,ex_flash) + explosion(target.loc,ex_severe,ex_heavy,ex_light,ex_flash) return \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index 73383cbebd..050e661dc5 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -245,6 +245,7 @@ #include "code\datums\dna.dm" #include "code\datums\dog_fashion.dm" #include "code\datums\emotes.dm" +#include "code\datums\explosion.dm" #include "code\datums\forced_movement.dm" #include "code\datums\holocall.dm" #include "code\datums\hud.dm" @@ -686,7 +687,6 @@ #include "code\game\mecha\working\working.dm" #include "code\game\objects\buckling.dm" #include "code\game\objects\empulse.dm" -#include "code\game\objects\explosion.dm" #include "code\game\objects\items.dm" #include "code\game\objects\obj_defense.dm" #include "code\game\objects\objs.dm"