Removes old unticked code

This commit is contained in:
Kelenius
2016-02-01 12:47:20 +03:00
parent b9233680d2
commit c9c9dde819
14 changed files with 0 additions and 3763 deletions

View File

@@ -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

View File

@@ -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)*/

View File

@@ -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

View File

@@ -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()
..()
*/

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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()

View File

@@ -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

View File

@@ -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])"

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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