mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
Removes old unticked code
This commit is contained in:
@@ -1,81 +0,0 @@
|
||||
#define RADIATION_CAPACITY 30000 //Radiation isn't particularly effective (TODO BALANCE)
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/unary/thermal_plate
|
||||
//Based off Heat Reservoir and Space Heater
|
||||
//Transfers heat between a pipe system and environment, based on which has a greater thermal energy concentration
|
||||
|
||||
icon = 'icons/obj/atmospherics/cold_sink.dmi'
|
||||
icon_state = "intact_off"
|
||||
|
||||
name = "Thermal Transfer Plate"
|
||||
desc = "Transfers heat to and from an area"
|
||||
|
||||
update_icon()
|
||||
if(node)
|
||||
icon_state = "intact_off"
|
||||
else
|
||||
icon_state = "exposed"
|
||||
return
|
||||
|
||||
process()
|
||||
..()
|
||||
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
|
||||
//Get processable air sample and thermal info from environment
|
||||
|
||||
var/transfer_moles = 0.25 * environment.total_moles()
|
||||
var/datum/gas_mixture/external_removed = environment.remove(transfer_moles)
|
||||
|
||||
if (!external_removed)
|
||||
return radiate()
|
||||
|
||||
if (external_removed.total_moles() < 10)
|
||||
return radiate()
|
||||
|
||||
//Get same info from connected gas
|
||||
|
||||
var/internal_transfer_moles = 0.25 * air_contents.total_moles()
|
||||
var/datum/gas_mixture/internal_removed = air_contents.remove(internal_transfer_moles)
|
||||
|
||||
if (!internal_removed)
|
||||
environment.merge(external_removed)
|
||||
return 1
|
||||
|
||||
var/combined_heat_capacity = internal_removed.heat_capacity() + external_removed.heat_capacity()
|
||||
var/combined_energy = internal_removed.temperature * internal_removed.heat_capacity() + external_removed.heat_capacity() * external_removed.temperature
|
||||
|
||||
if(!combined_heat_capacity) combined_heat_capacity = 1
|
||||
var/final_temperature = combined_energy / combined_heat_capacity
|
||||
|
||||
external_removed.temperature = final_temperature
|
||||
environment.merge(external_removed)
|
||||
|
||||
internal_removed.temperature = final_temperature
|
||||
air_contents.merge(internal_removed)
|
||||
|
||||
network.update = 1
|
||||
|
||||
return 1
|
||||
|
||||
proc/radiate()
|
||||
|
||||
var/internal_transfer_moles = 0.25 * air_contents.total_moles()
|
||||
var/datum/gas_mixture/internal_removed = air_contents.remove(internal_transfer_moles)
|
||||
|
||||
if (!internal_removed)
|
||||
return 1
|
||||
|
||||
var/combined_heat_capacity = internal_removed.heat_capacity() + RADIATION_CAPACITY
|
||||
var/combined_energy = internal_removed.temperature * internal_removed.heat_capacity() + (RADIATION_CAPACITY * 6.4)
|
||||
|
||||
var/final_temperature = combined_energy / combined_heat_capacity
|
||||
|
||||
internal_removed.temperature = final_temperature
|
||||
air_contents.merge(internal_removed)
|
||||
|
||||
if (network)
|
||||
network.update = 1
|
||||
|
||||
return 1
|
||||
@@ -1,645 +0,0 @@
|
||||
#define DEBUG
|
||||
|
||||
datum/air_group/var/marker
|
||||
datum/air_group/var/debugging = 0
|
||||
datum/pipe_network/var/marker
|
||||
|
||||
datum/gas_mixture
|
||||
var/turf/parent
|
||||
|
||||
/*
|
||||
turf/simulated
|
||||
New()
|
||||
..()
|
||||
|
||||
if(air)
|
||||
air.parent = src
|
||||
*/
|
||||
obj/machinery/door
|
||||
verb
|
||||
toggle_door()
|
||||
set src in world
|
||||
if(density)
|
||||
open()
|
||||
else
|
||||
close()
|
||||
|
||||
turf/space
|
||||
verb
|
||||
create_floor()
|
||||
set src in world
|
||||
new /turf/simulated/floor(src)
|
||||
|
||||
create_meteor(direction as num)
|
||||
set src in world
|
||||
|
||||
var/obj/effect/meteor/M = new( src )
|
||||
walk(M, direction,10)
|
||||
|
||||
|
||||
turf/simulated/wall
|
||||
verb
|
||||
create_floor()
|
||||
set src in world
|
||||
new /turf/simulated/floor(src)
|
||||
|
||||
obj/item/weapon/tank
|
||||
verb
|
||||
adjust_mixture(temperature as num, target_toxin_pressure as num, target_oxygen_pressure as num)
|
||||
set src in world
|
||||
if(!air_contents)
|
||||
usr << "<span class='warning'>ERROR: no gas_mixture associated with this tank</span>"
|
||||
return null
|
||||
|
||||
air_contents.temperature = temperature
|
||||
air_contents.oxygen = target_oxygen_pressure*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)
|
||||
air_contents.toxins = target_toxin_pressure*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature)
|
||||
|
||||
turf/simulated/floor
|
||||
verb
|
||||
parent_info()
|
||||
set src in world
|
||||
if(parent)
|
||||
usr << "<B>[x],[y] parent:</B> Processing: [parent.group_processing]"
|
||||
if(parent.members)
|
||||
usr << "Members: [parent.members.len]"
|
||||
else
|
||||
usr << "Members: None?"
|
||||
if(parent.borders)
|
||||
usr << "Borders: [parent.borders.len]"
|
||||
else
|
||||
usr << "Borders: None"
|
||||
if(parent.length_space_border)
|
||||
usr << "Space Borders: [parent.space_borders.len], Space Length: [parent.length_space_border]"
|
||||
else
|
||||
usr << "Space Borders: None"
|
||||
else
|
||||
usr << "<span class='notice'>[x],[y] has no parent air group.</span>"
|
||||
|
||||
verb
|
||||
create_wall()
|
||||
set src in world
|
||||
new /turf/simulated/wall(src)
|
||||
verb
|
||||
adjust_mixture(temp as num, tox as num, oxy as num)
|
||||
set src in world
|
||||
var/datum/gas_mixture/stuff = return_air()
|
||||
stuff.temperature = temp
|
||||
stuff.toxins = tox
|
||||
stuff.oxygen = oxy
|
||||
|
||||
verb
|
||||
boom(inner_range as num, middle_range as num, outer_range as num)
|
||||
set src in world
|
||||
explosion(src,inner_range,middle_range,outer_range,outer_range)
|
||||
|
||||
verb
|
||||
flag_parent()
|
||||
set src in world
|
||||
if(parent)
|
||||
parent.debugging = !parent.debugging
|
||||
usr << "[parent.members.len] set to [parent.debugging]"
|
||||
verb
|
||||
small_explosion()
|
||||
set src in world
|
||||
explosion(src, 1, 2, 3, 3)
|
||||
|
||||
verb
|
||||
large_explosion()
|
||||
set src in world
|
||||
explosion(src, 3, 5, 7, 5)
|
||||
|
||||
obj/machinery/portable_atmospherics/canister
|
||||
verb/test_release()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
valve_open = 1
|
||||
release_pressure = 1000
|
||||
/*
|
||||
obj/machinery/atmospherics
|
||||
unary
|
||||
heat_reservoir
|
||||
verb
|
||||
toggle_power()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
on = !on
|
||||
|
||||
update_icon()
|
||||
adjust_temp(temp as num)
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
current_temperature = temp
|
||||
cold_sink
|
||||
verb
|
||||
toggle_power()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
on = !on
|
||||
|
||||
update_icon()
|
||||
adjust_temp(temp as num)
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
current_temperature = temp
|
||||
vent_pump
|
||||
verb
|
||||
toggle_power()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
on = !on
|
||||
|
||||
update_icon()
|
||||
|
||||
toggle_direction()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
pump_direction = !pump_direction
|
||||
|
||||
update_icon()
|
||||
|
||||
change_pressure_parameters()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
usr << "current settings: PC=[pressure_checks], EB=[external_pressure_bound], IB=[internal_pressure_bound]"
|
||||
|
||||
var/mode = input(usr, "Select an option:") in list("Bound External", "Bound Internal", "Bound Both")
|
||||
|
||||
switch(mode)
|
||||
if("Bound External")
|
||||
pressure_checks = 1
|
||||
external_pressure_bound = input(usr, "External Pressure Bound?") as num
|
||||
if("Bound Internal")
|
||||
pressure_checks = 2
|
||||
internal_pressure_bound = input(usr, "Internal Pressure Bound?") as num
|
||||
else
|
||||
pressure_checks = 3
|
||||
external_pressure_bound = input(usr, "External Pressure Bound?") as num
|
||||
internal_pressure_bound = input(usr, "Internal Pressure Bound?") as num
|
||||
|
||||
outlet_injector
|
||||
verb
|
||||
toggle_power()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
on = !on
|
||||
|
||||
update_icon()
|
||||
verb
|
||||
trigger_inject()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
inject()
|
||||
|
||||
vent_scrubber
|
||||
verb
|
||||
toggle_power()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
on = !on
|
||||
|
||||
update_icon()
|
||||
|
||||
toggle_scrubbing()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
scrubbing = !scrubbing
|
||||
|
||||
update_icon()
|
||||
|
||||
change_rate(amount as num)
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
volume_rate = amount
|
||||
|
||||
mixer
|
||||
verb
|
||||
toggle()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
on = !on
|
||||
|
||||
update_icon()
|
||||
|
||||
change_pressure(amount as num)
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
target_pressure = amount
|
||||
|
||||
change_ratios()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
if(node_in1)
|
||||
var/node_ratio = input(usr, "Node 1 Ratio? ([dir2text(get_dir(src, node_in1))])") as num
|
||||
node_ratio = min(max(0,node_ratio),1)
|
||||
|
||||
node1_concentration = node_ratio
|
||||
node2_concentration = 1-node_ratio
|
||||
else
|
||||
node2_concentration = 1
|
||||
node1_concentration = 0
|
||||
|
||||
usr << "Node 1: [node1_concentration], Node 2: [node2_concentration]"
|
||||
|
||||
|
||||
filter
|
||||
verb
|
||||
toggle()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
on = !on
|
||||
|
||||
update_icon()
|
||||
|
||||
change_pressure(amount as num)
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
target_pressure = amount
|
||||
|
||||
unary/oxygen_generator
|
||||
verb
|
||||
toggle()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
on = !on
|
||||
|
||||
update_icon()
|
||||
|
||||
change_rate(amount as num)
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
oxygen_content = amount
|
||||
binary/pump
|
||||
verb
|
||||
debug()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
world << "Debugging: [x],[y]"
|
||||
|
||||
if(node1)
|
||||
world << "Input node: [node1.x],[node1.y] [network1]"
|
||||
if(node2)
|
||||
world << "Output node: [node2.x],[node2.y] [network2]"
|
||||
|
||||
toggle()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
on = !on
|
||||
|
||||
update_icon()
|
||||
change_pressure(amount as num)
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
target_pressure = amount
|
||||
|
||||
valve
|
||||
verb
|
||||
toggle()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
if(open)
|
||||
close()
|
||||
else
|
||||
open()
|
||||
network_data()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
world << "<span class='notice'>[x],[y]</span>"
|
||||
world << "network 1: [network_node1.normal_members.len], [network_node1.line_members.len]"
|
||||
for(var/obj/O in network_node1.normal_members)
|
||||
world << "member: [O.x], [O.y]"
|
||||
world << "network 2: [network_node2.normal_members.len], [network_node2.line_members.len]"
|
||||
for(var/obj/O in network_node2.normal_members)
|
||||
world << "member: [O.x], [O.y]"
|
||||
pipe
|
||||
verb
|
||||
destroy()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
qdel(src)
|
||||
|
||||
pipeline_data()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
if(parent)
|
||||
usr << "[x],[y] is in a pipeline with [parent.members.len] members ([parent.edges.len] edges)! Volume: [parent.air.volume]"
|
||||
usr << "Pressure: [parent.air.return_pressure()], Temperature: [parent.air.temperature]"
|
||||
usr << "[parent.air.oxygen], [parent.air.toxins], [parent.air.nitrogen], [parent.air.carbon_dioxide] .. [parent.alert_pressure]"
|
||||
*/
|
||||
mob
|
||||
verb
|
||||
flag_all_pipe_networks()
|
||||
set category = "Debug"
|
||||
|
||||
for(var/datum/pipe_network/network in pipe_networks)
|
||||
network.update = 1
|
||||
|
||||
mark_pipe_networks()
|
||||
set category = "Debug"
|
||||
|
||||
for(var/datum/pipe_network/network in pipe_networks)
|
||||
network.marker = rand(1,4)
|
||||
|
||||
for(var/obj/machinery/atmospherics/pipe/P in world)
|
||||
P.overlays.Cut()
|
||||
|
||||
var/datum/pipe_network/master = P.return_network()
|
||||
if(master)
|
||||
P.overlays += icon('icons/Testing/atmos_testing.dmi',"marker[master.marker]")
|
||||
else
|
||||
world << "error"
|
||||
P.overlays += icon('icons/Testing/atmos_testing.dmi',"marker0")
|
||||
|
||||
for(var/obj/machinery/atmospherics/valve/V in world)
|
||||
V.overlays.Cut()
|
||||
|
||||
if(V.network_node1)
|
||||
V.overlays += icon('icons/Testing/atmos_testing.dmi',"marker[V.network_node1.marker]")
|
||||
else
|
||||
V.overlays += icon('icons/Testing/atmos_testing.dmi',"marker0")
|
||||
|
||||
if(V.network_node2)
|
||||
V.overlays += icon('icons/Testing/atmos_testing.dmi',"marker[V.network_node2.marker]")
|
||||
else
|
||||
V.overlays += icon('icons/Testing/atmos_testing.dmi',"marker0")
|
||||
|
||||
turf/simulated
|
||||
var/fire_verbose = 0
|
||||
|
||||
verb
|
||||
mark_direction()
|
||||
set src in world
|
||||
overlays.Cut()
|
||||
for(var/direction in list(NORTH,SOUTH,EAST,WEST))
|
||||
if(group_border&direction)
|
||||
overlays += icon('icons/Testing/turf_analysis.dmi',"red_arrow",direction)
|
||||
else if(air_check_directions&direction)
|
||||
overlays += icon('icons/Testing/turf_analysis.dmi',"arrow",direction)
|
||||
air_status()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
var/datum/gas_mixture/GM = return_air()
|
||||
usr << "<span class='notice'>@[x],[y] ([GM.group_multiplier]): O:[GM.oxygen] T:[GM.toxins] N:[GM.nitrogen] C:[GM.carbon_dioxide] w [GM.temperature] Kelvin, [GM.return_pressure()] kPa [(active_hotspot)?("<span class='danger'>BURNING</span>"):(null)]</span>""
|
||||
for(var/datum/gas/trace_gas in GM.trace_gases)
|
||||
usr << "[trace_gas.type]: [trace_gas.moles]"
|
||||
|
||||
force_temperature(temp as num)
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
if(parent&&parent.group_processing)
|
||||
parent.suspend_group_processing()
|
||||
|
||||
air.temperature = temp
|
||||
|
||||
spark_temperature(temp as num, volume as num)
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
hotspot_expose(temp, volume)
|
||||
|
||||
fire_verbose()
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
fire_verbose = !fire_verbose
|
||||
usr << "[x],[y] now [fire_verbose]"
|
||||
|
||||
add_sleeping_agent(amount as num)
|
||||
set src in world
|
||||
set category = "Minor"
|
||||
|
||||
if(amount>1)
|
||||
var/datum/gas_mixture/adding = new
|
||||
var/datum/gas/sleeping_agent/trace_gas = new
|
||||
|
||||
trace_gas.moles = amount
|
||||
adding.trace_gases += trace_gas
|
||||
adding.temperature = T20C
|
||||
|
||||
assume_air(adding)
|
||||
|
||||
obj/indicator
|
||||
icon = 'icons/Testing/air_meter.dmi'
|
||||
var/measure = "temperature"
|
||||
anchored = 1
|
||||
|
||||
process()
|
||||
icon_state = measurement()
|
||||
|
||||
proc/measurement()
|
||||
var/turf/T = loc
|
||||
if(!isturf(T)) return
|
||||
var/datum/gas_mixture/GM = T.return_air()
|
||||
switch(measure)
|
||||
if("temperature")
|
||||
if(GM.temperature < 0)
|
||||
return "error"
|
||||
return "[round(GM.temperature/100+0.5)]"
|
||||
if("oxygen")
|
||||
if(GM.oxygen < 0)
|
||||
return "error"
|
||||
return "[round(GM.oxygen/MOLES_CELLSTANDARD*10+0.5)]"
|
||||
if("plasma")
|
||||
if(GM.toxins < 0)
|
||||
return "error"
|
||||
return "[round(GM.toxins/MOLES_CELLSTANDARD*10+0.5)]"
|
||||
if("nitrogen")
|
||||
if(GM.nitrogen < 0)
|
||||
return "error"
|
||||
return "[round(GM.nitrogen/MOLES_CELLSTANDARD*10+0.5)]"
|
||||
else
|
||||
return "[round((GM.total_moles())/MOLES_CELLSTANDARD*10+0.5)]"
|
||||
|
||||
|
||||
Click()
|
||||
process()
|
||||
|
||||
|
||||
obj/window
|
||||
verb
|
||||
destroy()
|
||||
set category = "Minor"
|
||||
set src in world
|
||||
qdel(src)
|
||||
|
||||
mob
|
||||
sight = SEE_OBJS|SEE_TURFS
|
||||
|
||||
verb
|
||||
update_indicators()
|
||||
set category = "Debug"
|
||||
if(!air_master)
|
||||
usr << "Cannot find air_system"
|
||||
return
|
||||
|
||||
for(var/obj/indicator/T in world)
|
||||
T.process()
|
||||
change_indicators()
|
||||
set category = "Debug"
|
||||
if(!air_master)
|
||||
usr << "Cannot find air_system"
|
||||
return
|
||||
|
||||
var/str = input("Select") in list("oxygen", "nitrogen","plasma","all","temperature")
|
||||
|
||||
for(var/obj/indicator/T in world)
|
||||
T.measure = str
|
||||
T.process()
|
||||
|
||||
fire_report()
|
||||
set category = "Debug"
|
||||
usr << "<span class='danger'>Fire Report</span>"
|
||||
for(var/obj/effect/hotspot/flame in world)
|
||||
usr << "[flame.x],[flame.y]: [flame.temperature]K, [flame.volume] L - [flame.loc:air:temperature]"
|
||||
|
||||
process_cycle()
|
||||
set category = "Debug"
|
||||
if(!master_controller)
|
||||
usr << "Cannot find master_controller"
|
||||
return
|
||||
|
||||
master_controller.process()
|
||||
update_indicators()
|
||||
|
||||
process_cycles(amount as num)
|
||||
set category = "Debug"
|
||||
if(!master_controller)
|
||||
usr << "Cannot find master_controller"
|
||||
return
|
||||
|
||||
var/start_time = world.timeofday
|
||||
|
||||
for(var/i=1; i<=amount; i++)
|
||||
master_controller.process()
|
||||
|
||||
world << "Ended [amount] cycles in [(world.timeofday-start_time)/10] seconds. [(world.timeofday-start_time)/10-amount] calculation lag"
|
||||
|
||||
update_indicators()
|
||||
|
||||
process_updates_early()
|
||||
set category = "Debug"
|
||||
if(!air_master)
|
||||
usr << "Cannot find air_system"
|
||||
return
|
||||
|
||||
air_master.process_update_tiles()
|
||||
air_master.process_rebuild_select_groups()
|
||||
|
||||
mark_group_delay()
|
||||
set category = "Debug"
|
||||
if(!air_master)
|
||||
usr << "Cannot find air_system"
|
||||
return
|
||||
|
||||
for(var/datum/air_group/group in air_master.air_groups)
|
||||
group.marker = 0
|
||||
|
||||
for(var/turf/simulated/floor/S in world)
|
||||
S.icon = 'icons/Testing/turf_analysis.dmi'
|
||||
if(S.parent)
|
||||
if(S.parent.group_processing)
|
||||
if (S.parent.check_delay < 2)
|
||||
S.parent.marker=1
|
||||
else if (S.parent.check_delay < 5)
|
||||
S.parent.marker=2
|
||||
else if (S.parent.check_delay < 15)
|
||||
S.parent.marker=3
|
||||
else if (S.parent.check_delay < 30)
|
||||
S.parent.marker=4
|
||||
else
|
||||
S.parent.marker=5
|
||||
if(S.parent.borders && S.parent.borders.Find(S))
|
||||
S.icon_state = "on[S.parent.marker]_border"
|
||||
else
|
||||
S.icon_state = "on[S.parent.marker]"
|
||||
|
||||
else
|
||||
if (S.check_delay < 2)
|
||||
S.icon_state= "on1_border"
|
||||
else if (S.check_delay < 5)
|
||||
S.icon_state= "on2_border"
|
||||
else if (S.check_delay < 15)
|
||||
S.icon_state= "on3_border"
|
||||
else if (S.check_delay < 30)
|
||||
S.icon_state= "on4_border"
|
||||
else
|
||||
S.icon_state = "suspended"
|
||||
else
|
||||
if(S.processing)
|
||||
S.icon_state = "individual_on"
|
||||
else
|
||||
S.icon_state = "individual_off"
|
||||
|
||||
|
||||
mark_groups()
|
||||
set category = "Debug"
|
||||
if(!air_master)
|
||||
usr << "Cannot find air_system"
|
||||
return
|
||||
|
||||
for(var/datum/air_group/group in air_master.air_groups)
|
||||
group.marker = 0
|
||||
|
||||
for(var/turf/simulated/floor/S in world)
|
||||
S.icon = 'icons/Testing/turf_analysis.dmi'
|
||||
if(S.parent)
|
||||
if(S.parent.group_processing)
|
||||
if(S.parent.marker == 0)
|
||||
S.parent.marker = rand(1,5)
|
||||
if(S.parent.borders && S.parent.borders.Find(S))
|
||||
S.icon_state = "on[S.parent.marker]_border"
|
||||
else
|
||||
S.icon_state = "on[S.parent.marker]"
|
||||
|
||||
else
|
||||
S.icon_state = "suspended"
|
||||
else
|
||||
if(S.processing)
|
||||
S.icon_state = "individual_on"
|
||||
else
|
||||
S.icon_state = "individual_off"
|
||||
|
||||
get_broken_icons()
|
||||
set category = "Debug"
|
||||
getbrokeninhands()
|
||||
|
||||
|
||||
/* jump_to_dead_group() Currently in the normal admin commands but fits here
|
||||
set category = "Debug"
|
||||
if(!air_master)
|
||||
usr << "Cannot find air_system"
|
||||
return
|
||||
|
||||
var/datum/air_group/dead_groups = list()
|
||||
for(var/datum/air_group/group in air_master.air_groups)
|
||||
if (!group.group_processing)
|
||||
dead_groups += group
|
||||
var/datum/air_group/dest_group = pick(dead_groups)
|
||||
usr.loc = pick(dest_group.members)*/
|
||||
@@ -1,286 +0,0 @@
|
||||
datum/air_group
|
||||
var/group_processing = 1 //Processing all tiles as one large tile if 1
|
||||
|
||||
var/datum/gas_mixture/air = new
|
||||
|
||||
var/current_cycle = 0 //cycle that oxygen value represents
|
||||
var/archived_cycle = 0 //cycle that oxygen_archived value represents
|
||||
//The use of archived cycle saves processing power by permitting the archiving step of FET
|
||||
// to be rolled into the updating step
|
||||
|
||||
//optimization vars
|
||||
var/next_check = 0 //number of ticks before this group updates
|
||||
var/check_delay = 10 //number of ticks between updates, starts fairly high to get boring groups out of the way
|
||||
|
||||
proc/members()
|
||||
//Returns the members of the group
|
||||
proc/process_group()
|
||||
|
||||
|
||||
var/list/borders //Tiles that connect this group to other groups/individual tiles
|
||||
var/list/members //All tiles in this group
|
||||
|
||||
var/list/space_borders
|
||||
var/length_space_border = 0
|
||||
|
||||
|
||||
proc/suspend_group_processing()
|
||||
group_processing = 0
|
||||
update_tiles_from_group()
|
||||
check_delay=0
|
||||
next_check=0
|
||||
|
||||
|
||||
//Copy group air information to individual tile air
|
||||
//Used right before turning on group processing
|
||||
proc/update_group_from_tiles()
|
||||
var/sample_member = pick(members)
|
||||
var/datum/gas_mixture/sample_air = sample_member:air
|
||||
|
||||
air.copy_from(sample_air)
|
||||
air.group_multiplier = members.len
|
||||
return 1
|
||||
|
||||
|
||||
//Copy group air information to individual tile air
|
||||
//Used right before turning off group processing
|
||||
proc/update_tiles_from_group()
|
||||
for(var/member in members)
|
||||
member:air.copy_from(air)
|
||||
if (istype(member,/turf/simulated))
|
||||
var/turf/simulated/turfmem=member
|
||||
turfmem.reset_delay()
|
||||
|
||||
|
||||
proc/archive()
|
||||
air.archive()
|
||||
archived_cycle = air_master.current_cycle
|
||||
|
||||
|
||||
//If individually processing tiles, checks all member tiles to see if they are close enough that the group may resume group processing
|
||||
//Warning: Do not call, called by air_master.process()
|
||||
proc/check_regroup()
|
||||
//Purpose: Checks to see if group processing should be turned back on
|
||||
//Returns: group_processing
|
||||
if(prevent_airgroup_regroup)
|
||||
return 0
|
||||
|
||||
if(group_processing) return 1
|
||||
|
||||
var/turf/simulated/sample = pick(members)
|
||||
for(var/member in members)
|
||||
if(member:active_hotspot)
|
||||
return 0
|
||||
if(member:air.compare(sample.air)) continue
|
||||
else
|
||||
return 0
|
||||
|
||||
update_group_from_tiles()
|
||||
group_processing = 1
|
||||
return 1
|
||||
|
||||
|
||||
//Look into this
|
||||
turf/process_group()
|
||||
current_cycle = air_master.current_cycle
|
||||
if(!group_processing) //Revert to individual processing then end
|
||||
for(var/T in members)
|
||||
var/turf/simulated/member = T
|
||||
member.process_cell()
|
||||
return
|
||||
|
||||
//check if we're skipping this tick
|
||||
if (next_check > 0)
|
||||
next_check--
|
||||
return 1
|
||||
var/player_count = max(player_list.len, 3) / 3
|
||||
next_check += check_delay + rand(player_count, player_count * 1.5)
|
||||
check_delay++
|
||||
|
||||
var/turf/simulated/list/border_individual = list()
|
||||
var/datum/air_group/list/border_group = list()
|
||||
|
||||
var/turf/simulated/list/enemies = list() //used to send the appropriate border tile of a group to the group proc
|
||||
var/turf/simulated/list/self_group_borders = list()
|
||||
var/turf/simulated/list/self_tile_borders = list()
|
||||
|
||||
if(archived_cycle < air_master.current_cycle)
|
||||
archive()
|
||||
//Archive air data for use in calculations
|
||||
//But only if another group didn't store it for us
|
||||
|
||||
for(var/turf/simulated/border_tile in src.borders)
|
||||
for(var/direction in cardinal) //Go through all border tiles and get bordering groups and individuals
|
||||
if(border_tile.group_border&direction)
|
||||
var/turf/simulated/enemy_tile = get_step(border_tile, direction) //Add found tile to appropriate category
|
||||
if(istype(enemy_tile) && enemy_tile.parent && enemy_tile.parent.group_processing)
|
||||
border_group += enemy_tile.parent
|
||||
enemies += enemy_tile
|
||||
self_group_borders += border_tile
|
||||
else
|
||||
border_individual += enemy_tile
|
||||
self_tile_borders += border_tile
|
||||
|
||||
var/abort_group = 0
|
||||
|
||||
// Process connections to adjacent groups
|
||||
var/border_index = 1
|
||||
for(var/datum/air_group/AG in border_group)
|
||||
if(AG.archived_cycle < archived_cycle) //archive other groups information if it has not been archived yet this cycle
|
||||
AG.archive()
|
||||
if(AG.current_cycle < current_cycle)
|
||||
//This if statement makes sure two groups only process their individual connections once!
|
||||
//Without it, each connection would be processed a second time as the second group is evaluated
|
||||
|
||||
var/connection_difference = 0
|
||||
var/turf/simulated/floor/self_border = self_group_borders[border_index]
|
||||
var/turf/simulated/floor/enemy_border = enemies[border_index]
|
||||
|
||||
var/result = air.check_gas_mixture(AG.air)
|
||||
if(result == 1)
|
||||
connection_difference = air.share(AG.air)
|
||||
else if(result == -1)
|
||||
AG.suspend_group_processing()
|
||||
connection_difference = air.share(enemy_border.air)
|
||||
else
|
||||
abort_group = 1
|
||||
break
|
||||
|
||||
if(connection_difference)
|
||||
if(connection_difference > 0)
|
||||
self_border.consider_pressure_difference(connection_difference, get_dir(self_border,enemy_border))
|
||||
else
|
||||
var/turf/enemy_turf = enemy_border
|
||||
if(!isturf(enemy_turf))
|
||||
enemy_turf = enemy_border.loc
|
||||
enemy_turf.consider_pressure_difference(-connection_difference, get_dir(enemy_turf,self_border))
|
||||
|
||||
border_index++
|
||||
|
||||
// Process connections to adjacent tiles
|
||||
border_index = 1
|
||||
if(!abort_group)
|
||||
for(var/atom/enemy_tile in border_individual)
|
||||
var/connection_difference = 0
|
||||
var/turf/simulated/floor/self_border = self_tile_borders[border_index]
|
||||
|
||||
if(istype(enemy_tile, /turf/simulated))
|
||||
if(enemy_tile:archived_cycle < archived_cycle) //archive tile information if not already done
|
||||
enemy_tile:archive()
|
||||
if(enemy_tile:current_cycle < current_cycle)
|
||||
if(air.check_gas_mixture(enemy_tile:air))
|
||||
connection_difference = air.share(enemy_tile:air)
|
||||
else
|
||||
abort_group = 1
|
||||
break
|
||||
else if(isturf(enemy_tile))
|
||||
if(air.check_turf(enemy_tile))
|
||||
connection_difference = air.mimic(enemy_tile)
|
||||
else
|
||||
abort_group = 1
|
||||
break
|
||||
|
||||
if(connection_difference)
|
||||
if(connection_difference > 0)
|
||||
self_border.consider_pressure_difference(connection_difference, get_dir(self_border,enemy_tile))
|
||||
else
|
||||
var/turf/enemy_turf = enemy_tile
|
||||
if(!isturf(enemy_turf))
|
||||
enemy_turf = enemy_tile.loc
|
||||
enemy_turf.consider_pressure_difference(-connection_difference, get_dir(enemy_tile,enemy_turf))
|
||||
|
||||
// Process connections to space
|
||||
border_index = 1
|
||||
if(!abort_group)
|
||||
if(length_space_border > 0)
|
||||
var/turf/space/sample = locate()
|
||||
var/connection_difference = 0
|
||||
|
||||
if(air.check_turf(sample))
|
||||
connection_difference = air.mimic(sample, length_space_border)
|
||||
else
|
||||
abort_group = 1
|
||||
|
||||
if(connection_difference)
|
||||
for(var/turf/simulated/self_border in space_borders)
|
||||
self_border.consider_pressure_difference_space(connection_difference)
|
||||
|
||||
if(abort_group)
|
||||
suspend_group_processing()
|
||||
else
|
||||
if(air.check_tile_graphic())
|
||||
for(var/T in members)
|
||||
var/turf/simulated/member = T
|
||||
member.update_visuals(air)
|
||||
|
||||
|
||||
if(air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
|
||||
for(var/T in members)
|
||||
var/turf/simulated/member = T
|
||||
member.hotspot_expose(air.temperature, CELL_VOLUME)
|
||||
member.consider_superconductivity(starting=1)
|
||||
|
||||
air.react()
|
||||
return
|
||||
|
||||
|
||||
|
||||
object/process_group()
|
||||
current_cycle = air_master.current_cycle
|
||||
|
||||
if(!group_processing) return //See if processing this group as a group
|
||||
|
||||
var/turf/simulated/list/border_individual = list()
|
||||
var/datum/air_group/list/border_group = list()
|
||||
|
||||
var/turf/simulated/list/enemies = list() //used to send the appropriate border tile of a group to the group proc
|
||||
var/enemy_index = 1
|
||||
|
||||
if(archived_cycle < air_master.current_cycle)
|
||||
archive()
|
||||
//Archive air data for use in calculations
|
||||
//But only if another group didn't store it for us
|
||||
|
||||
enemy_index = 1
|
||||
var/abort_group = 0
|
||||
for(var/datum/air_group/AG in border_group)
|
||||
if(AG.archived_cycle < archived_cycle) //archive other groups information if it has not been archived yet this cycle
|
||||
AG.archive()
|
||||
if(AG.current_cycle < current_cycle)
|
||||
//This if statement makes sure two groups only process their individual connections once!
|
||||
//Without it, each connection would be processed a second time as the second group is evaluated
|
||||
|
||||
var/result = air.check_gas_mixture(AG.air)
|
||||
if(result == 1)
|
||||
air.share(AG.air)
|
||||
else if(result == -1)
|
||||
AG.suspend_group_processing()
|
||||
var/turf/simulated/floor/enemy_border = enemies[enemy_index]
|
||||
air.share(enemy_border.air)
|
||||
else
|
||||
abort_group = 0
|
||||
break
|
||||
enemy_index++
|
||||
|
||||
if(!abort_group)
|
||||
for(var/enemy_tile in border_individual)
|
||||
if(istype(enemy_tile, /turf/simulated))
|
||||
if(enemy_tile:archived_cycle < archived_cycle) //archive tile information if not already done
|
||||
enemy_tile:archive()
|
||||
if(enemy_tile:current_cycle < current_cycle)
|
||||
if(air.check_gas_mixture(enemy_tile:air))
|
||||
air.share(enemy_tile:air)
|
||||
else
|
||||
abort_group = 1
|
||||
break
|
||||
else
|
||||
if(air.check_turf(enemy_tile))
|
||||
air.mimic(enemy_tile)
|
||||
else
|
||||
abort_group = 1
|
||||
break
|
||||
|
||||
if(abort_group)
|
||||
suspend_group_processing()
|
||||
|
||||
return
|
||||
@@ -1,178 +0,0 @@
|
||||
|
||||
/atom/proc/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
return null
|
||||
|
||||
|
||||
|
||||
/turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0)
|
||||
|
||||
|
||||
|
||||
/turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh)
|
||||
var/datum/gas_mixture/air_contents = return_air()
|
||||
if(!air_contents)
|
||||
return 0
|
||||
if(active_hotspot)
|
||||
if(soh)
|
||||
if(air_contents.toxins > 0.5 && air_contents.oxygen > 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 1
|
||||
|
||||
var/igniting = 0
|
||||
|
||||
if((exposed_temperature > PLASMA_MINIMUM_BURN_TEMPERATURE) && air_contents.toxins > 0.5)
|
||||
igniting = 1
|
||||
|
||||
if(igniting)
|
||||
if(air_contents.oxygen < 0.5 || air_contents.toxins < 0.5)
|
||||
return 0
|
||||
|
||||
if(parent&&parent.group_processing)
|
||||
parent.suspend_group_processing()
|
||||
|
||||
active_hotspot = new(src)
|
||||
active_hotspot.temperature = exposed_temperature
|
||||
active_hotspot.volume = exposed_volume
|
||||
|
||||
active_hotspot.just_spawned = (current_cycle < air_master.current_cycle)
|
||||
//remove just_spawned protection if no longer processing this cell
|
||||
|
||||
//start processing quickly if we aren't already
|
||||
reset_delay()
|
||||
|
||||
return igniting
|
||||
|
||||
//This is the icon for fire on turfs, also helps for nurturing small fires until they are full tile
|
||||
/obj/effect/hotspot
|
||||
anchored = 1
|
||||
mouse_opacity = 0
|
||||
unacidable = 1//So you can't melt fire with acid.
|
||||
icon = 'icons/effects/fire.dmi'
|
||||
icon_state = "1"
|
||||
layer = TURF_LAYER
|
||||
luminosity = 3
|
||||
|
||||
var/volume = 125
|
||||
var/temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST
|
||||
var/just_spawned = 1
|
||||
var/bypassing = 0
|
||||
|
||||
|
||||
/obj/effect/hotspot/proc/perform_exposure()
|
||||
var/turf/simulated/floor/location = loc
|
||||
if(!istype(location)) return 0
|
||||
|
||||
if(volume > CELL_VOLUME*0.95) bypassing = 1
|
||||
else bypassing = 0
|
||||
|
||||
if(bypassing)
|
||||
if(!just_spawned)
|
||||
volume = location.air.fuel_burnt*FIRE_GROWTH_RATE
|
||||
temperature = location.air.temperature
|
||||
else
|
||||
var/datum/gas_mixture/affected = location.air.remove_ratio(volume/location.air.volume)
|
||||
affected.temperature = temperature
|
||||
affected.react()
|
||||
temperature = affected.temperature
|
||||
volume = affected.fuel_burnt*FIRE_GROWTH_RATE
|
||||
location.assume_air(affected)
|
||||
|
||||
for(var/atom/item in loc)
|
||||
if(!bypassing)
|
||||
item.temperature_expose(null, temperature, volume)
|
||||
if(item) // It's possible that the item is deleted in temperature_expose
|
||||
item.fire_act(null, temperature, volume)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
/obj/effect/hotspot/process(turf/simulated/list/possible_spread)
|
||||
if(just_spawned)
|
||||
just_spawned = 0
|
||||
return 0
|
||||
|
||||
var/turf/simulated/floor/location = loc
|
||||
if(!istype(location))
|
||||
Kill()
|
||||
return
|
||||
|
||||
if((temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) || (volume <= 1))
|
||||
Kill()
|
||||
return
|
||||
|
||||
if(location.air.toxins < 0.5 || location.air.oxygen < 0.5)
|
||||
Kill()
|
||||
return
|
||||
|
||||
perform_exposure()
|
||||
|
||||
if(location.wet) location.wet = 0
|
||||
|
||||
if(bypassing)
|
||||
icon_state = "3"
|
||||
location.burn_tile()
|
||||
|
||||
//Possible spread due to radiated heat
|
||||
if(location.air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_SPREAD)
|
||||
var/radiated_temperature = location.air.temperature*FIRE_SPREAD_RADIOSITY_SCALE
|
||||
|
||||
for(var/turf/simulated/possible_target in possible_spread)
|
||||
if(!possible_target.active_hotspot)
|
||||
possible_target.hotspot_expose(radiated_temperature, CELL_VOLUME/4)
|
||||
|
||||
else
|
||||
if(volume > CELL_VOLUME*0.4)
|
||||
icon_state = "2"
|
||||
else
|
||||
icon_state = "1"
|
||||
|
||||
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 = 1
|
||||
/*if(prob(25))
|
||||
location.ReplaceWithSpace()
|
||||
return 0*/
|
||||
return 1
|
||||
|
||||
// Garbage collect itself by nulling reference to it
|
||||
|
||||
/obj/effect/hotspot/proc/Kill()
|
||||
DestroyTurf()
|
||||
if(istype(loc, /turf/simulated))
|
||||
var/turf/simulated/T = loc
|
||||
if(T.active_hotspot == src)
|
||||
T.active_hotspot = null
|
||||
loc = null
|
||||
|
||||
/obj/effect/hotspot/proc/DestroyTurf()
|
||||
|
||||
if(istype(loc, /turf/simulated))
|
||||
var/turf/simulated/T = loc
|
||||
if(T.to_be_destroyed)
|
||||
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.ChangeTurf(/turf/space)
|
||||
else
|
||||
T.to_be_destroyed = 0
|
||||
T.max_fire_temperature_sustained = 0
|
||||
|
||||
/obj/effect/hotspot/New()
|
||||
..()
|
||||
set_dir(pick(cardinal))
|
||||
return
|
||||
|
||||
/*
|
||||
/obj/effect/hotspot/Destroy()
|
||||
if (istype(loc, /turf/simulated))
|
||||
DestroyTurf()
|
||||
..()
|
||||
*/
|
||||
@@ -1,933 +0,0 @@
|
||||
/*
|
||||
What are the archived variables for?
|
||||
Calculations are done using the archived variables with the results merged into the regular variables.
|
||||
This prevents race conditions that arise based on the order of tile processing.
|
||||
*/
|
||||
|
||||
#define SPECIFIC_HEAT_TOXIN 200
|
||||
#define SPECIFIC_HEAT_AIR 20
|
||||
#define SPECIFIC_HEAT_CDO 30
|
||||
#define HEAT_CAPACITY_CALCULATION(oxygen,carbon_dioxide,nitrogen,toxins) \
|
||||
(carbon_dioxide*SPECIFIC_HEAT_CDO + (oxygen+nitrogen)*SPECIFIC_HEAT_AIR + toxins*SPECIFIC_HEAT_TOXIN)
|
||||
|
||||
#define MINIMUM_HEAT_CAPACITY 0.0003
|
||||
#define QUANTIZE(variable) (round(variable,0.0001))
|
||||
|
||||
/datum/gas
|
||||
sleeping_agent
|
||||
specific_heat = 40
|
||||
|
||||
oxygen_agent_b
|
||||
specific_heat = 300
|
||||
|
||||
volatile_fuel
|
||||
specific_heat = 30
|
||||
|
||||
var/moles = 0
|
||||
var/specific_heat = 0
|
||||
|
||||
var/moles_archived = 0
|
||||
|
||||
|
||||
/datum/gas_mixture
|
||||
var/oxygen = 0
|
||||
var/carbon_dioxide = 0
|
||||
var/nitrogen = 0
|
||||
var/toxins = 0
|
||||
|
||||
var/volume = CELL_VOLUME
|
||||
|
||||
var/temperature = 0 //in Kelvin, use calculate_temperature() to modify
|
||||
|
||||
var/group_multiplier = 1
|
||||
//Size of the group this gas_mixture is representing.
|
||||
//=1 for singletons
|
||||
|
||||
var/graphic
|
||||
|
||||
var/list/datum/gas/trace_gases = list()
|
||||
|
||||
|
||||
var/tmp/oxygen_archived
|
||||
var/tmp/carbon_dioxide_archived
|
||||
var/tmp/nitrogen_archived
|
||||
var/tmp/toxins_archived
|
||||
|
||||
var/tmp/temperature_archived
|
||||
|
||||
var/tmp/graphic_archived
|
||||
var/tmp/fuel_burnt = 0
|
||||
|
||||
//PV=nRT - related procedures
|
||||
proc/heat_capacity()
|
||||
var/heat_capacity = HEAT_CAPACITY_CALCULATION(oxygen,carbon_dioxide,nitrogen,toxins)
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
heat_capacity += trace_gas.moles*trace_gas.specific_heat
|
||||
return heat_capacity
|
||||
|
||||
|
||||
proc/heat_capacity_archived()
|
||||
var/heat_capacity_archived = HEAT_CAPACITY_CALCULATION(oxygen_archived,carbon_dioxide_archived,nitrogen_archived,toxins_archived)
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
heat_capacity_archived += trace_gas.moles_archived*trace_gas.specific_heat
|
||||
return heat_capacity_archived
|
||||
|
||||
|
||||
proc/total_moles()
|
||||
var/moles = oxygen + carbon_dioxide + nitrogen + toxins
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
moles += trace_gas.moles
|
||||
return moles
|
||||
|
||||
|
||||
proc/return_pressure()
|
||||
if(volume>0)
|
||||
return total_moles()*R_IDEAL_GAS_EQUATION*temperature/volume
|
||||
return 0
|
||||
|
||||
|
||||
proc/return_temperature()
|
||||
return temperature
|
||||
|
||||
|
||||
proc/return_volume()
|
||||
return max(0, volume)
|
||||
|
||||
|
||||
proc/thermal_energy()
|
||||
return temperature*heat_capacity()
|
||||
|
||||
|
||||
//Procedures used for very specific events
|
||||
proc/check_tile_graphic()
|
||||
//returns 1 if graphic changed
|
||||
graphic = null
|
||||
if(toxins > MOLES_PLASMA_VISIBLE)
|
||||
graphic = "plasma"
|
||||
else
|
||||
var/datum/gas/sleeping_agent = locate(/datum/gas/sleeping_agent) in trace_gases
|
||||
if(sleeping_agent && (sleeping_agent.moles > 1))
|
||||
graphic = "sleeping_agent"
|
||||
else
|
||||
graphic = null
|
||||
|
||||
return graphic != graphic_archived
|
||||
|
||||
proc/react(atom/dump_location)
|
||||
var/reacting = 0 //set to 1 if a notable reaction occured (used by pipe_network)
|
||||
|
||||
if(trace_gases.len > 0)
|
||||
if(temperature > 900)
|
||||
if(toxins > MINIMUM_HEAT_CAPACITY && carbon_dioxide > MINIMUM_HEAT_CAPACITY)
|
||||
var/datum/gas/oxygen_agent_b/trace_gas = locate(/datum/gas/oxygen_agent_b/) in trace_gases
|
||||
if(trace_gas)
|
||||
var/reaction_rate = min(carbon_dioxide*0.75, toxins*0.25, trace_gas.moles*0.05)
|
||||
|
||||
carbon_dioxide -= reaction_rate
|
||||
oxygen += reaction_rate
|
||||
|
||||
trace_gas.moles -= reaction_rate*0.05
|
||||
|
||||
temperature -= (reaction_rate*20000)/heat_capacity()
|
||||
|
||||
reacting = 1
|
||||
|
||||
fuel_burnt = 0
|
||||
if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
|
||||
//world << "pre [temperature], [oxygen], [toxins]"
|
||||
if(fire() > 0)
|
||||
reacting = 1
|
||||
//world << "post [temperature], [oxygen], [toxins]"
|
||||
|
||||
return reacting
|
||||
|
||||
proc/fire()
|
||||
var/energy_released = 0
|
||||
var/old_heat_capacity = heat_capacity()
|
||||
|
||||
var/datum/gas/volatile_fuel/fuel_store = locate(/datum/gas/volatile_fuel/) in trace_gases
|
||||
if(fuel_store) //General volatile gas burn
|
||||
var/burned_fuel = 0
|
||||
|
||||
if(oxygen < fuel_store.moles)
|
||||
burned_fuel = oxygen
|
||||
fuel_store.moles -= burned_fuel
|
||||
oxygen = 0
|
||||
else
|
||||
burned_fuel = fuel_store.moles
|
||||
oxygen -= fuel_store.moles
|
||||
trace_gases -= fuel_store
|
||||
fuel_store = null
|
||||
|
||||
energy_released += FIRE_CARBON_ENERGY_RELEASED * burned_fuel
|
||||
carbon_dioxide += burned_fuel
|
||||
fuel_burnt += burned_fuel
|
||||
|
||||
//Handle plasma burning
|
||||
if(toxins > MINIMUM_HEAT_CAPACITY)
|
||||
var/plasma_burn_rate = 0
|
||||
var/oxygen_burn_rate = 0
|
||||
//more plasma released at higher temperatures
|
||||
var/temperature_scale
|
||||
if(temperature > PLASMA_UPPER_TEMPERATURE)
|
||||
temperature_scale = 1
|
||||
else
|
||||
temperature_scale = (temperature-PLASMA_MINIMUM_BURN_TEMPERATURE)/(PLASMA_UPPER_TEMPERATURE-PLASMA_MINIMUM_BURN_TEMPERATURE)
|
||||
if(temperature_scale > 0)
|
||||
oxygen_burn_rate = 1.4 - temperature_scale
|
||||
if(oxygen > toxins*PLASMA_OXYGEN_FULLBURN)
|
||||
plasma_burn_rate = (toxins*temperature_scale)/4
|
||||
else
|
||||
plasma_burn_rate = (temperature_scale*(oxygen/PLASMA_OXYGEN_FULLBURN))/4
|
||||
if(plasma_burn_rate > MINIMUM_HEAT_CAPACITY)
|
||||
toxins -= plasma_burn_rate
|
||||
oxygen -= plasma_burn_rate*oxygen_burn_rate
|
||||
carbon_dioxide += plasma_burn_rate
|
||||
|
||||
energy_released += FIRE_PLASMA_ENERGY_RELEASED * (plasma_burn_rate)
|
||||
|
||||
fuel_burnt += (plasma_burn_rate)*(1+oxygen_burn_rate)
|
||||
|
||||
if(energy_released > 0)
|
||||
var/new_heat_capacity = heat_capacity()
|
||||
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
temperature = (temperature*old_heat_capacity + energy_released)/new_heat_capacity
|
||||
|
||||
return fuel_burnt
|
||||
|
||||
proc/archive()
|
||||
//Update archived versions of variables
|
||||
//Returns: 1 in all cases
|
||||
|
||||
proc/merge(datum/gas_mixture/giver)
|
||||
//Merges all air from giver into self. Deletes giver.
|
||||
//Returns: 1 on success (no failure cases yet)
|
||||
|
||||
proc/check_then_merge(datum/gas_mixture/giver)
|
||||
//Similar to merge(...) but first checks to see if the amount of air assumed is small enough
|
||||
// that group processing is still accurate for source (aborts if not)
|
||||
//Returns: 1 on successful merge, 0 if the check failed
|
||||
|
||||
proc/remove(amount)
|
||||
//Proportionally removes amount of gas from the gas_mixture
|
||||
//Returns: gas_mixture with the gases removed
|
||||
|
||||
proc/remove_ratio(ratio)
|
||||
//Proportionally removes amount of gas from the gas_mixture
|
||||
//Returns: gas_mixture with the gases removed
|
||||
|
||||
proc/subtract(datum/gas_mixture/right_side)
|
||||
//Subtracts right_side from air_mixture. Used to help turfs mingle
|
||||
|
||||
proc/check_then_remove(amount)
|
||||
//Similar to remove(...) but first checks to see if the amount of air removed is small enough
|
||||
// that group processing is still accurate for source (aborts if not)
|
||||
//Returns: gas_mixture with the gases removed or null
|
||||
|
||||
proc/copy_from(datum/gas_mixture/sample)
|
||||
//Copies variables from sample
|
||||
|
||||
proc/share(datum/gas_mixture/sharer)
|
||||
//Performs air sharing calculations between two gas_mixtures assuming only 1 boundary length
|
||||
//Return: amount of gas exchanged (+ if sharer received)
|
||||
|
||||
proc/mimic(turf/model)
|
||||
//Similar to share(...), except the model is not modified
|
||||
//Return: amount of gas exchanged
|
||||
|
||||
proc/check_gas_mixture(datum/gas_mixture/sharer)
|
||||
//Returns: 0 if the self-check failed then -1 if sharer-check failed then 1 if both checks pass
|
||||
|
||||
proc/check_turf(turf/model)
|
||||
//Returns: 0 if self-check failed or 1 if check passes
|
||||
|
||||
// check_me_then_share(datum/gas_mixture/sharer)
|
||||
//Similar to share(...) but first checks to see if amount of air moved is small enough
|
||||
// that group processing is still accurate for source (aborts if not)
|
||||
//Returns: 1 on successful share, 0 if the check failed
|
||||
|
||||
// check_me_then_mimic(turf/model)
|
||||
//Similar to mimic(...) but first checks to see if amount of air moved is small enough
|
||||
// that group processing is still accurate (aborts if not)
|
||||
//Returns: 1 on successful mimic, 0 if the check failed
|
||||
|
||||
// check_both_then_share(datum/gas_mixture/sharer)
|
||||
//Similar to check_me_then_share(...) but also checks to see if amount of air moved is small enough
|
||||
// that group processing is still accurate for the sharer (aborts if not)
|
||||
//Returns: 0 if the self-check failed then -1 if sharer-check failed then 1 if successful share
|
||||
|
||||
|
||||
proc/temperature_mimic(turf/model, conduction_coefficient)
|
||||
|
||||
proc/temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
|
||||
|
||||
proc/temperature_turf_share(turf/simulated/sharer, conduction_coefficient)
|
||||
|
||||
|
||||
proc/check_me_then_temperature_mimic(turf/model, conduction_coefficient)
|
||||
|
||||
proc/check_me_then_temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
|
||||
|
||||
proc/check_both_then_temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
|
||||
|
||||
proc/check_me_then_temperature_turf_share(turf/simulated/sharer, conduction_coefficient)
|
||||
|
||||
proc/compare(datum/gas_mixture/sample)
|
||||
//Compares sample to self to see if within acceptable ranges that group processing may be enabled
|
||||
|
||||
archive()
|
||||
oxygen_archived = oxygen
|
||||
carbon_dioxide_archived = carbon_dioxide
|
||||
nitrogen_archived = nitrogen
|
||||
toxins_archived = toxins
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
trace_gas.moles_archived = trace_gas.moles
|
||||
|
||||
temperature_archived = temperature
|
||||
|
||||
graphic_archived = graphic
|
||||
|
||||
return 1
|
||||
|
||||
check_then_merge(datum/gas_mixture/giver)
|
||||
if(!giver)
|
||||
return 0
|
||||
if(((giver.oxygen > MINIMUM_AIR_TO_SUSPEND) && (giver.oxygen >= oxygen*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((giver.carbon_dioxide > MINIMUM_AIR_TO_SUSPEND) && (giver.carbon_dioxide >= carbon_dioxide*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((giver.nitrogen > MINIMUM_AIR_TO_SUSPEND) && (giver.nitrogen >= nitrogen*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((giver.toxins > MINIMUM_AIR_TO_SUSPEND) && (giver.toxins >= toxins*MINIMUM_AIR_RATIO_TO_SUSPEND)))
|
||||
return 0
|
||||
if(abs(giver.temperature - temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
|
||||
return 0
|
||||
|
||||
if(giver.trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in giver.trace_gases)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
|
||||
if((trace_gas.moles > MINIMUM_AIR_TO_SUSPEND) && (!corresponding || (trace_gas.moles >= corresponding.moles*MINIMUM_AIR_RATIO_TO_SUSPEND)))
|
||||
return 0
|
||||
|
||||
return merge(giver)
|
||||
|
||||
merge(datum/gas_mixture/giver)
|
||||
if(!giver)
|
||||
return 0
|
||||
|
||||
if(abs(temperature-giver.temperature)>MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/self_heat_capacity = heat_capacity()*group_multiplier
|
||||
var/giver_heat_capacity = giver.heat_capacity()*giver.group_multiplier
|
||||
var/combined_heat_capacity = giver_heat_capacity + self_heat_capacity
|
||||
if(combined_heat_capacity != 0)
|
||||
temperature = (giver.temperature*giver_heat_capacity + temperature*self_heat_capacity)/combined_heat_capacity
|
||||
|
||||
if((group_multiplier>1)||(giver.group_multiplier>1))
|
||||
oxygen += giver.oxygen*giver.group_multiplier/group_multiplier
|
||||
carbon_dioxide += giver.carbon_dioxide*giver.group_multiplier/group_multiplier
|
||||
nitrogen += giver.nitrogen*giver.group_multiplier/group_multiplier
|
||||
toxins += giver.toxins*giver.group_multiplier/group_multiplier
|
||||
else
|
||||
oxygen += giver.oxygen
|
||||
carbon_dioxide += giver.carbon_dioxide
|
||||
nitrogen += giver.nitrogen
|
||||
toxins += giver.toxins
|
||||
|
||||
if(giver.trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in giver.trace_gases)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
|
||||
if(!corresponding)
|
||||
corresponding = new trace_gas.type()
|
||||
trace_gases += corresponding
|
||||
corresponding.moles += trace_gas.moles*giver.group_multiplier/group_multiplier
|
||||
|
||||
// qdel(giver)
|
||||
return 1
|
||||
|
||||
remove(amount)
|
||||
|
||||
var/sum = total_moles()
|
||||
amount = min(amount,sum) //Can not take more air than tile has!
|
||||
if(amount <= 0)
|
||||
return null
|
||||
|
||||
var/datum/gas_mixture/removed = new
|
||||
|
||||
|
||||
removed.oxygen = QUANTIZE((oxygen/sum)*amount)
|
||||
removed.nitrogen = QUANTIZE((nitrogen/sum)*amount)
|
||||
removed.carbon_dioxide = QUANTIZE((carbon_dioxide/sum)*amount)
|
||||
removed.toxins = QUANTIZE((toxins/sum)*amount)
|
||||
|
||||
oxygen -= removed.oxygen/group_multiplier
|
||||
nitrogen -= removed.nitrogen/group_multiplier
|
||||
carbon_dioxide -= removed.carbon_dioxide/group_multiplier
|
||||
toxins -= removed.toxins/group_multiplier
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
var/datum/gas/corresponding = new trace_gas.type()
|
||||
removed.trace_gases += corresponding
|
||||
|
||||
corresponding.moles = (trace_gas.moles/sum)*amount
|
||||
trace_gas.moles -= corresponding.moles/group_multiplier
|
||||
|
||||
removed.temperature = temperature
|
||||
|
||||
return removed
|
||||
|
||||
remove_ratio(ratio)
|
||||
|
||||
if(ratio <= 0)
|
||||
return null
|
||||
|
||||
ratio = min(ratio, 1)
|
||||
|
||||
var/datum/gas_mixture/removed = new
|
||||
|
||||
removed.oxygen = QUANTIZE(oxygen*ratio)
|
||||
removed.nitrogen = QUANTIZE(nitrogen*ratio)
|
||||
removed.carbon_dioxide = QUANTIZE(carbon_dioxide*ratio)
|
||||
removed.toxins = QUANTIZE(toxins*ratio)
|
||||
|
||||
oxygen -= removed.oxygen/group_multiplier
|
||||
nitrogen -= removed.nitrogen/group_multiplier
|
||||
carbon_dioxide -= removed.carbon_dioxide/group_multiplier
|
||||
toxins -= removed.toxins/group_multiplier
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
var/datum/gas/corresponding = new trace_gas.type()
|
||||
removed.trace_gases += corresponding
|
||||
|
||||
corresponding.moles = trace_gas.moles*ratio
|
||||
trace_gas.moles -= corresponding.moles/group_multiplier
|
||||
|
||||
removed.temperature = temperature
|
||||
|
||||
return removed
|
||||
|
||||
check_then_remove(amount)
|
||||
|
||||
//Since it is all proportional, the check may be done on the gas as a whole
|
||||
var/sum = total_moles()
|
||||
amount = min(amount,sum) //Can not take more air than tile has!
|
||||
|
||||
if((amount > MINIMUM_AIR_RATIO_TO_SUSPEND) && (amount > sum*MINIMUM_AIR_RATIO_TO_SUSPEND))
|
||||
return 0
|
||||
|
||||
return remove(amount)
|
||||
|
||||
copy_from(datum/gas_mixture/sample)
|
||||
oxygen = sample.oxygen
|
||||
carbon_dioxide = sample.carbon_dioxide
|
||||
nitrogen = sample.nitrogen
|
||||
toxins = sample.toxins
|
||||
|
||||
trace_gases.len=null
|
||||
if(sample.trace_gases.len > 0)
|
||||
for(var/datum/gas/trace_gas in sample.trace_gases)
|
||||
var/datum/gas/corresponding = new trace_gas.type()
|
||||
trace_gases += corresponding
|
||||
|
||||
corresponding.moles = trace_gas.moles
|
||||
|
||||
temperature = sample.temperature
|
||||
|
||||
return 1
|
||||
|
||||
subtract(datum/gas_mixture/right_side)
|
||||
oxygen -= right_side.oxygen
|
||||
carbon_dioxide -= right_side.carbon_dioxide
|
||||
nitrogen -= right_side.nitrogen
|
||||
toxins -= right_side.toxins
|
||||
|
||||
if((trace_gases.len > 0)||(right_side.trace_gases.len > 0))
|
||||
for(var/datum/gas/trace_gas in right_side.trace_gases)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
|
||||
if(!corresponding)
|
||||
corresponding = new trace_gas.type()
|
||||
trace_gases += corresponding
|
||||
|
||||
corresponding.moles -= trace_gas.moles
|
||||
|
||||
return 1
|
||||
|
||||
check_gas_mixture(datum/gas_mixture/sharer)
|
||||
if(!sharer) return 0
|
||||
var/delta_oxygen = (oxygen_archived - sharer.oxygen_archived)/5
|
||||
var/delta_carbon_dioxide = (carbon_dioxide_archived - sharer.carbon_dioxide_archived)/5
|
||||
var/delta_nitrogen = (nitrogen_archived - sharer.nitrogen_archived)/5
|
||||
var/delta_toxins = (toxins_archived - sharer.toxins_archived)/5
|
||||
|
||||
var/delta_temperature = (temperature_archived - sharer.temperature_archived)
|
||||
|
||||
if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= toxins_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)))
|
||||
return 0
|
||||
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
|
||||
return 0
|
||||
|
||||
if(sharer.trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in sharer.trace_gases)
|
||||
if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
|
||||
if(corresponding)
|
||||
if(trace_gas.moles_archived >= corresponding.moles_archived*MINIMUM_AIR_RATIO_TO_SUSPEND*4)
|
||||
return 0
|
||||
else
|
||||
return 0
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4)
|
||||
if(!locate(trace_gas.type) in sharer.trace_gases)
|
||||
return 0
|
||||
|
||||
if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= sharer.oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= sharer.carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= sharer.nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= sharer.toxins_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)))
|
||||
return -1
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in sharer.trace_gases
|
||||
if(corresponding)
|
||||
if(trace_gas.moles_archived >= corresponding.moles_archived*MINIMUM_AIR_RATIO_TO_SUSPEND*4)
|
||||
return -1
|
||||
else
|
||||
return -1
|
||||
|
||||
return 1
|
||||
|
||||
check_turf(turf/model)
|
||||
var/delta_oxygen = (oxygen_archived - model.oxygen)/5
|
||||
var/delta_carbon_dioxide = (carbon_dioxide_archived - model.carbon_dioxide)/5
|
||||
var/delta_nitrogen = (nitrogen_archived - model.nitrogen)/5
|
||||
var/delta_toxins = (toxins_archived - model.toxins)/5
|
||||
|
||||
var/delta_temperature = (temperature_archived - model.temperature)
|
||||
|
||||
if(((abs(delta_oxygen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_oxygen) >= oxygen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_carbon_dioxide) >= carbon_dioxide_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_nitrogen) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_nitrogen) >= nitrogen_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)) \
|
||||
|| ((abs(delta_toxins) > MINIMUM_AIR_TO_SUSPEND) && (abs(delta_toxins) >= toxins_archived*MINIMUM_AIR_RATIO_TO_SUSPEND)))
|
||||
return 0
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND)
|
||||
return 0
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND*4)
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
share(datum/gas_mixture/sharer)
|
||||
if(!sharer) return 0
|
||||
var/delta_oxygen = QUANTIZE(oxygen_archived - sharer.oxygen_archived)/5
|
||||
var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - sharer.carbon_dioxide_archived)/5
|
||||
var/delta_nitrogen = QUANTIZE(nitrogen_archived - sharer.nitrogen_archived)/5
|
||||
var/delta_toxins = QUANTIZE(toxins_archived - sharer.toxins_archived)/5
|
||||
|
||||
var/delta_temperature = (temperature_archived - sharer.temperature_archived)
|
||||
|
||||
var/old_self_heat_capacity = 0
|
||||
var/old_sharer_heat_capacity = 0
|
||||
|
||||
var/heat_capacity_self_to_sharer = 0
|
||||
var/heat_capacity_sharer_to_self = 0
|
||||
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
|
||||
var/delta_air = delta_oxygen+delta_nitrogen
|
||||
if(delta_air)
|
||||
var/air_heat_capacity = SPECIFIC_HEAT_AIR*delta_air
|
||||
if(delta_air > 0)
|
||||
heat_capacity_self_to_sharer += air_heat_capacity
|
||||
else
|
||||
heat_capacity_sharer_to_self -= air_heat_capacity
|
||||
|
||||
if(delta_carbon_dioxide)
|
||||
var/carbon_dioxide_heat_capacity = SPECIFIC_HEAT_CDO*delta_carbon_dioxide
|
||||
if(delta_carbon_dioxide > 0)
|
||||
heat_capacity_self_to_sharer += carbon_dioxide_heat_capacity
|
||||
else
|
||||
heat_capacity_sharer_to_self -= carbon_dioxide_heat_capacity
|
||||
|
||||
if(delta_toxins)
|
||||
var/toxins_heat_capacity = SPECIFIC_HEAT_TOXIN*delta_toxins
|
||||
if(delta_toxins > 0)
|
||||
heat_capacity_self_to_sharer += toxins_heat_capacity
|
||||
else
|
||||
heat_capacity_sharer_to_self -= toxins_heat_capacity
|
||||
|
||||
old_self_heat_capacity = heat_capacity()*group_multiplier
|
||||
old_sharer_heat_capacity = sharer.heat_capacity()*sharer.group_multiplier
|
||||
|
||||
oxygen -= delta_oxygen/group_multiplier
|
||||
sharer.oxygen += delta_oxygen/sharer.group_multiplier
|
||||
|
||||
carbon_dioxide -= delta_carbon_dioxide/group_multiplier
|
||||
sharer.carbon_dioxide += delta_carbon_dioxide/sharer.group_multiplier
|
||||
|
||||
nitrogen -= delta_nitrogen/group_multiplier
|
||||
sharer.nitrogen += delta_nitrogen/sharer.group_multiplier
|
||||
|
||||
toxins -= delta_toxins/group_multiplier
|
||||
sharer.toxins += delta_toxins/sharer.group_multiplier
|
||||
|
||||
var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_toxins)
|
||||
|
||||
var/list/trace_types_considered = list()
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in sharer.trace_gases
|
||||
var/delta = 0
|
||||
|
||||
if(corresponding)
|
||||
delta = QUANTIZE(trace_gas.moles_archived - corresponding.moles_archived)/5
|
||||
else
|
||||
corresponding = new trace_gas.type()
|
||||
sharer.trace_gases += corresponding
|
||||
|
||||
delta = trace_gas.moles_archived/5
|
||||
|
||||
trace_gas.moles -= delta/group_multiplier
|
||||
corresponding.moles += delta/sharer.group_multiplier
|
||||
|
||||
if(delta)
|
||||
var/individual_heat_capacity = trace_gas.specific_heat*delta
|
||||
if(delta > 0)
|
||||
heat_capacity_self_to_sharer += individual_heat_capacity
|
||||
else
|
||||
heat_capacity_sharer_to_self -= individual_heat_capacity
|
||||
|
||||
moved_moles += delta
|
||||
|
||||
trace_types_considered += trace_gas.type
|
||||
|
||||
|
||||
if(sharer.trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in sharer.trace_gases)
|
||||
if(trace_gas.type in trace_types_considered) continue
|
||||
else
|
||||
var/datum/gas/corresponding
|
||||
var/delta = 0
|
||||
|
||||
corresponding = new trace_gas.type()
|
||||
trace_gases += corresponding
|
||||
|
||||
delta = trace_gas.moles_archived/5
|
||||
|
||||
trace_gas.moles -= delta/sharer.group_multiplier
|
||||
corresponding.moles += delta/group_multiplier
|
||||
|
||||
//Guaranteed transfer from sharer to self
|
||||
var/individual_heat_capacity = trace_gas.specific_heat*delta
|
||||
heat_capacity_sharer_to_self += individual_heat_capacity
|
||||
|
||||
moved_moles += -delta
|
||||
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/new_self_heat_capacity = old_self_heat_capacity + heat_capacity_sharer_to_self - heat_capacity_self_to_sharer
|
||||
var/new_sharer_heat_capacity = old_sharer_heat_capacity + heat_capacity_self_to_sharer - heat_capacity_sharer_to_self
|
||||
|
||||
if(new_self_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
temperature = (old_self_heat_capacity*temperature - heat_capacity_self_to_sharer*temperature_archived + heat_capacity_sharer_to_self*sharer.temperature_archived)/new_self_heat_capacity
|
||||
|
||||
if(new_sharer_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
sharer.temperature = (old_sharer_heat_capacity*sharer.temperature-heat_capacity_sharer_to_self*sharer.temperature_archived + heat_capacity_self_to_sharer*temperature_archived)/new_sharer_heat_capacity
|
||||
|
||||
if(abs(old_sharer_heat_capacity) > MINIMUM_HEAT_CAPACITY)
|
||||
if(abs(new_sharer_heat_capacity/old_sharer_heat_capacity - 1) < 0.10) // <10% change in sharer heat capacity
|
||||
temperature_share(sharer, OPEN_HEAT_TRANSFER_COEFFICIENT)
|
||||
|
||||
if((delta_temperature > MINIMUM_TEMPERATURE_TO_MOVE) || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
|
||||
var/delta_pressure = temperature_archived*(total_moles() + moved_moles) - sharer.temperature_archived*(sharer.total_moles() - moved_moles)
|
||||
return delta_pressure*R_IDEAL_GAS_EQUATION/volume
|
||||
|
||||
else
|
||||
return 0
|
||||
|
||||
mimic(turf/model, border_multiplier)
|
||||
var/delta_oxygen = QUANTIZE(oxygen_archived - model.oxygen)/5
|
||||
var/delta_carbon_dioxide = QUANTIZE(carbon_dioxide_archived - model.carbon_dioxide)/5
|
||||
var/delta_nitrogen = QUANTIZE(nitrogen_archived - model.nitrogen)/5
|
||||
var/delta_toxins = QUANTIZE(toxins_archived - model.toxins)/5
|
||||
|
||||
var/delta_temperature = (temperature_archived - model.temperature)
|
||||
|
||||
var/heat_transferred = 0
|
||||
var/old_self_heat_capacity = 0
|
||||
var/heat_capacity_transferred = 0
|
||||
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
|
||||
var/delta_air = delta_oxygen+delta_nitrogen
|
||||
if(delta_air)
|
||||
var/air_heat_capacity = SPECIFIC_HEAT_AIR*delta_air
|
||||
heat_transferred -= air_heat_capacity*model.temperature
|
||||
heat_capacity_transferred -= air_heat_capacity
|
||||
|
||||
if(delta_carbon_dioxide)
|
||||
var/carbon_dioxide_heat_capacity = SPECIFIC_HEAT_CDO*delta_carbon_dioxide
|
||||
heat_transferred -= carbon_dioxide_heat_capacity*model.temperature
|
||||
heat_capacity_transferred -= carbon_dioxide_heat_capacity
|
||||
|
||||
if(delta_toxins)
|
||||
var/toxins_heat_capacity = SPECIFIC_HEAT_TOXIN*delta_toxins
|
||||
heat_transferred -= toxins_heat_capacity*model.temperature
|
||||
heat_capacity_transferred -= toxins_heat_capacity
|
||||
|
||||
old_self_heat_capacity = heat_capacity()*group_multiplier
|
||||
|
||||
if(border_multiplier)
|
||||
oxygen -= delta_oxygen*border_multiplier/group_multiplier
|
||||
carbon_dioxide -= delta_carbon_dioxide*border_multiplier/group_multiplier
|
||||
nitrogen -= delta_nitrogen*border_multiplier/group_multiplier
|
||||
toxins -= delta_toxins*border_multiplier/group_multiplier
|
||||
else
|
||||
oxygen -= delta_oxygen/group_multiplier
|
||||
carbon_dioxide -= delta_carbon_dioxide/group_multiplier
|
||||
nitrogen -= delta_nitrogen/group_multiplier
|
||||
toxins -= delta_toxins/group_multiplier
|
||||
|
||||
var/moved_moles = (delta_oxygen + delta_carbon_dioxide + delta_nitrogen + delta_toxins)
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
var/delta = 0
|
||||
|
||||
delta = trace_gas.moles_archived/5
|
||||
|
||||
if(border_multiplier)
|
||||
trace_gas.moles -= delta*border_multiplier/group_multiplier
|
||||
else
|
||||
trace_gas.moles -= delta/group_multiplier
|
||||
|
||||
var/heat_cap_transferred = delta*trace_gas.specific_heat
|
||||
heat_transferred += heat_cap_transferred*temperature_archived
|
||||
heat_capacity_transferred += heat_cap_transferred
|
||||
moved_moles += delta
|
||||
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/new_self_heat_capacity = old_self_heat_capacity - heat_capacity_transferred
|
||||
if(new_self_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
if(border_multiplier)
|
||||
temperature = (old_self_heat_capacity*temperature - heat_capacity_transferred*border_multiplier*temperature_archived)/new_self_heat_capacity
|
||||
else
|
||||
temperature = (old_self_heat_capacity*temperature - heat_capacity_transferred*border_multiplier*temperature_archived)/new_self_heat_capacity
|
||||
|
||||
temperature_mimic(model, model.thermal_conductivity, border_multiplier)
|
||||
|
||||
if((delta_temperature > MINIMUM_TEMPERATURE_TO_MOVE) || abs(moved_moles) > MINIMUM_MOLES_DELTA_TO_MOVE)
|
||||
var/delta_pressure = temperature_archived*(total_moles() + moved_moles) - model.temperature*(model.oxygen+model.carbon_dioxide+model.nitrogen+model.toxins)
|
||||
return delta_pressure*R_IDEAL_GAS_EQUATION/volume
|
||||
else
|
||||
return 0
|
||||
|
||||
check_both_then_temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
|
||||
var/delta_temperature = (temperature_archived - sharer.temperature_archived)
|
||||
|
||||
var/self_heat_capacity = heat_capacity_archived()
|
||||
var/sharer_heat_capacity = sharer.heat_capacity_archived()
|
||||
|
||||
var/self_temperature_delta = 0
|
||||
var/sharer_temperature_delta = 0
|
||||
|
||||
if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
|
||||
var/heat = conduction_coefficient*delta_temperature* \
|
||||
(self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity))
|
||||
|
||||
self_temperature_delta = -heat/(self_heat_capacity*group_multiplier)
|
||||
sharer_temperature_delta = heat/(sharer_heat_capacity*sharer.group_multiplier)
|
||||
else
|
||||
return 1
|
||||
|
||||
if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \
|
||||
&& (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived))
|
||||
return 0
|
||||
|
||||
if((abs(sharer_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \
|
||||
&& (abs(sharer_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*sharer.temperature_archived))
|
||||
return -1
|
||||
|
||||
temperature += self_temperature_delta
|
||||
sharer.temperature += sharer_temperature_delta
|
||||
|
||||
return 1
|
||||
//Logic integrated from: temperature_share(sharer, conduction_coefficient) for efficiency
|
||||
|
||||
check_me_then_temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
|
||||
var/delta_temperature = (temperature_archived - sharer.temperature_archived)
|
||||
|
||||
var/self_heat_capacity = heat_capacity_archived()
|
||||
var/sharer_heat_capacity = sharer.heat_capacity_archived()
|
||||
|
||||
var/self_temperature_delta = 0
|
||||
var/sharer_temperature_delta = 0
|
||||
|
||||
if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
|
||||
var/heat = conduction_coefficient*delta_temperature* \
|
||||
(self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity))
|
||||
|
||||
self_temperature_delta = -heat/(self_heat_capacity*group_multiplier)
|
||||
sharer_temperature_delta = heat/(sharer_heat_capacity*sharer.group_multiplier)
|
||||
else
|
||||
return 1
|
||||
|
||||
if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \
|
||||
&& (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived))
|
||||
return 0
|
||||
|
||||
temperature += self_temperature_delta
|
||||
sharer.temperature += sharer_temperature_delta
|
||||
|
||||
return 1
|
||||
//Logic integrated from: temperature_share(sharer, conduction_coefficient) for efficiency
|
||||
|
||||
check_me_then_temperature_turf_share(turf/simulated/sharer, conduction_coefficient)
|
||||
var/delta_temperature = (temperature_archived - sharer.temperature)
|
||||
|
||||
var/self_temperature_delta = 0
|
||||
var/sharer_temperature_delta = 0
|
||||
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/self_heat_capacity = heat_capacity_archived()
|
||||
|
||||
if((sharer.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
|
||||
var/heat = conduction_coefficient*delta_temperature* \
|
||||
(self_heat_capacity*sharer.heat_capacity/(self_heat_capacity+sharer.heat_capacity))
|
||||
|
||||
self_temperature_delta = -heat/(self_heat_capacity*group_multiplier)
|
||||
sharer_temperature_delta = heat/sharer.heat_capacity
|
||||
else
|
||||
return 1
|
||||
|
||||
if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \
|
||||
&& (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived))
|
||||
return 0
|
||||
|
||||
temperature += self_temperature_delta
|
||||
sharer.temperature += sharer_temperature_delta
|
||||
|
||||
return 1
|
||||
//Logic integrated from: temperature_turf_share(sharer, conduction_coefficient) for efficiency
|
||||
|
||||
check_me_then_temperature_mimic(turf/model, conduction_coefficient)
|
||||
var/delta_temperature = (temperature_archived - model.temperature)
|
||||
var/self_temperature_delta = 0
|
||||
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/self_heat_capacity = heat_capacity_archived()
|
||||
|
||||
if((model.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
|
||||
var/heat = conduction_coefficient*delta_temperature* \
|
||||
(self_heat_capacity*model.heat_capacity/(self_heat_capacity+model.heat_capacity))
|
||||
|
||||
self_temperature_delta = -heat/(self_heat_capacity*group_multiplier)
|
||||
|
||||
if((abs(self_temperature_delta) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) \
|
||||
&& (abs(self_temperature_delta) > MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND*temperature_archived))
|
||||
return 0
|
||||
|
||||
temperature += self_temperature_delta
|
||||
|
||||
return 1
|
||||
//Logic integrated from: temperature_mimic(model, conduction_coefficient) for efficiency
|
||||
|
||||
temperature_share(datum/gas_mixture/sharer, conduction_coefficient)
|
||||
|
||||
var/delta_temperature = (temperature_archived - sharer.temperature_archived)
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/self_heat_capacity = heat_capacity_archived()
|
||||
var/sharer_heat_capacity = sharer.heat_capacity_archived()
|
||||
|
||||
if((sharer_heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
|
||||
var/heat = conduction_coefficient*delta_temperature* \
|
||||
(self_heat_capacity*sharer_heat_capacity/(self_heat_capacity+sharer_heat_capacity))
|
||||
|
||||
temperature -= heat/(self_heat_capacity*group_multiplier)
|
||||
sharer.temperature += heat/(sharer_heat_capacity*sharer.group_multiplier)
|
||||
|
||||
temperature_mimic(turf/model, conduction_coefficient, border_multiplier)
|
||||
var/delta_temperature = (temperature - model.temperature)
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/self_heat_capacity = heat_capacity()//_archived()
|
||||
|
||||
if((model.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
|
||||
var/heat = conduction_coefficient*delta_temperature* \
|
||||
(self_heat_capacity*model.heat_capacity/(self_heat_capacity+model.heat_capacity))
|
||||
|
||||
if(border_multiplier)
|
||||
temperature -= heat*border_multiplier/(self_heat_capacity*group_multiplier)
|
||||
else
|
||||
temperature -= heat/(self_heat_capacity*group_multiplier)
|
||||
|
||||
temperature_turf_share(turf/simulated/sharer, conduction_coefficient)
|
||||
var/delta_temperature = (temperature_archived - sharer.temperature)
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
|
||||
var/self_heat_capacity = heat_capacity()
|
||||
|
||||
if((sharer.heat_capacity > MINIMUM_HEAT_CAPACITY) && (self_heat_capacity > MINIMUM_HEAT_CAPACITY))
|
||||
var/heat = conduction_coefficient*delta_temperature* \
|
||||
(self_heat_capacity*sharer.heat_capacity/(self_heat_capacity+sharer.heat_capacity))
|
||||
|
||||
temperature -= heat/(self_heat_capacity*group_multiplier)
|
||||
sharer.temperature += heat/sharer.heat_capacity
|
||||
|
||||
compare(datum/gas_mixture/sample)
|
||||
if((abs(oxygen-sample.oxygen) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((oxygen < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.oxygen) || (oxygen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.oxygen)))
|
||||
return 0
|
||||
if((abs(nitrogen-sample.nitrogen) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((nitrogen < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen) || (nitrogen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen)))
|
||||
return 0
|
||||
if((abs(carbon_dioxide-sample.carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((carbon_dioxide < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide) || (oxygen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide)))
|
||||
return 0
|
||||
if((abs(toxins-sample.toxins) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((toxins < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.toxins) || (toxins > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.toxins)))
|
||||
return 0
|
||||
|
||||
if(total_moles() > MINIMUM_AIR_TO_SUSPEND)
|
||||
if((abs(temperature-sample.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) && \
|
||||
((temperature < (1-MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature) || (temperature > (1+MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature)))
|
||||
//world << "temp fail [temperature] & [sample.temperature]"
|
||||
return 0
|
||||
|
||||
if(sample.trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in sample.trace_gases)
|
||||
if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
|
||||
if(corresponding)
|
||||
if((abs(trace_gas.moles - corresponding.moles) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((corresponding.moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles) || (corresponding.moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles)))
|
||||
return 0
|
||||
else
|
||||
return 0
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
if(trace_gas.moles > MINIMUM_AIR_TO_SUSPEND)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in sample.trace_gases
|
||||
if(corresponding)
|
||||
if((abs(trace_gas.moles - corresponding.moles) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((trace_gas.moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*corresponding.moles) || (trace_gas.moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*corresponding.moles)))
|
||||
return 0
|
||||
else
|
||||
return 0
|
||||
return 1
|
||||
@@ -1,101 +0,0 @@
|
||||
/turf/simulated/proc/find_group()
|
||||
//Basically, join any nearby valid groups
|
||||
// If more than one, pick one with most members at my borders
|
||||
// If can not find any but there was an ungrouped at border with me, call for group assembly
|
||||
|
||||
var/turf/simulated/floor/north = get_step(src,NORTH)
|
||||
var/turf/simulated/floor/south = get_step(src,SOUTH)
|
||||
var/turf/simulated/floor/east = get_step(src,EAST)
|
||||
var/turf/simulated/floor/west = get_step(src,WEST)
|
||||
|
||||
//Clear those we do not have access to
|
||||
if(!CanPass(null, north, null, 1) || !istype(north))
|
||||
north = null
|
||||
if(!CanPass(null, south, null, 1) || !istype(south))
|
||||
south = null
|
||||
if(!CanPass(null, east, null, 1) || !istype(east))
|
||||
east = null
|
||||
if(!CanPass(null, west, null, 1) || !istype(west))
|
||||
west = null
|
||||
|
||||
var/new_group_possible = 0
|
||||
|
||||
var/north_votes = 0
|
||||
var/south_votes = 0
|
||||
var/east_votes = 0
|
||||
|
||||
if(north)
|
||||
if(north.parent)
|
||||
north_votes = 1
|
||||
|
||||
if(south && (south.parent == north.parent))
|
||||
north_votes++
|
||||
south = null
|
||||
|
||||
if(east && (east.parent == north.parent))
|
||||
north_votes++
|
||||
east = null
|
||||
|
||||
if(west && (west.parent == north.parent))
|
||||
north_votes++
|
||||
west = null
|
||||
else
|
||||
new_group_possible = 1
|
||||
|
||||
if(south)
|
||||
if(south.parent)
|
||||
south_votes = 1
|
||||
|
||||
if(east && (east.parent == south.parent))
|
||||
south_votes++
|
||||
east = null
|
||||
|
||||
if(west && (west.parent == south.parent))
|
||||
south_votes++
|
||||
west = null
|
||||
else
|
||||
new_group_possible = 1
|
||||
|
||||
if(east)
|
||||
if(east.parent)
|
||||
east_votes = 1
|
||||
|
||||
if(west && (west.parent == east.parent))
|
||||
east_votes++
|
||||
west = null
|
||||
else
|
||||
new_group_possible = 1
|
||||
|
||||
// world << "[north_votes], [south_votes], [east_votes]"
|
||||
|
||||
var/datum/air_group/group_joined = null
|
||||
|
||||
if(west)
|
||||
if(west.parent)
|
||||
group_joined = west.parent
|
||||
else
|
||||
new_group_possible = 1
|
||||
|
||||
if(north_votes && (north_votes >= south_votes) && (north_votes >= east_votes))
|
||||
group_joined = north.parent
|
||||
else if(south_votes && (south_votes >= east_votes))
|
||||
group_joined = south.parent
|
||||
else if(east_votes)
|
||||
group_joined = east.parent
|
||||
|
||||
if (istype(group_joined))
|
||||
if (group_joined.group_processing)
|
||||
group_joined.suspend_group_processing()
|
||||
group_joined.members += src
|
||||
parent=group_joined
|
||||
|
||||
air_master.tiles_to_update += group_joined.members
|
||||
return 1
|
||||
|
||||
else if(new_group_possible)
|
||||
air_master.assemble_group_turf(src)
|
||||
return 1
|
||||
|
||||
else
|
||||
air_master.active_singletons += src
|
||||
return 1
|
||||
@@ -1,335 +0,0 @@
|
||||
/*
|
||||
Overview:
|
||||
The air_master global variable is the workhorse for the system.
|
||||
|
||||
Why are you archiving data before modifying it?
|
||||
The general concept with archiving data and having each tile keep track of when they were last updated is to keep everything symmetric
|
||||
and totally independent of the order they are read in an update cycle.
|
||||
This prevents abnormalities like air/fire spreading rapidly in one direction and super slowly in the other.
|
||||
|
||||
Why not just archive everything and then calculate?
|
||||
Efficiency. While a for-loop that goes through all tiles and groups to archive their information before doing any calculations seems simple, it is
|
||||
slightly less efficient than the archive-before-modify/read method.
|
||||
|
||||
Why is there a cycle check for calculating data as well?
|
||||
This ensures that every connection between group-tile, tile-tile, and group-group is only evaluated once per loop.
|
||||
|
||||
|
||||
|
||||
|
||||
Important variables:
|
||||
air_master.groups_to_rebuild (list)
|
||||
A list of air groups that have had their geometry occluded and thus may need to be split in half.
|
||||
A set of adjacent groups put in here will join together if validly connected.
|
||||
This is done before air system calculations for a cycle.
|
||||
air_master.tiles_to_update (list)
|
||||
Turfs that are in this list have their border data updated before the next air calculations for a cycle.
|
||||
Place turfs in this list rather than call the proc directly to prevent race conditions
|
||||
|
||||
turf/simulated.archive() and datum/air_group.archive()
|
||||
This stores all data for.
|
||||
If you modify, make sure to update the archived_cycle to prevent race conditions and maintain symmetry
|
||||
|
||||
atom/CanPass(atom/movable/mover, turf/target, height, air_group)
|
||||
returns 1 for allow pass and 0 for deny pass
|
||||
Turfs automatically call this for all objects/mobs in its turf.
|
||||
This is called both as source.CanPass(target, height, air_group)
|
||||
and target.CanPass(source, height, air_group)
|
||||
|
||||
Cases for the parameters
|
||||
1. This is called with args (mover, location, height>0, air_group=0) for normal objects.
|
||||
2. This is called with args (null, location, height=0, air_group=0) for flowing air.
|
||||
3. This is called with args (null, location, height=?, air_group=1) for determining group boundaries.
|
||||
|
||||
Cases 2 and 3 would be different for doors or other objects open and close fairly often.
|
||||
(Case 3 would return 0 always while Case 2 would return 0 only when the door is open)
|
||||
This prevents the necessity of re-evaluating group geometry every time a door opens/closes.
|
||||
|
||||
|
||||
Important Procedures
|
||||
air_master.process()
|
||||
This first processes the air_master update/rebuild lists then processes all groups and tiles for air calculations
|
||||
|
||||
|
||||
*/
|
||||
|
||||
var/kill_air = 0
|
||||
|
||||
atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
|
||||
return (!density || !height || air_group)
|
||||
|
||||
turf
|
||||
CanPass(atom/movable/mover, turf/target, height=1.5,air_group=0)
|
||||
if(!target) return 0
|
||||
|
||||
if(istype(mover)) // turf/Enter(...) will perform more advanced checks
|
||||
return !density
|
||||
|
||||
else // Now, doing more detailed checks for air movement and air group formation
|
||||
if(target.blocks_air||blocks_air)
|
||||
return 0
|
||||
|
||||
for(var/obj/obstacle in src)
|
||||
if(!obstacle.CanPass(mover, target, height, air_group))
|
||||
return 0
|
||||
for(var/obj/obstacle in target)
|
||||
if(!obstacle.CanPass(mover, src, height, air_group))
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
var/global/datum/controller/air_system/air_master
|
||||
|
||||
datum
|
||||
controller
|
||||
air_system
|
||||
//Geoemetry lists
|
||||
var/list/datum/air_group/air_groups = list()
|
||||
var/list/turf/simulated/active_singletons = list()
|
||||
|
||||
//Special functions lists
|
||||
var/list/turf/simulated/active_super_conductivity = list()
|
||||
var/list/turf/simulated/high_pressure_delta = list()
|
||||
|
||||
//Geometry updates lists
|
||||
var/list/turf/simulated/tiles_to_update = list()
|
||||
var/list/turf/simulated/groups_to_rebuild = list()
|
||||
|
||||
var/current_cycle = 0
|
||||
|
||||
proc
|
||||
setup()
|
||||
//Call this at the start to setup air groups geometry
|
||||
//Warning: Very processor intensive but only must be done once per round
|
||||
|
||||
assemble_group_turf(turf/simulated/base)
|
||||
//Call this to try to construct a group starting from base and merging with neighboring unparented tiles
|
||||
//Expands the group until all valid borders explored
|
||||
|
||||
// assemble_group_object(obj/movable/floor/base)
|
||||
|
||||
process()
|
||||
//Call this to process air movements for a cycle
|
||||
|
||||
process_groups()
|
||||
//Used by process()
|
||||
//Warning: Do not call this
|
||||
|
||||
process_singletons()
|
||||
//Used by process()
|
||||
//Warning: Do not call this
|
||||
|
||||
process_high_pressure_delta()
|
||||
//Used by process()
|
||||
//Warning: Do not call this
|
||||
|
||||
process_super_conductivity()
|
||||
//Used by process()
|
||||
//Warning: Do not call this
|
||||
|
||||
process_update_tiles()
|
||||
//Used by process()
|
||||
//Warning: Do not call this
|
||||
|
||||
process_rebuild_select_groups()
|
||||
//Used by process()
|
||||
//Warning: Do not call this
|
||||
|
||||
rebuild_group(datum/air_group)
|
||||
//Used by process_rebuild_select_groups()
|
||||
//Warning: Do not call this, add the group to air_master.groups_to_rebuild instead
|
||||
|
||||
add_singleton(turf/simulated/T)
|
||||
if(!active_singletons.Find(T))
|
||||
active_singletons += T
|
||||
|
||||
setup()
|
||||
set background = 1
|
||||
world << "<span class='danger'>Processing Geometry...</span>"
|
||||
sleep(1)
|
||||
|
||||
var/start_time = world.timeofday
|
||||
|
||||
for(var/turf/simulated/S in world)
|
||||
if(!S.blocks_air && !S.parent)
|
||||
assemble_group_turf(S)
|
||||
S.update_air_properties()
|
||||
|
||||
world << "<span class='danger'>Geometry processed in [(world.timeofday-start_time)/10] seconds!</span>"
|
||||
|
||||
assemble_group_turf(turf/simulated/base)
|
||||
|
||||
var/list/turf/simulated/members = list(base) //Confirmed group members
|
||||
var/list/turf/simulated/possible_members = list(base) //Possible places for group expansion
|
||||
var/list/turf/simulated/possible_borders = list()
|
||||
var/list/turf/simulated/possible_space_borders = list()
|
||||
var/possible_space_length = 0
|
||||
|
||||
while(possible_members.len>0) //Keep expanding, looking for new members
|
||||
for(var/turf/simulated/test in possible_members)
|
||||
test.length_space_border = 0
|
||||
for(var/direction in cardinal)
|
||||
var/turf/T = get_step(test,direction)
|
||||
if(T && !members.Find(T) && test.CanPass(null, T, null,1))
|
||||
if(istype(T,/turf/simulated) && !T:parent)
|
||||
possible_members += T
|
||||
members += T
|
||||
else if(istype(T,/turf/space))
|
||||
possible_space_borders -= test
|
||||
possible_space_borders += test
|
||||
test.length_space_border++
|
||||
else
|
||||
possible_borders -= test
|
||||
possible_borders += test
|
||||
if(test.length_space_border > 0)
|
||||
possible_space_length += test.length_space_border
|
||||
possible_members -= test
|
||||
|
||||
if(members.len > 1)
|
||||
var/datum/air_group/turf/group = new
|
||||
if(possible_borders.len>0)
|
||||
group.borders = possible_borders
|
||||
if(possible_space_borders.len>0)
|
||||
group.space_borders = possible_space_borders
|
||||
group.length_space_border = possible_space_length
|
||||
|
||||
for(var/turf/simulated/test in members)
|
||||
test.parent = group
|
||||
test.processing = 0
|
||||
active_singletons -= test
|
||||
|
||||
group.members = members
|
||||
air_groups += group
|
||||
|
||||
group.update_group_from_tiles() //Initialize air group variables
|
||||
return group
|
||||
else
|
||||
base.processing = 0 //singletons at startup are technically unconnected anyway
|
||||
base.parent = null
|
||||
|
||||
if(base.air.check_tile_graphic())
|
||||
base.update_visuals(base.air)
|
||||
|
||||
return null
|
||||
/*
|
||||
assemble_group_object(obj/movable/floor/base)
|
||||
|
||||
var/list/obj/movable/floor/members = list(base) //Confirmed group members
|
||||
var/list/obj/movable/floor/possible_members = list(base) //Possible places for group expansion
|
||||
var/list/obj/movable/floor/possible_borders = list()
|
||||
|
||||
while(possible_members.len>0) //Keep expanding, looking for new members
|
||||
for(var/obj/movable/floor/test in possible_members)
|
||||
for(var/direction in list(NORTH, SOUTH, EAST, WEST))
|
||||
var/turf/T = get_step(test.loc,direction)
|
||||
if(T && test.loc.CanPass(null, T, null, 1))
|
||||
var/obj/movable/floor/O = locate(/obj/movable/floor) in T
|
||||
if(istype(O) && !O.parent)
|
||||
if(!members.Find(O))
|
||||
possible_members += O
|
||||
members += O
|
||||
else
|
||||
possible_borders -= test
|
||||
possible_borders += test
|
||||
possible_members -= test
|
||||
|
||||
if(members.len > 1)
|
||||
var/datum/air_group/object/group = new
|
||||
if(possible_borders.len>0)
|
||||
group.borders = possible_borders
|
||||
|
||||
for(var/obj/movable/floor/test in members)
|
||||
test.parent = group
|
||||
test.processing = 0
|
||||
active_singletons -= test
|
||||
|
||||
group.members = members
|
||||
air_groups += group
|
||||
|
||||
group.update_group_from_tiles() //Initialize air group variables
|
||||
return group
|
||||
else
|
||||
base.processing = 0 //singletons at startup are technically unconnected anyway
|
||||
base.parent = null
|
||||
|
||||
return null
|
||||
*/
|
||||
process()
|
||||
if(kill_air)
|
||||
return 1
|
||||
current_cycle++
|
||||
if(groups_to_rebuild.len > 0) process_rebuild_select_groups()
|
||||
if(tiles_to_update.len > 0) process_update_tiles()
|
||||
|
||||
process_groups()
|
||||
process_singletons()
|
||||
|
||||
process_super_conductivity()
|
||||
process_high_pressure_delta()
|
||||
|
||||
if(current_cycle%10==5) //Check for groups of tiles to resume group processing every 10 cycles
|
||||
for(var/datum/air_group/AG in air_groups)
|
||||
AG.check_regroup()
|
||||
|
||||
return 1
|
||||
|
||||
process_update_tiles()
|
||||
for(var/turf/simulated/T in tiles_to_update)
|
||||
T.update_air_properties()
|
||||
/*
|
||||
for(var/obj/movable/floor/O in tiles_to_update)
|
||||
O.update_air_properties()
|
||||
*/
|
||||
tiles_to_update.len = 0
|
||||
|
||||
process_rebuild_select_groups()
|
||||
var/turf/list/turfs = list()
|
||||
|
||||
for(var/datum/air_group/turf/turf_AG in groups_to_rebuild) //Deconstruct groups, gathering their old members
|
||||
for(var/turf in turf_AG.members)
|
||||
var/turf/simulated/T = turf
|
||||
T.parent = null
|
||||
turfs += T
|
||||
qdel(turf_AG)
|
||||
|
||||
for(var/turf/simulated/S in turfs) //Have old members try to form new groups
|
||||
if(!S.parent)
|
||||
assemble_group_turf(S)
|
||||
for(var/turf/simulated/S in turfs)
|
||||
S.update_air_properties()
|
||||
|
||||
// var/obj/movable/list/movable_objects = list()
|
||||
|
||||
// for(var/datum/air_group/object/object_AG in groups_to_rebuild) //Deconstruct groups, gathering their old members
|
||||
/*
|
||||
for(var/obj/movable/floor/OM in object_AG.members)
|
||||
OM.parent = null
|
||||
movable_objects += OM
|
||||
qdel(object_AG)
|
||||
|
||||
for(var/obj/movable/floor/OM in movable_objects) //Have old members try to form new groups
|
||||
if(!OM.parent)
|
||||
assemble_group_object(OM)
|
||||
for(var/obj/movable/floor/OM in movable_objects)
|
||||
OM.update_air_properties()
|
||||
*/
|
||||
groups_to_rebuild.len = 0
|
||||
|
||||
process_groups()
|
||||
for(var/datum/air_group/AG in air_groups)
|
||||
AG.process_group()
|
||||
|
||||
process_singletons()
|
||||
for(var/item in active_singletons)
|
||||
item:process_cell()
|
||||
|
||||
process_super_conductivity()
|
||||
for(var/turf/simulated/hot_potato in active_super_conductivity)
|
||||
hot_potato.super_conduct()
|
||||
|
||||
process_high_pressure_delta()
|
||||
for(var/turf/pressurized in high_pressure_delta)
|
||||
pressurized.high_pressure_movements()
|
||||
|
||||
high_pressure_delta.len = 0
|
||||
@@ -1,560 +0,0 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
|
||||
|
||||
atom/movable/var/pressure_resistance = 5
|
||||
atom/movable/var/last_forced_movement = 0
|
||||
|
||||
atom/movable/proc/experience_pressure_difference(pressure_difference, direction)
|
||||
if(last_forced_movement >= air_master.current_cycle)
|
||||
return 0
|
||||
else if(!anchored)
|
||||
if(pressure_difference > pressure_resistance)
|
||||
last_forced_movement = air_master.current_cycle
|
||||
spawn step(src, direction)
|
||||
return 1
|
||||
|
||||
turf
|
||||
assume_air(datum/gas_mixture/giver) //use this for machines to adjust air
|
||||
qdel(giver)
|
||||
return 0
|
||||
|
||||
return_air()
|
||||
//Create gas mixture to hold data for passing
|
||||
var/datum/gas_mixture/GM = new
|
||||
|
||||
GM.oxygen = oxygen
|
||||
GM.carbon_dioxide = carbon_dioxide
|
||||
GM.nitrogen = nitrogen
|
||||
GM.toxins = toxins
|
||||
|
||||
GM.temperature = temperature
|
||||
|
||||
return GM
|
||||
|
||||
remove_air(amount as num)
|
||||
var/datum/gas_mixture/GM = new
|
||||
|
||||
var/sum = oxygen + carbon_dioxide + nitrogen + toxins
|
||||
if(sum>0)
|
||||
GM.oxygen = (oxygen/sum)*amount
|
||||
GM.carbon_dioxide = (carbon_dioxide/sum)*amount
|
||||
GM.nitrogen = (nitrogen/sum)*amount
|
||||
GM.toxins = (toxins/sum)*amount
|
||||
|
||||
GM.temperature = temperature
|
||||
|
||||
return GM
|
||||
|
||||
turf
|
||||
var/pressure_difference = 0
|
||||
var/pressure_direction = 0
|
||||
var/reporting_pressure_difference
|
||||
|
||||
//optimization vars
|
||||
var/next_check = 0 //number of ticks before this tile updates
|
||||
var/check_delay = 0 //number of ticks between updates
|
||||
|
||||
proc/high_pressure_movements()
|
||||
if(reporting_pressure_difference)
|
||||
world << "pressure_difference = [pressure_difference]; pressure_direction = [pressure_direction]"
|
||||
for(var/atom/movable/in_tile in src)
|
||||
in_tile.experience_pressure_difference(pressure_difference, pressure_direction)
|
||||
|
||||
pressure_difference = 0
|
||||
|
||||
proc/consider_pressure_difference(connection_difference, connection_direction)
|
||||
if(connection_difference < 0)
|
||||
connection_difference = -connection_difference
|
||||
connection_direction = turn(connection_direction,180)
|
||||
|
||||
if(connection_difference > pressure_difference)
|
||||
if(!pressure_difference)
|
||||
air_master.high_pressure_delta += src
|
||||
pressure_difference = connection_difference
|
||||
pressure_direction = connection_direction
|
||||
|
||||
turf/simulated/proc/consider_pressure_difference_space(connection_difference)
|
||||
for(var/direction in cardinal)
|
||||
if(direction&group_border)
|
||||
if(istype(get_step(src,direction),/turf/space))
|
||||
if(!pressure_difference)
|
||||
air_master.high_pressure_delta += src
|
||||
pressure_direction = direction
|
||||
pressure_difference = connection_difference
|
||||
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
turf/simulated
|
||||
|
||||
var/current_graphic = null
|
||||
|
||||
var/tmp/datum/gas_mixture/air
|
||||
|
||||
var/tmp/processing = 1
|
||||
var/tmp/datum/air_group/turf/parent
|
||||
var/tmp/group_border = 0
|
||||
var/tmp/length_space_border = 0
|
||||
|
||||
var/tmp/air_check_directions = 0 //Do not modify this, just add turf to air_master.tiles_to_update
|
||||
|
||||
var/tmp/archived_cycle = 0
|
||||
var/tmp/current_cycle = 0
|
||||
|
||||
var/tmp/obj/effect/hotspot/active_hotspot
|
||||
|
||||
var/tmp/temperature_archived //USED ONLY FOR SOLIDS
|
||||
var/tmp/being_superconductive = 0
|
||||
|
||||
proc/update_visuals(datum/gas_mixture/model)
|
||||
overlays.Cut()
|
||||
|
||||
var/siding_icon_state = return_siding_icon_state()
|
||||
if(siding_icon_state)
|
||||
overlays += image('icons/turf/floors.dmi',siding_icon_state)
|
||||
|
||||
switch(model.graphic)
|
||||
if("plasma")
|
||||
overlays.Add(plmaster)
|
||||
if("sleeping_agent")
|
||||
overlays.Add(slmaster)
|
||||
|
||||
|
||||
|
||||
New()
|
||||
..()
|
||||
|
||||
if(!blocks_air)
|
||||
air = new
|
||||
|
||||
air.oxygen = oxygen
|
||||
air.carbon_dioxide = carbon_dioxide
|
||||
air.nitrogen = nitrogen
|
||||
air.toxins = toxins
|
||||
|
||||
air.temperature = temperature
|
||||
|
||||
if(air_master)
|
||||
air_master.tiles_to_update.Add(src)
|
||||
|
||||
find_group()
|
||||
|
||||
// air.parent = src //TODO DEBUG REMOVE
|
||||
|
||||
else
|
||||
if(air_master)
|
||||
for(var/direction in cardinal)
|
||||
var/turf/simulated/floor/target = get_step(src,direction)
|
||||
if(istype(target))
|
||||
air_master.tiles_to_update.Add(target)
|
||||
|
||||
Destroy()
|
||||
if(air_master)
|
||||
if(parent)
|
||||
air_master.groups_to_rebuild.Add(parent)
|
||||
parent.members.Remove(src)
|
||||
else
|
||||
air_master.active_singletons.Remove(src)
|
||||
if(active_hotspot)
|
||||
active_hotspot.Kill()
|
||||
if(blocks_air)
|
||||
for(var/direction in list(NORTH, SOUTH, EAST, WEST))
|
||||
var/turf/simulated/tile = get_step(src,direction)
|
||||
if(istype(tile) && !tile.blocks_air)
|
||||
air_master.tiles_to_update.Add(tile)
|
||||
..()
|
||||
|
||||
assume_air(datum/gas_mixture/giver)
|
||||
if(!giver) return 0
|
||||
var/datum/gas_mixture/receiver = air
|
||||
if(istype(receiver))
|
||||
if(parent&&parent.group_processing)
|
||||
if(!parent.air.check_then_merge(giver))
|
||||
parent.suspend_group_processing()
|
||||
air.merge(giver)
|
||||
else
|
||||
if (giver.total_moles() > MINIMUM_AIR_TO_SUSPEND)
|
||||
reset_delay()
|
||||
|
||||
air.merge(giver)
|
||||
|
||||
if(!processing)
|
||||
if(air.check_tile_graphic())
|
||||
update_visuals(air)
|
||||
|
||||
return 1
|
||||
|
||||
else return ..()
|
||||
|
||||
proc/archive()
|
||||
if(air) //For open space like floors
|
||||
air.archive()
|
||||
|
||||
temperature_archived = temperature
|
||||
archived_cycle = air_master.current_cycle
|
||||
|
||||
proc/share_air_with_tile(turf/simulated/T)
|
||||
return air.share(T.air)
|
||||
|
||||
proc/mimic_air_with_tile(turf/T)
|
||||
return air.mimic(T)
|
||||
|
||||
return_air()
|
||||
if(air)
|
||||
if(parent&&parent.group_processing)
|
||||
return parent.air
|
||||
else return air
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
remove_air(amount as num)
|
||||
if(air)
|
||||
var/datum/gas_mixture/removed = null
|
||||
|
||||
if(parent&&parent.group_processing)
|
||||
removed = parent.air.check_then_remove(amount)
|
||||
if(!removed)
|
||||
parent.suspend_group_processing()
|
||||
removed = air.remove(amount)
|
||||
else
|
||||
removed = air.remove(amount)
|
||||
|
||||
if(!processing)
|
||||
if(air.check_tile_graphic())
|
||||
update_visuals(air)
|
||||
|
||||
return removed
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
proc/update_air_properties()//OPTIMIZE
|
||||
air_check_directions = 0
|
||||
|
||||
for(var/direction in cardinal)
|
||||
if(CanPass(null, get_step(src,direction), 0, 0))
|
||||
air_check_directions |= direction
|
||||
|
||||
if(parent)
|
||||
if(parent.borders)
|
||||
parent.borders -= src
|
||||
if(length_space_border > 0)
|
||||
parent.length_space_border -= length_space_border
|
||||
length_space_border = 0
|
||||
|
||||
group_border = 0
|
||||
for(var/direction in cardinal)
|
||||
if(air_check_directions&direction)
|
||||
var/turf/simulated/T = get_step(src,direction)
|
||||
|
||||
//See if actually a border
|
||||
if(!istype(T) || (T.parent!=parent))
|
||||
|
||||
//See what kind of border it is
|
||||
if(istype(T,/turf/space))
|
||||
if(parent.space_borders)
|
||||
parent.space_borders -= src
|
||||
parent.space_borders += src
|
||||
else
|
||||
parent.space_borders = list(src)
|
||||
length_space_border++
|
||||
|
||||
else
|
||||
if(parent.borders)
|
||||
parent.borders -= src
|
||||
parent.borders += src
|
||||
else
|
||||
parent.borders = list(src)
|
||||
|
||||
group_border |= direction
|
||||
|
||||
parent.length_space_border += length_space_border
|
||||
|
||||
if(air_check_directions)
|
||||
processing = 1
|
||||
if(!parent)
|
||||
air_master.add_singleton(src)
|
||||
else
|
||||
processing = 0
|
||||
|
||||
proc/process_cell()
|
||||
//this proc does all the heavy lifting for individual tile processing
|
||||
//it shares with all of its neighbors, spreads fire, calls superconduction
|
||||
//and doesn't afraid of anything
|
||||
//Comment by errorage: In other words, this is the proc that lags the game.
|
||||
|
||||
//check if we're skipping this tick
|
||||
if (next_check > 0)
|
||||
next_check--
|
||||
return 1
|
||||
var/player_count = max(player_list.len, 3) / 3
|
||||
next_check += check_delay + rand(player_count, player_count * 1.5)
|
||||
check_delay++
|
||||
|
||||
var/turf/simulated/list/possible_fire_spreads = list()
|
||||
if(processing)
|
||||
if(archived_cycle < air_master.current_cycle) //archive self if not already done
|
||||
archive()
|
||||
current_cycle = air_master.current_cycle
|
||||
|
||||
for(var/direction in cardinal)
|
||||
if(air_check_directions&direction) //Grab all valid bordering tiles
|
||||
var/turf/simulated/enemy_tile = get_step(src, direction)
|
||||
var/connection_difference = 0
|
||||
|
||||
if(istype(enemy_tile)) //enemy_tile == neighbor, btw
|
||||
if(enemy_tile.archived_cycle < archived_cycle) //archive bordering tile information if not already done
|
||||
enemy_tile.archive()
|
||||
|
||||
if (air && enemy_tile.air)
|
||||
var/delay_trigger = air.compare(enemy_tile.air)
|
||||
if (!delay_trigger) //if compare() didn't return 1, air is different enough to trigger processing
|
||||
reset_delay()
|
||||
enemy_tile.reset_delay()
|
||||
|
||||
if(enemy_tile.parent && enemy_tile.parent.group_processing) //apply tile to group sharing
|
||||
if(enemy_tile.parent.current_cycle < current_cycle) //if the group hasn't been archived, it could just be out of date
|
||||
if(enemy_tile.parent.air.check_gas_mixture(air))
|
||||
connection_difference = air.share(enemy_tile.parent.air)
|
||||
else
|
||||
enemy_tile.parent.suspend_group_processing()
|
||||
connection_difference = air.share(enemy_tile.air)
|
||||
//group processing failed so interact with individual tile
|
||||
|
||||
else
|
||||
if(enemy_tile.current_cycle < current_cycle)
|
||||
connection_difference = air.share(enemy_tile.air)
|
||||
|
||||
if(active_hotspot)
|
||||
possible_fire_spreads += enemy_tile
|
||||
else
|
||||
/* var/obj/movable/floor/movable_on_enemy = locate(/obj/movable/floor) in enemy_tile
|
||||
|
||||
if(movable_on_enemy)
|
||||
if(movable_on_enemy.parent && movable_on_enemy.parent.group_processing) //apply tile to group sharing
|
||||
if(movable_on_enemy.parent.current_cycle < current_cycle)
|
||||
if(movable_on_enemy.parent.air.check_gas_mixture(air))
|
||||
connection_difference = air.share(movable_on_enemy.parent.air)
|
||||
|
||||
else
|
||||
movable_on_enemy.parent.suspend_group_processing()
|
||||
|
||||
if(movable_on_enemy.archived_cycle < archived_cycle) //archive bordering tile information if not already done
|
||||
movable_on_enemy.archive()
|
||||
connection_difference = air.share(movable_on_enemy.air)
|
||||
//group processing failed so interact with individual tile
|
||||
else
|
||||
if(movable_on_enemy.archived_cycle < archived_cycle) //archive bordering tile information if not already done
|
||||
movable_on_enemy.archive()
|
||||
|
||||
if(movable_on_enemy.current_cycle < current_cycle)
|
||||
connection_difference = share_air_with_tile(movable_on_enemy)
|
||||
|
||||
else*/
|
||||
connection_difference = mimic_air_with_tile(enemy_tile)
|
||||
//bordering a tile with fixed air properties
|
||||
|
||||
if(connection_difference)
|
||||
if(connection_difference > 0)
|
||||
consider_pressure_difference(connection_difference, direction)
|
||||
else
|
||||
enemy_tile.consider_pressure_difference(connection_difference, direction)
|
||||
else
|
||||
air_master.active_singletons -= src //not active if not processing!
|
||||
|
||||
air.react()
|
||||
|
||||
if(active_hotspot)
|
||||
if (!active_hotspot.process(possible_fire_spreads))
|
||||
return 0
|
||||
|
||||
if(air.temperature > MINIMUM_TEMPERATURE_START_SUPERCONDUCTION)
|
||||
consider_superconductivity(starting = 1)
|
||||
|
||||
if(air.check_tile_graphic())
|
||||
update_visuals(air)
|
||||
|
||||
if(air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
|
||||
reset_delay() //hotspots always process quickly
|
||||
hotspot_expose(air.temperature, CELL_VOLUME)
|
||||
for(var/atom/movable/item in src)
|
||||
item.temperature_expose(air, air.temperature, CELL_VOLUME)
|
||||
temperature_expose(air, air.temperature, CELL_VOLUME)
|
||||
|
||||
return 1
|
||||
|
||||
proc/super_conduct()
|
||||
var/conductivity_directions = 0
|
||||
if(blocks_air)
|
||||
//Does not participate in air exchange, so will conduct heat across all four borders at this time
|
||||
conductivity_directions = NORTH|SOUTH|EAST|WEST
|
||||
|
||||
if(archived_cycle < air_master.current_cycle)
|
||||
archive()
|
||||
|
||||
else
|
||||
//Does particate in air exchange so only consider directions not considered during process_cell()
|
||||
conductivity_directions = ~air_check_directions & (NORTH|SOUTH|EAST|WEST)
|
||||
|
||||
if(conductivity_directions>0)
|
||||
//Conduct with tiles around me
|
||||
for(var/direction in cardinal)
|
||||
if(conductivity_directions&direction)
|
||||
var/turf/neighbor = get_step(src,direction)
|
||||
|
||||
if(istype(neighbor, /turf/simulated)) //anything under this subtype will share in the exchange
|
||||
var/turf/simulated/modeled_neighbor = neighbor
|
||||
|
||||
if(modeled_neighbor.archived_cycle < air_master.current_cycle)
|
||||
modeled_neighbor.archive()
|
||||
|
||||
if(modeled_neighbor.air)
|
||||
if(air) //Both tiles are open
|
||||
|
||||
if(modeled_neighbor.parent && modeled_neighbor.parent.group_processing)
|
||||
if(parent && parent.group_processing)
|
||||
//both are acting as a group
|
||||
//modified using construct developed in datum/air_group/share_air_with_group(...)
|
||||
|
||||
var/result = parent.air.check_both_then_temperature_share(modeled_neighbor.parent.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
|
||||
if(result==0)
|
||||
//have to deconstruct parent air group
|
||||
|
||||
parent.suspend_group_processing()
|
||||
if(!modeled_neighbor.parent.air.check_me_then_temperature_share(air, WINDOW_HEAT_TRANSFER_COEFFICIENT))
|
||||
//may have to deconstruct neighbors air group
|
||||
|
||||
modeled_neighbor.parent.suspend_group_processing()
|
||||
air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
|
||||
else if(result==-1)
|
||||
// have to deconstruct neightbors air group but not mine
|
||||
|
||||
modeled_neighbor.parent.suspend_group_processing()
|
||||
parent.air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
|
||||
else
|
||||
air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
|
||||
else
|
||||
if(parent && parent.group_processing)
|
||||
if(!parent.air.check_me_then_temperature_share(air, WINDOW_HEAT_TRANSFER_COEFFICIENT))
|
||||
//may have to deconstruct neighbors air group
|
||||
|
||||
parent.suspend_group_processing()
|
||||
air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
|
||||
|
||||
else
|
||||
air.temperature_share(modeled_neighbor.air, WINDOW_HEAT_TRANSFER_COEFFICIENT)
|
||||
// world << "OPEN, OPEN"
|
||||
|
||||
else //Solid but neighbor is open
|
||||
if(modeled_neighbor.parent && modeled_neighbor.parent.group_processing)
|
||||
if(!modeled_neighbor.parent.air.check_me_then_temperature_turf_share(src, modeled_neighbor.thermal_conductivity))
|
||||
|
||||
modeled_neighbor.parent.suspend_group_processing()
|
||||
modeled_neighbor.air.temperature_turf_share(src, modeled_neighbor.thermal_conductivity)
|
||||
else
|
||||
modeled_neighbor.air.temperature_turf_share(src, modeled_neighbor.thermal_conductivity)
|
||||
// world << "SOLID, OPEN"
|
||||
|
||||
else
|
||||
if(air) //Open but neighbor is solid
|
||||
if(parent && parent.group_processing)
|
||||
if(!parent.air.check_me_then_temperature_turf_share(modeled_neighbor, modeled_neighbor.thermal_conductivity))
|
||||
parent.suspend_group_processing()
|
||||
air.temperature_turf_share(modeled_neighbor, modeled_neighbor.thermal_conductivity)
|
||||
else
|
||||
air.temperature_turf_share(modeled_neighbor, modeled_neighbor.thermal_conductivity)
|
||||
// world << "OPEN, SOLID"
|
||||
|
||||
else //Both tiles are solid
|
||||
share_temperature_mutual_solid(modeled_neighbor, modeled_neighbor.thermal_conductivity)
|
||||
// world << "SOLID, SOLID"
|
||||
|
||||
modeled_neighbor.consider_superconductivity()
|
||||
|
||||
else
|
||||
if(air) //Open
|
||||
if(parent && parent.group_processing)
|
||||
if(!parent.air.check_me_then_temperature_mimic(neighbor, neighbor.thermal_conductivity))
|
||||
parent.suspend_group_processing()
|
||||
air.temperature_mimic(neighbor, neighbor.thermal_conductivity)
|
||||
else
|
||||
air.temperature_mimic(neighbor, neighbor.thermal_conductivity)
|
||||
else
|
||||
mimic_temperature_solid(neighbor, neighbor.thermal_conductivity)
|
||||
|
||||
//Radiate excess tile heat to space
|
||||
if(temperature > T0C)
|
||||
// Is there a pre-defined Space Tile?
|
||||
if(!Space_Tile)
|
||||
Space_Tile = locate(/turf/space) // Define one
|
||||
//Considering 0 degC as te break even point for radiation in and out
|
||||
mimic_temperature_solid(Space_Tile, FLOOR_HEAT_TRANSFER_COEFFICIENT)
|
||||
|
||||
//Conduct with air on my tile if I have it
|
||||
if(air)
|
||||
if(parent && parent.group_processing)
|
||||
if(!parent.air.check_me_then_temperature_turf_share(src, thermal_conductivity))
|
||||
parent.suspend_group_processing()
|
||||
air.temperature_turf_share(src, thermal_conductivity)
|
||||
else
|
||||
air.temperature_turf_share(src, thermal_conductivity)
|
||||
|
||||
|
||||
//Make sure still hot enough to continue conducting heat
|
||||
if(air)
|
||||
if(air.temperature < MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION)
|
||||
being_superconductive = 0
|
||||
air_master.active_super_conductivity -= src
|
||||
return 0
|
||||
|
||||
else
|
||||
if(temperature < MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION)
|
||||
being_superconductive = 0
|
||||
air_master.active_super_conductivity -= src
|
||||
return 0
|
||||
|
||||
proc/mimic_temperature_solid(turf/model, conduction_coefficient)
|
||||
var/delta_temperature = (temperature_archived - model.temperature)
|
||||
if((heat_capacity > 0) && (abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER))
|
||||
|
||||
var/heat = conduction_coefficient*delta_temperature* \
|
||||
(heat_capacity*model.heat_capacity/(heat_capacity+model.heat_capacity))
|
||||
temperature -= heat/heat_capacity
|
||||
|
||||
proc/share_temperature_mutual_solid(turf/simulated/sharer, conduction_coefficient)
|
||||
var/delta_temperature = (temperature_archived - sharer.temperature_archived)
|
||||
if(abs(delta_temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER && heat_capacity && sharer.heat_capacity)
|
||||
|
||||
var/heat = conduction_coefficient*delta_temperature* \
|
||||
(heat_capacity*sharer.heat_capacity/(heat_capacity+sharer.heat_capacity))
|
||||
|
||||
temperature -= heat/heat_capacity
|
||||
sharer.temperature += heat/sharer.heat_capacity
|
||||
|
||||
proc/consider_superconductivity(starting)
|
||||
|
||||
if(being_superconductive || !thermal_conductivity)
|
||||
return 0
|
||||
|
||||
if(air)
|
||||
if(air.temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
|
||||
return 0
|
||||
if(air.heat_capacity() < MOLES_CELLSTANDARD*0.1*0.05)
|
||||
return 0
|
||||
else
|
||||
if(temperature < (starting?MINIMUM_TEMPERATURE_START_SUPERCONDUCTION:MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION))
|
||||
return 0
|
||||
|
||||
being_superconductive = 1
|
||||
|
||||
air_master.active_super_conductivity += src
|
||||
|
||||
proc/reset_delay()
|
||||
//sets this turf to process quickly again
|
||||
next_check=0
|
||||
check_delay= -5 //negative numbers mean a mandatory quick-update period
|
||||
|
||||
//if this turf has a parent air group, suspend its processing
|
||||
if (parent && parent.group_processing)
|
||||
parent.suspend_group_processing()
|
||||
@@ -1,376 +0,0 @@
|
||||
/atom/DblClick(location, control, params) //TODO: DEFERRED: REWRITE
|
||||
if(!usr) return
|
||||
|
||||
// ------- TIME SINCE LAST CLICK -------
|
||||
if (world.time <= usr:lastDblClick+1)
|
||||
return
|
||||
else
|
||||
usr:lastDblClick = world.time
|
||||
|
||||
//Putting it here for now. It diverts stuff to the mech clicking procs. Putting it here stops us drilling items in our inventory Carn
|
||||
if(istype(usr.loc,/obj/mecha))
|
||||
if(usr.client && (src in usr.client.screen))
|
||||
return
|
||||
var/obj/mecha/Mech = usr.loc
|
||||
Mech.click_action(src,usr)
|
||||
return
|
||||
|
||||
// ------- DIR CHANGING WHEN CLICKING ------
|
||||
if( iscarbon(usr) && !usr.buckled )
|
||||
if( src.x && src.y && usr.x && usr.y )
|
||||
var/dx = src.x - usr.x
|
||||
var/dy = src.y - usr.y
|
||||
|
||||
if(dy || dx)
|
||||
if(abs(dx) < abs(dy))
|
||||
if(dy > 0) usr.set_dir(NORTH)
|
||||
else usr.set_dir(SOUTH)
|
||||
else
|
||||
if(dx > 0) usr.set_dir(EAST)
|
||||
else usr.set_dir(WEST)
|
||||
else
|
||||
if(pixel_y > 16) usr.set_dir(NORTH)
|
||||
else if(pixel_y < -16) usr.set_dir(SOUTH)
|
||||
else if(pixel_x > 16) usr.set_dir(EAST)
|
||||
else if(pixel_x < -16) usr.set_dir(WEST)
|
||||
|
||||
|
||||
|
||||
|
||||
// ------- AI -------
|
||||
else if (istype(usr, /mob/living/silicon/ai))
|
||||
var/mob/living/silicon/ai/ai = usr
|
||||
if (ai.control_disabled)
|
||||
return
|
||||
|
||||
// ------- CYBORG -------
|
||||
else if (istype(usr, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/bot = usr
|
||||
if (bot.lockcharge) return
|
||||
..()
|
||||
|
||||
|
||||
// ------- SHIFT-CLICK -------
|
||||
|
||||
if(params)
|
||||
var/parameters = params2list(params)
|
||||
|
||||
if(parameters["shift"]){
|
||||
if(!isAI(usr))
|
||||
ShiftClick(usr)
|
||||
else
|
||||
AIShiftClick(usr)
|
||||
return
|
||||
}
|
||||
|
||||
// ------- ALT-CLICK -------
|
||||
|
||||
if(parameters["alt"]){
|
||||
if(!isAI(usr))
|
||||
AltClick(usr)
|
||||
else
|
||||
AIAltClick(usr)
|
||||
return
|
||||
}
|
||||
|
||||
// ------- CTRL-CLICK -------
|
||||
|
||||
if(parameters["ctrl"]){
|
||||
if(!isAI(usr))
|
||||
CtrlClick(usr)
|
||||
else
|
||||
AICtrlClick(usr)
|
||||
return
|
||||
}
|
||||
|
||||
// ------- MIDDLE-CLICK -------
|
||||
|
||||
if(parameters["middle"]){
|
||||
if(!isAI(usr))
|
||||
MiddleClick(usr)
|
||||
return
|
||||
}
|
||||
|
||||
// ------- THROW -------
|
||||
if(usr.in_throw_mode)
|
||||
return usr:throw_item(src)
|
||||
|
||||
// ------- ITEM IN HAND DEFINED -------
|
||||
var/obj/item/W = usr.get_active_hand()
|
||||
/* Now handled by get_active_hand()
|
||||
// ------- ROBOT -------
|
||||
if(istype(usr, /mob/living/silicon/robot))
|
||||
if(!isnull(usr:module_active))
|
||||
W = usr:module_active
|
||||
else
|
||||
W = null
|
||||
*/
|
||||
// ------- ATTACK SELF -------
|
||||
if (W == src && usr.stat == 0)
|
||||
W.attack_self(usr)
|
||||
if(usr.hand)
|
||||
usr.update_inv_l_hand(0) //update in-hand overlays
|
||||
else
|
||||
usr.update_inv_r_hand(0)
|
||||
return
|
||||
|
||||
// ------- PARALYSIS, STUN, WEAKENED, DEAD, (And not AI) -------
|
||||
if (((usr.paralysis || usr.stunned || usr.weakened) && !istype(usr, /mob/living/silicon/ai)) || usr.stat != 0)
|
||||
return
|
||||
|
||||
// ------- CLICKING STUFF IN CONTAINERS -------
|
||||
if ((!( src in usr.contents ) && (((!( isturf(src) ) && (!( isturf(src.loc) ) && (src.loc && !( isturf(src.loc.loc) )))) || !( isturf(usr.loc) )) && (src.loc != usr.loc && (!( istype(src, /obj/screen) ) && !( usr.contents.Find(src.loc) ))))))
|
||||
if (istype(usr, /mob/living/silicon/ai))
|
||||
var/mob/living/silicon/ai/ai = usr
|
||||
if (ai.control_disabled)
|
||||
return
|
||||
else
|
||||
return
|
||||
|
||||
// ------- 1 TILE AWAY -------
|
||||
var/t5
|
||||
// ------- AI CAN CLICK ANYTHING -------
|
||||
if(istype(usr, /mob/living/silicon/ai))
|
||||
t5 = 1
|
||||
// ------- CYBORG CAN CLICK ANYTHING WHEN NOT HOLDING STUFF -------
|
||||
else if(istype(usr, /mob/living/silicon/robot) && !W)
|
||||
t5 = 1
|
||||
else
|
||||
t5 = in_range(src, usr) || src.loc == usr
|
||||
|
||||
// world << "according to dblclick(), t5 is [t5]"
|
||||
|
||||
// ------- ACTUALLY DETERMINING STUFF -------
|
||||
if (((t5 || (W && (W.flags & USEDELAY))) && !( istype(src, /obj/screen) )))
|
||||
|
||||
// ------- ( CAN USE ITEM OR HAS 1 SECOND USE DELAY ) AND NOT CLICKING ON SCREEN -------
|
||||
|
||||
if (usr.next_move < world.time)
|
||||
usr.prev_move = usr.next_move
|
||||
usr.next_move = world.time + 10
|
||||
else
|
||||
// ------- ALREADY USED ONE ITEM WITH USE DELAY IN THE PREVIOUS SECOND -------
|
||||
return
|
||||
|
||||
// ------- DELAY CHECK PASSED -------
|
||||
|
||||
if ((src.loc && (get_dist(src, usr) < 2 || src.loc == usr.loc)))
|
||||
|
||||
// ------- CLICKED OBJECT EXISTS IN GAME WORLD, DISTANCE FROM PERSON TO OBJECT IS 1 SQUARE OR THEY'RE ON THE SAME SQUARE -------
|
||||
|
||||
var/direct = get_dir(usr, src)
|
||||
var/obj/item/weapon/dummy/D = new /obj/item/weapon/dummy( usr.loc )
|
||||
var/ok = 0
|
||||
if ( (direct - 1) & direct)
|
||||
|
||||
// ------- CLICKED OBJECT IS LOCATED IN A DIAGONAL POSITION FROM THE PERSON -------
|
||||
|
||||
var/turf/Step_1
|
||||
var/turf/Step_2
|
||||
switch(direct)
|
||||
if(5.0)
|
||||
Step_1 = get_step(usr, NORTH)
|
||||
Step_2 = get_step(usr, EAST)
|
||||
|
||||
if(6.0)
|
||||
Step_1 = get_step(usr, SOUTH)
|
||||
Step_2 = get_step(usr, EAST)
|
||||
|
||||
if(9.0)
|
||||
Step_1 = get_step(usr, NORTH)
|
||||
Step_2 = get_step(usr, WEST)
|
||||
|
||||
if(10.0)
|
||||
Step_1 = get_step(usr, SOUTH)
|
||||
Step_2 = get_step(usr, WEST)
|
||||
|
||||
else
|
||||
if(Step_1 && Step_2)
|
||||
|
||||
// ------- BOTH CARDINAL DIRECTIONS OF THE DIAGONAL EXIST IN THE GAME WORLD -------
|
||||
|
||||
var/check_1 = 0
|
||||
var/check_2 = 0
|
||||
if(step_to(D, Step_1))
|
||||
check_1 = 1
|
||||
for(var/obj/border_obstacle in Step_1)
|
||||
if(border_obstacle.flags & ON_BORDER)
|
||||
if(!border_obstacle.CheckExit(D, src))
|
||||
check_1 = 0
|
||||
// ------- YOU TRIED TO CLICK ON AN ITEM THROUGH A WINDOW (OR SIMILAR THING THAT LIMITS ON BORDERS) ON ONE OF THE DIRECITON TILES -------
|
||||
for(var/obj/border_obstacle in get_turf(src))
|
||||
if((border_obstacle.flags & ON_BORDER) && (src != border_obstacle))
|
||||
if(!border_obstacle.CanPass(D, D.loc, 1, 0))
|
||||
// ------- YOU TRIED TO CLICK ON AN ITEM THROUGH A WINDOW (OR SIMILAR THING THAT LIMITS ON BORDERS) ON THE TILE YOU'RE ON -------
|
||||
check_1 = 0
|
||||
|
||||
D.loc = usr.loc
|
||||
if(step_to(D, Step_2))
|
||||
check_2 = 1
|
||||
|
||||
for(var/obj/border_obstacle in Step_2)
|
||||
if(border_obstacle.flags & ON_BORDER)
|
||||
if(!border_obstacle.CheckExit(D, src))
|
||||
check_2 = 0
|
||||
for(var/obj/border_obstacle in get_turf(src))
|
||||
if((border_obstacle.flags & ON_BORDER) && (src != border_obstacle))
|
||||
if(!border_obstacle.CanPass(D, D.loc, 1, 0))
|
||||
check_2 = 0
|
||||
|
||||
|
||||
if(check_1 || check_2)
|
||||
ok = 1
|
||||
// ------- YOU CAN REACH THE ITEM THROUGH AT LEAST ONE OF THE TWO DIRECTIONS. GOOD. -------
|
||||
|
||||
/*
|
||||
More info:
|
||||
If you're trying to click an item in the north-east of your mob, the above section of code will first check if tehre's a tile to the north or you and to the east of you
|
||||
These two tiles are Step_1 and Step_2. After this, a new dummy object is created on your location. It then tries to move to Step_1, If it succeeds, objects on the turf you're on and
|
||||
the turf that Step_1 is are checked for items which have the ON_BORDER flag set. These are itmes which limit you on only one tile border. Windows, for the most part.
|
||||
CheckExit() and CanPass() are use to determine this. The dummy object is then moved back to your location and it tries to move to Step_2. Same checks are performed here.
|
||||
If at least one of the two checks succeeds, it means you can reach the item and ok is set to 1.
|
||||
*/
|
||||
else
|
||||
// ------- OBJECT IS ON A CARDINAL TILE (NORTH, SOUTH, EAST OR WEST OR THE TILE YOU'RE ON) -------
|
||||
if(loc == usr.loc)
|
||||
ok = 1
|
||||
// ------- OBJECT IS ON THE SAME TILE AS YOU -------
|
||||
else
|
||||
ok = 1
|
||||
|
||||
//Now, check objects to block exit that are on the border
|
||||
for(var/obj/border_obstacle in usr.loc)
|
||||
if(border_obstacle.flags & ON_BORDER)
|
||||
if(!border_obstacle.CheckExit(D, src))
|
||||
ok = 0
|
||||
|
||||
//Next, check objects to block entry that are on the border
|
||||
for(var/obj/border_obstacle in get_turf(src))
|
||||
if((border_obstacle.flags & ON_BORDER) && (src != border_obstacle))
|
||||
if(!border_obstacle.CanPass(D, D.loc, 1, 0))
|
||||
ok = 0
|
||||
/*
|
||||
See the previous More info, for... more info...
|
||||
*/
|
||||
|
||||
//qdel(D)
|
||||
// Garbage Collect Dummy
|
||||
D.loc = null
|
||||
D = null
|
||||
|
||||
// ------- DUMMY OBJECT'S SERVED IT'S PURPOSE, IT'S REWARDED WITH A SWIFT DELETE -------
|
||||
if (!( ok ))
|
||||
// ------- TESTS ABOVE DETERMINED YOU CANNOT REACH THE TILE -------
|
||||
return 0
|
||||
|
||||
if (!( usr.restrained() || (usr.lying && usr.buckled!=src) ))
|
||||
// ------- YOU ARE NOT REASTRAINED -------
|
||||
|
||||
if (W)
|
||||
// ------- YOU HAVE AN ITEM IN YOUR HAND - HANDLE ATTACKBY AND AFTERATTACK -------
|
||||
var/ignoreAA = 0 //Ignore afterattack(). Surgery uses this.
|
||||
if (t5)
|
||||
ignoreAA = src.attackby(W, usr)
|
||||
if (W && !ignoreAA)
|
||||
W.afterattack(src, usr, (t5 ? 1 : 0), params)
|
||||
|
||||
else
|
||||
// ------- YOU DO NOT HAVE AN ITEM IN YOUR HAND -------
|
||||
if (istype(usr, /mob/living/carbon/human))
|
||||
// ------- YOU ARE HUMAN -------
|
||||
src.attack_hand(usr, usr.hand)
|
||||
else
|
||||
// ------- YOU ARE NOT HUMAN. WHAT ARE YOU - DETERMINED HERE AND PROPER ATTACK_MOBTYPE CALLED -------
|
||||
if (istype(usr, /mob/living/carbon/monkey))
|
||||
src.attack_paw(usr, usr.hand)
|
||||
else if (istype(usr, /mob/living/carbon/alien/humanoid))
|
||||
if(usr.m_intent == "walk" && istype(usr, /mob/living/carbon/alien/humanoid/hunter))
|
||||
usr.m_intent = "run"
|
||||
usr.hud_used.move_intent.icon_state = "running"
|
||||
usr.update_icons()
|
||||
src.attack_alien(usr, usr.hand)
|
||||
else if (istype(usr, /mob/living/carbon/alien/larva))
|
||||
src.attack_larva(usr)
|
||||
else if (istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/living/silicon/robot))
|
||||
src.attack_ai(usr, usr.hand)
|
||||
else if(istype(usr, /mob/living/carbon/slime))
|
||||
src.attack_slime(usr)
|
||||
else if(istype(usr, /mob/living/simple_animal))
|
||||
src.attack_animal(usr)
|
||||
else
|
||||
// ------- YOU ARE RESTRAINED. DETERMINE WHAT YOU ARE AND ATTACK WITH THE PROPER HAND_X PROC -------
|
||||
if (istype(usr, /mob/living/carbon/human))
|
||||
src.hand_h(usr, usr.hand)
|
||||
else if (istype(usr, /mob/living/carbon/monkey))
|
||||
src.hand_p(usr, usr.hand)
|
||||
else if (istype(usr, /mob/living/carbon/alien/humanoid))
|
||||
src.hand_al(usr, usr.hand)
|
||||
else if (istype(usr, /mob/living/silicon/ai) || istype(usr, /mob/living/silicon/robot))
|
||||
src.hand_a(usr, usr.hand)
|
||||
|
||||
else
|
||||
// ------- ITEM INACESSIBLE OR CLICKING ON SCREEN -------
|
||||
if (istype(src, /obj/screen))
|
||||
// ------- IT'S THE HUD YOU'RE CLICKING ON -------
|
||||
usr.prev_move = usr.next_move
|
||||
usr:lastDblClick = world.time + 2
|
||||
if (usr.next_move < world.time)
|
||||
usr.next_move = world.time + 2
|
||||
else
|
||||
return
|
||||
|
||||
// ------- 2 DECISECOND DELAY FOR CLICKING PASSED -------
|
||||
|
||||
if (!( usr.restrained() ))
|
||||
|
||||
// ------- YOU ARE NOT RESTRAINED -------
|
||||
if ((W && !( istype(src, /obj/screen) )))
|
||||
// ------- IT SHOULD NEVER GET TO HERE, DUE TO THE ISTYPE(SRC, /OBJ/SCREEN) FROM PREVIOUS IF-S - I TESTED IT WITH A DEBUG OUTPUT AND I COULDN'T GET THIST TO SHOW UP. -------
|
||||
src.attackby(W, usr)
|
||||
if (W)
|
||||
W.afterattack(src, usr,, params)
|
||||
else
|
||||
// ------- YOU ARE NOT RESTRAINED, AND ARE CLICKING A HUD OBJECT -------
|
||||
if (istype(usr, /mob/living/carbon/human))
|
||||
src.attack_hand(usr, usr.hand)
|
||||
else if (istype(usr, /mob/living/carbon/monkey))
|
||||
src.attack_paw(usr, usr.hand)
|
||||
else if (istype(usr, /mob/living/carbon/alien/humanoid))
|
||||
src.attack_alien(usr, usr.hand)
|
||||
else
|
||||
// ------- YOU ARE RESTRAINED CLICKING ON A HUD OBJECT -------
|
||||
if (istype(usr, /mob/living/carbon/human))
|
||||
src.hand_h(usr, usr.hand)
|
||||
else if (istype(usr, /mob/living/carbon/monkey))
|
||||
src.hand_p(usr, usr.hand)
|
||||
else if (istype(usr, /mob/living/carbon/alien/humanoid))
|
||||
src.hand_al(usr, usr.hand)
|
||||
else
|
||||
// ------- YOU ARE CLICKING ON AN OBJECT THAT'S INACCESSIBLE TO YOU AND IS NOT YOUR HUD -------
|
||||
if((LASER in usr:mutations) && usr:a_intent == I_HURT && world.time >= usr.next_move)
|
||||
// ------- YOU HAVE THE LASER MUTATION, YOUR INTENT SET TO HURT AND IT'S BEEN MORE THAN A DECISECOND SINCE YOU LAS TATTACKED -------
|
||||
|
||||
var/turf/T = get_turf(usr)
|
||||
var/turf/U = get_turf(src)
|
||||
|
||||
|
||||
if(istype(usr, /mob/living/carbon/human))
|
||||
usr:nutrition -= rand(1,5)
|
||||
usr:handle_regular_hud_updates()
|
||||
|
||||
var/obj/item/projectile/beam/A = new /obj/item/projectile/beam( usr.loc )
|
||||
A.icon = 'icons/effects/genetics.dmi'
|
||||
A.icon_state = "eyelasers"
|
||||
playsound(usr.loc, 'sound/weapons/taser2.ogg', 75, 1)
|
||||
|
||||
A.firer = usr
|
||||
A.def_zone = usr:get_organ_target()
|
||||
A.original = src
|
||||
A.current = T
|
||||
A.yo = U.y - T.y
|
||||
A.xo = U.x - T.x
|
||||
spawn( 1 )
|
||||
A.process()
|
||||
|
||||
usr.next_move = world.time + 6
|
||||
return
|
||||
@@ -1,31 +0,0 @@
|
||||
var/list/pending_init_objects
|
||||
|
||||
/datum/controller/process/initialize
|
||||
var/list/objects_to_initialize
|
||||
|
||||
/datum/controller/process/initialize/setup()
|
||||
name = "init"
|
||||
schedule_interval = 1 // Every tick, scary
|
||||
objects_to_initialize = pending_init_objects
|
||||
|
||||
/datum/controller/process/initialize/doWork()
|
||||
for(var/atom/movable/A in objects_to_initialize)
|
||||
A.initialize()
|
||||
scheck()
|
||||
objects_to_initialize.Remove(A)
|
||||
|
||||
if(!objects_to_initialize.len)
|
||||
disable()
|
||||
|
||||
/proc/initialize_object(var/atom/movable/obj_to_init)
|
||||
if(processScheduler.hasProcess("init"))
|
||||
var/datum/controller/process/initialize/init = processScheduler.getProcess("init")
|
||||
init.objects_to_initialize += obj_to_init
|
||||
init.enable()
|
||||
else
|
||||
world.log << "Not yet"
|
||||
if(!pending_init_objects) pending_init_objects = list()
|
||||
pending_init_objects += obj_to_init
|
||||
|
||||
/datum/controller/process/initialize/getStatName()
|
||||
return ..()+"([objects_to_initialize.len])"
|
||||
@@ -1,26 +0,0 @@
|
||||
/datum/controller/process/lighting/setup()
|
||||
name = "lighting"
|
||||
schedule_interval = 5 // every .5 second
|
||||
lighting_controller.initializeLighting()
|
||||
|
||||
/datum/controller/process/lighting/doWork()
|
||||
lighting_controller.lights_workload_max = \
|
||||
max(lighting_controller.lights_workload_max, lighting_controller.lights.len)
|
||||
|
||||
for(var/datum/light_source/L in lighting_controller.lights)
|
||||
if(L && L.check())
|
||||
lighting_controller.lights.Remove(L)
|
||||
|
||||
scheck()
|
||||
|
||||
lighting_controller.changed_turfs_workload_max = \
|
||||
max(lighting_controller.changed_turfs_workload_max, lighting_controller.changed_turfs.len)
|
||||
|
||||
for(var/turf/T in lighting_controller.changed_turfs)
|
||||
if(T && T.lighting_changed)
|
||||
T.shift_to_subarea()
|
||||
|
||||
scheck()
|
||||
|
||||
if(lighting_controller.changed_turfs && lighting_controller.changed_turfs.len)
|
||||
lighting_controller.changed_turfs.len = 0 // reset the changed list
|
||||
@@ -1,50 +0,0 @@
|
||||
var/datum/controller/failsafe/Failsafe
|
||||
|
||||
/datum/controller/failsafe // This thing pretty much just keeps poking the master controller
|
||||
var/processing = 0
|
||||
var/processing_interval = 100 //poke the MC every 10 seconds
|
||||
|
||||
var/MC_iteration = 0
|
||||
var/MC_defcon = 0 //alert level. For every poke that fails this is raised by 1. When it reaches 5 the MC is replaced with a new one. (effectively killing any master_controller.process() and starting a new one)
|
||||
|
||||
var/lighting_iteration = 0
|
||||
var/lighting_defcon = 0 //alert level for lighting controller.
|
||||
|
||||
/datum/controller/failsafe/New()
|
||||
//There can be only one failsafe. Out with the old in with the new (that way we can restart the Failsafe by spawning a new one)
|
||||
if(Failsafe != src)
|
||||
if(istype(Failsafe))
|
||||
qdel(Failsafe)
|
||||
Failsafe = src
|
||||
Failsafe.process()
|
||||
|
||||
|
||||
/datum/controller/failsafe/proc/process()
|
||||
processing = 1
|
||||
spawn(0)
|
||||
set background = 1
|
||||
while(1) //more efficient than recursivly calling ourself over and over. background = 1 ensures we do not trigger an infinite loop
|
||||
if(!master_controller) new /datum/controller/game_controller() //replace the missing master_controller! This should never happen.
|
||||
|
||||
if(processing)
|
||||
if(lighting_controller.processing)
|
||||
if(lighting_iteration == lighting_controller.iteration) //master_controller hasn't finished processing in the defined interval
|
||||
switch(lighting_defcon)
|
||||
if(0 to 3)
|
||||
lighting_defcon++
|
||||
if(4)
|
||||
admins << "<font color='red' size='2'><b>Warning. The Lighting Controller has not fired in the last [lighting_defcon*processing_interval] ticks. Automatic restart in [processing_interval] ticks.</b></font>"
|
||||
lighting_defcon = 5
|
||||
if(5)
|
||||
admins << "<font color='red' size='2'><b>Warning. The Lighting Controller has still not fired within the last [lighting_defcon*processing_interval] ticks. Killing and restarting...</b></font>"
|
||||
new /datum/controller/lighting() //replace the old lighting_controller (hence killing the old one's process)
|
||||
lighting_controller.process() //Start it rolling again
|
||||
lighting_defcon = 0
|
||||
else
|
||||
lighting_defcon = 0
|
||||
lighting_iteration = lighting_controller.iteration
|
||||
else
|
||||
MC_defcon = 0
|
||||
lighting_defcon = 0
|
||||
|
||||
sleep(processing_interval)
|
||||
@@ -1,128 +0,0 @@
|
||||
/////////////////////////// DNA DATUM
|
||||
/datum/dna
|
||||
var/unique_enzymes = null
|
||||
var/struc_enzymes = null
|
||||
var/uni_identity = null
|
||||
var/b_type = "A+"
|
||||
var/mutantrace = null //The type of mutant race the player is if applicable (i.e. potato-man)
|
||||
var/real_name //Stores the real name of the person who originally got this dna datum. Used primarely for changelings,
|
||||
|
||||
/datum/dna/proc/check_integrity(var/mob/living/carbon/human/character)
|
||||
if(character)
|
||||
if(length(uni_identity) != 39)
|
||||
//Lazy.
|
||||
var/temp
|
||||
|
||||
//Hair
|
||||
var/hair = 0
|
||||
if(!character.h_style)
|
||||
character.h_style = "Skinhead"
|
||||
|
||||
var/hrange = round(4095 / hair_styles_list.len)
|
||||
var/index = hair_styles_list.Find(character.h_style)
|
||||
if(index)
|
||||
hair = index * hrange - rand(1,hrange-1)
|
||||
|
||||
//Facial Hair
|
||||
var/beard = 0
|
||||
if(!character.f_style)
|
||||
character.f_style = "Shaved"
|
||||
|
||||
var/f_hrange = round(4095 / facial_hair_styles_list.len)
|
||||
index = facial_hair_styles_list.Find(character.f_style)
|
||||
if(index)
|
||||
beard = index * f_hrange - rand(1,f_hrange-1)
|
||||
|
||||
temp = add_zero2(num2hex((character.r_hair),1), 3)
|
||||
temp += add_zero2(num2hex((character.b_hair),1), 3)
|
||||
temp += add_zero2(num2hex((character.g_hair),1), 3)
|
||||
temp += add_zero2(num2hex((character.r_facial),1), 3)
|
||||
temp += add_zero2(num2hex((character.b_facial),1), 3)
|
||||
temp += add_zero2(num2hex((character.g_facial),1), 3)
|
||||
temp += add_zero2(num2hex(((character.s_tone + 220) * 16),1), 3)
|
||||
temp += add_zero2(num2hex((character.r_eyes),1), 3)
|
||||
temp += add_zero2(num2hex((character.g_eyes),1), 3)
|
||||
temp += add_zero2(num2hex((character.b_eyes),1), 3)
|
||||
|
||||
var/gender
|
||||
|
||||
if (character.gender == MALE)
|
||||
gender = add_zero2(num2hex((rand(1,(2050+BLOCKADD))),1), 3)
|
||||
else
|
||||
gender = add_zero2(num2hex((rand((2051+BLOCKADD),4094)),1), 3)
|
||||
|
||||
temp += gender
|
||||
temp += add_zero2(num2hex((beard),1), 3)
|
||||
temp += add_zero2(num2hex((hair),1), 3)
|
||||
|
||||
uni_identity = temp
|
||||
if(length(struc_enzymes)!= 3*STRUCDNASIZE)
|
||||
var/mutstring = ""
|
||||
for(var/i = 1, i <= STRUCDNASIZE, i++)
|
||||
mutstring += add_zero2(num2hex(rand(1,1024)),3)
|
||||
|
||||
struc_enzymes = mutstring
|
||||
if(length(unique_enzymes) != 32)
|
||||
unique_enzymes = md5(character.real_name)
|
||||
else
|
||||
if(length(uni_identity) != 39) uni_identity = "00600200A00E0110148FC01300B0095BD7FD3F4"
|
||||
if(length(struc_enzymes)!= 3*STRUCDNASIZE) struc_enzymes = "43359156756131E13763334D1C369012032164D4FE4CD61544B6C03F251B6C60A42821D26BA3B0FD6"
|
||||
|
||||
/datum/dna/proc/ready_dna(mob/living/carbon/human/character)
|
||||
var/temp
|
||||
|
||||
//Hair
|
||||
var/hair = 0
|
||||
if(!character.h_style)
|
||||
character.h_style = "Bald"
|
||||
|
||||
var/hrange = round(4095 / hair_styles_list.len)
|
||||
var/index = hair_styles_list.Find(character.h_style)
|
||||
if(index)
|
||||
hair = index * hrange - rand(1,hrange-1)
|
||||
|
||||
//Facial Hair
|
||||
var/beard = 0
|
||||
if(!character.f_style)
|
||||
character.f_style = "Shaved"
|
||||
|
||||
var/f_hrange = round(4095 / facial_hair_styles_list.len)
|
||||
index = facial_hair_styles_list.Find(character.f_style)
|
||||
if(index)
|
||||
beard = index * f_hrange - rand(1,f_hrange-1)
|
||||
|
||||
temp = add_zero2(num2hex((character.r_hair),1), 3)
|
||||
temp += add_zero2(num2hex((character.b_hair),1), 3)
|
||||
temp += add_zero2(num2hex((character.g_hair),1), 3)
|
||||
temp += add_zero2(num2hex((character.r_facial),1), 3)
|
||||
temp += add_zero2(num2hex((character.b_facial),1), 3)
|
||||
temp += add_zero2(num2hex((character.g_facial),1), 3)
|
||||
temp += add_zero2(num2hex(((character.s_tone + 220) * 16),1), 3)
|
||||
temp += add_zero2(num2hex((character.r_eyes),1), 3)
|
||||
temp += add_zero2(num2hex((character.g_eyes),1), 3)
|
||||
temp += add_zero2(num2hex((character.b_eyes),1), 3)
|
||||
|
||||
var/gender
|
||||
|
||||
if (character.gender == MALE)
|
||||
gender = add_zero2(num2hex((rand(1,(2050+BLOCKADD))),1), 3)
|
||||
else
|
||||
gender = add_zero2(num2hex((rand((2051+BLOCKADD),4094)),1), 3)
|
||||
|
||||
temp += gender
|
||||
temp += add_zero2(num2hex((beard),1), 3)
|
||||
temp += add_zero2(num2hex((hair),1), 3)
|
||||
|
||||
uni_identity = temp
|
||||
|
||||
var/mutstring = ""
|
||||
for(var/i = 1, i <= STRUCDNASIZE, i++)
|
||||
mutstring += add_zero2(num2hex(rand(1,1024)),3)
|
||||
|
||||
|
||||
struc_enzymes = mutstring
|
||||
|
||||
unique_enzymes = md5(character.real_name)
|
||||
reg_dna[unique_enzymes] = character.real_name
|
||||
|
||||
/////////////////////////// DNA DATUM
|
||||
@@ -1,33 +0,0 @@
|
||||
/obj/structure/walllocker
|
||||
name = "Wall Locker"
|
||||
icon = 'icons/obj/lockwall.dmi'
|
||||
icon_state = "emerg"
|
||||
var/list/spawnitems = list()
|
||||
anchored = 1
|
||||
var/amount = 3 // spawns each items X times.
|
||||
/obj/structure/walllocker/attack_hand(mob/user as mob)
|
||||
if (istype(user, /mob/living/silicon/ai)) //Added by Strumpetplaya - AI shouldn't be able to
|
||||
return //activate emergency lockers. This fixes that. (Does this make sense, the AI can't call attack_hand, can it? --Mloc)
|
||||
if(!amount)
|
||||
usr << "It's empty.."
|
||||
return
|
||||
if(amount)
|
||||
for(var/path in spawnitems)
|
||||
new path(src.loc)
|
||||
amount--
|
||||
return
|
||||
/obj/structure/walllocker/emerglocker
|
||||
name = "Emergency Locker"
|
||||
spawnitems = list(/obj/item/weapon/tank/emergency_oxygen,/obj/item/clothing/mask/breath,/obj/item/weapon/crowbar)
|
||||
/obj/structure/walllocker/emerglocker/north
|
||||
pixel_y = 32
|
||||
dir = SOUTH
|
||||
/obj/structure/walllocker/emerglocker/south
|
||||
pixel_y = -32
|
||||
dir = NORTH
|
||||
/obj/structure/walllocker/emerglocker/west
|
||||
pixel_x = -32
|
||||
dir = WEST
|
||||
/obj/structure/walllocker/emerglocker/east
|
||||
pixel_x = 32
|
||||
dir = EAST
|
||||
Reference in New Issue
Block a user