[MIRROR] Desnowflakes tank integrity (#4286)

* Desnowflakes tank integrity (#56443)

Makes tanks use obj_integrity instead of their own snowflaked version.
Makes tanks check for exploding when they are destroyed, rather than once every process.
Makes tanks always leak their gases when they are deconstructed.
Removes the ability for tanks to seal themselves back up over time.
Makes the bomb spawner actually produce functional bombs.
Removes the extraneous syndicate bomb spawner subtype.
Miscellaneous code improvements to tanks, bomb spawners, and the blastcannon.
Fixes the explosives compressor doubling the power of any bomb you put in it.

The changes to tank rupturing behavior shouldn't effect most tritium fueled TTVs including the 50K recipe. Toxins players don't need to worry about suddenly being incapable of getting points or refining anomaly cores. They should only really effect singlecaps, but I don't know enough about singlecaps to know what recipes I should test. I have confirmation that at least one mix is not effected by this.

The self-sealing properties of tanks have been removed. I'm not sure what the purpose of it was, I have heard that it was used to enable hand-portable plasmaflooding, but I'm not familiar with the practice.

As it turns out, the basic bomb spawners were broken on master! I have made the bombs they produce maxcap instead of just spring a leak. Since they maxcap by default now I have removed the syndicate subtype used to spawn the TTV produced by the cuban pete arcade game and replaced it with the normal timer subtype. Since none of the bomb spawner subtypes were used for anything else this shouldn't have any effect on the game.

On a similar note, I have discovered that the maxcap recipe on the wiki stopped working at some point since it was written. I will replace it with a functioning set of instructions.

Less snowflake code.
Bomb spawners are actually functional now.
Slightly better code.
The explosives compressor accurately reflects the power of the bomb you put into it.

* Desnowflakes tank integrity

Co-authored-by: TemporalOroboros <TemporalOroboros@gmail.com>
This commit is contained in:
SkyratBot
2021-03-21 13:58:18 +00:00
committed by GitHub
co-authored by TemporalOroboros
parent c1f619559f
commit e043a3a1f7
6 changed files with 144 additions and 128 deletions
@@ -1,67 +1,57 @@
#define CELSIUS_TO_KELVIN(T_K) ((T_K) + T0C)
#define OPTIMAL_TEMP_K_PLA_BURN_SCALE(PRESSURE_P,PRESSURE_O,TEMP_O) (((PRESSURE_P) * GLOB.meta_gas_info[/datum/gas/plasma][META_GAS_SPECIFIC_HEAT]) / (((PRESSURE_P) * GLOB.meta_gas_info[/datum/gas/plasma][META_GAS_SPECIFIC_HEAT] + (PRESSURE_O) * GLOB.meta_gas_info[/datum/gas/oxygen][META_GAS_SPECIFIC_HEAT]) / PLASMA_UPPER_TEMPERATURE - (PRESSURE_O) * GLOB.meta_gas_info[/datum/gas/oxygen][META_GAS_SPECIFIC_HEAT] / CELSIUS_TO_KELVIN(TEMP_O)))
#define OPTIMAL_TEMP_K_PLA_BURN_RATIO(PRESSURE_P,PRESSURE_O,TEMP_O) (CELSIUS_TO_KELVIN(TEMP_O) * PLASMA_OXYGEN_FULLBURN * (PRESSURE_P) / (PRESSURE_O))
/**
* Spawns a TTV.
*
*/
/obj/effect/spawner/newbomb
name = "bomb"
icon = 'icons/hud/screen_gen.dmi'
icon_state = "x"
var/temp_p = 1500
var/temp_o = 1000 // tank temperatures
var/pressure_p = 10 * ONE_ATMOSPHERE
var/pressure_o = 10 * ONE_ATMOSPHERE //tank pressures
/// The initial temperature of the plasma tank.
var/temp_p = 1413
/// The initial temperature of the oxygen tank.
var/temp_o = 141.3
/// The initial pressure of the plasma tank.
var/pressure_p = TANK_LEAK_PRESSURE - 1
/// The initial pressure of the oxygen tank.
var/pressure_o = TANK_LEAK_PRESSURE - 1
/// The typepath of the assembly to attach to the TTV.
var/assembly_type
/obj/effect/spawner/newbomb/Initialize()
. = ..()
var/obj/item/transfer_valve/V = new(src.loc)
var/obj/item/tank/internals/plasma/PT = new(V)
var/obj/item/tank/internals/oxygen/OT = new(V)
var/obj/item/transfer_valve/ttv = new(loc)
var/obj/item/tank/internals/plasma/plasma_tank = new(ttv)
var/obj/item/tank/internals/oxygen/oxygen_tank = new(ttv)
PT.air_contents.assert_gas(/datum/gas/plasma)
PT.air_contents.gases[/datum/gas/plasma][MOLES] = pressure_p*PT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_p))
PT.air_contents.temperature = CELSIUS_TO_KELVIN(temp_p)
var/datum/gas_mixture/plasma_mix = plasma_tank.air_contents
plasma_mix.assert_gas(/datum/gas/plasma)
plasma_mix.gases[/datum/gas/plasma][MOLES] = pressure_p*plasma_mix.volume/(R_IDEAL_GAS_EQUATION*temp_p)
plasma_mix.temperature = temp_p
OT.air_contents.assert_gas(/datum/gas/oxygen)
OT.air_contents.gases[/datum/gas/oxygen][MOLES] = pressure_o*OT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_o))
OT.air_contents.temperature = CELSIUS_TO_KELVIN(temp_o)
var/datum/gas_mixture/oxygen_mix = oxygen_tank.air_contents
oxygen_mix.assert_gas(/datum/gas/oxygen)
oxygen_mix.gases[/datum/gas/oxygen][MOLES] = pressure_o*oxygen_mix.volume/(R_IDEAL_GAS_EQUATION*temp_o)
oxygen_mix.temperature = temp_o
V.tank_one = PT
V.tank_two = OT
PT.master = V
OT.master = V
ttv.tank_one = plasma_tank
ttv.tank_two = oxygen_tank
plasma_tank.master = ttv
oxygen_tank.master = ttv
if(assembly_type)
var/obj/item/assembly/A = new assembly_type(V)
V.attached_device = A
A.holder = V
var/obj/item/assembly/detonator = new assembly_type(ttv)
ttv.attached_device = detonator
detonator.holder = ttv
V.update_appearance()
ttv.update_appearance()
return INITIALIZE_HINT_QDEL
/obj/effect/spawner/newbomb/timer/syndicate/Initialize()
temp_p = (OPTIMAL_TEMP_K_PLA_BURN_SCALE(pressure_p, pressure_o, temp_o)/2 + OPTIMAL_TEMP_K_PLA_BURN_RATIO(pressure_p, pressure_o, temp_o)/2) - T0C
. = ..()
/obj/effect/spawner/newbomb/timer
assembly_type = /obj/item/assembly/timer
/obj/effect/spawner/newbomb/timer/syndicate
pressure_o = TANK_LEAK_PRESSURE - 1
temp_o = 20
pressure_p = TANK_LEAK_PRESSURE - 1
/obj/effect/spawner/newbomb/proximity
assembly_type = /obj/item/assembly/prox_sensor
/obj/effect/spawner/newbomb/radio
assembly_type = /obj/item/assembly/signaler
#undef CELSIUS_TO_KELVIN
#undef OPTIMAL_TEMP_K_PLA_BURN_SCALE
#undef OPTIMAL_TEMP_K_PLA_BURN_RATIO
+1 -1
View File
@@ -232,7 +232,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
/obj/item/blob_act(obj/structure/blob/B)
if(B && B.loc == loc)
qdel(src)
obj_destruction(MELEE)
/obj/item/ComponentInitialize()
. = ..()
+96 -68
View File
@@ -1,3 +1,12 @@
/// How much time (in seconds) is assumed to pass while assuming air. Used to scale overpressure/overtemp damage when assuming air.
#define ASSUME_AIR_DT_FACTOR 1
/**
* # Gas Tank
*
* Handheld gas canisters
* Can rupture explosively if overpressurized
*/
/obj/item/tank
name = "tank"
icon = 'icons/obj/tank.dmi'
@@ -16,10 +25,15 @@
custom_materials = list(/datum/material/iron = 500)
actions_types = list(/datum/action/item_action/set_internals)
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 80, ACID = 30)
integrity_failure = 0.5
/// The gases this tank contains.
var/datum/gas_mixture/air_contents = null
var/distribute_pressure = ONE_ATMOSPHERE
var/integrity = 3
/// The volume of this tank.
var/volume = 70
/// Whether the tank is currently leaking.
var/leaking = FALSE
/// The pressure of the gases this tank supplies to internals.
var/distribute_pressure = ONE_ATMOSPHERE
/// Icon state when in a tank holder. Null makes it incompatible with tank holder.
var/tank_holder_icon_state = "holder_generic"
@@ -74,7 +88,7 @@
QDEL_NULL(air_contents)
STOP_PROCESSING(SSobj, src)
. = ..()
return ..()
/obj/item/tank/ComponentInitialize()
. = ..()
@@ -111,25 +125,13 @@
. += "<span class='notice'>It feels [descriptive].</span>"
/obj/item/tank/blob_act(obj/structure/blob/B)
if(B && B.loc == loc)
var/turf/location = get_turf(src)
if(!location)
qdel(src)
if(air_contents)
location.assume_air(air_contents)
qdel(src)
/obj/item/tank/deconstruct(disassembled = TRUE)
if(!disassembled)
var/turf/T = get_turf(src)
if(T)
T.assume_air(air_contents)
air_update_turf(FALSE, FALSE)
playsound(src.loc, 'sound/effects/spray.ogg', 10, TRUE, -3)
qdel(src)
var/turf/location = get_turf(src)
if(location)
location.assume_air(air_contents)
location.air_update_turf(FALSE, FALSE)
playsound(location, 'sound/effects/spray.ogg', 10, TRUE, -3)
return ..()
/obj/item/tank/suicide_act(mob/user)
var/mob/living/carbon/human/H = user
@@ -146,9 +148,9 @@
/obj/item/tank/attackby(obj/item/W, mob/user, params)
add_fingerprint(user)
if(istype(W, /obj/item/assembly_holder))
bomb_assemble(W,user)
else
. = ..()
bomb_assemble(W, user)
return TRUE
return ..()
/obj/item/tank/ui_state(mob/user)
return GLOB.hands_state
@@ -213,10 +215,15 @@
/obj/item/tank/assume_air(datum/gas_mixture/giver)
air_contents.merge(giver)
handle_tolerances(ASSUME_AIR_DT_FACTOR)
return TRUE
check_status()
return 1
/**
* Removes some volume of the tanks gases as the tanks distribution pressure.
*
* Arguments:
* - volume_to_return: The amount of volume to remove from the tank.
*/
/obj/item/tank/proc/remove_air_volume(volume_to_return)
if(!air_contents)
return null
@@ -235,59 +242,78 @@
return remove_air(moles_needed)
/obj/item/tank/process()
//Allow for reactions
air_contents.react()
check_status()
/obj/item/tank/proc/check_status()
//Handle exploding, leaking, and rupturing of the tank
/obj/item/tank/process(delta_time)
if(!air_contents)
return 0
return
//Allow for reactions
air_contents.react(src)
handle_tolerances(delta_time)
if(QDELETED(src) || !leaking || !air_contents)
return
var/turf/location = get_turf(src)
if(!location)
return
var/datum/gas_mixture/leaked_gas = air_contents.remove_ratio(0.25)
location.assume_air(leaked_gas)
location.air_update_turf(FALSE, FALSE)
/**
* Handles the minimum and maximum pressure tolerances of the tank.
*
* Arguments:
* - delta_time: How long has passed between ticks.
*/
/obj/item/tank/proc/handle_tolerances(delta_time)
if(!air_contents)
return FALSE
var/pressure = air_contents.return_pressure()
var/temperature = air_contents.return_temperature()
if(temperature >= TANK_MELT_TEMPERATURE)
var/temperature_damage_ratio = (temperature - TANK_MELT_TEMPERATURE) / temperature
take_damage(max_integrity * temperature_damage_ratio * delta_time, BURN, FIRE, FALSE, NONE)
if(QDELETED(src))
return TRUE
if(pressure >= TANK_LEAK_PRESSURE)
var/pressure_damage_ratio = (pressure - TANK_LEAK_PRESSURE) / (TANK_RUPTURE_PRESSURE - TANK_LEAK_PRESSURE)
take_damage(max_integrity * pressure_damage_ratio * delta_time, BRUTE, BOMB, FALSE, NONE)
return TRUE
/// Handles the tank springing a leak.
/obj/item/tank/obj_break(damage_flag)
. = ..()
if(leaking)
return
leaking = TRUE
if(obj_integrity < 0) // So we don't play the alerts while we are exploding or rupturing.
return
visible_message("<span class='warning'>[src] springs a leak!</span>")
playsound(src, 'sound/effects/spray.ogg', 10, TRUE, -3)
/// Handles rupturing and fragmenting
/obj/item/tank/obj_destruction(damage_flag)
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)
if(!istype(src.loc, /obj/item/transfer_valve))
if(!istype(loc, /obj/item/transfer_valve))
log_bomber(get_mob_by_key(fingerprintslast), "was last key to touch", src, "which ruptured explosively")
//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
var/turf/epicenter = get_turf(loc)
explosion(epicenter, round(range*0.25), round(range*0.5), round(range), round(range*1.5))
if(istype(src.loc, /obj/item/transfer_valve))
qdel(src.loc)
else
qdel(src)
else if(pressure > TANK_RUPTURE_PRESSURE || temperature > TANK_MELT_TEMPERATURE)
if(integrity <= 0)
var/turf/T = get_turf(src)
if(!T)
return
T.assume_air(air_contents)
playsound(src.loc, 'sound/effects/spray.ogg', 10, TRUE, -3)
qdel(src)
else
integrity--
else if(pressure > TANK_LEAK_PRESSURE)
if(integrity <= 0)
var/turf/T = get_turf(src)
if(!T)
return
var/datum/gas_mixture/leaked_gas = air_contents.remove_ratio(0.25)
T.assume_air(leaked_gas)
else
integrity--
else if(integrity < 3)
integrity++
explosion(location, round(range*0.25), round(range*0.5), round(range), round(range*1.5))
return ..()
/obj/item/tank/rad_act(strength)
. = ..()
@@ -312,3 +338,5 @@
if(gas_change)
air_contents.garbage_collect()
#undef ASSUME_AIR_DT_FACTOR