mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-21 12:08:55 +01:00
[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:
co-authored by
TemporalOroboros
parent
c1f619559f
commit
e043a3a1f7
@@ -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
|
||||
|
||||
@@ -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()
|
||||
. = ..()
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user