diff --git a/code/__DEFINES/_helpers.dm b/code/__DEFINES/_helpers.dm index 22ca001ae4e..bcea96cc598 100644 --- a/code/__DEFINES/_helpers.dm +++ b/code/__DEFINES/_helpers.dm @@ -7,3 +7,6 @@ //Returns an integer given a hex input, supports negative values "-ff" //skips preceding invalid characters #define hex2num(X) text2num(X, 16) + +/// Stringifies whatever you put into it. +#define STRINGIFY(argument) #argument diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index e03fd64be6f..4e269c649ef 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -237,11 +237,8 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list( #define HIS_GRACE_FORCE_BONUS 4 //How much force is gained per kill. -#define EXPLODE_NONE 0 //Don't even ask me why we need this. -#define EXPLODE_DEVASTATE 1 -#define EXPLODE_HEAVY 2 -#define EXPLODE_LIGHT 3 -#define EXPLODE_GIB_THRESHOLD 50 //ex_act() with EXPLODE_DEVASTATE severity will gib mobs with less than this much bomb armor +/// ex_act() with EXPLODE_DEVASTATE severity will gib mobs with less than this much bomb armor +#define EXPLODE_GIB_THRESHOLD 50 #define EMP_HEAVY 1 #define EMP_LIGHT 2 diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index ee70d6613ba..05df0e26a13 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -162,6 +162,15 @@ ///from obj/machinery/bsa/full/proc/fire(): () #define COMSIG_ATOM_BSA_BEAM "atom_bsa_beam_pass" #define COMSIG_ATOM_BLOCKS_BSA_BEAM (1<<0) + +///from [/datum/controller/subsystem/explosions/proc/explode]: (/list(/atom, devastation_range, heavy_impact_range, light_impact_range, flame_range, flash_range, adminlog, ignorecap, silent, smoke)) +#define COMSIG_ATOM_EXPLODE "atom_explode" +///from [/datum/controller/subsystem/explosions/proc/explode]: (/list(/atom, devastation_range, heavy_impact_range, light_impact_range, flame_range, flash_range, adminlog, ignorecap, silent, smoke)) +#define COMSIG_ATOM_INTERNAL_EXPLOSION "atom_internal_explosion" +///from [/datum/controller/subsystem/explosions/proc/explode]: (/list(/atom, devastation_range, heavy_impact_range, light_impact_range, flame_range, flash_range, adminlog, ignorecap, silent, smoke)) +#define COMSIG_AREA_INTERNAL_EXPLOSION "area_internal_explosion" + /// When returned on a signal hooked to [COMSIG_ATOM_EXPLODE], [COMSIG_ATOM_INTERNAL_EXPLOSION], or [COMSIG_AREA_INTERNAL_EXPLOSION] it prevents the explosion from being propagated further. + #define COMSIG_CANCEL_EXPLOSION (1<<0) ///from /obj/machinery/doppler_array/proc/sense_explosion(...): Runs when an explosion is succesfully detected by a doppler array(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, took, orig_dev_range, orig_heavy_range, orig_light_range) #define COMSIG_DOPPLER_ARRAY_EXPLOSION_DETECTED "atom_dopplerarray_explosion_detected" diff --git a/code/__DEFINES/explosions.dm b/code/__DEFINES/explosions.dm new file mode 100644 index 00000000000..a05e3bd33c7 --- /dev/null +++ b/code/__DEFINES/explosions.dm @@ -0,0 +1,32 @@ +// The severity of explosions. Why are these inverted? I have no idea, but git blame doesn't go back far enough for me to find out. +/// The (current) highest possible explosion severity. +#define EXPLODE_DEVASTATE 3 +/// The (current) middling explosion severity. +#define EXPLODE_HEAVY 2 +/// The (current) lowest possible explosion severity. +#define EXPLODE_LIGHT 1 +/// The default explosion severity used to mark that an object is beyond the impact range of the explosion. +#define EXPLODE_NONE 0 + +// Internal explosion argument list keys. +// Must match the arguments to [/datum/controller/subsystem/explosions/proc/propagate_blastwave] +/// The origin atom of the explosion. +#define EXARG_KEY_ORIGIN "origin" +/// The devastation range of the explosion. +#define EXARG_KEY_DEV_RANGE STRINGIFY(devastation_range) +/// The heavy impact range of the explosion. +#define EXARG_KEY_HEAVY_RANGE STRINGIFY(heavy_impact_range) +/// The light impact range of the explosion. +#define EXARG_KEY_LIGHT_RANGE STRINGIFY(light_impact_range) +/// The flame range of the explosion. +#define EXARG_KEY_FLAME_RANGE STRINGIFY(flame_range) +/// The flash range of the explosion. +#define EXARG_KEY_FLASH_RANGE STRINGIFY(flash_range) +/// Whether or not the explosion should be logged. +#define EXARG_KEY_ADMIN_LOG STRINGIFY(adminlog) +/// Whether or not the explosion should ignore the bombcap. +#define EXARG_KEY_IGNORE_CAP STRINGIFY(ignorecap) +/// Whether or not the explosion should produce sound effects and screenshake if it is large enough to warrant it. +#define EXARG_KEY_SILENT STRINGIFY(silent) +/// Whether or not the explosion should produce smoke if it is large enough to warrant it. +#define EXARG_KEY_SMOKE STRINGIFY(smoke) diff --git a/code/controllers/subsystem/explosions.dm b/code/controllers/subsystem/explosions.dm index 010e57be1f4..1354a4fabff 100644 --- a/code/controllers/subsystem/explosions.dm +++ b/code/controllers/subsystem/explosions.dm @@ -153,12 +153,12 @@ SUBSYSTEM_DEF(explosions) A.color = null A.maptext = "" -/proc/dyn_explosion(turf/epicenter, power, flash_range, adminlog = TRUE, ignorecap = TRUE, flame_range = 0, silent = FALSE, smoke = TRUE) +/proc/dyn_explosion(turf/epicenter, power, flame_range = 0, flash_range = null, adminlog = TRUE, ignorecap = TRUE, silent = FALSE, smoke = TRUE) if(!power) return var/range = 0 range = round((2 * power)**GLOB.DYN_EX_SCALE) - explosion(epicenter, round(range * 0.25), round(range * 0.5), round(range), flash_range*range, adminlog, ignorecap, flame_range*range, silent, smoke) + explosion(epicenter, devastation_range = round(range * 0.25), heavy_impact_range = round(range * 0.5), light_impact_range = round(range), flame_range = flame_range*range, flash_range = flash_range*range, adminlog = adminlog, ignorecap = ignorecap, silent = silent, smoke = smoke) // Using default dyn_ex scale: // 100 explosion power is a (5, 10, 20) explosion. @@ -169,20 +169,86 @@ SUBSYSTEM_DEF(explosions) // 5 explosion power is a (0, 1, 3) explosion. // 1 explosion power is a (0, 0, 1) explosion. -/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) +/** + * Makes a given atom explode. + * + * Arguments: + * - [origin][/atom]: The atom that's exploding. + * - devastation_range: The range at which the effects of the explosion are at their strongest. + * - heavy_impact_range: The range at which the effects of the explosion are relatively severe. + * - light_impact_range: The range at which the effects of the explosion are relatively weak. + * - flash_range: The range at which the explosion flashes people. + * - adminlog: Whether to log the explosion/report it to the administration. + * - ignorecap: Whether to ignore the relevant bombcap. Defaults to FALSE. + * - flame_range: The range at which the explosion should produce hotspots. + * - silent: Whether to generate/execute sound effects. + * - smoke: Whether to generate a smoke cloud provided the explosion is powerful enough to warrant it. + */ +/proc/explosion(atom/origin, devastation_range = 0, heavy_impact_range = 0, light_impact_range = 0, flame_range = 0, flash_range = 0, adminlog = TRUE, ignorecap = FALSE, silent = FALSE, smoke = FALSE) . = SSexplosions.explode(arglist(args)) -#define CREAK_DELAY 5 SECONDS //Time taken for the creak to play after explosion, if applicable. -#define DEVASTATION_PROB 30 //The probability modifier for devistation, maths! -#define HEAVY_IMPACT_PROB 5 //ditto -#define FAR_UPPER 60 //Upper limit for the far_volume, distance, clamped. -#define FAR_LOWER 40 //lower limit for the far_volume, distance, clamped. -#define PROB_SOUND 75 //The probability modifier for a sound to be an echo, or a far sound. (0-100) -#define SHAKE_CLAMP 2.5 //The limit for how much the camera can shake for out of view booms. -#define FREQ_UPPER 40 //The upper limit for the randomly selected frequency. -#define FREQ_LOWER 25 //The lower of the above. -/datum/controller/subsystem/explosions/proc/explode(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog, ignorecap, flame_range, silent, smoke) +/** + * Makes a given atom explode. Now on the explosions subsystem! + * + * Arguments: + * - [origin][/atom]: The atom that's exploding. + * - devastation_range: The range at which the effects of the explosion are at their strongest. + * - heavy_impact_range: The range at which the effects of the explosion are relatively severe. + * - light_impact_range: The range at which the effects of the explosion are relatively weak. + * - flash_range: The range at which the explosion flashes people. + * - adminlog: Whether to log the explosion/report it to the administration. + * - ignorecap: Whether to ignore the relevant bombcap. Defaults to FALSE. + * - flame_range: The range at which the explosion should produce hotspots. + * - silent: Whether to generate/execute sound effects. + * - smoke: Whether to generate a smoke cloud provided the explosion is powerful enough to warrant it. + */ +/datum/controller/subsystem/explosions/proc/explode(atom/origin, devastation_range = 0, heavy_impact_range = 0, light_impact_range = 0, flame_range = 0, flash_range = 0, adminlog = TRUE, ignorecap = FALSE, silent = FALSE, smoke = FALSE) + var/list/arguments = list(EXARG_KEY_ORIGIN = origin, EXARG_KEY_DEV_RANGE = devastation_range, EXARG_KEY_HEAVY_RANGE = heavy_impact_range, EXARG_KEY_LIGHT_RANGE = light_impact_range, EXARG_KEY_FLAME_RANGE = flame_range, EXARG_KEY_FLASH_RANGE = flash_range, EXARG_KEY_ADMIN_LOG = adminlog, EXARG_KEY_IGNORE_CAP = ignorecap, EXARG_KEY_SILENT = silent, EXARG_KEY_SMOKE = smoke) + var/atom/location = isturf(origin) ? origin : origin.loc + if(SEND_SIGNAL(origin, COMSIG_ATOM_EXPLODE, arguments) & COMSIG_CANCEL_EXPLOSION) + return // Signals are incompatible with `arglist(...)` so we can't actually use that for these. Additionally, + + while(location) + var/next_loc = location.loc + if(SEND_SIGNAL(location, COMSIG_ATOM_INTERNAL_EXPLOSION, arguments) & COMSIG_CANCEL_EXPLOSION) + return + if(isturf(location)) + break + location = next_loc + + if(!location) + return + + var/area/epicenter_area = get_area(location) + if(SEND_SIGNAL(epicenter_area, COMSIG_AREA_INTERNAL_EXPLOSION, arguments) & COMSIG_CANCEL_EXPLOSION) + return + + arguments -= EXARG_KEY_ORIGIN + propagate_blastwave(arglist(list(location) + arguments)) + + +/** + * Handles the effects of an explosion originating from a given point. + * + * Primarily handles popagating the balstwave of the explosion to the relevant turfs. + * Also handles the fireball from the explosion. + * Also handles the smoke cloud from the explosion. + * Also handles sfx and screenshake. + * + * Arguments: + * - [epicenter][/atom]: The location of the explosion rounded to the nearest turf. + * - devastation_range: The range at which the effects of the explosion are at their strongest. + * - heavy_impact_range: The range at which the effects of the explosion are relatively severe. + * - light_impact_range: The range at which the effects of the explosion are relatively weak. + * - flash_range: The range at which the explosion flashes people. + * - adminlog: Whether to log the explosion/report it to the administration. + * - ignorecap: Whether to ignore the relevant bombcap. Defaults to TRUE for some mysterious reason. + * - flame_range: The range at which the explosion should produce hotspots. + * - silent: Whether to generate/execute sound effects. + * - smoke: Whether to generate a smoke cloud provided the explosion is powerful enough to warrant it. + */ +/datum/controller/subsystem/explosions/proc/propagate_blastwave(atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, flame_range, flash_range, adminlog, ignorecap, silent, smoke) epicenter = get_turf(epicenter) if(!epicenter) return @@ -197,7 +263,7 @@ SUBSYSTEM_DEF(explosions) var/orig_heavy_range = heavy_impact_range var/orig_light_range = light_impact_range - var/orig_max_distance = max(devastation_range, heavy_impact_range, light_impact_range, flash_range, flame_range) + var/orig_max_distance = max(devastation_range, heavy_impact_range, light_impact_range, flame_range, flash_range) //Zlevel specific bomb cap multiplier var/cap_multiplier = SSmapping.level_trait(epicenter.z, ZTRAIT_BOMBCAP_MULTIPLIER) @@ -221,7 +287,7 @@ SUBSYSTEM_DEF(explosions) var/y0 = epicenter.y var/z0 = epicenter.z var/area/areatype = get_area(epicenter) - SSblackbox.record_feedback("associative", "explosion", 1, list("dev" = devastation_range, "heavy" = heavy_impact_range, "light" = light_impact_range, "flash" = flash_range, "flame" = flame_range, "orig_dev" = orig_dev_range, "orig_heavy" = orig_heavy_range, "orig_light" = orig_light_range, "x" = x0, "y" = y0, "z" = z0, "area" = areatype.type, "time" = time_stamp("YYYY-MM-DD hh:mm:ss", 1))) + SSblackbox.record_feedback("associative", "explosion", 1, list("dev" = devastation_range, "heavy" = heavy_impact_range, "light" = light_impact_range, "flame" = flame_range, "flash" = flash_range, "orig_dev" = orig_dev_range, "orig_heavy" = orig_heavy_range, "orig_light" = orig_light_range, "x" = x0, "y" = y0, "z" = z0, "area" = areatype.type, "time" = time_stamp("YYYY-MM-DD hh:mm:ss", 1))) // 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! @@ -234,56 +300,7 @@ SUBSYSTEM_DEF(explosions) far_dist += devastation_range * 20 if(!silent) - var/frequency = get_rand_frequency() - var/sound/explosion_sound = sound(get_sfx("explosion")) - var/sound/far_explosion_sound = sound('sound/effects/explosionfar.ogg') - var/sound/creaking_explosion_sound = sound(get_sfx("explosion_creaking")) - var/sound/hull_creaking_sound = sound(get_sfx("hull_creaking")) - var/sound/explosion_echo_sound = sound('sound/effects/explosion_distant.ogg') - var/on_station = SSmapping.level_trait(epicenter.z, ZTRAIT_STATION) - var/creaking_explosion = FALSE - - if(prob(devastation_range*DEVASTATION_PROB+heavy_impact_range*HEAVY_IMPACT_PROB) && on_station) // Huge explosions are near guaranteed to make the station creak and whine, smaller ones might. - creaking_explosion = TRUE // prob over 100 always returns true - - for(var/MN in GLOB.player_list) - var/mob/M = MN - // 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) - var/baseshakeamount - if(orig_max_distance - dist > 0) - baseshakeamount = sqrt((orig_max_distance - dist)*0.1) - // If inside the blast radius + world.view - 2 - if(dist <= round(max_range + world.view - 2, 1)) - M.playsound_local(epicenter, null, 100, 1, frequency, S = explosion_sound) - if(baseshakeamount > 0) - shake_camera(M, 25, clamp(baseshakeamount, 0, 10)) - // 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/2, FAR_LOWER, FAR_UPPER) // Volume is based on explosion size and dist - if(creaking_explosion) - M.playsound_local(epicenter, null, far_volume, 1, frequency, S = creaking_explosion_sound, distance_multiplier = 0) - else if(prob(PROB_SOUND)) // Sound variety during meteor storm/tesloose/other bad event - M.playsound_local(epicenter, null, far_volume, 1, frequency, S = far_explosion_sound, distance_multiplier = 0) // Far sound - else - M.playsound_local(epicenter, null, far_volume, 1, frequency, S = explosion_echo_sound, distance_multiplier = 0) // Echo sound - - if(baseshakeamount > 0 || devastation_range) - if(!baseshakeamount) // Devastating explosions rock the station and ground - baseshakeamount = devastation_range*3 - shake_camera(M, 10, clamp(baseshakeamount*0.25, 0, SHAKE_CLAMP)) - else if(!isspaceturf(get_turf(M)) && heavy_impact_range) // Big enough explosions echo throughout the hull - var/echo_volume = 40 - if(devastation_range) - baseshakeamount = devastation_range - shake_camera(M, 10, clamp(baseshakeamount*0.25, 0, SHAKE_CLAMP)) - echo_volume = 60 - M.playsound_local(epicenter, null, echo_volume, 1, frequency, S = explosion_echo_sound, distance_multiplier = 0) - - if(creaking_explosion) // 5 seconds after the bang, the station begins to creak - addtimer(CALLBACK(M, /mob/proc/playsound_local, epicenter, null, rand(FREQ_LOWER, FREQ_UPPER), 1, frequency, null, null, FALSE, hull_creaking_sound, 0), CREAK_DELAY) + shake_the_room(epicenter, orig_max_distance, far_dist, devastation_range, heavy_impact_range) if(heavy_impact_range > 1) var/datum/effect_system/explosion/E @@ -383,13 +400,110 @@ SUBSYSTEM_DEF(explosions) SEND_GLOBAL_SIGNAL(COMSIG_GLOB_EXPLOSION, epicenter, devastation_range, heavy_impact_range, light_impact_range, took, orig_dev_range, orig_heavy_range, orig_light_range) +// Explosion SFX defines... +/// The probability that a quaking explosion will make the station creak per unit. Maths! +#define QUAKE_CREAK_PROB 30 +/// The probability that an echoing explosion will make the station creak per unit. +#define ECHO_CREAK_PROB 5 +/// Time taken for the hull to begin to creak after an explosion, if applicable. +#define CREAK_DELAY (5 SECONDS) +/// Lower limit for far explosion SFX volume. +#define FAR_LOWER 40 +/// Upper limit for far explosion SFX volume. +#define FAR_UPPER 60 +/// The probability that a distant explosion SFX will be a far explosion sound rather than an echo. (0-100) +#define FAR_SOUND_PROB 75 +/// The upper limit on screenshake amplitude for nearby explosions. +#define NEAR_SHAKE_CAP 10 +/// The upper limit on screenshake amplifude for distant explosions. +#define FAR_SHAKE_CAP 2.5 +/// The duration of the screenshake for nearby explosions. +#define NEAR_SHAKE_DURATION (2.5 SECONDS) +/// The duration of the screenshake for distant explosions. +#define FAR_SHAKE_DURATION (1 SECONDS) +/// The lower limit for the randomly selected hull creaking frequency. +#define FREQ_LOWER 25 +/// The upper limit for the randomly selected hull creaking frequency. +#define FREQ_UPPER 40 + +/** + * Handles the sfx and screenshake caused by an explosion. + * + * Arguments: + * - [epicenter][/turf]: The location of the explosion. + * - near_distance: How close to the explosion you need to be to get the full effect of the explosion. + * - far_distance: How close to the explosion you need to be to hear more than echos. + * - quake_factor: Main scaling factor for screenshake. + * - echo_factor: Whether to make the explosion echo off of very distant parts of the station. + * - creaking: Whether to make the station creak. Autoset if null. + * - [near_sound][/sound]: The sound that plays if you are close to the explosion. + * - [far_sound][/sound]: The sound that plays if you are far from the explosion. + * - [echo_sound][/sound]: The sound that plays as echos for the explosion. + * - [creaking_sound][/sound]: The sound that plays when the station creaks during the explosion. + * - [hull_creaking_sound][/sound]: The sound that plays when the station creaks after the explosion. + */ +/datum/controller/subsystem/explosions/proc/shake_the_room(turf/epicenter, near_distance, far_distance, quake_factor, echo_factor, creaking, sound/near_sound = sound(get_sfx("explosion")), sound/far_sound = sound('sound/effects/explosionfar.ogg'), sound/echo_sound = sound('sound/effects/explosion_distant.ogg'), sound/creaking_sound = sound(get_sfx("explosion_creaking")), hull_creaking_sound = sound(get_sfx("hull_creaking"))) + var/frequency = get_rand_frequency() + var/blast_z = epicenter.z + if(isnull(creaking)) // Autoset creaking. + var/on_station = SSmapping.level_trait(epicenter.z, ZTRAIT_STATION) + if(on_station && prob((quake_factor * QUAKE_CREAK_PROB) + (echo_factor * ECHO_CREAK_PROB))) // Huge explosions are near guaranteed to make the station creak and whine, smaller ones might. + creaking = TRUE // prob over 100 always returns true + else + creaking = FALSE + + for(var/mob/listener as anything in GLOB.player_list) + var/turf/listener_turf = get_turf(listener) + if(!listener_turf || listener_turf.z != blast_z) + continue + + var/distance = get_dist(epicenter, listener_turf) + var/base_shake_amount + if(near_distance > distance) + base_shake_amount = sqrt((near_distance - distance) / 10) + + if(distance <= round(near_distance + world.view - 2, 1)) // If you are close enough to see the effects of the explosion first-hand (ignoring walls) + listener.playsound_local(epicenter, null, 100, TRUE, frequency, S = near_sound) + if(base_shake_amount > 0) + shake_camera(listener, NEAR_SHAKE_DURATION, clamp(base_shake_amount, 0, NEAR_SHAKE_CAP)) + + else if(distance < far_distance) // You can hear a far explosion if you are outside the blast radius. Small explosions shouldn't be heard throughout the station. + var/far_volume = clamp(far_distance / 2, FAR_LOWER, FAR_UPPER) + if(creaking) + listener.playsound_local(epicenter, null, far_volume, TRUE, frequency, S = creaking_sound, distance_multiplier = 0) + else if(prob(FAR_SOUND_PROB)) // Sound variety during meteor storm/tesloose/other bad event + listener.playsound_local(epicenter, null, far_volume, TRUE, frequency, S = far_sound, distance_multiplier = 0) + else + listener.playsound_local(epicenter, null, far_volume, TRUE, frequency, S = echo_sound, distance_multiplier = 0) + + if(base_shake_amount || quake_factor) + if(!base_shake_amount) // Devastating explosions rock the station and ground + base_shake_amount = quake_factor * 3 + shake_camera(listener, FAR_SHAKE_DURATION, clamp(base_shake_amount / 4, 0, FAR_SHAKE_CAP)) + + else if(!isspaceturf(listener_turf) && echo_factor) // Big enough explosions echo through the hull. + var/echo_volume + if(quake_factor) + base_shake_amount = quake_factor + echo_volume = 60 + shake_camera(listener, FAR_SHAKE_DURATION, clamp(base_shake_amount / 4, 0, FAR_SHAKE_CAP)) + else + echo_volume = 40 + listener.playsound_local(epicenter, null, echo_volume, TRUE, frequency, S = echo_sound, distance_multiplier = 0) + + if(creaking) // 5 seconds after the bang, the station begins to creak + addtimer(CALLBACK(listener, /mob/proc/playsound_local, epicenter, null, rand(FREQ_LOWER, FREQ_UPPER), TRUE, frequency, null, null, FALSE, hull_creaking_sound, 0), CREAK_DELAY) + #undef CREAK_DELAY -#undef DEVASTATION_PROB -#undef HEAVY_IMPACT_PROB +#undef QUAKE_CREAK_PROB +#undef ECHO_CREAK_PROB #undef FAR_UPPER #undef FAR_LOWER -#undef PROB_SOUND -#undef SHAKE_CLAMP +#undef FAR_SOUND_PROB +#undef NEAR_SHAKE_CAP +#undef FAR_SHAKE_CAP +#undef NEAR_SHAKE_DURATION +#undef FAR_SHAKE_DURATION #undef FREQ_UPPER #undef FREQ_LOWER diff --git a/code/datums/components/explodable.dm b/code/datums/components/explodable.dm index 360ab1dca84..0bc8214c2fc 100644 --- a/code/datums/components/explodable.dm +++ b/code/datums/components/explodable.dm @@ -1,14 +1,21 @@ ///Component specifically for explosion sensetive things, currently only applies to heat based explosions but can later perhaps be used for things that are dangerous to handle carelessly like nitroglycerin. /datum/component/explodable + /// The devastation range of the resulting explosion. var/devastation_range = 0 + /// The heavy impact range of the resulting explosion. var/heavy_impact_range = 0 + /// The light impact range of the resulting explosion. var/light_impact_range = 2 + /// The flame range of the resulting explosion. + var/flame_range = 0 + /// The flash range of the resulting explosion. var/flash_range = 3 - var/equipped_slot //For items, lets us determine where things should be hit. - ///wheter we always delete. useful for nukes turned plasma and such, so they don't default delete and can survive + /// For items, lets us determine where things should be hit. + var/equipped_slot + /// Whether we always delete. Useful for nukes turned plasma and such, so they don't default delete and can survive var/always_delete -/datum/component/explodable/Initialize(devastation_range_override, heavy_impact_range_override, light_impact_range_override, flash_range_override, _always_delete = TRUE) +/datum/component/explodable/Initialize(devastation_range_override, heavy_impact_range_override, light_impact_range_override, flame_range_override, flash_range_override, _always_delete = TRUE) if(!isatom(parent)) return COMPONENT_INCOMPATIBLE @@ -31,6 +38,8 @@ heavy_impact_range = heavy_impact_range_override if(light_impact_range_override) light_impact_range = light_impact_range_override + if(flame_range_override) + flame_range = flame_range_override if(flash_range_override) flash_range = flash_range_override always_delete = _always_delete @@ -123,7 +132,7 @@ var/log = TRUE if(light_impact_range < 1) log = FALSE - explosion(A, devastation_range, heavy_impact_range, light_impact_range, flash_range, log) //epic explosion time + explosion(A, devastation_range, heavy_impact_range, light_impact_range, flame_range, flash_range, log) //epic explosion time if(always_delete) qdel(A) diff --git a/code/datums/components/uplink.dm b/code/datums/components/uplink.dm index 009ad1ecc90..064f39c8888 100644 --- a/code/datums/components/uplink.dm +++ b/code/datums/components/uplink.dm @@ -354,5 +354,5 @@ return message_admins("[ADMIN_LOOKUPFLW(user)] has triggered an uplink failsafe explosion at [AREACOORD(T)] The owner of the uplink was [ADMIN_LOOKUPFLW(owner)].") log_game("[key_name(user)] triggered an uplink failsafe explosion. The owner of the uplink was [key_name(owner)].") - explosion(T,1,2,3) + explosion(parent, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 3) qdel(parent) //Alternatively could brick the uplink. diff --git a/code/datums/diseases/advance/symptoms/fire.dm b/code/datums/diseases/advance/symptoms/fire.dm index 7424c155d46..fa446eb077a 100644 --- a/code/datums/diseases/advance/symptoms/fire.dm +++ b/code/datums/diseases/advance/symptoms/fire.dm @@ -147,7 +147,7 @@ Bonus if(4) if(M.fire_stacks < 0) M.visible_message("[M]'s sweat sizzles and pops on contact with water!") - explosion(get_turf(M),-1,(-1 + explosion_power),(2 * explosion_power)) + explosion(M, devastation_range = -1, heavy_impact_range = (-1 + explosion_power), light_impact_range = (2 * explosion_power)) Alkali_fire_stage_4(M, A) M.IgniteMob() to_chat(M, "Your sweat bursts into flames!") @@ -155,7 +155,7 @@ Bonus if(5) if(M.fire_stacks < 0) M.visible_message("[M]'s sweat sizzles and pops on contact with water!") - explosion(get_turf(M),-1,(-1 + explosion_power),(2 * explosion_power)) + explosion(M, devastation_range = -1, heavy_impact_range = (-1 + explosion_power), light_impact_range = (2 * explosion_power)) Alkali_fire_stage_5(M, A) M.IgniteMob() to_chat(M, "Your skin erupts into an inferno!") diff --git a/code/datums/diseases/rhumba_beat.dm b/code/datums/diseases/rhumba_beat.dm index 32c81f43be2..91c06097bcc 100644 --- a/code/datums/diseases/rhumba_beat.dm +++ b/code/datums/diseases/rhumba_beat.dm @@ -39,4 +39,4 @@ if(5) to_chat(affected_mob, "Your body is unable to contain the Rhumba Beat...") if(DT_PROB(29, delta_time)) - explosion(get_turf(affected_mob), -1, 0, 2, 3, 0, 2) // This is equivalent to a lvl 1 fireball + explosion(affected_mob, devastation_range = -1, light_impact_range = 2, flame_range = 2, flash_range = 3, adminlog = FALSE) // This is equivalent to a lvl 1 fireball diff --git a/code/datums/martial/plasma_fist.dm b/code/datums/martial/plasma_fist.dm index 5f06345acd2..71799e7f0fa 100644 --- a/code/datums/martial/plasma_fist.dm +++ b/code/datums/martial/plasma_fist.dm @@ -84,10 +84,10 @@ animate(A, color = oldcolor, time = 3 SECONDS) -/datum/martial_art/plasma_fist/proc/Apotheosis(mob/living/A, mob/living/D) - A.say("APOTHEOSIS!!", forced="plasma fist") - if (ishuman(A)) - var/mob/living/carbon/human/human_attacker = A +/datum/martial_art/plasma_fist/proc/Apotheosis(mob/living/user, mob/living/target) + user.say("APOTHEOSIS!!", forced="plasma fist") + if (ishuman(user)) + var/mob/living/carbon/human/human_attacker = user human_attacker.set_species(/datum/species/plasmaman) human_attacker.dna.species.species_traits += TRAIT_BOMBIMMUNE human_attacker.unequip_everything() @@ -95,20 +95,20 @@ human_attacker.undershirt = "Nude" human_attacker.socks = "Nude" human_attacker.update_body() - var/turf/boomspot = get_turf(A) + var/turf/boomspot = get_turf(user) //before ghosting to prevent issues - log_combat(A, A, "triggered final plasma explosion with size [plasma_power], [plasma_power*2], [plasma_power*4] (Plasma Fist)") - message_admins("[key_name_admin(A)] triggered final plasma explosion with size [plasma_power], [plasma_power*2], [plasma_power*4].") + log_combat(user, user, "triggered final plasma explosion with size [plasma_power], [plasma_power*2], [plasma_power*4] (Plasma Fist)") + message_admins("[key_name_admin(user)] triggered final plasma explosion with size [plasma_power], [plasma_power*2], [plasma_power*4].") - to_chat(A, "The explosion knocks your soul out of your body!") - A.ghostize(FALSE) //prevents... horrible memes just believe me + to_chat(user, "The explosion knocks your soul out of your body!") + user.ghostize(FALSE) //prevents... horrible memes just believe me - A.apply_damage(rand(50,70), BRUTE) + user.apply_damage(rand(50,70), BRUTE) - addtimer(CALLBACK(src,.proc/Apotheosis_end, A), 6 SECONDS) + addtimer(CALLBACK(src,.proc/Apotheosis_end, user), 6 SECONDS) playsound(boomspot, 'sound/weapons/punch1.ogg', 50, TRUE, -1) - explosion(boomspot,plasma_power,plasma_power*2,plasma_power*4,ignorecap = TRUE) + explosion(user, devastation_range = plasma_power, heavy_impact_range = plasma_power*2, light_impact_range = plasma_power*4, ignorecap = TRUE) plasma_power = 1 //just in case there is any clever way to cause it to happen again /datum/martial_art/plasma_fist/proc/Apotheosis_end(mob/living/dying) diff --git a/code/datums/materials/basemats.dm b/code/datums/materials/basemats.dm index 4cad06fe31c..0f4765cdeea 100644 --- a/code/datums/materials/basemats.dm +++ b/code/datums/materials/basemats.dm @@ -120,7 +120,7 @@ Unless you know what you're doing, only use the first three numbers. They're in . = ..() if(ismovable(source)) source.AddElement(/datum/element/firestacker, amount=1) - source.AddComponent(/datum/component/explodable, 0, 0, amount / 2500, amount / 1250) + source.AddComponent(/datum/component/explodable, 0, 0, amount / 2500, 0, amount / 1250) /datum/material/plasma/on_removed(atom/source, amount, material_flags) . = ..() diff --git a/code/datums/mutations/body.dm b/code/datums/mutations/body.dm index 9adf316db83..e42eecf1229 100644 --- a/code/datums/mutations/body.dm +++ b/code/datums/mutations/body.dm @@ -451,7 +451,7 @@ for(var/obj/item/organ/I in organs) qdel(I) - explosion(get_turf(owner), 0, 0, 2, 0, TRUE) + explosion(owner, light_impact_range = 2, adminlog = TRUE) for(var/mob/living/carbon/human/H in view(2,owner)) var/obj/item/organ/eyes/eyes = H.getorganslot(ORGAN_SLOT_EYES) if(eyes) diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 14c1efc82c8..3e6e381e9b5 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -728,7 +728,7 @@ /obj/machinery/zap_act(power, zap_flags) if(prob(85) && (zap_flags & ZAP_MACHINE_EXPLOSIVE) && !(resistance_flags & INDESTRUCTIBLE)) - explosion(src, 1, 2, 4, flame_range = 2, adminlog = FALSE, smoke = FALSE) + explosion(src, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 4, flame_range = 2, adminlog = FALSE, smoke = FALSE) else if(zap_flags & ZAP_OBJ_DAMAGE) take_damage(power * 0.0005, BURN, ENERGY) if(prob(40)) diff --git a/code/game/machinery/computer/arcade/arcade.dm b/code/game/machinery/computer/arcade/arcade.dm index 604df2883e0..3ccf14fba3a 100644 --- a/code/game/machinery/computer/arcade/arcade.dm +++ b/code/game/machinery/computer/arcade/arcade.dm @@ -123,7 +123,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list( else empprize = pickweight(GLOB.arcade_prize_pool) new empprize(loc) - explosion(loc, -1, 0, 1+num_of_prizes, flame_range = 1+num_of_prizes) + explosion(src, devastation_range = -1, light_impact_range = 1+num_of_prizes, flame_range = 1+num_of_prizes) /obj/machinery/computer/arcade/attackby(obj/item/O, mob/user, params) if(istype(O, /obj/item/stack/arcadeticket)) diff --git a/code/game/machinery/computer/arcade/orion.dm b/code/game/machinery/computer/arcade/orion.dm index dc9f1e88dde..c418a8f5f69 100644 --- a/code/game/machinery/computer/arcade/orion.dm +++ b/code/game/machinery/computer/arcade/orion.dm @@ -531,7 +531,7 @@ GLOBAL_LIST_INIT(orion_events, generate_orion_events()) playsound(loc, 'sound/machines/buzz-sigh.ogg', 25, TRUE) sleep(3.6) visible_message("[src] explodes!") - explosion(loc, 2,4,8, flame_range = 16) + explosion(src, devastation_range = 2, heavy_impact_range = 4, light_impact_range = 8, flame_range = 16) qdel(src) #undef ORION_TRAIL_WINTURN diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index b0052d8775b..8c7f26694b5 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -459,7 +459,7 @@ /obj/machinery/door/ex_act(severity, target) //if it blows up a wall it should blow up a door - return ..(severity ? max(1, severity - 1) : 0, target) + return ..(severity ? min(EXPLODE_DEVASTATE, severity + 1) : EXPLODE_NONE, target) /obj/machinery/door/GetExplosionBlock() return density ? real_explosion_block : 0 diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm index 79510b3dc21..67e8af0ccd8 100644 --- a/code/game/machinery/doors/poddoor.dm +++ b/code/game/machinery/doors/poddoor.dm @@ -151,7 +151,7 @@ //"BLAST" doors are obviously stronger than regular doors when it comes to BLASTS. /obj/machinery/door/poddoor/ex_act(severity, target) - if(severity == EXPLODE_LIGHT) + if(severity <= EXPLODE_LIGHT) return FALSE return ..() diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index 5cbb77270c1..5410e0bd566 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -298,7 +298,7 @@ if(adminlog) message_admins(adminlog) log_game(adminlog) - explosion(src, range_heavy, range_medium, range_light, flame_range = range_flame) + explosion(src, range_heavy, range_medium, range_light, range_flame) if(loc && istype(loc, /obj/machinery/syndicatebomb/)) qdel(loc) qdel(src) diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index d651b767468..cfd9a318e42 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -75,7 +75,7 @@ return /obj/effect/anomaly/ex_act(severity, target) - if(severity == EXPLODE_DEVASTATE) + if(severity >= EXPLODE_DEVASTATE) qdel(src) /obj/effect/anomaly/proc/anomalyNeutralize() @@ -192,7 +192,7 @@ /obj/effect/anomaly/flux/detonate() if(explosive) - explosion(src, 1, 4, 16, 18) //Low devastation, but hits a lot of stuff. + explosion(src, devastation_range = 1, heavy_impact_range = 4, light_impact_range = 16, flash_range = 18) //Low devastation, but hits a lot of stuff. else new /obj/effect/particle_effect/sparks(loc) diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index be1a4005910..0da93d9043e 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -69,10 +69,10 @@ else return ..() -/obj/effect/decal/cleanable/ex_act() +/obj/effect/decal/cleanable/ex_act(severity) if(reagents) for(var/datum/reagent/R in reagents.reagent_list) - R.on_ex_act() + R.on_ex_act(severity) return ..() /obj/effect/decal/cleanable/fire_act(exposed_temperature, exposed_volume) diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm index 847daa4766b..3272e3dd452 100644 --- a/code/game/objects/effects/decals/cleanable/misc.dm +++ b/code/game/objects/effects/decals/cleanable/misc.dm @@ -181,7 +181,7 @@ mergeable_decal = FALSE /obj/effect/decal/cleanable/shreds/ex_act(severity, target) - if(severity == EXPLODE_DEVASTATE) //so shreds created during an explosion aren't deleted by the explosion. + if(severity >= EXPLODE_DEVASTATE) //so shreds created during an explosion aren't deleted by the explosion. qdel(src) /obj/effect/decal/cleanable/shreds/Initialize(mapload, oldname) diff --git a/code/game/objects/effects/effect_system/effects_other.dm b/code/game/objects/effects/effect_system/effects_other.dm index 49b3869f140..bd8816b92da 100644 --- a/code/game/objects/effects/effect_system/effects_other.dm +++ b/code/game/objects/effects/effect_system/effects_other.dm @@ -105,4 +105,4 @@ location.visible_message("The solution violently explodes!", \ "You hear an explosion!") - dyn_explosion(location, amount, flashing_factor) + dyn_explosion(location, amount, flash_range = flashing_factor) diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm index fcb1d958789..e435b2937ca 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -72,13 +72,19 @@ /obj/effect/mine/explosive name = "explosive mine" + /// The devastation range of the resulting explosion. var/range_devastation = 0 + /// The heavy impact range of the resulting explosion. var/range_heavy = 1 + /// The light impact range of the resulting explosion. var/range_light = 2 + /// The flame range of the resulting explosion. + var/range_flame = 0 + /// The flash range of the resulting explosion. var/range_flash = 3 /obj/effect/mine/explosive/mineEffect(mob/victim) - explosion(loc, range_devastation, range_heavy, range_light, range_flash) + explosion(src, range_devastation, range_heavy, range_light, range_flame, range_flash) /obj/effect/mine/stun name = "stun mine" diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index 6042db68e20..a5eb11898c1 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -758,7 +758,7 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) addtimer(CALLBACK(src, .proc/detonate_pulse_explode), 50) /obj/item/construction/rcd/proc/detonate_pulse_explode() - explosion(src, 0, 0, 3, 1, flame_range = 1) + explosion(src, light_impact_range = 3, flame_range = 1, flash_range = 1) qdel(src) /obj/item/construction/rcd/update_overlays() diff --git a/code/game/objects/items/crab17.dm b/code/game/objects/items/crab17.dm index 12637a3e485..d57cf15d188 100644 --- a/code/game/objects/items/crab17.dm +++ b/code/game/objects/items/crab17.dm @@ -158,7 +158,7 @@ stop_dumping() STOP_PROCESSING(SSfastprocess, src) priority_announce("The credit deposit machine at [get_area(src)] has been destroyed. Station funds have stopped draining!", sender_override = "CRAB-17 Protocol") - explosion(src, 0,0,1, flame_range = 2) + explosion(src, light_impact_range = 1, flame_range = 2) SSeconomy.market_crashing = FALSE return ..() diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index be9a6be50ee..9560494a9d7 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -1119,9 +1119,9 @@ GLOBAL_LIST_EMPTY(PDAs) if(T) T.hotspot_expose(700,125) if(istype(cartridge, /obj/item/cartridge/virus/syndicate)) - explosion(T, -1, 1, 3, 4) + explosion(src, devastation_range = -1, heavy_impact_range = 1, light_impact_range = 3, flash_range = 4) else - explosion(T, -1, -1, 2, 3) + explosion(src, devastation_range = -1, heavy_impact_range = -1, light_impact_range = 2, flash_range = 3) qdel(src) return diff --git a/code/game/objects/items/devices/portable_chem_mixer.dm b/code/game/objects/items/devices/portable_chem_mixer.dm index 7e666969234..c1a4dbc7cd4 100644 --- a/code/game/objects/items/devices/portable_chem_mixer.dm +++ b/code/game/objects/items/devices/portable_chem_mixer.dm @@ -36,7 +36,7 @@ return ..() /obj/item/storage/portable_chem_mixer/ex_act(severity, target) - if(severity < EXPLODE_LIGHT) + if(severity > EXPLODE_LIGHT) return ..() /obj/item/storage/portable_chem_mixer/attackby(obj/item/I, mob/user, params) diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index 76f8e95ac29..3681eecea2a 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -159,7 +159,7 @@ if(power_drained >= max_power) STOP_PROCESSING(SSobj, src) - explosion(src.loc, 4,8,16,32) + explosion(src, devastation_range = 4, heavy_impact_range = 8, light_impact_range = 16, flash_range = 32) qdel(src) #undef DISCONNECTED diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 1c1725057e5..0de5775ee96 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -19,6 +19,17 @@ /obj/item/transfer_valve/IsAssemblyHolder() return TRUE +/obj/item/transfer_valve/handle_atom_del(atom/deleted_atom) + . = ..() + if(deleted_atom == tank_one) + tank_one = null + update_appearance() + return + if(deleted_atom == tank_two) + tank_two = null + update_appearance() + return + /obj/item/transfer_valve/attackby(obj/item/item, mob/user, params) if(istype(item, /obj/item/tank)) if(tank_one && tank_two) diff --git a/code/game/objects/items/granters.dm b/code/game/objects/items/granters.dm index 4b285e7344e..3df423b7fdf 100644 --- a/code/game/objects/items/granters.dm +++ b/code/game/objects/items/granters.dm @@ -159,7 +159,7 @@ /obj/item/book/granter/spell/fireball/recoil(mob/user) ..() - explosion(user.loc, 1, 0, 2, 3, FALSE, FALSE, 2) + explosion(user, devastation_range = 1, light_impact_range = 2, flame_range = 2, flash_range = 3, adminlog = FALSE) qdel(src) /obj/item/book/granter/spell/sacredflame diff --git a/code/game/objects/items/grenades/festive.dm b/code/game/objects/items/grenades/festive.dm index 4f68e7c1267..0ec661c9814 100644 --- a/code/game/objects/items/grenades/festive.dm +++ b/code/game/objects/items/grenades/festive.dm @@ -113,8 +113,7 @@ /obj/item/grenade/firecracker/detonate(mob/living/lanced_by) . = ..() update_mob() - var/explosion_loc = get_turf(src) + explosion(src, devastation_range = -1, heavy_impact_range = -1, light_impact_range = 2) qdel(src) - explosion(explosion_loc,-1,-1,2) diff --git a/code/game/objects/items/grenades/ghettobomb.dm b/code/game/objects/items/grenades/ghettobomb.dm index c9fe83ae22f..d9cfcd1d9f6 100644 --- a/code/game/objects/items/grenades/ghettobomb.dm +++ b/code/game/objects/items/grenades/ghettobomb.dm @@ -66,7 +66,7 @@ /obj/item/grenade/iedcasing/detonate(mob/living/lanced_by) //Blowing that can up . = ..() update_mob() - explosion(src.loc,-1,-1,2, flame_range = 4) // small explosion, plus a very large fireball. + explosion(src, devastation_range = -1, heavy_impact_range = -1, light_impact_range = 2, flame_range = 4) // small explosion, plus a very large fireball. qdel(src) /obj/item/grenade/iedcasing/change_det_time() diff --git a/code/game/objects/items/grenades/grenade.dm b/code/game/objects/items/grenades/grenade.dm index eae73e59817..23f90340409 100644 --- a/code/game/objects/items/grenades/grenade.dm +++ b/code/game/objects/items/grenades/grenade.dm @@ -122,7 +122,7 @@ SEND_SIGNAL(src, COMSIG_GRENADE_DETONATE, lanced_by) if(ex_dev || ex_heavy || ex_light || ex_flame) - explosion(loc, ex_dev, ex_heavy, ex_light, flame_range = ex_flame) + explosion(src, ex_dev, ex_heavy, ex_light, ex_flame) /obj/item/grenade/proc/update_mob() if(ismob(loc)) diff --git a/code/game/objects/items/grenades/plastic.dm b/code/game/objects/items/grenades/plastic.dm index b48ba4d4ecb..d9e0cb4a648 100644 --- a/code/game/objects/items/grenades/plastic.dm +++ b/code/game/objects/items/grenades/plastic.dm @@ -59,9 +59,9 @@ if(location) if(directional && target?.density) var/turf/T = get_step(location, aim_dir) - explosion(get_step(T, aim_dir), boom_sizes[1], boom_sizes[2], boom_sizes[3]) + explosion(get_step(T, aim_dir), devastation_range = boom_sizes[1], heavy_impact_range = boom_sizes[2], light_impact_range = boom_sizes[3]) else - explosion(location, boom_sizes[1], boom_sizes[2], boom_sizes[3]) + explosion(location, devastation_range = boom_sizes[1], heavy_impact_range = boom_sizes[2], light_impact_range = boom_sizes[3]) qdel(src) //assembly stuff @@ -148,7 +148,7 @@ log_game("[key_name(user)] suicided with [src] at [AREACOORD(user)]") user.visible_message("[user] activates [src] and holds it above [user.p_their()] head! It looks like [user.p_theyre()] going out with a bang!") shout_syndicate_crap(user) - explosion(user,0,2,0) //Cheap explosion imitation because putting detonate() here causes runtimes + explosion(user, heavy_impact_range = 2) //Cheap explosion imitation because putting detonate() here causes runtimes user.gib(1, 1) qdel(src) diff --git a/code/game/objects/items/hot_potato.dm b/code/game/objects/items/hot_potato.dm index 1c0b3c0dbf5..02874eafad5 100644 --- a/code/game/objects/items/hot_potato.dm +++ b/code/game/objects/items/hot_potato.dm @@ -52,7 +52,7 @@ var/atom/location = loc location.visible_message("[src] [detonate_explosion? "explodes" : "activates"]!", "[src] activates! You've ran out of time!") if(detonate_explosion) - explosion(src, detonate_dev_range, detonate_heavy_range, detonate_light_range, detonate_flash_range, flame_range = detonate_fire_range) + explosion(src, detonate_dev_range, detonate_heavy_range, detonate_light_range, detonate_fire_range, detonate_flash_range) deactivate() if(!reusable) var/mob/M = loc diff --git a/code/game/objects/items/implants/implant_explosive.dm b/code/game/objects/items/implants/implant_explosive.dm index f505dd338d3..c854193b042 100644 --- a/code/game/objects/items/implants/implant_explosive.dm +++ b/code/game/objects/items/implants/implant_explosive.dm @@ -51,7 +51,7 @@ message_admins("[ADMIN_LOOKUPFLW(imp_in)] has activated their [name] at [ADMIN_VERBOSEJMP(boomturf)], with cause of [cause].") //If the delay is short, just blow up already jeez if(delay <= 7) - explosion(src,heavy,medium,weak,weak, flame_range = weak) + explosion(src, devastation_range = heavy, heavy_impact_range = medium, light_impact_range = weak, flame_range = weak, flash_range = weak) if(imp_in) imp_in.gib(1) qdel(src) @@ -86,7 +86,7 @@ sleep(delay*0.25) playsound(loc, 'sound/items/timer.ogg', 30, FALSE) sleep(delay*0.25) - explosion(src,heavy,medium,weak,weak, flame_range = weak) + explosion(src, devastation_range = heavy, heavy_impact_range = medium, light_impact_range = weak, flame_range = weak, flash_range = weak) if(imp_in) imp_in.gib(1) qdel(src) diff --git a/code/game/objects/items/plushes.dm b/code/game/objects/items/plushes.dm index 8f5d60ee69c..e8bb8593deb 100644 --- a/code/game/objects/items/plushes.dm +++ b/code/game/objects/items/plushes.dm @@ -473,7 +473,7 @@ P.say(pick("Nooooo...", "Not die. To y-", "Die. Ratv-", "Sas tyen re-")) playsound(src, 'sound/magic/clockwork/anima_fragment_attack.ogg', 50, TRUE, frequency = 2) playsound(P, 'sound/magic/demon_dies.ogg', 50, TRUE, frequency = 2) - explosion(P, 0, 0, 1) + explosion(P, light_impact_range = 1) qdel(P) clash_target = null else @@ -481,7 +481,7 @@ P.say(pick("Ha.", "Ra'sha fonn dest.", "You fool. To come here.")) playsound(src, 'sound/magic/clockwork/anima_fragment_death.ogg', 62, TRUE, frequency = 2) playsound(P, 'sound/magic/demon_attack1.ogg', 50, TRUE, frequency = 2) - explosion(src, 0, 0, 1) + explosion(src, light_impact_range = 1) qdel(src) P.clashing = FALSE diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index f315b69e053..a0bcb731cb4 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -126,7 +126,7 @@ . += "It feels [descriptive]." /obj/item/tank/deconstruct(disassembled = TRUE) - var/turf/location = get_turf(src) + var/atom/location = loc if(location) location.assume_air(air_contents) location.air_update_turf(FALSE, FALSE) @@ -251,7 +251,7 @@ handle_tolerances(delta_time) if(QDELETED(src) || !leaking || !air_contents) return - var/turf/location = get_turf(src) + var/atom/location = loc if(!location) return var/datum/gas_mixture/leaked_gas = air_contents.remove_ratio(0.25) @@ -298,10 +298,6 @@ if(!air_contents) return ..() - var/turf/location = get_turf(src) - if(!location) - return ..() - /// Handle fragmentation var/pressure = air_contents.return_pressure() if(pressure > TANK_FRAGMENT_PRESSURE) @@ -312,7 +308,7 @@ pressure = air_contents.return_pressure() var/range = (pressure-TANK_FRAGMENT_PRESSURE)/TANK_FRAGMENT_SCALE - explosion(location, round(range*0.25), round(range*0.5), round(range), round(range*1.5)) + explosion(src, devastation_range = round(range*0.25), heavy_impact_range = round(range*0.5), light_impact_range = round(range), flash_range = round(range*1.5)) return ..() /obj/item/tank/rad_act(strength) diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index 5997b2913ac..51a005aacaf 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -111,9 +111,8 @@ update_appearance() /obj/item/weldingtool/proc/explode() - var/turf/T = get_turf(loc) var/plasmaAmount = reagents.get_reagent_amount(/datum/reagent/toxin/plasma) - dyn_explosion(T, plasmaAmount/5)//20 plasma in a standard welder has a 4 power explosion. no breaches, but enough to kill/dismember holder + dyn_explosion(src, plasmaAmount/5)//20 plasma in a standard welder has a 4 power explosion. no breaches, but enough to kill/dismember holder qdel(src) /obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/living/user) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 103603c9ae4..fcd5860d152 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -1038,7 +1038,7 @@ playsound(src, 'sound/machines/alarm.ogg', 20, FALSE) sleep(140) user.visible_message("[src] violently explodes!") - explosion(src, 0, 0, 1, 0) + explosion(src, light_impact_range = 1) qdel(src) else if (cooldown < world.time) cooldown = world.time + 600 //1 minute @@ -1081,7 +1081,7 @@ /obj/item/toy/minimeteor/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if (obj_flags & EMAGGED) playsound(src, 'sound/effects/meteorimpact.ogg', 40, TRUE) - explosion(get_turf(hit_atom), -1, -1, 1) + explosion(src, devastation_range = -1, heavy_impact_range = -1, light_impact_range = 1) for(var/mob/M in urange(10, src)) if(!M.stat && !isAI(M)) shake_camera(M, 3, 1) diff --git a/code/game/objects/items/wayfinding.dm b/code/game/objects/items/wayfinding.dm index a597d6eb766..6cd9158b83b 100644 --- a/code/game/objects/items/wayfinding.dm +++ b/code/game/objects/items/wayfinding.dm @@ -95,7 +95,7 @@ say("Ouch.") //An inexplicable explosion is never not funny plus it kind of explains why the machine just disappears if(!isnull(loc)) - explosion(get_turf(src), devastation_range = 0, heavy_impact_range = 0, light_impact_range = 1, flash_range = 3, flame_range = 1, smoke = TRUE) + explosion(src, light_impact_range = 1, flame_range = 1, flash_range = 3, smoke = TRUE) return ..() /obj/machinery/pinpointer_dispenser/attack_hand(mob/living/user, list/modifiers) diff --git a/code/game/objects/structures/crates_lockers/crates/secure.dm b/code/game/objects/structures/crates_lockers/crates/secure.dm index 44f4f4fd761..e08ec573f5e 100644 --- a/code/game/objects/structures/crates_lockers/crates/secure.dm +++ b/code/game/objects/structures/crates_lockers/crates/secure.dm @@ -32,7 +32,7 @@ log_bomber(user, "has detonated a", src) for(var/atom/movable/AM in src) qdel(AM) - explosion(get_turf(src), 0, 1, 5, 5) + explosion(src, heavy_impact_range = 1, light_impact_range = 5, flash_range = 5) qdel(src) /obj/structure/closet/crate/secure/weapon diff --git a/code/game/objects/structures/industrial_lift.dm b/code/game/objects/structures/industrial_lift.dm index 1ca7a2a274d..fbeea2779eb 100644 --- a/code/game/objects/structures/industrial_lift.dm +++ b/code/game/objects/structures/industrial_lift.dm @@ -211,7 +211,7 @@ GLOBAL_LIST_EMPTY(lifts) tram_part.travel_distance = 0 tram_part.travelling = FALSE if(prob(15) || locate(/mob/living) in tram_part.lift_load) //always go boom on people on the track - explosion(get_turf(tram_part),rand(0,1),2,3) //50% chance of gib + explosion(tram_part, devastation_range = rand(0,1), heavy_impact_range = 2, light_impact_range = 3) //50% chance of gib qdel(tram_part) /obj/structure/industrial_lift/proc/lift_platform_expansion(datum/lift_master/lift_master_datum) diff --git a/code/game/objects/structures/training_machine.dm b/code/game/objects/structures/training_machine.dm index 171557a4ffb..5086ea07cc3 100644 --- a/code/game/objects/structures/training_machine.dm +++ b/code/game/objects/structures/training_machine.dm @@ -49,7 +49,7 @@ */ /obj/structure/training_machine/obj_destruction(damage_flag) remove_attached_item(throwing = TRUE) - explosion(src, 0,0,1, flame_range = 2) + explosion(src, light_impact_range = 1, flash_range = 2) return ..() /obj/structure/training_machine/ui_state(mob/user) diff --git a/code/game/turfs/closed/minerals.dm b/code/game/turfs/closed/minerals.dm index 37b6a43f01c..33e55d0dd9f 100644 --- a/code/game/turfs/closed/minerals.dm +++ b/code/game/turfs/closed/minerals.dm @@ -567,7 +567,7 @@ var/turf/bombturf = get_turf(src) mineralAmt = 0 stage = GIBTONITE_DETONATE - explosion(bombturf,1,3,5, adminlog = notify_admins) + explosion(bombturf, devastation_range = 1, heavy_impact_range = 3, light_impact_range = 5, adminlog = notify_admins) /turf/closed/mineral/gibtonite/proc/defuse() if(stage == GIBTONITE_ACTIVE) @@ -589,7 +589,7 @@ var/turf/bombturf = get_turf(src) mineralAmt = 0 stage = GIBTONITE_DETONATE - explosion(bombturf,1,2,5, adminlog = FALSE) + explosion(bombturf, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 5, adminlog = FALSE) if(stage == GIBTONITE_STABLE) //Gibtonite deposit is now benign and extractable. Depending on how close you were to it blowing up before defusing, you get better quality ore. var/obj/item/gibtonite/G = new (src) if(det_time <= 0) diff --git a/code/game/turfs/open/floor.dm b/code/game/turfs/open/floor.dm index 1893c206454..b6a3836f477 100644 --- a/code/game/turfs/open/floor.dm +++ b/code/game/turfs/open/floor.dm @@ -66,7 +66,7 @@ if(target == src) ScrapeAway(flags = CHANGETURF_INHERIT_AIR) return TRUE - if(severity != EXPLODE_DEVASTATE && is_shielded()) + if(severity < EXPLODE_DEVASTATE && is_shielded()) return FALSE if(target) diff --git a/code/game/turfs/open/floor/reinf_floor.dm b/code/game/turfs/open/floor/reinf_floor.dm index b577cbed6af..9987c396974 100644 --- a/code/game/turfs/open/floor/reinf_floor.dm +++ b/code/game/turfs/open/floor/reinf_floor.dm @@ -58,7 +58,7 @@ if(target == src) ScrapeAway(flags = CHANGETURF_INHERIT_AIR) return TRUE - if(severity != EXPLODE_DEVASTATE && is_shielded()) + if(severity < EXPLODE_DEVASTATE && is_shielded()) return FALSE switch(severity) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 732f77e6eb2..4343f068741 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -499,31 +499,31 @@ GLOBAL_PROTECT(admin_verbs_hideable) if(null) return if("Small Bomb (1, 2, 3, 3)") - explosion(epicenter, 1, 2, 3, 3, TRUE, TRUE) + explosion(epicenter, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 3, flash_range = 3, adminlog = TRUE, ignorecap = TRUE) if("Medium Bomb (2, 3, 4, 4)") - explosion(epicenter, 2, 3, 4, 4, TRUE, TRUE) + explosion(epicenter, devastation_range = 2, heavy_impact_range = 3, light_impact_range = 4, flash_range = 4, adminlog = TRUE, ignorecap = TRUE) if("Big Bomb (3, 5, 7, 5)") - explosion(epicenter, 3, 5, 7, 5, TRUE, TRUE) + explosion(epicenter, devastation_range = 3, heavy_impact_range = 5, light_impact_range = 7, flash_range = 5, adminlog = TRUE, ignorecap = TRUE) if("Maxcap") - explosion(epicenter, GLOB.MAX_EX_DEVESTATION_RANGE, GLOB.MAX_EX_HEAVY_RANGE, GLOB.MAX_EX_LIGHT_RANGE, GLOB.MAX_EX_FLASH_RANGE) + explosion(epicenter, 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, adminlog = TRUE, ignorecap = TRUE) if("Custom Bomb") - var/devastation_range = input("Devastation range (in tiles):") as null|num - if(devastation_range == null) + var/range_devastation = input("Devastation range (in tiles):") as null|num + if(range_devastation == null) return - var/heavy_impact_range = input("Heavy impact range (in tiles):") as null|num - if(heavy_impact_range == null) + var/range_heavy = input("Heavy impact range (in tiles):") as null|num + if(range_heavy == null) return - var/light_impact_range = input("Light impact range (in tiles):") as null|num - if(light_impact_range == null) + var/range_light = input("Light impact range (in tiles):") as null|num + if(range_light == null) return - var/flash_range = input("Flash range (in tiles):") as null|num - if(flash_range == null) + var/range_flash = input("Flash range (in tiles):") as null|num + if(range_flash == null) return - 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(range_devastation > GLOB.MAX_EX_DEVESTATION_RANGE || range_heavy > GLOB.MAX_EX_HEAVY_RANGE || range_light > GLOB.MAX_EX_LIGHT_RANGE || range_flash > 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 - explosion(epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, TRUE, TRUE) + explosion(epicenter, devastation_range = range_devastation, heavy_impact_range = range_heavy, light_impact_range = range_light, flash_range = range_flash, adminlog = TRUE, ignorecap = 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].") SSblackbox.record_feedback("tally", "admin_verb", 1, "Drop Bomb") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/smites/bsa.dm b/code/modules/admin/smites/bsa.dm index 7df6bc8ad42..d8ba8e3e771 100644 --- a/code/modules/admin/smites/bsa.dm +++ b/code/modules/admin/smites/bsa.dm @@ -10,7 +10,7 @@ /datum/smite/bsa/effect(client/user, mob/living/target) . = ..() - explosion(target.loc, 0, 0, 0, 0) + explosion(target.loc) var/turf/open/floor/target_turf = get_turf(target) if (istype(target_turf)) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 149d9be1365..1b1d62a1a01 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -592,7 +592,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 - explosion(O, devastation, heavy, light, flash, null, null,flames) + explosion(O, devastation, heavy, light, flames, flash) log_admin("[key_name(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at [AREACOORD(O)]") message_admins("[key_name_admin(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at [AREACOORD(O)]") SSblackbox.record_feedback("tally", "admin_verb", 1, "Explosion") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/antagonists/blob/structures/core.dm b/code/modules/antagonists/blob/structures/core.dm index 9d5d65a758f..f1828635a17 100644 --- a/code/modules/antagonists/blob/structures/core.dm +++ b/code/modules/antagonists/blob/structures/core.dm @@ -53,7 +53,7 @@ return ..() /obj/structure/blob/special/core/ex_act(severity, target) - var/damage = 50 - 10 * severity //remember, the core takes half brute damage, so this is 20/15/10 damage based on severity + var/damage = 10 * (severity + 1) //remember, the core takes half brute damage, so this is 20/15/10 damage based on severity take_damage(damage, BRUTE, BOMB, 0) /obj/structure/blob/special/core/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir, overmind_reagent_trigger = 1) diff --git a/code/modules/antagonists/changeling/powers/headcrab.dm b/code/modules/antagonists/changeling/powers/headcrab.dm index e96b5f4cf02..855fa4dc572 100644 --- a/code/modules/antagonists/changeling/powers/headcrab.dm +++ b/code/modules/antagonists/changeling/powers/headcrab.dm @@ -18,7 +18,7 @@ for(var/obj/item/organ/I in organs) I.Remove(user, 1) - explosion(get_turf(user), 0, 0, 2, 0, TRUE) + explosion(user, light_impact_range = 2, adminlog = TRUE) for(var/mob/living/carbon/human/H in range(2,user)) var/obj/item/organ/eyes/eyes = H.getorganslot(ORGAN_SLOT_EYES) to_chat(H, "You are blinded by a shower of blood!") diff --git a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm index 19358d49ce3..6ef88f37df0 100644 --- a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm +++ b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm @@ -515,7 +515,7 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module)) var/turf/T = get_turf(M) message_admins("[ADMIN_LOOKUPFLW(usr)] overloaded [M.name] ([M.type]) at [ADMIN_VERBOSEJMP(T)].") log_game("[key_name(usr)] overloaded [M.name] ([M.type]) at [AREACOORD(T)].") - explosion(get_turf(M), 0, 2, 3, 0) + explosion(M, heavy_impact_range = 2, light_impact_range = 3) if(M) //to check if the explosion killed it before we try to delete it qdel(M) diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm index b89b2a2a776..00389085e45 100644 --- a/code/modules/assembly/bomb.dm +++ b/code/modules/assembly/bomb.dm @@ -161,13 +161,13 @@ strength = (fuel_moles/15) if(strength >=2) - explosion(ground_zero, round(strength,1), round(strength*2,1), round(strength*3,1), round(strength*4,1)) + explosion(src, devastation_range = round(strength,1), heavy_impact_range = round(strength*2,1), light_impact_range = round(strength*3,1), flash_range = round(strength*4,1)) else if(strength >=1) - explosion(ground_zero, round(strength,1), round(strength*2,1), round(strength*2,1), round(strength*3,1)) + explosion(src, devastation_range = round(strength,1), heavy_impact_range = round(strength*2,1), light_impact_range = round(strength*2,1), flash_range = round(strength*3,1)) else if(strength >=0.5) - explosion(ground_zero, 0, 1, 2, 4) + explosion(src, heavy_impact_range = 1, light_impact_range = 2, flash_range = 4) else if(strength >=0.2) - explosion(ground_zero, -1, 0, 1, 2) + explosion(src, devastation_range = -1, light_impact_range = 1, flash_range = 2) else ground_zero.assume_air(bomb_mixture) ground_zero.hotspot_expose(1000, 125) @@ -176,9 +176,9 @@ strength = (fuel_moles/20) if(strength >=1) - explosion(ground_zero, 0, round(strength,1), round(strength*2,1), round(strength*3,1)) + explosion(ground_zero, heavy_impact_range = round(strength,1), light_impact_range = round(strength*2,1), flash_range = round(strength*3,1)) else if(strength >=0.5) - explosion(ground_zero, -1, 0, 1, 2) + explosion(ground_zero, devastation_range = -1, light_impact_range = 1, flash_range = 2) else ground_zero.assume_air(bomb_mixture) ground_zero.hotspot_expose(1000, 125) @@ -187,7 +187,7 @@ strength = (fuel_moles/25) if(strength >=1) - explosion(ground_zero, -1, 0, round(strength,1), round(strength*3,1)) + explosion(ground_zero, devastation_range = -1, light_impact_range = round(strength,1), flash_range = round(strength*3,1)) else ground_zero.assume_air(bomb_mixture) ground_zero.hotspot_expose(1000, 125) diff --git a/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm b/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm index d2462a1ce97..8497b576893 100644 --- a/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm +++ b/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm @@ -309,7 +309,7 @@ * Create the explosion + the gas emission before deleting the machine core. */ /obj/machinery/atmospherics/components/unary/hypertorus/core/proc/meltdown() - explosion(loc, 0, 0, power_level * 5, power_level * 6, 1, 1) + explosion(src, light_impact_range = power_level * 5, flash_range = power_level * 6, adminlog = TRUE, ignorecap = TRUE) radiation_pulse(loc, power_level * 7000, (1 / (power_level + 5)), TRUE) empulse(loc, power_level * 5, power_level * 7) var/fusion_moles = internal_fusion.total_moles() ? internal_fusion.total_moles() : 0 diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index 97037eb5134..efef3d46c72 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -481,7 +481,7 @@ GLOBAL_LIST_INIT(gas_id_to_canister, init_gas_id_to_canister()) var/pressure_dif = expelled_pressure - pressure_limit var/max_pressure_difference = 20000 var/explosion_range = CEILING(min(pressure_dif, max_pressure_difference) / 1000, 1) - explosion(T, 0, 0, explosion_range, 0, smoke = FALSE) + explosion(T, light_impact_range = explosion_range, smoke = FALSE) density = FALSE playsound(src.loc, 'sound/effects/spray.ogg', 10, TRUE, -3) diff --git a/code/modules/awaymissions/bluespaceartillery.dm b/code/modules/awaymissions/bluespaceartillery.dm index 9949840923b..2c1e30ba56d 100644 --- a/code/modules/awaymissions/bluespaceartillery.dm +++ b/code/modules/awaymissions/bluespaceartillery.dm @@ -51,5 +51,5 @@ 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 diff --git a/code/modules/awaymissions/mission_code/Academy.dm b/code/modules/awaymissions/mission_code/Academy.dm index 2bc8abd2de0..60ce808895a 100644 --- a/code/modules/awaymissions/mission_code/Academy.dm +++ b/code/modules/awaymissions/mission_code/Academy.dm @@ -271,7 +271,7 @@ if(8) //Fuel tank Explosion T.visible_message("An explosion bursts into existence around [user]!") - explosion(get_turf(user),-1,0,2, flame_range = 2) + explosion(get_turf(user), devastation_range = -1, light_impact_range = 2, flame_range = 2) if(9) //Cold var/datum/disease/D = new /datum/disease/cold() diff --git a/code/modules/awaymissions/mission_code/wildwest.dm b/code/modules/awaymissions/mission_code/wildwest.dm index b2bf3bbd747..5b8467ec535 100644 --- a/code/modules/awaymissions/mission_code/wildwest.dm +++ b/code/modules/awaymissions/mission_code/wildwest.dm @@ -146,7 +146,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(src, devastation_range = 1) qdel(src) /////For the Wishgranter/////////// diff --git a/code/modules/buildmode/submodes/boom.dm b/code/modules/buildmode/submodes/boom.dm index a8460956a0c..d79f2164000 100644 --- a/code/modules/buildmode/submodes/boom.dm +++ b/code/modules/buildmode/submodes/boom.dm @@ -34,5 +34,5 @@ var/list/modifiers = params2list(params) if(LAZYACCESS(modifiers, LEFT_CLICK)) - explosion(object, devastation, heavy, light, flash, FALSE, TRUE, flames) + explosion(object, devastation, heavy, light, flames, flash, adminlog = FALSE, ignorecap = TRUE) log_admin("Build Mode: [key_name(c)] caused an explosion(dev=[devastation], hvy=[heavy], lgt=[light], flash=[flash], flames=[flames]) at [AREACOORD(object)]") diff --git a/code/modules/events/crystal_event.dm b/code/modules/events/crystal_event.dm index d17bbf14d8e..d48e417438b 100644 --- a/code/modules/events/crystal_event.dm +++ b/code/modules/events/crystal_event.dm @@ -121,7 +121,7 @@ This section is for the event controller var/area/center_area = get_area(center_turf) center_areas += center_area - explosion(center_turf,0,0,5,7,7) + explosion(center_turf, light_impact_range = 5, flame_range = 7, flash_range = 7) new /obj/structure/crystal_portal/huge(center_turf) @@ -249,7 +249,7 @@ This section is for the event controller spawners += temp for(var/i in 1 to rand(15, 25)) spawn_portal(GLOB.crystal_invasion_waves["huge wave"], spawners) - explosion(dest_crystal.loc, 15, 26, 33, 35, 1, 1) //a bit smaller than max supermatter explosion + explosion(dest_crystal, devastation_range = 15, heavy_impact_range = 26, light_impact_range = 33, flash_range = 35, adminlog = TRUE, ignorecap = TRUE) //a bit smaller than max supermatter explosion priority_announce("WARNING - Portal are appearing everywhere, you failed to contain the event. You people should feel ashamed of yourselves!","Alarm") QDEL_NULL(dest_crystal) @@ -550,13 +550,13 @@ This section is for the crystal portals variations if(!closed) switch(name) if("Small Portal") - explosion(loc, 0,1,3) + explosion(src, heavy_impact_range = 1, light_impact_range = 3) if("Medium Portal") - explosion(loc, 0,3,5) + explosion(src, heavy_impact_range = 3, light_impact_range = 5) if("Big Portal") - explosion(loc, 1,3,5) + explosion(src, devastation_range = 1, heavy_impact_range = 3, light_impact_range = 5) if("Huge Portal") - explosion(loc, 2,5,7) + explosion(src, devastation_range = 2, heavy_impact_range = 5, light_impact_range = 7) new/obj/item/stack/sheet/otherworld_crystal(loc) return ..() diff --git a/code/modules/events/processor_overload.dm b/code/modules/events/processor_overload.dm index 742af87fb2c..4ce140b6b85 100644 --- a/code/modules/events/processor_overload.dm +++ b/code/modules/events/processor_overload.dm @@ -31,7 +31,7 @@ if(prob(10)) announce_to_ghosts(P) // Damage the surrounding area to indicate that it popped - explosion(get_turf(P), 0, 0, 2) + explosion(P, light_impact_range = 2) // Only a level 1 explosion actually damages the machine // at all SSexplosions.high_mov_atom += P diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index e90a8a12a32..559c6cd6204 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -116,7 +116,7 @@ QDEL_IN(holder, 5) /datum/spacevine_mutation/explosive/on_death(obj/structure/spacevine/holder, mob/hitter, obj/item/I) - explosion(holder.loc, 0, 0, severity, 0, 0) + explosion(holder, light_impact_range = severity, adminlog = FALSE) /datum/spacevine_mutation/fire_proof name = "fire proof" @@ -571,7 +571,7 @@ var/i for(var/datum/spacevine_mutation/SM in mutations) i += SM.on_explosion(severity, target, src) - if(!i && prob(100/severity)) + if(!i && prob(34 * severity)) qdel(src) /obj/structure/spacevine/should_atmos_process(datum/gas_mixture/air, exposed_temperature) diff --git a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm index 95e88e5ef6e..12bf6344d88 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm @@ -333,7 +333,7 @@ spark() broken = 2 if(prob(max(metal / 2, 33))) - explosion(loc, 0, 1, 2) + explosion(src, heavy_impact_range = 1, light_impact_range = 2) else dump_inventory_contents() diff --git a/code/modules/hydroponics/grown/citrus.dm b/code/modules/hydroponics/grown/citrus.dm index cfaafc94b40..0dfe1b5f5d6 100644 --- a/code/modules/hydroponics/grown/citrus.dm +++ b/code/modules/hydroponics/grown/citrus.dm @@ -133,23 +133,23 @@ switch(seed.potency) //Combustible lemons are alot like IEDs, lots of flame, very little bang. if(0 to 30) update_mob() - explosion(src.loc,-1,-1,2, flame_range = 1) + explosion(src, devastation_range = -1, heavy_impact_range = -1, light_impact_range = 2, flame_range = 1) qdel(src) if(31 to 50) update_mob() - explosion(src.loc,-1,-1,2, flame_range = 2) + explosion(src, devastation_range = -1, heavy_impact_range = -1, light_impact_range = 2, flame_range = 2) qdel(src) if(51 to 70) update_mob() - explosion(src.loc,-1,-1,2, flame_range = 3) + explosion(src, devastation_range = -1, heavy_impact_range = -1, light_impact_range = 2, flame_range = 3) qdel(src) if(71 to 90) update_mob() - explosion(src.loc,-1,-1,2, flame_range = 4) + explosion(src, devastation_range = -1, heavy_impact_range = -1, light_impact_range = 2, flame_range = 4) qdel(src) else update_mob() - explosion(src.loc,-1,-1,2, flame_range = 5) + explosion(src, devastation_range = -1, heavy_impact_range = -1, light_impact_range = 2, flame_range = 5) qdel(src) //3D Orange diff --git a/code/modules/meteors/meteors.dm b/code/modules/meteors/meteors.dm index 986ef990c05..8950d77b435 100644 --- a/code/modules/meteors/meteors.dm +++ b/code/modules/meteors/meteors.dm @@ -91,7 +91,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event density = TRUE anchored = TRUE var/hits = 4 - var/hitpwr = 2 //Level of ex_act to be called on hit. + var/hitpwr = EXPLODE_HEAVY //Level of ex_act to be called on hit. var/dest pass_flags = PASSTABLE var/heavy = FALSE @@ -223,7 +223,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event icon_state = "dust" pass_flags = PASSTABLE | PASSGRILLE hits = 1 - hitpwr = 3 + hitpwr = EXPLODE_LIGHT meteorsound = 'sound/weapons/gun/smg/shot.ogg' meteordrop = list(/obj/item/stack/ore/glass) threat = 1 @@ -236,7 +236,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event /obj/effect/meteor/medium/meteor_effect() ..() - explosion(src.loc, 0, 1, 2, 3, 0) + explosion(src, heavy_impact_range = 1, light_impact_range = 2, flash_range = 3, adminlog = FALSE) //Large-sized /obj/effect/meteor/big @@ -249,7 +249,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event /obj/effect/meteor/big/meteor_effect() ..() - explosion(src.loc, 1, 2, 3, 4, 0) + explosion(src, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 3, flash_range = 4, adminlog = FALSE) //Flaming meteor /obj/effect/meteor/flaming @@ -263,7 +263,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event /obj/effect/meteor/flaming/meteor_effect() ..() - explosion(src.loc, 1, 2, 3, 4, 0, 0, 5) + explosion(src, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 3, flame_range = 5, flash_range = 4, adminlog = FALSE) //Radiation meteor /obj/effect/meteor/irradiated @@ -276,7 +276,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event /obj/effect/meteor/irradiated/meteor_effect() ..() - explosion(src.loc, 0, 0, 4, 3, 0) + explosion(src, light_impact_range = 4, flash_range = 3, adminlog = FALSE) new /obj/effect/decal/cleanable/greenglow(get_turf(src)) radiation_pulse(src, 500) @@ -337,7 +337,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event icon_state = "flaming" desc = "Your life briefly passes before your eyes the moment you lay them on this monstrosity." hits = 30 - hitpwr = 1 + hitpwr = EXPLODE_DEVASTATE heavy = TRUE meteorsound = 'sound/effects/bamf.ogg' meteordrop = list(/obj/item/stack/ore/plasma) @@ -350,12 +350,12 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event /obj/effect/meteor/tunguska/meteor_effect() ..() - explosion(src.loc, 5, 10, 15, 20, 0) + explosion(src, devastation_range = 5, heavy_impact_range = 10, light_impact_range = 15, flash_range = 20, adminlog = FALSE) /obj/effect/meteor/tunguska/Bump() ..() if(prob(20)) - explosion(src.loc,2,4,6,8) + explosion(src, devastation_range = 2, heavy_impact_range = 4, light_impact_range = 6, flash_range = 8, adminlog = FALSE) ////////////////////////// //Spookoween meteors diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm index 3327d425f77..92ab899b131 100644 --- a/code/modules/mining/machine_vending.dm +++ b/code/modules/mining/machine_vending.dm @@ -204,7 +204,7 @@ /obj/machinery/mineral/equipment_vendor/ex_act(severity, target) do_sparks(5, TRUE, src) - if(prob(50 / severity) && severity < EXPLODE_LIGHT) + if(severity > EXPLODE_LIGHT && prob(17 * severity)) qdel(src) /****************Golem Point Vendor**************************/ diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index c3771b741c6..b111e12f2f3 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -131,7 +131,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ qdel(src) /obj/item/stack/ore/glass/ex_act(severity, target) - if(severity != EXPLODE_NONE) + if(severity) qdel(src) /obj/item/stack/ore/glass/basalt @@ -321,11 +321,11 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ if(primed) switch(quality) if(GIBTONITE_QUALITY_HIGH) - explosion(src,2,4,9,adminlog = notify_admins) + explosion(src, devastation_range = 2, heavy_impact_range = 4, light_impact_range = 9, adminlog = notify_admins) if(GIBTONITE_QUALITY_MEDIUM) - explosion(src,1,2,5,adminlog = notify_admins) + explosion(src, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 5, adminlog = notify_admins) if(GIBTONITE_QUALITY_LOW) - explosion(src,0,1,3,adminlog = notify_admins) + explosion(src, heavy_impact_range = 1, light_impact_range = 3, adminlog = notify_admins) qdel(src) /obj/item/stack/ore/Initialize(mapload, new_amount, merge = TRUE, list/mat_override=null, mat_amt=1) @@ -334,7 +334,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ pixel_y = base_pixel_y + rand(0, 8) - 8 /obj/item/stack/ore/ex_act(severity, target) - if(severity == EXPLODE_DEVASTATE) + if(severity >= EXPLODE_DEVASTATE) qdel(src) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 5dcdaa0d9ca..d9b86cc799b 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -435,7 +435,7 @@ take_overall_damage(brute_loss,burn_loss) //attempt to dismember bodyparts - if(severity <= EXPLODE_HEAVY || !bomb_armor) + if(severity >= EXPLODE_HEAVY || !bomb_armor) var/max_limb_loss = round(4/severity) //so you don't lose four limbs at severity 3. for(var/X in bodyparts) var/obj/item/bodypart/BP = X diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index da5311be591..43cab939dc5 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -134,7 +134,7 @@ boom_warning = FALSE if(H.bodytemperature > 850 && H.on_fire && prob(25)) - explosion(get_turf(H), 1, 2, 4, flame_range = 5) + explosion(H, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 4, flame_range = 5) if(H) H.gib() if(H.fire_stacks < 2) //flammable diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm index 445db853fed..892d593b821 100644 --- a/code/modules/mob/living/silicon/ai/death.dm +++ b/code/modules/mob/living/silicon/ai/death.dm @@ -33,7 +33,7 @@ ShutOffDoomsdayDevice() if(explosive) - addtimer(CALLBACK(GLOBAL_PROC, .proc/explosion, loc, 3, 6, 12, 15), 1 SECONDS) + addtimer(CALLBACK(GLOBAL_PROC, .proc/explosion, loc, 3, 6, 12, null, 15), 1 SECONDS) if(istype(loc, /obj/item/aicard/aitater)) loc.icon_state = "aitater-404" diff --git a/code/modules/mob/living/silicon/pai/pai_defense.dm b/code/modules/mob/living/silicon/pai/pai_defense.dm index 92bf7ea215a..7d930fa79e9 100644 --- a/code/modules/mob/living/silicon/pai/pai_defense.dm +++ b/code/modules/mob/living/silicon/pai/pai_defense.dm @@ -28,7 +28,7 @@ /mob/living/silicon/pai/ex_act(severity, target) - take_holo_damage(severity * 50) + take_holo_damage(50 * severity) switch(severity) if(EXPLODE_DEVASTATE) //RIP qdel(card) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 0f29093ad59..a934c19e062 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -395,9 +395,9 @@ /mob/living/silicon/robot/proc/self_destruct() if(emagged) QDEL_NULL(mmi) - explosion(loc,1,2,4,flame_range = 2) + explosion(src, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 4, flame_range = 2) else - explosion(loc,-1,0,2) + explosion(src, devastation_range = -1, light_impact_range = 2) gib() /mob/living/silicon/robot/proc/UnlinkSelf() diff --git a/code/modules/mob/living/simple_animal/guardian/types/protector.dm b/code/modules/mob/living/simple_animal/guardian/types/protector.dm index 2eeb8573343..b042372af21 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/protector.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/protector.dm @@ -13,7 +13,7 @@ var/toggle = FALSE /mob/living/simple_animal/hostile/guardian/protector/ex_act(severity) - if(severity == EXPLODE_DEVASTATE) + if(severity >= EXPLODE_DEVASTATE) adjustBruteLoss(400) //if in protector mode, will do 20 damage and not actually necessarily kill the summoner else . = ..() diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm index 91699a3367d..32b7fc6cd9f 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm @@ -438,7 +438,7 @@ Difficulty: Hard return ..() /mob/living/simple_animal/hostile/megafauna/bubblegum/ex_act(severity, target) - if(severity >= EXPLODE_LIGHT) + if(severity <= EXPLODE_LIGHT) return FALSE severity = EXPLODE_LIGHT // puny mortals diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm index 9d8245545ac..067dc2e9240 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/demonic_frost_miner.dm @@ -151,7 +151,7 @@ Difficulty: Extremely Hard target.ex_act(EXPLODE_HEAVY) /mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/ex_act(severity, target) - adjustBruteLoss((30 * severity) - 120) + adjustBruteLoss(-30 * severity) visible_message("[src] absorbs the explosion!", "You absorb the explosion!") /mob/living/simple_animal/hostile/megafauna/demonic_frost_miner/Goto(target, delay, minimum_distance) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm index 7d6fd7939ae..f11f24ba723 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm @@ -401,7 +401,7 @@ arena_escape_enrage() /mob/living/simple_animal/hostile/megafauna/dragon/ex_act(severity, target) - if(severity == EXPLODE_LIGHT) + if(severity <= EXPLODE_LIGHT) return FALSE return ..() diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm index 3a7ba71219a..d486c00356f 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm @@ -199,7 +199,7 @@ if(mother != null) mother.children_list -= src visible_message("[src] explodes!") - explosion(get_turf(loc),0,0,0,flame_range = 3, adminlog = FALSE) + explosion(src, flame_range = 3, adminlog = FALSE) gib() //Tentacles have less stun time compared to regular variant, to balance being able to use them much more often. Also, 10 more damage. diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index e5177a75784..304503731d5 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -104,11 +104,11 @@ var/turf/T = get_turf(src.loc) if (charge==0) return - var/devastation_range = -1 //round(charge/11000) - var/heavy_impact_range = round(sqrt(charge)/60) - var/light_impact_range = round(sqrt(charge)/30) - var/flash_range = light_impact_range - if (light_impact_range==0) + var/range_devastation = -1 //round(charge/11000) + var/range_heavy = round(sqrt(charge)/60) + var/range_light = round(sqrt(charge)/30) + var/range_flash = range_light + if (range_light==0) rigged = FALSE corrupt() return @@ -117,7 +117,7 @@ log_game("[key_name(usr)] has triggered a rigged/corrupted power cell explosion at [AREACOORD(T)].") //explosion(T, 0, 1, 2, 2) - explosion(T, devastation_range, heavy_impact_range, light_impact_range, flash_range) + explosion(src, devastation_range = range_devastation, heavy_impact_range = range_heavy, light_impact_range = range_light, flash_range = range_flash) qdel(src) /obj/item/stock_parts/cell/proc/corrupt() diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm index 7d218a0f5f2..63aa6a4bf7e 100644 --- a/code/modules/power/gravitygenerator.dm +++ b/code/modules/power/gravitygenerator.dm @@ -38,7 +38,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne return FALSE /obj/machinery/gravity_generator/ex_act(severity, target) - if(severity == EXPLODE_DEVASTATE) // Very sturdy. + if(severity >= EXPLODE_DEVASTATE) // Very sturdy. set_broken() /obj/machinery/gravity_generator/blob_act(obj/structure/blob/B) diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 7261d447005..9f0dda0a5c6 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -842,7 +842,7 @@ zap_flags &= ~(ZAP_MACHINE_EXPLOSIVE | ZAP_OBJ_DAMAGE) . = ..() if(explosive) - explosion(src,0,0,0,flame_range = 5, adminlog = FALSE) + explosion(src, flame_range = 5, adminlog = FALSE) qdel(src) // called when area power state changes @@ -864,10 +864,9 @@ /obj/machinery/light/proc/explode() set waitfor = 0 - var/turf/T = get_turf(src.loc) break_light_tube() // break it first to give a warning sleep(2) - explosion(T, 0, 0, 2, 2) + explosion(src, light_impact_range = 2, flash_range = -1) sleep(1) qdel(src) diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index 214c0ff7a47..61206609605 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -171,7 +171,7 @@ STOP_PROCESSING(SSmachines, src) /obj/machinery/power/port_gen/pacman/proc/overheat() - explosion(src.loc, 2, 5, 2, -1) + explosion(src, devastation_range = 2, heavy_impact_range = 5, light_impact_range = 2, flash_range = -1) /obj/machinery/power/port_gen/pacman/set_anchored(anchorvalue) . = ..() @@ -285,4 +285,4 @@ time_per_sheet = 85 /obj/machinery/power/port_gen/pacman/super/overheat() - explosion(src.loc, 3, 3, 3, -1) + explosion(src, devastation_range = 3, heavy_impact_range = 3, light_impact_range = 3, flash_range = -1) diff --git a/code/modules/power/rtg.dm b/code/modules/power/rtg.dm index 9eff3ce3f8e..3cccca8d0f3 100644 --- a/code/modules/power/rtg.dm +++ b/code/modules/power/rtg.dm @@ -76,7 +76,7 @@ "You hear a loud electrical crack!") playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, TRUE, extrarange = 5) tesla_zap(src, 5, power_gen * 0.05) - addtimer(CALLBACK(GLOBAL_PROC, .proc/explosion, get_turf(src), 2, 3, 4, 8), 100) // Not a normal explosion. + addtimer(CALLBACK(GLOBAL_PROC, .proc/explosion, src, 2, 3, 4, null, 8), 10 SECONDS) // Not a normal explosion. /obj/machinery/power/rtg/abductor/bullet_act(obj/projectile/Proj) . = ..() diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 8cee829297f..0ccfd492ed2 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -418,7 +418,7 @@ /obj/singularity/singularity_act() var/gain = (energy/2) var/dist = max((current_size - 2),1) - explosion(src.loc,(dist),(dist*2),(dist*4)) + explosion(src, devastation_range = (dist), heavy_impact_range = (dist*2), light_impact_range = (dist*4)) qdel(src) return gain diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 7c5ea6f5e08..c64c673462a 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -395,7 +395,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) crystals.runEvent() return //No boom for me sir //Dear mappers, balance the sm max explosion radius to 17.5, 37, 39, 41 - 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) + explosion(src, devastation_range = explosion_power * max(gasmix_power_ratio, 0.205) * 0.5 , heavy_impact_range = explosion_power * max(gasmix_power_ratio, 0.205) + 2, light_impact_range = explosion_power * max(gasmix_power_ratio, 0.205) + 4 , flash_range = explosion_power * max(gasmix_power_ratio, 0.205) + 6, adminlog = TRUE, ignorecap = TRUE) qdel(src) @@ -1230,7 +1230,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) var/turf/turf_loc = get_turf(src) if(!turf_loc) return - explosion(turf_loc,0,round(portal_numbers/5),round(portal_numbers),1,1,1) + explosion(turf_loc, heavy_impact_range = round(portal_numbers/5), light_impact_range = round(portal_numbers), flash_range = 1, adminlog = TRUE, ignorecap = TRUE) . = new/obj/machinery/destabilized_crystal(turf_loc) qdel(src) diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm index 26d57e37034..124e4ef3d9d 100644 --- a/code/modules/projectiles/guns/magic/wand.dm +++ b/code/modules/projectiles/guns/magic/wand.dm @@ -241,7 +241,7 @@ /obj/item/gun/magic/wand/fireball/zap_self(mob/living/user) ..() - explosion(user.loc, -1, 0, 2, 3, 0, flame_range = 2) + explosion(user, devastation_range = -1, light_impact_range = 2, flame_range = 2, flash_range = 3, adminlog = FALSE) charges-- ///////////////////////////////////// diff --git a/code/modules/projectiles/guns/misc/blastcannon.dm b/code/modules/projectiles/guns/misc/blastcannon.dm index 52a4cb622b7..85460bb6e62 100644 --- a/code/modules/projectiles/guns/misc/blastcannon.dm +++ b/code/modules/projectiles/guns/misc/blastcannon.dm @@ -15,16 +15,18 @@ item_flags = NONE clumsy_check = FALSE randomspread = FALSE + + // Firing data. + /// The person who opened the valve on the TTV loaded into this. + var/datum/weakref/cached_firer + /// The target from the last click. + var/datum/weakref/cached_target + /// The modifiers from the last click. + var/cached_modifiers + + // Explosion data: /// The TTV this contains that will be used to create the projectile var/obj/item/transfer_valve/bomb - /// Additional volume added to the gasmixture used to calculate the bombs power. - var/reaction_volume_mod = 0 - /// Whether the gases are reacted once before calculating the range - var/prereaction = TRUE - /// How many times gases react() before calculation. Very finnicky value, do not mess with without good reason. - var/reaction_cycles = 3 - /// The maximum power the blastcannon is capable of reaching - var/max_power = INFINITY // For debugging/badminry /// Whether you can fire this without a bomb. @@ -33,25 +35,35 @@ var/debug_power = 0 -/obj/item/gun/blastcannon/debug - debug_power = 80 - bombcheck = FALSE +/obj/item/gun/blastcannon/Initialize() + . = ..() + if(!pin) + pin = new + RegisterSignal(src, COMSIG_ATOM_INTERNAL_EXPLOSION, .proc/channel_blastwave) + +/obj/item/gun/blastcannon/Destroy() + if(bomb) + QDEL_NULL(bomb) + UnregisterSignal(src, COMSIG_ATOM_INTERNAL_EXPLOSION) + cached_firer = null + cached_target = null + return ..() + +/obj/item/gun/blastcannon/handle_atom_del(atom/A) + if(A == bomb) + bomb = null + update_appearance() + return ..() + +/obj/item/gun/blastcannon/assume_air(datum/gas_mixture/giver) + qdel(giver) + return null // Required to make the TTV not vent gas directly into the firer. /obj/item/gun/blastcannon/examine(mob/user) . = ..() if(bomb) . += "A bomb is loaded inside." -/obj/item/gun/blastcannon/Initialize() - . = ..() - if(!pin) - pin = new - -/obj/item/gun/blastcannon/Destroy() - if(bomb) - QDEL_NULL(bomb) - return ..() - /obj/item/gun/blastcannon/attack_self(mob/user) if(bomb) bomb.forceMove(user.loc) @@ -69,6 +81,9 @@ if(!istype(bomb_to_attach)) return ..() + if(bomb) + to_chat(user, "[bomb] is already attached to [src]!") + return if(!bomb_to_attach.ready()) to_chat(user, "What good would an incomplete bomb do?") return FALSE @@ -81,52 +96,177 @@ update_appearance() return TRUE -/// Handles the bomb power calculations -/obj/item/gun/blastcannon/proc/calculate_bomb() - if(!istype(bomb) || !bomb.ready()) - return 0 - - var/datum/gas_mixture/temp = new(max(reaction_volume_mod, 0)) - bomb.merge_gases(temp) - - if(prereaction) - temp.react(src) - var/prereaction_pressure = temp.return_pressure() - if(prereaction_pressure < TANK_FRAGMENT_PRESSURE) - return 0 - for(var/i in 1 to reaction_cycles) - temp.react(src) - - var/pressure = temp.return_pressure() - if(pressure < TANK_FRAGMENT_PRESSURE) - return 0 - return ((pressure - TANK_FRAGMENT_PRESSURE) / TANK_FRAGMENT_SCALE) - - /obj/item/gun/blastcannon/afterattack(atom/target, mob/user, flag, params) - if((!bomb && bombcheck) || (!target) || (get_dist(get_turf(target), get_turf(user)) <= 2)) + if((!bomb && bombcheck) || !target || (get_dist(get_turf(target), get_turf(user)) <= 2)) return ..() - var/power = bomb ? calculate_bomb() : debug_power - power = min(power, max_power) - QDEL_NULL(bomb) - update_appearance() + cached_target = WEAKREF(target) + cached_modifiers = params + if(bomb?.valve_open) + user.visible_message( + "[user] points [src] at [target]!", + "You point [src] at [target]!" + ) + return + + cached_firer = WEAKREF(user) + if(!bomb) + fire_debug(target, user, flag, params) + return + + playsound(src, dry_fire_sound, 30, TRUE) // *click + user.visible_message( + "[user] opens [bomb] on [user.p_their()] [src] and points [p_them()] at [target]!", + "You open [bomb] on your [src] and point [p_them()] at [target]!" + ) + var/turf/current_turf = get_turf(src) + var/turf/target_turf = get_turf(target) + message_admins("Blastcannon transfer valve opened by [ADMIN_LOOKUPFLW(user)] at [ADMIN_VERBOSEJMP(current_turf)] while aiming at [ADMIN_VERBOSEJMP(target_turf)] (target).") + log_game("Blastcannon transfer valve opened by [key_name(user)] at [AREACOORD(current_turf)] while aiming at [AREACOORD(target_turf)] (target).") + bomb.toggle_valve() + return + + +/** + * Channels an internal explosion into a blastwave projectile. + * + * Arguments: + * - [blastwave_data][/list]: A list containing all of the data for the blastwave. + */ +/obj/item/gun/blastcannon/proc/channel_blastwave(atom/source, list/arguments) + . = COMSIG_CANCEL_EXPLOSION + + var/heavy = arguments[EXARG_KEY_DEV_RANGE] + var/medium = arguments[EXARG_KEY_HEAVY_RANGE] + var/light = arguments[EXARG_KEY_LIGHT_RANGE] + var/range = max(heavy, medium, light, 0) + if(!range) + visible_message("[src] lets out a little \"phut\".") + return + + if(!ismob(loc)) + fire_dropped(heavy, medium, light) + return + + var/mob/holding = loc + var/target = cached_target?.resolve() + if(target && (holding.get_active_held_item() == src) && cached_firer && (holding == cached_firer.resolve())) + fire_intentionally(target, holding, heavy, medium, light, cached_modifiers) + else + fire_accidentally(holding, heavy, medium, light) + return + +/** + * Prepares and fires a blastwave. + * + * Arguments: + * - [target][/atom]: The thing that the blastwave is being fired at. + * - heavy: The devastation range of the blastwave. + * - medium: The heavy impact range of the blastwave. + * - light: The light impact range of the blastwave. + * - modifiers: Modifiers as a string used while firing this. + * - spread: How inaccurate the blastwave is. + */ +/obj/item/gun/blastcannon/proc/fire_blastwave(atom/target, heavy, medium, light, modifiers, spread = 0) + var/turf/start_turf = get_turf(src) + + var/cap_multiplier = SSmapping.level_trait(start_turf.z, ZTRAIT_BOMBCAP_MULTIPLIER) + if(isnull(cap_multiplier)) + cap_multiplier = 1 + var/capped_heavy = min(GLOB.MAX_EX_DEVESTATION_RANGE * cap_multiplier, heavy) + var/capped_medium = min(GLOB.MAX_EX_HEAVY_RANGE * cap_multiplier, medium) + SSexplosions.shake_the_room(start_turf, max(heavy, medium, light, 0), (capped_heavy * 15) + (capped_medium * 20), capped_heavy, capped_medium) + + var/obj/projectile/blastwave/blastwave = new(loc, heavy, medium, light) + blastwave.preparePixelProjectile(target, start_turf, params2list(modifiers), spread) + blastwave.fire() + cached_firer = null + cached_target = null + cached_modifiers = null + return + + +/** + * Handles firing the blastcannon intentionally at a specific target. + * + * Arguments: + * - [firer][/mob]: The mob who is firing this weapon. + * - [target][/atom]: The target we are firing the + * - heavy: The devastation range of the blastwave. + * - medium: The heavy impact range of the blastwave. + * - light: The light impact range of the blastwave. + * - modifiers: The modifier string to use when preparing the blastwave. + */ +/obj/item/gun/blastcannon/proc/fire_intentionally(atom/target, mob/firer, heavy, medium, light, modifiers) + firer.visible_message( + "[firer] fires a blast wave at [target]!", + "You fire a blast wave at [target]!" + ) + var/turf/start_turf = get_turf(src) + var/turf/target_turf = get_turf(target) + message_admins("Blast wave fired from [ADMIN_VERBOSEJMP(start_turf)] at [ADMIN_VERBOSEJMP(target_turf)] ([target]) by [ADMIN_LOOKUPFLW(firer)] with power [heavy]/[medium]/[light].") + log_game("Blast wave fired from [AREACOORD(start_turf)] at [AREACOORD(target_turf)] ([target]) by [key_name(firer)] with power [heavy]/[medium]/[light].") + fire_blastwave(target, heavy, medium, light, modifiers) + return + +/** + * Handles firing the blastcannon if it was handed to someone else between opening the valve and the bomb exploding. + * + * Arguments: + * - [holder][/mob]: The person who happened to be holding the cannon when it went off. + * - heavy: The devastation range of the blastwave. + * - medium: The heavy impact range of the blastwave. + * - light: The light impact range of the blastwave. + */ +/obj/item/gun/blastcannon/proc/fire_accidentally(mob/holder, heavy, medium, light) + var/turf/target + var/holding + if(holder.is_holding(src)) + target = get_edge_target_turf(holder, holder.dir) + holding = TRUE + else + target = get_edge_target_turf(holder, dir) + holding = FALSE + + var/mob/firer = cached_firer?.resolve() + var/turf/start_turf = get_turf(src) + holder.visible_message( + "[src] suddenly goes off[holding ? " in [holder]'s hands" : null]!", + "[src] suddenly goes off[holding ? " in your hands" : null]!" + ) + message_admins("Blast wave primed by [ADMIN_LOOKUPFLW(firer)] fired from [ADMIN_VERBOSEJMP(start_turf)] roughly towards [ADMIN_VERBOSEJMP(target)] while being held by [ADMIN_LOOKUPFLW(holder)] with power [heavy]/[medium]/[light].") + log_game("Blast wave primed by [key_name(firer)] fired from [AREACOORD(start_turf)] roughly towards [AREACOORD(target)] while being held by [key_name(holder)] with power [heavy]/[medium]/[light].") + return fire_blastwave(target, heavy, medium, light, null, (90 * (rand() - 0.5))) // +- anywhere between 0 and 45 degrees + +/** + * Handles firing the blastcannon if it was dropped on the ground or shoved into a backpack. + * + * Arguments: + * - heavy: The devastation range of the blastwave. + * - medium: The heavy impact range of the blastwave. + * - light: The light impact range of the blastwave. + */ +/obj/item/gun/blastcannon/proc/fire_dropped(heavy, medium, light) + src.visible_message("[src] suddenly goes off!") + var/turf/target = get_edge_target_turf(src, dir) + var/mob/firer = cached_firer.resolve() + var/turf/start_turf = get_turf(src) + message_admins("Blast wave primed by [ADMIN_LOOKUPFLW(firer)] fired from [ADMIN_VERBOSEJMP(start_turf)] roughly towards [ADMIN_VERBOSEJMP(target)] at [ADMIN_VERBOSEJMP(loc)] ([loc]) with power [heavy]/[medium]/[light].") + log_game("Blast wave primed by [key_name(firer)] fired from [AREACOORD(start_turf)] roughly towards [AREACOORD(target)] at [AREACOORD(loc)] ([loc]) with power [heavy]/[medium]/[light].") + return fire_blastwave(target, heavy, medium, light, null, 360 * rand()) + +/** + * Handles firing the blastcannon with debug power. + * + * Arguments: + * - [target][/atom]: The thing the blastcannon is being fired at. + * - [user][/mob]: The person firing the blastcannon. + * - modifiers: A string containing click data. + */ +/obj/item/gun/blastcannon/proc/fire_debug(atom/target, mob/user, modifiers) + fire_intentionally(target, user, debug_power * 0.25, debug_power * 0.5, debug_power, modifiers) + return - var/heavy = power * 0.25 - var/medium = power * 0.5 - var/light = power - user.visible_message("[user] opens [bomb] on [user.p_their()] [name] and fires a blast wave at [target]!","You open [bomb] on your [name] and fire a blast wave at [target]!") - playsound(user, "explosion", 100, TRUE) - var/turf/starting = get_turf(user) - var/turf/targturf = get_turf(target) - message_admins("Blast wave fired from [ADMIN_VERBOSEJMP(starting)] at [ADMIN_VERBOSEJMP(targturf)] ([target.name]) by [ADMIN_LOOKUPFLW(user)] with power [heavy]/[medium]/[light].") - log_game("Blast wave fired from [AREACOORD(starting)] at [AREACOORD(targturf)] ([target.name]) by [key_name(user)] with power [heavy]/[medium]/[light].") - var/obj/projectile/blastwave/BW = new(loc, heavy, medium, light) - var/modifiers = params2list(params) - BW.preparePixelProjectile(target, get_turf(src), modifiers, 0) - BW.fire() - name = initial(name) - desc = initial(desc) /// The projectile used by the blastcannon /obj/projectile/blastwave @@ -137,17 +277,17 @@ movement_type = FLYING projectile_phasing = ALL // just blows up the turfs lmao /// The maximum distance this will inflict [EXPLODE_DEVASTATE] - var/heavyr = 0 + var/heavy_ex_range = 0 /// The maximum distance this will inflict [EXPLODE_HEAVY] - var/mediumr = 0 + var/medium_ex_range = 0 /// The maximum distance this will inflict [EXPLODE_LIGHT] - var/lightr = 0 + var/light_ex_range = 0 -/obj/projectile/blastwave/Initialize(mapload, _heavy, _medium, _light) - range = max(_heavy, _medium, _light, 0) - heavyr = _heavy - mediumr = _medium - lightr = _light +/obj/projectile/blastwave/Initialize(mapload, heavy_ex_range, medium_ex_range, light_ex_range) + range = max(heavy_ex_range, medium_ex_range, light_range, 0) + src.heavy_ex_range = heavy_ex_range + src.medium_ex_range = medium_ex_range + src.light_ex_range = light_ex_range return ..() /obj/projectile/blastwave/Range() @@ -155,15 +295,15 @@ if(QDELETED(src)) return - heavyr = max(heavyr - 1, 0) - mediumr = max(mediumr - 1, 0) - lightr = max(lightr - 1, 0) + heavy_ex_range = max(heavy_ex_range - 1, 0) + medium_ex_range = max(medium_ex_range - 1, 0) + light_ex_range = max(light_ex_range - 1, 0) - if(heavyr) + if(heavy_ex_range) SSexplosions.highturf += loc - else if(mediumr) + else if(medium_ex_range) SSexplosions.medturf += loc - else if(lightr) + else if(light_range) SSexplosions.lowturf += loc else qdel(src) diff --git a/code/modules/projectiles/guns/misc/medbeam.dm b/code/modules/projectiles/guns/misc/medbeam.dm index 390a5ec6aea..23a53c195fd 100644 --- a/code/modules/projectiles/guns/misc/medbeam.dm +++ b/code/modules/projectiles/guns/misc/medbeam.dm @@ -112,7 +112,7 @@ return FALSE for(var/obj/effect/ebeam/medical/B in turf)// Don't cross the str-beams! if(B.owner.origin != current_beam.origin) - explosion(B.loc,0,3,5,8) + explosion(B.loc, heavy_impact_range = 3, light_impact_range = 5, flash_range = 8) qdel(dummy) return FALSE qdel(dummy) diff --git a/code/modules/projectiles/pins.dm b/code/modules/projectiles/pins.dm index 9bccd89d488..c28247e98ac 100644 --- a/code/modules/projectiles/pins.dm +++ b/code/modules/projectiles/pins.dm @@ -69,7 +69,7 @@ if(user) user.show_message("SELF-DESTRUCTING...
", MSG_VISUAL) to_chat(user, "[gun] explodes!") - explosion(get_turf(gun), -1, 0, 2, 3) + explosion(src, devastation_range = -1, light_impact_range = 2, flash_range = 3) if(gun) qdel(gun) diff --git a/code/modules/projectiles/projectile/bullets/cannon.dm b/code/modules/projectiles/projectile/bullets/cannon.dm index cdaf7e32875..c01c1fc867a 100644 --- a/code/modules/projectiles/projectile/bullets/cannon.dm +++ b/code/modules/projectiles/projectile/bullets/cannon.dm @@ -34,7 +34,7 @@ damage = 40 //set to 30 before first mob impact, but they're gonna be gibbed by the explosion /obj/projectile/bullet/cannonball/explosive/on_hit(atom/target, blocked = FALSE) - explosion(target, 2, 3, 4) + explosion(target, devastation_range = 2, heavy_impact_range = 3, light_impact_range = 4) . = ..() /obj/projectile/bullet/cannonball/emp @@ -54,5 +54,5 @@ /obj/projectile/bullet/cannonball/biggest_one/on_hit(atom/target, blocked = FALSE) if(projectile_piercing == NONE) - explosion(target, GLOB.MAX_EX_DEVESTATION_RANGE, GLOB.MAX_EX_HEAVY_RANGE, GLOB.MAX_EX_LIGHT_RANGE, GLOB.MAX_EX_FLASH_RANGE) + explosion(target, 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) . = ..() diff --git a/code/modules/projectiles/projectile/bullets/grenade.dm b/code/modules/projectiles/projectile/bullets/grenade.dm index 89f350af432..bb9071a6ca3 100644 --- a/code/modules/projectiles/projectile/bullets/grenade.dm +++ b/code/modules/projectiles/projectile/bullets/grenade.dm @@ -10,5 +10,5 @@ /obj/projectile/bullet/a40mm/on_hit(atom/target, blocked = FALSE) ..() - explosion(target, -1, 0, 2, 1, 0, flame_range = 3) + explosion(target, devastation_range = -1, light_impact_range = 2, flame_range = 3, flash_range = 1, adminlog = FALSE) return BULLET_ACT_HIT diff --git a/code/modules/projectiles/projectile/bullets/shotgun.dm b/code/modules/projectiles/projectile/bullets/shotgun.dm index 343a9bfedca..7486423b15c 100644 --- a/code/modules/projectiles/projectile/bullets/shotgun.dm +++ b/code/modules/projectiles/projectile/bullets/shotgun.dm @@ -68,7 +68,7 @@ /obj/projectile/bullet/shotgun_frag12/on_hit(atom/target, blocked = FALSE) ..() - explosion(target, -1, 0, 1) + explosion(target, devastation_range = -1, light_impact_range = 1) return BULLET_ACT_HIT /obj/projectile/bullet/pellet diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index 4b65d9d8e8b..cb9065c8aa7 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -676,7 +676,7 @@ return BULLET_ACT_BLOCK M.take_overall_damage(0,10) //between this 10 burn, the 10 brute, the explosion brute, and the onfire burn, your at about 65 damage if you stop drop and roll immediately var/turf/T = get_turf(target) - explosion(T, -1, exp_heavy, exp_light, exp_flash, 0, flame_range = exp_fire) + explosion(T, devastation_range = -1, heavy_impact_range = exp_heavy, light_impact_range = exp_light, flame_range = exp_fire, flash_range = exp_flash, adminlog = FALSE) //still magic related, but a different path diff --git a/code/modules/projectiles/projectile/special/rocket.dm b/code/modules/projectiles/projectile/special/rocket.dm index f50a08f6b51..23e60f8f7ed 100644 --- a/code/modules/projectiles/projectile/special/rocket.dm +++ b/code/modules/projectiles/projectile/special/rocket.dm @@ -7,7 +7,7 @@ /obj/projectile/bullet/gyro/on_hit(atom/target, blocked = FALSE) ..() - explosion(target, -1, 0, 2) + explosion(target, devastation_range = -1, light_impact_range = 2) return BULLET_ACT_HIT /// PM9 HEDP rocket @@ -24,7 +24,7 @@ /obj/projectile/bullet/a84mm/on_hit(atom/target, blocked = FALSE) ..() - explosion(target, -1, 1, 3, 1, 0, flame_range = 4) + explosion(target, devastation_range = -1, heavy_impact_range = 1, light_impact_range = 3, flame_range = 4, flash_range = 1, adminlog = FALSE) if(ismecha(target)) var/obj/vehicle/sealed/mecha/M = target @@ -47,9 +47,9 @@ /obj/projectile/bullet/a84mm_he/on_hit(atom/target, blocked=0) ..() if(!isliving(target)) //if the target isn't alive, so is a wall or something - explosion(target, 0, 1, 2, 4, flame_range = 3) + explosion(target, heavy_impact_range = 1, light_impact_range = 2, flame_range = 3, flash_range = 4) else - explosion(target, 0, 0, 2, 4, flame_range = 3) + explosion(target, light_impact_range = 2, flame_range = 3, flash_range = 4) return BULLET_ACT_HIT /// PM9 weak rocket @@ -65,9 +65,9 @@ /obj/projectile/bullet/a84mm_weak/on_hit(atom/target, blocked=0) ..() if(!isliving(target)) //if the target isn't alive, so is a wall or something - explosion(target, 0, 1, 2, 4, flame_range = 3) + explosion(target, heavy_impact_range = 1, light_impact_range = 2, flame_range = 3, flash_range = 4) else - explosion(target, 0, 0, 2, 4, flame_range = 3) + explosion(target, light_impact_range = 2, flame_range = 3, flash_range = 4) return BULLET_ACT_HIT /// Mech BRM-6 missile @@ -99,7 +99,7 @@ ..() for(var/i in sturdy) if(istype(target, i)) - explosion(target, 0, 1, 1, 2) + explosion(target, heavy_impact_range = 1, light_impact_range = 1, flash_range = 2) return BULLET_ACT_HIT //if(istype(target, /turf/closed) || ismecha(target)) new /obj/item/broken_missile(get_turf(src), 1) diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 7315874b53c..2c2afa7756f 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -205,7 +205,7 @@ obj_flags |= EMAGGED /obj/machinery/chem_dispenser/ex_act(severity, target) - if(severity >= EXPLODE_LIGHT) // Note that the explosion defines are inverted. Stronger explosions have smaller numbers. + if(severity <= EXPLODE_LIGHT) return FALSE return ..() diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm index b3bf6e8672c..5a0e044db2d 100644 --- a/code/modules/reagents/chemistry/machinery/chem_master.dm +++ b/code/modules/reagents/chemistry/machinery/chem_master.dm @@ -65,7 +65,7 @@ reagents.maximum_volume += B.reagents.maximum_volume /obj/machinery/chem_master/ex_act(severity, target) - if(severity >= EXPLODE_LIGHT) // This actually makes the dispenser immune to explosions at least as weak as [EXPLODE_LIGHT]. Don't ask me why the defines are inverted. I don't know. + if(severity <= EXPLODE_LIGHT) return FALSE return ..() diff --git a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm index 32a05cdfef8..84a891b1bda 100644 --- a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm @@ -544,7 +544,7 @@ Basically, we fill the time between now and 2s from now with hands based off the remove_buffs(owner) var/obj/item/organ/heart/heart = owner.getorganslot(ORGAN_SLOT_HEART) if(owner.health < -500 || heart.organ_flags & ORGAN_FAILING)//Honestly commendable if you get -500 - explosion(owner, 0, 0, 1) + explosion(owner, light_impact_range = 1) qdel(heart) owner.visible_message("[owner]'s heart explodes!") return ..() @@ -557,7 +557,7 @@ Basically, we fill the time between now and 2s from now with hands based off the REMOVE_TRAIT(owner, TRAIT_NODEATH, type) owner.stat = DEAD return ..() - explosion(owner, 0, 0, 1) + explosion(owner, light_impact_range = 1) qdel(heart) owner.visible_message("[owner]'s heart explodes!") return..() diff --git a/code/modules/reagents/chemistry/recipes.dm b/code/modules/reagents/chemistry/recipes.dm index 7d8d5142cc8..f8451b9b990 100644 --- a/code/modules/reagents/chemistry/recipes.dm +++ b/code/modules/reagents/chemistry/recipes.dm @@ -440,7 +440,7 @@ //Calls the default explosion subsystem handiler to explode with fire (random firespots and noise) /datum/chemical_reaction/proc/explode_fire(datum/reagents/holder, datum/equilibrium/equilibrium, range = 3) - explosion(holder.my_atom, 0, 0, 0, 0, flame_range = range) + explosion(holder.my_atom, flame_range = range) holder.my_atom.audible_message("The [holder.my_atom] suddenly errupts in flames!") //Creates a ring of fire in a set range around the beaker location diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm index 8380168e162..84d0c2d2cc1 100644 --- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm +++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm @@ -392,7 +392,7 @@ /datum/chemical_reaction/slime/slimeexplosion/proc/boom(datum/reagents/holder) if(holder?.my_atom) - explosion(get_turf(holder.my_atom), 1 ,3, 6) + explosion(holder.my_atom, devastation_range = 1, heavy_impact_range = 3, light_impact_range = 6) /datum/chemical_reaction/slime/slimecornoil diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 60d38a875c3..207e091887b 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -143,10 +143,10 @@ return ..() -/obj/item/reagent_containers/ex_act() +/obj/item/reagent_containers/ex_act(severity) if(reagents) for(var/datum/reagent/R in reagents.reagent_list) - R.on_ex_act() + R.on_ex_act(severity) if(!QDELETED(src)) return ..() diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 25905d7d4c2..837250acbc4 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -87,7 +87,7 @@ reagent_id = /datum/reagent/fuel /obj/structure/reagent_dispensers/fueltank/boom() - explosion(get_turf(src), 0, 1, 5, flame_range = 5) + explosion(src, heavy_impact_range = 1, light_impact_range = 5, flame_range = 5) qdel(src) /obj/structure/reagent_dispensers/fueltank/blob_act(obj/structure/blob/B) @@ -139,7 +139,7 @@ tank_volume = 5000 /obj/structure/reagent_dispensers/fueltank/large/boom() - explosion(get_turf(src), 1, 2, 7, flame_range = 12) + explosion(src, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 7, flame_range = 12) qdel(src) /obj/structure/reagent_dispensers/peppertank @@ -193,7 +193,7 @@ reagent_id = /datum/reagent/consumable/ethanol/beer /obj/structure/reagent_dispensers/beerkeg/blob_act(obj/structure/blob/B) - explosion(src.loc,0,3,5,7,10) + explosion(src, heavy_impact_range = 3, light_impact_range = 5, flame_range = 10, flash_range = 7) if(!QDELETED(src)) qdel(src) diff --git a/code/modules/research/anomaly/explosive_compressor.dm b/code/modules/research/anomaly/explosive_compressor.dm index 5b5573f0f41..e41fe01a7b8 100644 --- a/code/modules/research/anomaly/explosive_compressor.dm +++ b/code/modules/research/anomaly/explosive_compressor.dm @@ -1,5 +1,8 @@ #define MAX_RADIUS_REQUIRED 20 //maxcap #define MIN_RADIUS_REQUIRED 4 //1, 2, 4 +/// How long the compression test can last before the machine just gives up and ejects the items. +#define COMPRESSION_TEST_TIME (SSOBJ_DT SECONDS * 5) + /** * # Explosive compressor machines * @@ -18,14 +21,32 @@ var/obj/item/raw_anomaly_core/inserted_core /// The TTV inserted in the machine. var/obj/item/transfer_valve/inserted_bomb + /// The timer that lets us timeout the test. + var/datum/timedevent/timeout_timer + /// Whether we are currently testing a bomb and core. + var/testing = FALSE + /// The message produced by the explosive compressor at the end of the compression test. + var/test_status = null /// The last time we did say_requirements(), because someone will inevitably click spam this. var/last_requirements_say = 0 +/obj/machinery/research/explosive_compressor/Initialize() + . = ..() + RegisterSignal(src, COMSIG_ATOM_INTERNAL_EXPLOSION, .proc/check_test) + +/obj/machinery/research/explosive_compressor/Destroy() + UnregisterSignal(src, COMSIG_ATOM_INTERNAL_EXPLOSION) + return ..() + /obj/machinery/research/explosive_compressor/examine(mob/user) . = ..() . += "Ctrl-Click to remove an inserted core." . += "Click with an empty hand to gather information about the required radius of an inserted core. Insert a ready TTV to start the implosion process if a core is inserted." +/obj/machinery/research/explosive_compressor/assume_air(datum/gas_mixture/giver) + qdel(giver) + return null // Required to make the TTV not vent directly into the air. + /obj/machinery/research/explosive_compressor/attack_hand(mob/living/user, list/modifiers) . = ..() if(.) @@ -45,6 +66,9 @@ if(!inserted_core) to_chat(user, "There is no core inserted.") return + if(testing) + to_chat(user, "You can't remove [inserted_core] from [src] while [p_theyre()] in testing mode.") + return inserted_core.forceMove(get_turf(user)) to_chat(user, "You remove [inserted_core] from [src].") user.put_in_hands(inserted_core) @@ -53,12 +77,12 @@ /** * Says (no, literally) the data of required explosive power for a certain anomaly type. */ -/obj/machinery/research/explosive_compressor/proc/say_requirements(obj/item/raw_anomaly_core/C) - var/required = get_required_radius(C.anomaly_type) +/obj/machinery/research/explosive_compressor/proc/say_requirements(obj/item/raw_anomaly_core/core) + var/required = get_required_radius(core.anomaly_type) if(isnull(required)) - say("Unfortunately, due to diminishing supplies of condensed anomalous matter, [C] and any cores of its type are no longer of a sufficient quality level to be compressed into a working core.") + say("Unfortunately, due to diminishing supplies of condensed anomalous matter, [core] and any cores of its type are no longer of a sufficient quality level to be compressed into a working core.") else - say("[C] requires a minimum of a theoretical radius of [required] to successfully implode into a charged anomaly core.") + say("[core] requires a minimum of a theoretical radius of [required] to successfully implode into a charged anomaly core.") /** * Determines how much explosive power (last value, so light impact theoretical radius) is required to make a certain anomaly type. @@ -80,65 +104,117 @@ var/radius = clamp(round(MIN_RADIUS_REQUIRED + radius_increase_per_core * already_made, 1), MIN_RADIUS_REQUIRED, MAX_RADIUS_REQUIRED) return radius -/obj/machinery/research/explosive_compressor/attackby(obj/item/I, mob/living/user, params) +/obj/machinery/research/explosive_compressor/attackby(obj/item/tool, mob/living/user, params) . = ..() - if(istype(I, /obj/item/raw_anomaly_core)) + if(istype(tool, /obj/item/raw_anomaly_core)) if(inserted_core) to_chat(user, "There is already a core in [src].") return - if(!user.transferItemToLoc(I, src)) - to_chat(user, "[I] is stuck to your hand.") + if(testing) + to_chat(user, "You can't insert [tool] into [src] while [p_theyre()] in testing mode.") return - inserted_core = I - to_chat(user, "You insert [I] into [src].") + if(!user.transferItemToLoc(tool, src)) + to_chat(user, "[tool] is stuck to your hand.") + return + inserted_core = tool + to_chat(user, "You insert [tool] into [src].") return - if(istype(I, /obj/item/transfer_valve)) + if(istype(tool, /obj/item/transfer_valve)) // If they don't have a bomb core inserted, don't let them insert this. If they do, insert and do implosion. if(!inserted_core) to_chat(user, "There is no core inserted in [src]. What would be the point of detonating an implosion without a core?") return - var/obj/item/transfer_valve/valve = I + if(testing) + to_chat(user, "You can't insert [tool] into [src] while [p_theyre()] in testing mode.") + return + var/obj/item/transfer_valve/valve = tool if(!valve.ready()) to_chat(user, "[valve] is incomplete.") return - if(!user.transferItemToLoc(I, src)) - to_chat(user, "[I] is stuck to your hand.") + if(!user.transferItemToLoc(tool, src)) + to_chat(user, "[tool] is stuck to your hand.") return - inserted_bomb = I - to_chat(user, "You insert [I] and press the start button.") - do_implosion() + inserted_bomb = tool + to_chat(user, "You insert [tool] and press the start button.") + start_test() + /** - * The ""explosion"" proc. + * Starts a compression test. */ -/obj/machinery/research/explosive_compressor/proc/do_implosion() - var/required_radius = get_required_radius(inserted_core.anomaly_type) - // By now, we should be sure that we have a core, a TTV, and that the TTV has both tanks in place. - var/datum/gas_mixture/mix = new(0) - inserted_bomb.merge_gases(mix) - mix.react() - if(mix.return_pressure() < TANK_FRAGMENT_PRESSURE) - // They failed so miserably we're going to give them their bomb back. +/obj/machinery/research/explosive_compressor/proc/start_test() + if(!istype(inserted_core) || !istype(inserted_bomb)) + end_test("ERROR: Missing equpment. Items ejected.") + return + + say("Beginning compression test. Opening transfer valve.") + testing = TRUE + test_status = null + inserted_bomb.toggle_valve() + timeout_timer = addtimer(CALLBACK(src, .proc/timeout_test), COMPRESSION_TEST_TIME, TIMER_STOPPABLE | TIMER_UNIQUE | TIMER_NO_HASH_WAIT) + return + +/** + * Ends a compression test. + * + * Arguments: + * - message: A message for the compressor to say when the test ends. + */ +/obj/machinery/research/explosive_compressor/proc/end_test(message) + if(inserted_core) + inserted_core.forceMove(drop_location()) + inserted_core = null + if(inserted_bomb) inserted_bomb.forceMove(drop_location()) inserted_bomb = null - inserted_core.forceMove(drop_location()) - inserted_core = null - say("Transfer valve resulted in negligible explosive power. Items ejected.") - return FALSE - mix.react() // build more pressure + if(timeout_timer) + QDEL_NULL(timeout_timer) + if(message) + say(message) + testing = FALSE + return - var/range = (mix.return_pressure() - TANK_FRAGMENT_PRESSURE) / TANK_FRAGMENT_SCALE - QDEL_NULL(inserted_bomb) // bomb goes poof - if(range < required_radius) - say("Resultant detonation failed to produce enough implosive power to compress [inserted_core]. Core ejected.") - inserted_core.forceMove(drop_location()) - inserted_core = null - return FALSE +/** + * Checks whether an internal explosion was sufficient to compress the core. + */ +/obj/machinery/research/explosive_compressor/proc/check_test(atom/source, list/arguments) + . = COMSIG_CANCEL_EXPLOSION + if(!inserted_core) + test_status = "ERROR: No core present during detonation." + return - inserted_core.create_core(drop_location(), TRUE, TRUE) - inserted_core = null - say("Success. Resultant detonation has theoretical range of [range]. Required radius was [required_radius]. Core production complete.") - return TRUE + var/heavy = arguments[EXARG_KEY_DEV_RANGE] + var/medium = arguments[EXARG_KEY_HEAVY_RANGE] + var/light = arguments[EXARG_KEY_LIGHT_RANGE] + var/explosion_range = max(heavy, medium, light, 0) + var/required_range = get_required_radius(inserted_core.anomaly_type) + var/turf/location = get_turf(src) + + var/cap_multiplier = SSmapping.level_trait(location.z, ZTRAIT_BOMBCAP_MULTIPLIER) + if(isnull(cap_multiplier)) + cap_multiplier = 1 + var/capped_heavy = min(GLOB.MAX_EX_DEVESTATION_RANGE * cap_multiplier, heavy) + var/capped_medium = min(GLOB.MAX_EX_HEAVY_RANGE * cap_multiplier, medium) + SSexplosions.shake_the_room(location, explosion_range, (capped_heavy * 15) + (capped_medium * 20), capped_heavy, capped_medium) + + if(explosion_range < required_range) + test_status = "Resultant detonation failed to produce enough implosive power to compress [inserted_core]. Core ejected." + return + + if(test_status) + return + inserted_core = inserted_core.create_core(src, TRUE, TRUE) + test_status = "Success. Resultant detonation has theoretical range of [explosion_range]. Required radius was [required_range]. Core production complete." + return + +/** + * Handles timing out the test after a while. + */ +/obj/machinery/research/explosive_compressor/proc/timeout_test() + timeout_timer = null + if(!test_status) + test_status = "Transfer valve resulted in negligible explosive power. Items ejected." + end_test(test_status) #undef MAX_RADIUS_REQUIRED #undef MIN_RADIUS_REQUIRED diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index 5cfa4a6c112..35f391ced8f 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -360,7 +360,7 @@ FB.fire() else if(prob(EFFECT_PROB_LOW-badThingCoeff)) visible_message("[src] malfunctions, melting [exp_on] and releasing a burst of flame!") - explosion(loc, -1, 0, 0, 0, 0, flame_range = 2) + explosion(src, devastation_range = -1, flame_range = 2, adminlog = FALSE) investigate_log("Experimentor started a fire.", INVESTIGATE_EXPERIMENTOR) ejectItem(TRUE) else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff)) @@ -517,7 +517,7 @@ addtimer(CALLBACK(src, .proc/reset_exp), resetTime) /obj/machinery/rnd/experimentor/proc/boom() - explosion(src, 1, 5, 10, 5, 1) + explosion(src, devastation_range = 1, heavy_impact_range = 5, light_impact_range = 10, flash_range = 5, adminlog = TRUE) /obj/machinery/rnd/experimentor/proc/honk() playsound(src, 'sound/items/bikehorn.ogg', 500) @@ -654,7 +654,7 @@ /obj/item/relic/proc/do_explode(mob/user) if(loc == user) visible_message("\The [src]'s top opens, releasing a powerful blast!") - explosion(user.loc, 0, rand(1,5), rand(1,5), rand(1,5), rand(1,5), flame_range = 2) + explosion(src, heavy_impact_range = rand(1,5), light_impact_range = rand(1,5), flame_range = 2, flash_range = rand(1,5), adminlog = TRUE) 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/research/nanites/nanite_programs/weapon.dm b/code/modules/research/nanites/nanite_programs/weapon.dm index a8d276919ec..79bf0444938 100644 --- a/code/modules/research/nanites/nanite_programs/weapon.dm +++ b/code/modules/research/nanites/nanite_programs/weapon.dm @@ -88,7 +88,7 @@ addtimer(CALLBACK(src, .proc/boom), clamp((nanites.nanite_volume * 0.35), 25, 150)) /datum/nanite_program/explosive/proc/boom() - dyn_explosion(get_turf(host_mob), nanites.nanite_volume / 50) + dyn_explosion(host_mob, nanites.nanite_volume / 50) qdel(nanites) //TODO make it defuse if triggered again diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index 1a6b59a02a3..ccc6a26ac27 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -859,7 +859,7 @@ /datum/status_effect/stabilized/oil/tick() if(owner.stat == DEAD) - explosion(get_turf(owner),1,2,4,flame_range = 5) + explosion(owner, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 4, flame_range = 5) return ..() /datum/status_effect/stabilized/black diff --git a/code/modules/research/xenobiology/crossbreeding/charged.dm b/code/modules/research/xenobiology/crossbreeding/charged.dm index 7b41c0a4661..d23fe1d2687 100644 --- a/code/modules/research/xenobiology/crossbreeding/charged.dm +++ b/code/modules/research/xenobiology/crossbreeding/charged.dm @@ -224,7 +224,7 @@ Charged extracts: addtimer(CALLBACK(src, .proc/boom), 50) /obj/item/slimecross/charged/oil/proc/boom() - explosion(get_turf(src), 2, 3, 4) //Much smaller effect than normal oils, but devastatingly strong where it does hit. + explosion(src, devastation_range = 2, heavy_impact_range = 3, light_impact_range = 4) //Much smaller effect than normal oils, but devastatingly strong where it does hit. qdel(src) /obj/item/slimecross/charged/black diff --git a/code/modules/research/xenobiology/crossbreeding/chilling.dm b/code/modules/research/xenobiology/crossbreeding/chilling.dm index 5987dc21269..f7aaede8c81 100644 --- a/code/modules/research/xenobiology/crossbreeding/chilling.dm +++ b/code/modules/research/xenobiology/crossbreeding/chilling.dm @@ -290,7 +290,7 @@ Chilling extracts: addtimer(CALLBACK(src, .proc/boom), 50) /obj/item/slimecross/chilling/oil/proc/boom() - explosion(get_turf(src), -1, -1, 10, 0) //Large radius, but mostly light damage, and no flash. + explosion(src, devastation_range = -1, heavy_impact_range = -1, light_impact_range = 10) //Large radius, but mostly light damage, and no flash. qdel(src) /obj/item/slimecross/chilling/black diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index f9f3acb9ba7..d657b1bc7fa 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -457,7 +457,7 @@ user.visible_message("[user]'s skin starts pulsing and glowing ominously...", "You feel unstable...") if(do_after(user, 60, target = user)) to_chat(user, "You explode!") - explosion(get_turf(user), 1 ,3, 6) + explosion(user, devastation_range = 1, heavy_impact_range = 3, light_impact_range = 6) user.gib() return to_chat(user, "You stop feeding [src], and the feeling passes.") diff --git a/code/modules/spells/spell_types/explosion.dm b/code/modules/spells/spell_types/explosion.dm index dadbd190fa6..a0878826f97 100644 --- a/code/modules/spells/spell_types/explosion.dm +++ b/code/modules/spells/spell_types/explosion.dm @@ -4,15 +4,19 @@ school = SCHOOL_EVOCATION + /// The devastation range of the resulting explosion. var/ex_severe = 1 + /// The heavy impact range of the resulting explosion. var/ex_heavy = 2 + /// The light impact range of the resulting explosion. var/ex_light = 3 + /// The flash range of the resulting explosion. var/ex_flash = 4 /obj/effect/proc_holder/spell/targeted/explosion/cast(list/targets,mob/user = usr) for(var/mob/living/target in targets) if(target.anti_magic_check()) continue - explosion(target.loc,ex_severe,ex_heavy,ex_light,ex_flash) + explosion(target, devastation_range = ex_severe, heavy_impact_range = ex_heavy, light_impact_range = ex_light, flash_range = ex_flash) return diff --git a/code/modules/station_goals/bsa.dm b/code/modules/station_goals/bsa.dm index f75cd18c5d3..d46a7cc30dc 100644 --- a/code/modules/station_goals/bsa.dm +++ b/code/modules/station_goals/bsa.dm @@ -205,7 +205,7 @@ if(!blocker) message_admins("[ADMIN_LOOKUPFLW(user)] has launched an artillery strike targeting [ADMIN_VERBOSEJMP(bullseye)].") log_game("[key_name(user)] has launched an artillery strike targeting [AREACOORD(bullseye)].") - explosion(bullseye, ex_power, ex_power*2, ex_power*4) + explosion(bullseye, devastation_range = ex_power, heavy_impact_range = ex_power*2, light_impact_range = ex_power*4) else message_admins("[ADMIN_LOOKUPFLW(user)] has launched an artillery strike targeting [ADMIN_VERBOSEJMP(bullseye)] but it was blocked by [blocker] at [ADMIN_VERBOSEJMP(target)].") log_game("[key_name(user)] has launched an artillery strike targeting [AREACOORD(bullseye)] but it was blocked by [blocker] at [AREACOORD(target)].") diff --git a/code/modules/vehicles/atv.dm b/code/modules/vehicles/atv.dm index 3ae406bdc03..63aec5b1d55 100644 --- a/code/modules/vehicles/atv.dm +++ b/code/modules/vehicles/atv.dm @@ -92,7 +92,7 @@ return TRUE /obj/vehicle/ridden/atv/obj_destruction() - explosion(src, -1, 0, 2, 4, flame_range = 3) + explosion(src, devastation_range = -1, light_impact_range = 2, flame_range = 3, flash_range = 4) return ..() /obj/vehicle/ridden/atv/Destroy() diff --git a/code/modules/vehicles/cars/car.dm b/code/modules/vehicles/cars/car.dm index 32e3364b27f..7cd57e4b463 100644 --- a/code/modules/vehicles/cars/car.dm +++ b/code/modules/vehicles/cars/car.dm @@ -75,7 +75,7 @@ add_occupant(kidnapped, VEHICLE_CONTROL_KIDNAPPED) /obj/vehicle/sealed/car/obj_destruction(damage_flag) - explosion(loc, 0, 1, 2, 3, 0) + explosion(src, heavy_impact_range = 1, light_impact_range = 2, flash_range = 3, adminlog = FALSE) log_message("[src] exploded due to destruction", LOG_ATTACK) return ..() diff --git a/code/modules/vehicles/mecha/mecha_defense.dm b/code/modules/vehicles/mecha/mecha_defense.dm index 193aa8164e8..cd6e032b1df 100644 --- a/code/modules/vehicles/mecha/mecha_defense.dm +++ b/code/modules/vehicles/mecha/mecha_defense.dm @@ -120,12 +120,12 @@ /obj/vehicle/sealed/mecha/ex_act(severity, target) log_message("Affected by explosion of severity: [severity].", LOG_MECHA, color="red") if(prob(deflect_chance)) - severity++ + severity-- log_message("Armor saved, changing severity to [severity]", LOG_MECHA) return ..() /obj/vehicle/sealed/mecha/contents_explosion(severity, target) - severity++ + severity-- switch(severity) if(EXPLODE_DEVASTATE) diff --git a/code/modules/vehicles/mecha/working/ripley.dm b/code/modules/vehicles/mecha/working/ripley.dm index 223505cb8c1..e4c531adc31 100644 --- a/code/modules/vehicles/mecha/working/ripley.dm +++ b/code/modules/vehicles/mecha/working/ripley.dm @@ -180,7 +180,7 @@ /obj/vehicle/sealed/mecha/working/ripley/contents_explosion(severity, target) for(var/i in cargo) var/obj/cargoobj = i - if(prob(30/severity)) + if(prob(10 * severity)) LAZYREMOVE(cargo, cargoobj) cargoobj.forceMove(drop_location()) return ..() diff --git a/code/modules/vehicles/motorized_wheelchair.dm b/code/modules/vehicles/motorized_wheelchair.dm index 9b7b3c72745..0e55406ae61 100644 --- a/code/modules/vehicles/motorized_wheelchair.dm +++ b/code/modules/vehicles/motorized_wheelchair.dm @@ -144,7 +144,7 @@ . = ..() // Here is the shitty emag functionality. if(obj_flags & EMAGGED && (istype(A, /turf/closed) || isliving(A))) - explosion(src, -1, 1, 3, 2, 0) + explosion(src, devastation_range = -1, heavy_impact_range = 1, light_impact_range = 3, flash_range = 2, adminlog = FALSE) visible_message("[src] explodes!!") return // If the speed is higher than delay_multiplier throw the person on the wheelchair away diff --git a/code/modules/vehicles/secway.dm b/code/modules/vehicles/secway.dm index d73e4cae7e0..140197acb0e 100644 --- a/code/modules/vehicles/secway.dm +++ b/code/modules/vehicles/secway.dm @@ -71,7 +71,7 @@ . += "Something appears to be stuck in its exhaust..." /obj/vehicle/ridden/secway/obj_destruction() - explosion(src, -1, 0, 2, 4, flame_range = 3) + explosion(src, devastation_range = -1, light_impact_range = 2, flame_range = 3, flash_range = 4) return ..() /obj/vehicle/ridden/secway/Destroy() diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index 966d59978c9..1ec01d6f94b 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -1170,7 +1170,7 @@ GLOBAL_LIST_EMPTY(vending_products) if(T) for(var/obj/item/I in contents) I.forceMove(T) - explosion(T, -1, 0, 3) + explosion(src, devastation_range = -1, light_impact_range = 3) return ..() /obj/machinery/vending/custom/unbreakable diff --git a/tgstation.dme b/tgstation.dme index d21976789a2..fd901e2fdbb 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -58,6 +58,7 @@ #include "code\__DEFINES\events.dm" #include "code\__DEFINES\exosuit_fab.dm" #include "code\__DEFINES\experisci.dm" +#include "code\__DEFINES\explosions.dm" #include "code\__DEFINES\exports.dm" #include "code\__DEFINES\fantasy_affixes.dm" #include "code\__DEFINES\flags.dm"