Files
Yogstation/code/modules/atmospherics/environmental/LINDA_fire.dm
monster860 bf810f49c2 C++ Monstermos - Putting the 99% LAG FREE in 99% LAG FREE (#7981)
* c++ monstermos

fuck

Fixes the server hemorrhaging memory due to extools not decrementing ref counts

Increases defauilt tank pressure

make space cold or some shit

floor tile rips

Fixes code assuming that the heat capacity is nonzero

🤦

Fixes crash

fixes some bugs

fuck *facepalm*

the fastening

removes Del() in favor of an internal c++ hook

Fixes vent-pump math

* Fix the invisible gases bug

* Linux support

* fix the deploy.sh

* Uses newer BYOND 513 because older one is probably missing an important pattern (it segfaulted on pattern search)

* Updates windows dll to match linux version and cleans up unused BYOND code
2020-04-24 10:29:51 -04:00

246 lines
8.1 KiB
Plaintext

/atom/proc/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return null
/turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0)
return
/turf/open/hotspot_expose(exposed_temperature, exposed_volume, soh)
if(!air)
return
var/oxy = air.get_moles(/datum/gas/oxygen)
if (oxy < 0.5)
return
var/tox = air.get_moles(/datum/gas/plasma)
var/trit = air.get_moles(/datum/gas/tritium)
if(active_hotspot)
if(soh)
if(tox > 0.5 || trit > 0.5)
if(active_hotspot.temperature < exposed_temperature)
active_hotspot.temperature = exposed_temperature
if(active_hotspot.volume < exposed_volume)
active_hotspot.volume = exposed_volume
return
if((exposed_temperature > PLASMA_MINIMUM_BURN_TEMPERATURE) && (tox > 0.5 || trit > 0.5))
active_hotspot = new /obj/effect/hotspot(src, exposed_volume*25, exposed_temperature)
active_hotspot.just_spawned = (current_cycle < SSair.times_fired)
//remove just_spawned protection if no longer processing this cell
SSair.add_to_active(src, 0)
//This is the icon for fire on turfs, also helps for nurturing small fires until they are full tile
/obj/effect/hotspot
anchored = TRUE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
icon = 'icons/effects/fire.dmi'
icon_state = "1"
layer = GASFIRE_LAYER
light_range = LIGHT_RANGE_FIRE
light_color = LIGHT_COLOR_FIRE
blend_mode = BLEND_ADD
var/volume = 125
var/temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST
var/just_spawned = TRUE
var/bypassing = FALSE
var/visual_update_tick = 0
/obj/effect/hotspot/Initialize(mapload, starting_volume, starting_temperature)
. = ..()
SSair.hotspots += src
if(!isnull(starting_volume))
volume = starting_volume
if(!isnull(starting_temperature))
temperature = starting_temperature
perform_exposure()
setDir(pick(GLOB.cardinals))
air_update_turf()
/obj/effect/hotspot/proc/perform_exposure()
var/turf/open/location = loc
if(!istype(location) || !(location.air))
return
location.active_hotspot = src
bypassing = !just_spawned && (volume > CELL_VOLUME*0.95)
if(bypassing)
volume = location.air.reaction_results["fire"]*FIRE_GROWTH_RATE
temperature = location.air.return_temperature()
else
var/datum/gas_mixture/affected = location.air.remove_ratio(volume/location.air.return_volume())
if(affected) //in case volume is 0
affected.set_temperature(temperature)
affected.react(src)
temperature = affected.return_temperature()
volume = affected.reaction_results["fire"]*FIRE_GROWTH_RATE
location.assume_air(affected)
for(var/A in location)
var/atom/AT = A
if(!QDELETED(AT) && AT != src) // It's possible that the item is deleted in temperature_expose
AT.fire_act(temperature, volume)
return
/obj/effect/hotspot/proc/gauss_lerp(x, x1, x2)
var/b = (x1 + x2) * 0.5
var/c = (x2 - x1) / 6
return NUM_E ** -((x - b) ** 2 / (2 * c) ** 2)
/obj/effect/hotspot/proc/update_color()
cut_overlays()
var/heat_r = heat2colour_r(temperature)
var/heat_g = heat2colour_g(temperature)
var/heat_b = heat2colour_b(temperature)
var/heat_a = 255
var/greyscale_fire = 1 //This determines how greyscaled the fire is.
if(temperature < 5000) //This is where fire is very orange, we turn it into the normal fire texture here.
var/normal_amt = gauss_lerp(temperature, 1000, 3000)
heat_r = LERP(heat_r,255,normal_amt)
heat_g = LERP(heat_g,255,normal_amt)
heat_b = LERP(heat_b,255,normal_amt)
heat_a -= gauss_lerp(temperature, -5000, 5000) * 128
greyscale_fire -= normal_amt
if(temperature > 40000) //Past this temperature the fire will gradually turn a bright purple
var/purple_amt = temperature < LERP(40000,200000,0.5) ? gauss_lerp(temperature, 40000, 200000) : 1
heat_r = LERP(heat_r,255,purple_amt)
if(temperature > 200000 && temperature < 500000) //Somewhere at this temperature nitryl happens.
var/sparkle_amt = gauss_lerp(temperature, 200000, 500000)
var/mutable_appearance/sparkle_overlay = mutable_appearance('icons/effects/effects.dmi', "shieldsparkles")
sparkle_overlay.blend_mode = BLEND_ADD
sparkle_overlay.alpha = sparkle_amt * 255
add_overlay(sparkle_overlay)
if(temperature > 400000 && temperature < 1500000) //Lightning because very anime.
var/mutable_appearance/lightning_overlay = mutable_appearance(icon, "overcharged")
lightning_overlay.blend_mode = BLEND_ADD
add_overlay(lightning_overlay)
if(temperature > 4500000) //This is where noblium happens. Some fusion-y effects.
var/fusion_amt = temperature < LERP(4500000,12000000,0.5) ? gauss_lerp(temperature, 4500000, 12000000) : 1
var/mutable_appearance/fusion_overlay = mutable_appearance('icons/effects/atmospherics.dmi', "fusion_gas")
fusion_overlay.blend_mode = BLEND_ADD
fusion_overlay.alpha = fusion_amt * 255
var/mutable_appearance/rainbow_overlay = mutable_appearance('icons/mob/screen_gen.dmi', "druggy")
rainbow_overlay.blend_mode = BLEND_ADD
rainbow_overlay.alpha = fusion_amt * 255
rainbow_overlay.appearance_flags = RESET_COLOR
heat_r = LERP(heat_r,150,fusion_amt)
heat_g = LERP(heat_g,150,fusion_amt)
heat_b = LERP(heat_b,150,fusion_amt)
add_overlay(fusion_overlay)
add_overlay(rainbow_overlay)
set_light(l_color = rgb(LERP(250,heat_r,greyscale_fire),LERP(160,heat_g,greyscale_fire),LERP(25,heat_b,greyscale_fire)))
heat_r /= 255
heat_g /= 255
heat_b /= 255
color = list(LERP(0.3, 1, 1-greyscale_fire) * heat_r,0.3 * heat_g * greyscale_fire,0.3 * heat_b * greyscale_fire, 0.59 * heat_r * greyscale_fire,LERP(0.59, 1, 1-greyscale_fire) * heat_g,0.59 * heat_b * greyscale_fire, 0.11 * heat_r * greyscale_fire,0.11 * heat_g * greyscale_fire,LERP(0.11, 1, 1-greyscale_fire) * heat_b, 0,0,0)
alpha = heat_a
#define INSUFFICIENT(path) (location.air.get_moles(path) < 0.5)
/obj/effect/hotspot/process()
if(just_spawned)
just_spawned = FALSE
return
var/turf/open/location = loc
if(!istype(location))
qdel(src)
return
location.eg_reset_cooldowns()
if((temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) || (volume <= 1))
qdel(src)
return
if(!location.air || (INSUFFICIENT(/datum/gas/plasma) && INSUFFICIENT(/datum/gas/tritium)) || INSUFFICIENT(/datum/gas/oxygen))
qdel(src)
return
//Not enough to burn
// god damn it previous coder you made the INSUFFICIENT macro for a fucking reason why didn't you use it here smh
if((INSUFFICIENT(/datum/gas/plasma) && INSUFFICIENT(/datum/gas/tritium)) || INSUFFICIENT(/datum/gas/oxygen))
qdel(src)
return
perform_exposure()
if(bypassing)
icon_state = "3"
location.burn_tile()
//Possible spread due to radiated heat
if(location.air.return_temperature() > FIRE_MINIMUM_TEMPERATURE_TO_SPREAD)
var/radiated_temperature = location.air.return_temperature()*FIRE_SPREAD_RADIOSITY_SCALE
for(var/t in location.atmos_adjacent_turfs)
var/turf/open/T = t
if(!T.active_hotspot)
T.hotspot_expose(radiated_temperature, CELL_VOLUME/4)
else
if(volume > CELL_VOLUME*0.4)
icon_state = "2"
else
icon_state = "1"
if((visual_update_tick++ % 7) == 0)
update_color()
if(temperature > location.max_fire_temperature_sustained)
location.max_fire_temperature_sustained = temperature
if(location.heat_capacity && temperature > location.heat_capacity)
location.to_be_destroyed = TRUE
return TRUE
/obj/effect/hotspot/Destroy()
set_light(0)
SSair.hotspots -= src
var/turf/open/T = loc
if(istype(T) && T.active_hotspot == src)
T.active_hotspot = null
DestroyTurf()
return ..()
/obj/effect/hotspot/proc/DestroyTurf()
if(isturf(loc))
var/turf/T = loc
if(T.to_be_destroyed && !T.changing_turf)
var/chance_of_deletion
if (T.heat_capacity) //beware of division by zero
chance_of_deletion = T.max_fire_temperature_sustained / T.heat_capacity * 8 //there is no problem with prob(23456), min() was redundant --rastaf0
else
chance_of_deletion = 100
if(prob(chance_of_deletion))
T.Melt()
else
T.to_be_destroyed = FALSE
T.max_fire_temperature_sustained = 0
/obj/effect/hotspot/Crossed(atom/movable/AM, oldLoc)
..()
if(isliving(AM))
var/mob/living/L = AM
L.fire_act(temperature, volume)
/obj/effect/hotspot/singularity_pull()
return
/obj/effect/dummy/lighting_obj/moblight/fire
name = "fire"
light_color = LIGHT_COLOR_FIRE
light_range = LIGHT_RANGE_FIRE
#undef INSUFFICIENT