add: Fusion is back add: Fusion now happens with large quantities of hot plasma and CO2, consuming all the plasma rapidly and producing large amounts of energy. Other gases can also effect the performance of the reaction. add: Fusion now produces radiation. Be careful around reactors. fix: fixes fusion dividing by zero and destroying everything code: Gas reactions now have access to where they are occurring fix: Prevents some other reactions from producing matter from nothing
252 lines
7.6 KiB
Plaintext
252 lines
7.6 KiB
Plaintext
/datum/pipeline
|
|
var/datum/gas_mixture/air
|
|
var/list/datum/gas_mixture/other_airs
|
|
|
|
var/list/obj/machinery/atmospherics/pipe/members
|
|
var/list/obj/machinery/atmospherics/components/other_atmosmch
|
|
|
|
var/update = TRUE
|
|
|
|
/datum/pipeline/New()
|
|
other_airs = list()
|
|
members = list()
|
|
other_atmosmch = list()
|
|
SSair.networks += src
|
|
|
|
/datum/pipeline/Destroy()
|
|
SSair.networks -= src
|
|
if(air && air.volume)
|
|
temporarily_store_air()
|
|
for(var/obj/machinery/atmospherics/pipe/P in members)
|
|
P.parent = null
|
|
for(var/obj/machinery/atmospherics/components/C in other_atmosmch)
|
|
C.nullifyPipenet(src)
|
|
return ..()
|
|
|
|
/datum/pipeline/process()
|
|
if(update)
|
|
update = FALSE
|
|
reconcile_air()
|
|
update = air.react(src)
|
|
|
|
/datum/pipeline/proc/build_pipeline(obj/machinery/atmospherics/base)
|
|
var/volume = 0
|
|
if(istype(base, /obj/machinery/atmospherics/pipe))
|
|
var/obj/machinery/atmospherics/pipe/E = base
|
|
volume = E.volume
|
|
members += E
|
|
if(E.air_temporary)
|
|
air = E.air_temporary
|
|
E.air_temporary = null
|
|
else
|
|
addMachineryMember(base)
|
|
if(!air)
|
|
air = new
|
|
var/list/possible_expansions = list(base)
|
|
while(possible_expansions.len>0)
|
|
for(var/obj/machinery/atmospherics/borderline in possible_expansions)
|
|
|
|
var/list/result = borderline.pipeline_expansion(src)
|
|
|
|
if(result.len>0)
|
|
for(var/obj/machinery/atmospherics/P in result)
|
|
if(istype(P, /obj/machinery/atmospherics/pipe))
|
|
var/obj/machinery/atmospherics/pipe/item = P
|
|
if(!members.Find(item))
|
|
|
|
if(item.parent)
|
|
var/static/pipenetwarnings = 10
|
|
if(pipenetwarnings > 0)
|
|
warning("build_pipeline(): [item.type] added to a pipenet while still having one. (pipes leading to the same spot stacking in one turf) Nearby: ([item.x], [item.y], [item.z])")
|
|
pipenetwarnings -= 1
|
|
if(pipenetwarnings == 0)
|
|
warning("build_pipeline(): further messages about pipenets will be supressed")
|
|
members += item
|
|
possible_expansions += item
|
|
|
|
volume += item.volume
|
|
item.parent = src
|
|
|
|
if(item.air_temporary)
|
|
air.merge(item.air_temporary)
|
|
item.air_temporary = null
|
|
else
|
|
P.setPipenet(src, borderline)
|
|
addMachineryMember(P)
|
|
|
|
possible_expansions -= borderline
|
|
|
|
air.volume = volume
|
|
|
|
/datum/pipeline/proc/addMachineryMember(obj/machinery/atmospherics/components/C)
|
|
other_atmosmch |= C
|
|
var/datum/gas_mixture/G = C.returnPipenetAir(src)
|
|
if(!G)
|
|
stack_trace("addMachineryMember: Null gasmix added to pipeline datum from [C] which is of type [C.type]. Nearby: ([C.x], [C.y], [C.z])")
|
|
other_airs |= G
|
|
|
|
/datum/pipeline/proc/addMember(obj/machinery/atmospherics/A, obj/machinery/atmospherics/N)
|
|
if(istype(A, /obj/machinery/atmospherics/pipe))
|
|
var/obj/machinery/atmospherics/pipe/P = A
|
|
if(P.parent)
|
|
merge(P.parent)
|
|
P.parent = src
|
|
var/list/adjacent = P.pipeline_expansion()
|
|
for(var/obj/machinery/atmospherics/pipe/I in adjacent)
|
|
if(I.parent == src)
|
|
continue
|
|
var/datum/pipeline/E = I.parent
|
|
merge(E)
|
|
if(!members.Find(P))
|
|
members += P
|
|
air.volume += P.volume
|
|
else
|
|
A.setPipenet(src, N)
|
|
addMachineryMember(A)
|
|
|
|
/datum/pipeline/proc/merge(datum/pipeline/E)
|
|
if(E == src)
|
|
return
|
|
air.volume += E.air.volume
|
|
members.Add(E.members)
|
|
for(var/obj/machinery/atmospherics/pipe/S in E.members)
|
|
S.parent = src
|
|
air.merge(E.air)
|
|
for(var/obj/machinery/atmospherics/components/C in E.other_atmosmch)
|
|
C.replacePipenet(E, src)
|
|
other_atmosmch.Add(E.other_atmosmch)
|
|
other_airs.Add(E.other_airs)
|
|
E.members.Cut()
|
|
E.other_atmosmch.Cut()
|
|
update = TRUE
|
|
qdel(E)
|
|
|
|
/obj/machinery/atmospherics/proc/addMember(obj/machinery/atmospherics/A)
|
|
return
|
|
|
|
/obj/machinery/atmospherics/pipe/addMember(obj/machinery/atmospherics/A)
|
|
parent.addMember(A, src)
|
|
|
|
/obj/machinery/atmospherics/components/addMember(obj/machinery/atmospherics/A)
|
|
var/datum/pipeline/P = returnPipenet(A)
|
|
P.addMember(A, src)
|
|
|
|
|
|
/datum/pipeline/proc/temporarily_store_air()
|
|
//Update individual gas_mixtures by volume ratio
|
|
|
|
for(var/obj/machinery/atmospherics/pipe/member in members)
|
|
member.air_temporary = new
|
|
member.air_temporary.volume = member.volume
|
|
member.air_temporary.copy_from(air)
|
|
var/member_gases = member.air_temporary.gases
|
|
|
|
for(var/id in member_gases)
|
|
member_gases[id][MOLES] *= member.volume/air.volume
|
|
|
|
member.air_temporary.temperature = air.temperature
|
|
|
|
/datum/pipeline/proc/temperature_interact(turf/target, share_volume, thermal_conductivity)
|
|
var/total_heat_capacity = air.heat_capacity()
|
|
var/partial_heat_capacity = total_heat_capacity*(share_volume/air.volume)
|
|
var/target_temperature
|
|
var/target_heat_capacity
|
|
|
|
if(isopenturf(target))
|
|
|
|
var/turf/open/modeled_location = target
|
|
target_temperature = modeled_location.GetTemperature()
|
|
target_heat_capacity = modeled_location.GetHeatCapacity()
|
|
|
|
if(modeled_location.blocks_air)
|
|
|
|
if((modeled_location.heat_capacity>0) && (partial_heat_capacity>0))
|
|
var/delta_temperature = air.temperature - target_temperature
|
|
|
|
var/heat = thermal_conductivity*delta_temperature* \
|
|
(partial_heat_capacity*target_heat_capacity/(partial_heat_capacity+target_heat_capacity))
|
|
|
|
air.temperature -= heat/total_heat_capacity
|
|
modeled_location.TakeTemperature(heat/target_heat_capacity)
|
|
|
|
else
|
|
var/delta_temperature = 0
|
|
var/sharer_heat_capacity = 0
|
|
|
|
delta_temperature = (air.temperature - target_temperature)
|
|
sharer_heat_capacity = target_heat_capacity
|
|
|
|
var/self_temperature_delta = 0
|
|
var/sharer_temperature_delta = 0
|
|
|
|
if((sharer_heat_capacity>0) && (partial_heat_capacity>0))
|
|
var/heat = thermal_conductivity*delta_temperature* \
|
|
(partial_heat_capacity*sharer_heat_capacity/(partial_heat_capacity+sharer_heat_capacity))
|
|
|
|
self_temperature_delta = -heat/total_heat_capacity
|
|
sharer_temperature_delta = heat/sharer_heat_capacity
|
|
else
|
|
return 1
|
|
|
|
air.temperature += self_temperature_delta
|
|
modeled_location.TakeTemperature(sharer_temperature_delta)
|
|
|
|
|
|
else
|
|
if((target.heat_capacity>0) && (partial_heat_capacity>0))
|
|
var/delta_temperature = air.temperature - target.temperature
|
|
|
|
var/heat = thermal_conductivity*delta_temperature* \
|
|
(partial_heat_capacity*target.heat_capacity/(partial_heat_capacity+target.heat_capacity))
|
|
|
|
air.temperature -= heat/total_heat_capacity
|
|
update = TRUE
|
|
|
|
/datum/pipeline/proc/return_air()
|
|
. = other_airs + air
|
|
if(null in .)
|
|
stack_trace("[src] has one or more null gas mixtures, which may cause bugs. Null mixtures will not be considered in reconcile_air().")
|
|
return removeNullsFromList(.)
|
|
|
|
/datum/pipeline/proc/reconcile_air()
|
|
var/list/datum/gas_mixture/GL = list()
|
|
var/list/datum/pipeline/PL = list()
|
|
PL += src
|
|
|
|
for(var/i = 1; i <= PL.len; i++) //can't do a for-each here because we may add to the list within the loop
|
|
var/datum/pipeline/P = PL[i]
|
|
if(!P)
|
|
continue
|
|
GL += P.return_air()
|
|
for(var/obj/machinery/atmospherics/components/binary/valve/V in P.other_atmosmch)
|
|
if(V.open)
|
|
PL |= V.parents[1]
|
|
PL |= V.parents[2]
|
|
for(var/obj/machinery/atmospherics/components/unary/portables_connector/C in P.other_atmosmch)
|
|
if(C.connected_device)
|
|
GL += C.portableConnectorReturnAir()
|
|
|
|
var/total_thermal_energy = 0
|
|
var/total_heat_capacity = 0
|
|
var/datum/gas_mixture/total_gas_mixture = new(0)
|
|
|
|
for(var/i in GL)
|
|
var/datum/gas_mixture/G = i
|
|
total_gas_mixture.volume += G.volume
|
|
|
|
total_gas_mixture.merge(G)
|
|
|
|
total_thermal_energy += THERMAL_ENERGY(G)
|
|
total_heat_capacity += G.heat_capacity()
|
|
|
|
total_gas_mixture.temperature = total_heat_capacity ? total_thermal_energy/total_heat_capacity : 0
|
|
|
|
if(total_gas_mixture.volume > 0)
|
|
//Update individual gas_mixtures by volume ratio
|
|
for(var/i in GL)
|
|
var/datum/gas_mixture/G = i
|
|
G.copy_from(total_gas_mixture)
|
|
var/list/G_gases = G.gases
|
|
for(var/id in G_gases)
|
|
G_gases[id][MOLES] *= G.volume/total_gas_mixture.volume
|