From f4506cae0b5eb517dca36d0053a3c7bca2ead8f6 Mon Sep 17 00:00:00 2001 From: TemporalOroboros Date: Tue, 14 Sep 2021 18:13:50 -0700 Subject: [PATCH] Makes tank explosions scale with volume and have diminishing returns. (Nerfs singlecaps) (#60600) Changes tank explosions to take tank volume into account and use sqrt scaling when calculating explosion range. This basically means that they scale faster at lower pressures and slower at high pressures. Rebalances tank explosion scaling so that maxcap TTVs are where they used to be pressure-wise. Rebalances the research doppler arrays cash generation algorithm so it maxes out at the same TTV pressure. This does however mean that the doppler array will grant more points at lower explosion pressures. Rebalances blastcannon shot range calculation so it scales as it used to with normal TTVs. The comparatively tiny emergency tanks no longer produce the same size explosion as a TTV at the same pressure. It is much more difficult to carry around 70 maxcaps in a single duffle bag. (I don't think it renders this completely impossible but it does kill oxy-trit emergency tank singlecaps as far as I know.) Lemon posting past this line. How it works: Change assumes maxcaps should be just as easy with the standard ttv setup of 2 70L tanks. So it divides the bomb's strength by 14, then scales it using dyn_explosion's (x*2)^0.5. If you graph it the strength is exactly the same with a 140L reaction vessel, but as volume goes down, strength falls off very quickly because of that division, and the use of dyn_explosion. Hopefully this will effectively disincentivize singlecapping, and remove the everpresent threat of someone leaking the station leveling method. Reasoning for when github blows up: I don't think single caps are on the same level as typical atmos antag threats. They're a hell problem 1: tanks should explode when someone hyper pressurizes them 2: we want all tank explosions to act the same, for the sake of a believable world 3: really well put together tank explosions (ttvs), should be really powerful 4: reaction code is a son of a bitch I do think knowledge gating has some place. Knowing how to do something well should have a benefit. but that isn't like, an ultimate truth. I've seen what proper, full on atmos autism single capping looks like. I don't like that level of absolute destruction at speed being feasible full stop. I consider single caps to be a necessary side effect of how explosion code works. I think it's really cool that people have gotten so deep into this game and the systems around it that they've started optimizing this side effect into a tool/bragging rights thing. But I'm still not a huge fan. If big booms are gated only by knowledge, then as soon as that knowledge spreads we're fucked. I've seen this happen before with things like rad batteries (cue crit being cringe). It's not just single caps mind, the destruction you can make with em scales with knowledge. I'm not in love with this pr mind, because it means I need to worry about bomb code when someone makes some silly tank volume balance pr. but it's a good solution. better then what's been tried in the past. still leaves space for things just blowing up in your face without maxcaps coming into the equation easily. --- code/__DEFINES/atmospherics/atmos_piping.dm | 27 +++++++++++-------- code/__DEFINES/research.dm | 10 ++++++- code/game/machinery/doppler_array.dm | 8 +++--- code/game/objects/items/tanks/tanks.dm | 9 ++++--- .../projectiles/guns/special/blastcannon.dm | 21 ++++++++++++--- 5 files changed, 52 insertions(+), 23 deletions(-) diff --git a/code/__DEFINES/atmospherics/atmos_piping.dm b/code/__DEFINES/atmospherics/atmos_piping.dm index 4b866879805..f206d95a5f8 100644 --- a/code/__DEFINES/atmospherics/atmos_piping.dm +++ b/code/__DEFINES/atmospherics/atmos_piping.dm @@ -31,19 +31,24 @@ #define QUATERNARY 4 //TANKS -/// temperature in kelvins at which a tank will start to melt -#define TANK_MELT_TEMPERATURE 1000000 -/// Tank starts leaking -#define TANK_LEAK_PRESSURE (30.*ONE_ATMOSPHERE) -/// Tank spills all contents into atmosphere -#define TANK_RUPTURE_PRESSURE (35.*ONE_ATMOSPHERE) -/// Boom 3x3 base explosion -#define TANK_FRAGMENT_PRESSURE (40.*ONE_ATMOSPHERE) -/// +1 for each SCALE kPa aboe threshold -#define TANK_FRAGMENT_SCALE (6.*ONE_ATMOSPHERE) -#define TANK_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE*3) +/// The volume of the standard handheld gas tanks on the station. +#define TANK_STANDARD_VOLUME 70 +/// The minimum pressure an gas tanks release valve can be set to. #define TANK_MIN_RELEASE_PRESSURE 0 +/// The maximum pressure an gas tanks release valve can be set to. +#define TANK_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE*3) +/// The default initial value gas tanks release valves are set to. (At least the ones containing pure plasma/oxygen.) #define TANK_DEFAULT_RELEASE_PRESSURE 16 +/// The internal temperature in kelvins at which a handheld gas tank begins to take damage. +#define TANK_MELT_TEMPERATURE 1000000 +/// The internal pressure in kPa at which a handheld gas tank begins to take damage. +#define TANK_LEAK_PRESSURE (30.*ONE_ATMOSPHERE) +/// The internal pressure in kPa at which a handheld gas tank almost immediately ruptures. +#define TANK_RUPTURE_PRESSURE (35.*ONE_ATMOSPHERE) +/// The internal pressure in kPa at which an gas tank that breaks will cause an explosion. +#define TANK_FRAGMENT_PRESSURE (40.*ONE_ATMOSPHERE) +/// Range scaling constant for tank explosions. Calibrated so that a TTV assembled using two 70L tanks will hit the maxcap at at least 160atm. +#define TANK_FRAGMENT_SCALE (84.*ONE_ATMOSPHERE) //MULTIPIPES //IF YOU EVER CHANGE THESE CHANGE SPRITES TO MATCH. diff --git a/code/__DEFINES/research.dm b/code/__DEFINES/research.dm index a43053e262c..8780ebc8850 100644 --- a/code/__DEFINES/research.dm +++ b/code/__DEFINES/research.dm @@ -30,8 +30,16 @@ TECHWEB_POINT_TYPE_GENERIC = "General Research",\ ) -/// Amount of cash you can get from a maxcap +/// The maximum amount of cash you can get from toxins experiments. #define TECHWEB_BOMB_CASHCAP 50000 +/// The range required to generate any cash from toxins experiments. +#define TECHWEB_BOMB_MIN_RANGE (GLOB.MAX_EX_LIGHT_RANGE) +/// The range required to produce the maximum amount of cash from toxins experiments. +#define TECHWEB_BOMB_MAX_RANGE 300 +/// A constant used to scale the cash produced by toxins experiments. +#define TECHWEB_BOMB_SCALE_CONST 300000 +/// A constant used to scale the cash produced by toxins experiments. +#define TECHWEB_BOMB_SCALE_DIVISOR 1500 //! Amount of points gained per second by a single R&D server, see: [research][code/controllers/subsystem/research.dm] #define TECHWEB_SINGLE_SERVER_INCOME 52.3 diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm index 147e1ac21ae..fa251dad4b0 100644 --- a/code/game/machinery/doppler_array.dm +++ b/code/game/machinery/doppler_array.dm @@ -226,11 +226,11 @@ var/cash_gain = 0 /*****The Point Calculator*****/ - if(orig_light_range < 10) + if(orig_light_range < TECHWEB_BOMB_MIN_RANGE) say("Explosion not large enough for profitability.") return - else if(orig_light_range < 4500) - cash_gain = (83300 * orig_light_range) / (orig_light_range + 3000) + else if(orig_light_range < TECHWEB_BOMB_MAX_RANGE) + cash_gain = (TECHWEB_BOMB_SCALE_CONST * orig_light_range) / (TECHWEB_BOMB_SCALE_DIVISOR + orig_light_range) else cash_gain = TECHWEB_BOMB_CASHCAP @@ -240,7 +240,7 @@ var/old_tech_largest_bomb_value = linked_techweb.largest_bomb_value //held so we can pull old before we do math linked_techweb.largest_bomb_value = cash_gain cash_gain -= old_tech_largest_bomb_value - cash_gain = min(cash_gain,TECHWEB_BOMB_CASHCAP) + cash_gain = min(cash_gain, TECHWEB_BOMB_CASHCAP) else linked_techweb.largest_bomb_value = TECHWEB_BOMB_CASHCAP cash_gain = 1000 diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index 2d4e2ba7bf2..ac1345286a1 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -28,8 +28,8 @@ integrity_failure = 0.5 /// The gases this tank contains. Don't modify this directly, use return_air() to get it instead var/datum/gas_mixture/air_contents = null - /// The volume of this tank. - var/volume = 70 + /// The volume of this tank. Among other things gas tank explosions (including TTVs) scale off of this. Be sure to account for that if you change this or you will break ~~toxins~~ordinance. + var/volume = TANK_STANDARD_VOLUME /// Whether the tank is currently leaking. var/leaking = FALSE /// The pressure of the gases this tank supplies to internals. @@ -317,9 +317,10 @@ //Give the gas a chance to build up more pressure through reacting air_contents.react(src) pressure = air_contents.return_pressure() - var/range = (pressure-TANK_FRAGMENT_PRESSURE)/TANK_FRAGMENT_SCALE - 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)) + // As of writing this this is calibrated to maxcap at 140L and 160atm. + var/power = (air_contents.volume * (pressure - TANK_FRAGMENT_PRESSURE)) / TANK_FRAGMENT_SCALE + dyn_explosion(src, power, flash_range = 1.5, ignorecap = FALSE) return ..() /obj/item/tank/rad_act(strength) diff --git a/code/modules/projectiles/guns/special/blastcannon.dm b/code/modules/projectiles/guns/special/blastcannon.dm index 8f2d607e5be..70f00a06528 100644 --- a/code/modules/projectiles/guns/special/blastcannon.dm +++ b/code/modules/projectiles/guns/special/blastcannon.dm @@ -1,3 +1,13 @@ +/// How much to scale the light range of the explosion for blastcannon shots. +#define BLASTCANNON_LIGHT_RANGE_SCALE (1/20) +/// How much to scale the heavy range of the explosion for blastcannon shots. +#define BLASTCANNON_HEAVY_RANGE_SCALE (1/10) +/// How much to scale the devastation range of the explosion for blastcannon shots. +#define BLASTCANNON_DEV_RANGE_SCALE (1/5) +/// How much to scale the explosion ranges for blastcannon shots. +#define BLASTCANNON_RANGE_EXP (1 / GLOB.DYN_EX_SCALE) + + /** * A gun that consumes a TTV to shoot an projectile with equivalent power. * @@ -137,9 +147,9 @@ SIGNAL_HANDLER . = 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/heavy = (arguments[EXARG_KEY_DEV_RANGE]**BLASTCANNON_RANGE_EXP) * BLASTCANNON_DEV_RANGE_SCALE + var/medium = (arguments[EXARG_KEY_HEAVY_RANGE]**BLASTCANNON_RANGE_EXP) * BLASTCANNON_HEAVY_RANGE_SCALE + var/light = (arguments[EXARG_KEY_LIGHT_RANGE]**BLASTCANNON_RANGE_EXP) * BLASTCANNON_LIGHT_RANGE_SCALE var/range = max(heavy, medium, light, 0) if(!range) visible_message(span_warning("[src] lets out a little \"phut\".")) @@ -312,3 +322,8 @@ /obj/projectile/blastwave/ex_act() return FALSE + +#undef BLASTCANNON_LIGHT_RANGE_SCALE +#undef BLASTCANNON_HEAVY_RANGE_SCALE +#undef BLASTCANNON_DEV_RANGE_SCALE +#undef BLASTCANNON_RANGE_EXP