mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-10 09:54:52 +00:00
Refactors explosions
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
510
code/controllers/subsystem/explosion.dm
Normal file
510
code/controllers/subsystem/explosion.dm
Normal file
@@ -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
|
||||
@@ -1,14 +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
|
||||
|
||||
if(isnull(flame_range))
|
||||
flame_range = light_impact_range
|
||||
if(isnull(flash_range))
|
||||
flash_range = devastation_range
|
||||
GLOB.explosions += src
|
||||
|
||||
// Archive the uncapped explosion for the doppler array
|
||||
var/orig_dev_range = devastation_range
|
||||
@@ -30,14 +64,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,14 +86,17 @@
|
||||
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)
|
||||
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))
|
||||
@@ -70,6 +106,7 @@
|
||||
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 +114,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 = 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,9 +171,9 @@
|
||||
|
||||
//------- 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
|
||||
@@ -161,14 +184,48 @@
|
||||
|
||||
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 +239,67 @@
|
||||
UnexplodeT.explosion_level = 0
|
||||
exploded_this_tick.Cut()
|
||||
|
||||
var/took = (world.timeofday-start)/10
|
||||
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.")
|
||||
|
||||
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)
|
||||
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"
|
||||
53
code/datums/explosion.dm.rej
Normal file
53
code/datums/explosion.dm.rej
Normal file
@@ -0,0 +1,53 @@
|
||||
diff a/code/datums/explosion.dm b/code/datums/explosion.dm (rejected hunks)
|
||||
@@ -1,10 +1,48 @@
|
||||
-/proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, ignorecap = 0, flame_range = 0 ,silent = 0, smoke = 1)
|
||||
- set waitfor = 0
|
||||
- src = null //so we don't abort once src is deleted
|
||||
+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
|
||||
+// --Cyberboss
|
||||
+/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 threads
|
||||
+//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
|
||||
+
|
||||
// Archive the uncapped explosion for the doppler array
|
||||
var/orig_dev_range = devastation_range
|
||||
var/orig_heavy_range = heavy_impact_range
|
||||
@@ -274,7 +274,6 @@
|
||||
return
|
||||
|
||||
/atom/proc/ex_act(severity, target)
|
||||
set waitfor = FALSE
|
||||
contents_explosion(severity, target)
|
||||
|
||||
/atom/proc/blob_act(obj/structure/blob/B)
|
||||
|
||||
9
code/game/atoms.dm.rej
Normal file
9
code/game/atoms.dm.rej
Normal file
@@ -0,0 +1,9 @@
|
||||
diff a/code/game/atoms.dm b/code/game/atoms.dm (rejected hunks)
|
||||
@@ -267,6 +267,7 @@
|
||||
return
|
||||
|
||||
/atom/proc/ex_act(severity, target)
|
||||
+ set waitfor = FALSE
|
||||
contents_explosion(severity, target)
|
||||
|
||||
/atom/proc/blob_act(obj/structure/blob/B)
|
||||
@@ -0,0 +1,10 @@
|
||||
diff a/code/game/objects/items/weapons/implants/implant_explosive.dm b/code/game/objects/items/weapons/implants/implant_explosive.dm (rejected hunks)
|
||||
@@ -47,7 +47,7 @@
|
||||
message_admins("[key_name_admin(imp_in)]<A HREF='?_src_=holder;adminmoreinfo=\ref[imp_in]'>?</A> (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[imp_in]'>FLW</A>) has activated their [name] at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[imp_in.x];Y=[imp_in.y];Z=[imp_in.z]'>[A.name] (JMP)</a>.")
|
||||
//If the delay is short, just blow up already jeez
|
||||
if(delay <= 7)
|
||||
- SSexplosion.Create(src,heavy,medium,weak,weak, flame_range = weak)
|
||||
+ explosion(src,heavy,medium,weak,weak, flame_range = weak)
|
||||
if(imp_in)
|
||||
imp_in.gib(1)
|
||||
qdel(src)
|
||||
24
code/modules/admin/admin_verbs.dm.rej
Normal file
24
code/modules/admin/admin_verbs.dm.rej
Normal file
@@ -0,0 +1,24 @@
|
||||
diff a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm (rejected hunks)
|
||||
@@ -515,11 +515,11 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, AVerbsHideable())
|
||||
var/flash_range = input("Flash range (in tiles):") as null|num
|
||||
if(flash_range == null)
|
||||
return
|
||||
- if(devastation_range > SSexplosion.devastation_cap || heavy_impact_range > SSexplosion.heavy_cap || light_impact_range > SSexplosion.light_cap || flash_range > SSexplosion.flash_cap)
|
||||
+ if(devastation_range > GLOB.MAX_EX_DEVESTATION_RANGE || heavy_impact_range > GLOB.MAX_EX_HEAVY_RANGE || light_impact_range > GLOB.MAX_EX_LIGHT_RANGE || flash_range > GLOB.MAX_EX_FLASH_RANGE)
|
||||
if(alert("Bomb is bigger than the maxcap. Continue?",,"Yes","No") != "Yes")
|
||||
return
|
||||
epicenter = mob.loc //We need to reupdate as they may have moved again
|
||||
- SSexplosion.Create(epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, TRUE, TRUE)
|
||||
+ explosion(epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, TRUE, TRUE)
|
||||
message_admins("[ADMIN_LOOKUPFLW(usr)] creating an admin explosion at [epicenter.loc].")
|
||||
log_admin("[key_name(usr)] created an admin explosion at [epicenter.loc].")
|
||||
feedback_add_details("admin_verb","Drop Bomb") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
@@ -532,7 +532,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, AVerbsHideable())
|
||||
var/ex_power = input("Explosive Power:") as null|num
|
||||
var/turf/epicenter = mob.loc
|
||||
if(ex_power && epicenter)
|
||||
- SSexplosion.CreateDynamic(epicenter, ex_power)
|
||||
+ dyn_explosion(epicenter, ex_power)
|
||||
message_admins("[ADMIN_LOOKUPFLW(usr)] creating an admin explosion at [epicenter.loc].")
|
||||
log_admin("[key_name(usr)] created an admin explosion at [epicenter.loc].")
|
||||
feedback_add_details("admin_verb","Drop Dynamic Bomb") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
29
code/modules/admin/secrets.dm.rej
Normal file
29
code/modules/admin/secrets.dm.rej
Normal file
@@ -0,0 +1,29 @@
|
||||
diff a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm (rejected hunks)
|
||||
@@ -386,19 +386,19 @@
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","BC")
|
||||
|
||||
- var/newBombCap = input(usr,"What would you like the new bomb cap to be. (entered as the light damage range (the 3rd number in common (1,2,3) notation)) Must be above 4)", "New Bomb Cap", SSexplosion.light_cap) as num|null
|
||||
+ var/newBombCap = input(usr,"What would you like the new bomb cap to be. (entered as the light damage range (the 3rd number in common (1,2,3) notation)) Must be above 4)", "New Bomb Cap", GLOB.MAX_EX_LIGHT_RANGE) as num|null
|
||||
if (newBombCap < 4)
|
||||
return
|
||||
|
||||
- SSexplosion.devastation_cap = round(newBombCap/4)
|
||||
- SSexplosion.heavy_cap = round(newBombCap/2)
|
||||
- SSexplosion.light_cap = newBombCap
|
||||
+ GLOB.MAX_EX_DEVESTATION_RANGE = round(newBombCap/4)
|
||||
+ GLOB.MAX_EX_HEAVY_RANGE = round(newBombCap/2)
|
||||
+ GLOB.MAX_EX_LIGHT_RANGE = newBombCap
|
||||
//I don't know why these are their own variables, but fuck it, they are.
|
||||
- SSexplosion.flash_cap = newBombCap
|
||||
- SSexplosion.flame_cap = newBombCap
|
||||
+ GLOB.MAX_EX_FLASH_RANGE = newBombCap
|
||||
+ GLOB.MAX_EX_FLAME_RANGE = newBombCap
|
||||
|
||||
- message_admins("<span class='boldannounce'>[key_name_admin(usr)] changed the bomb cap to [SSexplosion.devastation_cap], [SSexplosion.heavy_cap], [SSexplosion.light_cap]</span>")
|
||||
- log_admin("[key_name(usr)] changed the bomb cap to [SSexplosion.devastation_cap], [SSexplosion.heavy_cap], [SSexplosion.light_cap]")
|
||||
+ message_admins("<span class='boldannounce'>[key_name_admin(usr)] changed the bomb cap to [GLOB.MAX_EX_DEVESTATION_RANGE], [GLOB.MAX_EX_HEAVY_RANGE], [GLOB.MAX_EX_LIGHT_RANGE]</span>")
|
||||
+ log_admin("[key_name(usr)] changed the bomb cap to [GLOB.MAX_EX_DEVESTATION_RANGE], [GLOB.MAX_EX_HEAVY_RANGE], [GLOB.MAX_EX_LIGHT_RANGE]")
|
||||
|
||||
|
||||
if("lightsout")
|
||||
10
code/modules/admin/verbs/randomverbs.dm.rej
Normal file
10
code/modules/admin/verbs/randomverbs.dm.rej
Normal file
@@ -0,0 +1,10 @@
|
||||
diff a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm (rejected hunks)
|
||||
@@ -557,7 +557,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
if (alert(src, "Are you sure you want to do this? It will laaag.", "Confirmation", "Yes", "No") == "No")
|
||||
return
|
||||
|
||||
- SSexplosion.Create(O, devastation, heavy, light, flash, null, null,flames)
|
||||
+ explosion(O, devastation, heavy, light, flash, null, null,flames)
|
||||
log_admin("[key_name(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at ([O.x],[O.y],[O.z])")
|
||||
message_admins("[key_name_admin(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at ([O.x],[O.y],[O.z])")
|
||||
feedback_add_details("admin_verb","Explosion") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
@@ -0,0 +1,10 @@
|
||||
diff a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm (rejected hunks)
|
||||
@@ -72,7 +72,7 @@
|
||||
special_names = list("Flood","Fire","Bar","Man")
|
||||
|
||||
/datum/species/golem/plasma/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
- SSexplosion.Create(get_turf(H),0,1,2,flame_range = 5)
|
||||
+ explosion(get_turf(H),0,1,2,flame_range = 5)
|
||||
if(H)
|
||||
H.gib()
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
diff a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm (rejected hunks)
|
||||
@@ -130,7 +130,7 @@ Difficulty: Medium
|
||||
playsound(T,'sound/magic/Fireball.ogg', 200, 1)
|
||||
new /obj/effect/overlay/temp/fireball(T)
|
||||
sleep(12)
|
||||
- SSexplosion.Create(T, 0, 0, 1, 0, 0, 0, 1)
|
||||
+ explosion(T, 0, 0, 1, 0, 0, 0, 1)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/OpenFire()
|
||||
anger_modifier = Clamp(((maxHealth - health)/50),0,20)
|
||||
10
code/modules/power/supermatter/supermatter.dm.rej
Normal file
10
code/modules/power/supermatter/supermatter.dm.rej
Normal file
@@ -0,0 +1,10 @@
|
||||
diff a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm (rejected hunks)
|
||||
@@ -174,7 +174,7 @@
|
||||
S.consume(src)
|
||||
else
|
||||
investigate_log("has exploded.", "supermatter")
|
||||
- SSexplosion.Create(get_turf(T), explosion_power * max(gasmix_power_ratio, 0.205) * 0.5 , explosion_power * max(gasmix_power_ratio, 0.205) + 2, explosion_power * max(gasmix_power_ratio, 0.205) + 4 , explosion_power * max(gasmix_power_ratio, 0.205) + 6, 1, 1)
|
||||
+ explosion(get_turf(T), explosion_power * max(gasmix_power_ratio, 0.205) * 0.5 , explosion_power * max(gasmix_power_ratio, 0.205) + 2, explosion_power * max(gasmix_power_ratio, 0.205) + 4 , explosion_power * max(gasmix_power_ratio, 0.205) + 6, 1, 1)
|
||||
if(power > CRITICAL_POWER_PENALTY_THRESHOLD)
|
||||
investigate_log("has spawned additional energy balls.", "supermatter")
|
||||
var/obj/singularity/energy_ball/E = new(T)
|
||||
10
code/modules/research/experimentor.dm.rej
Normal file
10
code/modules/research/experimentor.dm.rej
Normal file
@@ -0,0 +1,10 @@
|
||||
diff a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm (rejected hunks)
|
||||
@@ -352,7 +352,7 @@
|
||||
FB.fire()
|
||||
else if(prob(EFFECT_PROB_LOW-badThingCoeff))
|
||||
visible_message("<span class='danger'>[src] malfunctions, melting [exp_on] and releasing a burst of flame!</span>")
|
||||
- SSexplosion.Create(src.loc, -1, 0, 0, 0, 0, flame_range = 2)
|
||||
+ explosion(src.loc, -1, 0, 0, 0, 0, flame_range = 2)
|
||||
investigate_log("Experimentor started a fire.", "experimentor")
|
||||
ejectItem(TRUE)
|
||||
else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
|
||||
@@ -687,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"
|
||||
|
||||
9
tgstation.dme.rej
Normal file
9
tgstation.dme.rej
Normal file
@@ -0,0 +1,9 @@
|
||||
diff a/tgstation.dme b/tgstation.dme (rejected hunks)
|
||||
@@ -212,6 +211,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\hud.dm"
|
||||
#include "code\datums\map_config.dm"
|
||||
Reference in New Issue
Block a user