From 0b11295c8ef808a229da910b02ed85599d80c61b Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sun, 7 Sep 2014 01:19:16 -0400 Subject: [PATCH] Supermatter balance Attempts to rebalance SM to work with new atmos machinery. Testing with a 2-freezer 2-canister default setup, the engine can run to 500 kW at 700 K. --- code/modules/supermatter/supermatter.dm | 51 +++++++++++-------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/code/modules/supermatter/supermatter.dm b/code/modules/supermatter/supermatter.dm index 2af7a67868..b71b8b5af6 100644 --- a/code/modules/supermatter/supermatter.dm +++ b/code/modules/supermatter/supermatter.dm @@ -16,10 +16,11 @@ */ //Controls how much power is produced by each collector in range - this is the main parameter for tweaking SM balance, as it basically controls how the power variable relates to the rest of the game. -#define POWER_FACTOR 0.5 //Obtained from testing. Aiming to make the ideal running output (600 kW) run the SM to ~85% of the safety level. -#define CRITICAL_TEMPERATURE 800 //K -#define CHARGING_FACTOR 0.11 -#define DAMAGE_RATE_LIMIT 5 //damage rate cap at power = 900, scales linearly with power +#define POWER_FACTOR 0.7 //Obtained from testing. Aiming to make the ideal running output (500 kW) run the SM to ~85% of the safety level. +#define DECAY_FACTOR 700 //Affects how fast the supermatter power decays +#define CRITICAL_TEMPERATURE 800 //K +#define CHARGING_FACTOR 0.05 +#define DAMAGE_RATE_LIMIT 5 //damage rate cap at power = 300, scales linearly with power //These would be what you would get at point blank, decreases with distance @@ -172,8 +173,8 @@ var/datum/gas_mixture/env = null //ensure that damage doesn't increase too quickly due to super high temperatures resulting from no coolant, for example. We dont want the SM exploding before anyone can react. - //We want the cap to scale linearly with power (and explosion_point). Let's aim for a cap of 5 at power = 900 (based on testing, equals roughly 5% per SM alert announcement). - var/damage_inc_limit = (power/900)*(explosion_point/1000)*DAMAGE_RATE_LIMIT + //We want the cap to scale linearly with power (and explosion_point). Let's aim for a cap of 5 at power = 300 (based on testing, equals roughly 5% per SM alert announcement). + var/damage_inc_limit = (power/300)*(explosion_point/1000)*DAMAGE_RATE_LIMIT if(!istype(L, /turf/space)) env = L.return_air() @@ -193,17 +194,17 @@ //calculate power gain for oxygen reaction var/temp_factor + var/equilibrium_power if (oxygen > 0.8) //If chain reacting at oxygen == 1, we want the power at 800 K to stabilize at a level of 1200*POWER_FACTOR - var/equilibrium_power = 1200*POWER_FACTOR - temp_factor = ( (equilibrium_power/500)**3 )/800 + equilibrium_power = 400 icon_state = "[base_icon_state]_glow" else - //If chain reacting at oxygen == 0.8, we want the power at 700 K to stabilize at a power level of 300 - var/equilibrium_power = 860*POWER_FACTOR - temp_factor = ( (equilibrium_power/500)**3 )/(700*0.8) + //If chain reacting at oxygen == 0.8, we want the power at 800 K to stabilize at a power level of 250 + equilibrium_power = 250 icon_state = base_icon_state + temp_factor = ( (equilibrium_power/DECAY_FACTOR)**3 )/(800*0.8) power = max( (removed.temperature * temp_factor) * oxygen + power, 0) //We've generated power, now let's transfer it to the collectors for storing/usage @@ -211,21 +212,12 @@ var/device_energy = power * REACTION_POWER_MODIFIER - //To figure out how much temperature to add each tick, consider that at one atmosphere's worth - //of pure oxygen, with all four lasers firing at standard energy and no N2 present, at room temperature - //that the device energy is around 2140. At that stage, we don't want too much heat to be put out - //Since the core is effectively "cold" - - //Also keep in mind we are only adding this temperature to (efficiency)% of the one tile the rock - //is on. An increase of 4*C @ 25% efficiency here results in an increase of 1*C / (#tilesincore) overall. - - var/thermal_power = THERMAL_RELEASE_MODIFIER * device_energy - //Release reaction gasses var/heat_capacity = removed.heat_capacity() removed.adjust_multi("phoron", max(device_energy / PHORON_RELEASE_MODIFIER, 0), \ "oxygen", max((device_energy + removed.temperature - T0C) / OXYGEN_RELEASE_MODIFIER, 0)) + var/thermal_power = THERMAL_RELEASE_MODIFIER * device_energy if (debug) var/heat_capacity_new = removed.heat_capacity() visible_message("[src]: Releasing [round(thermal_power)] W.") @@ -236,17 +228,16 @@ env.merge(removed) - for(var/mob/living/carbon/human/l in view(src, min(7, round(power ** 0.25)))) // If they can see it without mesons on. Bad on them. + for(var/mob/living/carbon/human/l in view(src, min(7, round(sqrt(power/6))))) // If they can see it without mesons on. Bad on them. if(!istype(l.glasses, /obj/item/clothing/glasses/meson)) l.hallucination = max(0, min(200, l.hallucination + power * config_hallucination_power * sqrt( 1 / max(1,get_dist(l, src)) ) ) ) - //adjusted range so that a power of 600 (pretty high) results in 8 tiles, roughly the distance from the core to the engine monitoring room. - //at power of 1210 this becomes 9 tiles --> increases very very slowly. - for(var/mob/living/l in range(src, round((power / 0.146484375) ** 0.25))) + //adjusted range so that a power of 300 (pretty high) results in 8 tiles, roughly the distance from the core to the engine monitoring room. + for(var/mob/living/l in range(src, round(sqrt(power / 5)))) var/rads = (power / 10) * sqrt( 1 / get_dist(l, src) ) l.apply_effect(rads, IRRADIATE) - power -= (power/500)**3 //energy losses due to radiation + power -= (power/DECAY_FACTOR)**3 //energy losses due to radiation return 1 @@ -259,7 +250,7 @@ if(istype(Proj, /obj/item/projectile/beam)) - power += Proj.damage * config_bullet_energy * CHARGING_FACTOR + power += Proj.damage * config_bullet_energy * CHARGING_FACTOR / POWER_FACTOR else damage += Proj.damage * config_bullet_energy return 0 @@ -288,8 +279,10 @@ /obj/machinery/power/supermatter/proc/transfer_energy() for(var/obj/machinery/power/rad_collector/R in rad_collectors) - if(get_dist(R, src) <= 15) // Better than using orange() every process - R.receive_pulse(power * POWER_FACTOR) //for collectors using standard phoron tanks at 1013 kPa, the actual power generated will be this power*POWER_FACTOR*20*29 = power*POWER_FACTOR*580 + var/distance = get_dist(R, src) + if(distance <= 15) + //for collectors using standard phoron tanks at 1013 kPa, the actual power generated will be this power*POWER_FACTOR*20*29 = power*POWER_FACTOR*580 + R.receive_pulse(power * POWER_FACTOR * (min(3/distance, 1))**2) return /obj/machinery/power/supermatter/attackby(obj/item/weapon/W as obj, mob/living/user as mob)