From 56a2c1d77a9f340efb4e2524ac21ebd3732b102f Mon Sep 17 00:00:00 2001 From: Aryn Date: Sat, 26 May 2012 22:00:38 -0600 Subject: [PATCH] Added comments and updated the changelog. --- code/ZAS/Connection.dm | 5 + code/ZAS/Creation.dm | 17 ++++ code/ZAS/Definition.dm | 2 +- code/ZAS/Fire.dm | 207 ++++++++++++++--------------------------- code/ZAS/Functions.dm | 94 ++++++++++++------- code/ZAS/Plasma.dm | 98 +++++-------------- code/ZAS/Processing.dm | 43 +++++++-- html/changelog.html | 11 +++ 8 files changed, 222 insertions(+), 255 deletions(-) diff --git a/code/ZAS/Connection.dm b/code/ZAS/Connection.dm index 022a714222..af113cc514 100644 --- a/code/ZAS/Connection.dm +++ b/code/ZAS/Connection.dm @@ -1,3 +1,8 @@ +/* +This object is contained within zone/var/connections. It's generated whenever two turfs from different zones are linked. +Indirect connections will not merge the two zones after they reach equilibrium. +*/ + connection var turf //The turfs involved in the connection. diff --git a/code/ZAS/Creation.dm b/code/ZAS/Creation.dm index 1dba1d296b..10508e0aa2 100644 --- a/code/ZAS/Creation.dm +++ b/code/ZAS/Creation.dm @@ -1,13 +1,19 @@ zone New(turf/start) + //Get the turfs that are part of the zone using a floodfill method if(istype(start,/list)) contents = start else contents = FloodFill(start) + + //Change all the zone vars of the turfs, check for space to be added to space_tiles. for(var/turf/T in contents) T.zone = src if(istype(T,/turf/space)) AddSpace(T) + + //Generate the gas_mixture for use in this zone by using the average of the gases + //defined at startup. air = new var/members = contents.len for(var/turf/simulated/T in contents) @@ -18,8 +24,12 @@ zone air.temperature += T.temperature / members air.group_multiplier = contents.len air.update_values() + + //Add this zone to the global list. zones += src + Del() + //Ensuring the zone list doesn't get clogged with null values. zones -= src . = ..() @@ -31,17 +41,23 @@ proc/FloodFill(turf/start) while(open.len) for(var/turf/T in open) + //Stop if there's a door, even if it's open. These are handled by indirect connection. if(!T.HasDoor()) + for(var/d in cardinal) var/turf/O = get_step(T,d) + //Simple pass check. if(O.ZCanPass(T) && !(O in open) && !(O in closed)) open += O + open -= T closed += T return closed turf/proc/ZCanPass(turf/T) + //Fairly standard pass checks for turfs, objects and directional windows. Also stops at the edge of space. + if(istype(T,/turf/space)) return 0 else if(T.blocks_air||blocks_air) @@ -52,6 +68,7 @@ turf/proc/ZCanPass(turf/T) continue if(!obstacle.CanPass(0, T, 0, 1)) return 0 + for(var/obj/obstacle in T) if(istype(obstacle,/obj/machinery/door) && !istype(obstacle,/obj/machinery/door/window)) continue diff --git a/code/ZAS/Definition.dm b/code/ZAS/Definition.dm index b092dc304b..90e88a6c61 100644 --- a/code/ZAS/Definition.dm +++ b/code/ZAS/Definition.dm @@ -5,7 +5,7 @@ var/list/zones = list() zone var dbg_output = 0 //Enables debug output. - rebuild = 0 //If 1, zone will be rebuilt on next process. + rebuild = 0 //If 1, zone will be rebuilt on next process. Not sure if used. datum/gas_mixture/air //The air contents of the zone. list/contents //All the tiles that are contained in this zone. list/connections // /connection objects which refer to connections with other zones, e.g. through a door. diff --git a/code/ZAS/Fire.dm b/code/ZAS/Fire.dm index 24f98ccb02..0159bfa056 100644 --- a/code/ZAS/Fire.dm +++ b/code/ZAS/Fire.dm @@ -1,11 +1,14 @@ vs_control/var/IgnitionLevel = 10 //Moles of oxygen+plasma - co2 needed to burn. -#define OXYGEN +//Some legacy definitions so fires can be started. 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) if(fire_protection > world.time-300) return var/datum/gas_mixture/air_contents = return_air(1) @@ -40,109 +43,6 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh) return igniting -obj/effect/hotspot - //Icon for fire on turfs, also helps for nurturing small fires until they are full tile - - anchored = 1 - - mouse_opacity = 0 - - //luminosity = 3 - - icon = 'fire.dmi' - icon_state = "1" - - layer = TURF_LAYER - - var - volume = 125 - temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - - just_spawned = 1 - - 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) - item.temperature_expose(null, temperature, volume) - -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)) - del(src) - - if((temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) || (volume <= 1)) - del(src) - - if(location.air.toxins < 0.5 || location.air.oxygen < 0.5) - del(src) - - - 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(!locate(/obj/effect/hotspot) in possible_target) - possible_target.hotspot_expose(radiated_temperature, CELL_VOLUME/4) - - else - if(volume > CELL_VOLUME*0.4) - icon_state = "2" - else - icon_state = "1" - - return 1 - -obj/effect/hotspot/New() - ..() - dir = pick(cardinal) - sd_SetLuminosity(3) - -obj/effect/hotspot/Del() - src.sd_SetLuminosity(0) - loc = null - ..() - -var - fire_ratio_1 = 0.05 - obj fire //Icon for fire on turfs, also helps for nurturing small fires until they are full tile @@ -160,73 +60,82 @@ obj var volume = CELL_VOLUME temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST - firelevel = 10000 + firelevel = 10000 //Calculated by gas_mixture.calculate_firelevel() archived_firelevel = 0 process() + if(firelevel > vsc.IgnitionLevel) + var/turf/simulated/floor/S = loc - if(!S.zone) del src - //src.temperature += (src.firelevel/FireTempDivider+FireOffset - src.temperature) / FireRate + if(!S.zone) del src //Cannot exist where zones are broken. + if(istype(S,/turf/simulated/floor)) var datum/gas_mixture/air_contents = S.return_air() + //Get whatever trace fuels are in the area datum/gas/volatile_fuel/fuel = locate(/datum/gas/volatile_fuel/) in air_contents.trace_gases + //Also get liquid fuels on the ground. obj/liquid_fuel/liquid = locate() in S firelevel = air_contents.calculate_firelevel(liquid) + //Ensure that there is an appropriate amount of fuel and O2 here. if(firelevel > 25 && (air_contents.toxins || fuel || liquid)) + for(var/direction in cardinal) if(S.air_check_directions&direction) //Grab all valid bordering tiles + var/turf/simulated/enemy_tile = get_step(S, direction) + if(istype(enemy_tile)) + //If extinguisher mist passed over the turf it's trying to spread to, don't spread and + //reduce firelevel. if(enemy_tile.fire_protection > world.time-30) firelevel -= 150 continue + + //Spread the fire. if(!(locate(/obj/fire) in enemy_tile)) if( prob( firelevel/2.5 ) ) new/obj/fire(enemy_tile,firelevel) - // else - // world << "Spread Probability: [firelevel/(vsc.IgnitionLevel*0.1)]%." - // else - // world << "There's a fire there bitch." - // else - // world << "[enemy_tile] cannot be spread to." - //else - // world << "Not enough firelevel to spread: [firelevel]/[vsc.IgnitionLevel*1.5]" - var/datum/gas_mixture/flow = air_contents.remove_ratio(0.5) - //n = PV/RT, taking the volume of a single tile from the gas. + var/datum/gas_mixture/flow = air_contents.remove_ratio(0.5) //Take half the air from the room I guess. if(flow) + //Ensure adequate oxygen and fuel. if(flow.oxygen > 0.3 && (flow.toxins || fuel || liquid)) + //Change icon depending on the fuel, and thus temperature. icon_state = "1" if(firelevel > 25) icon_state = "2" if(firelevel > 100) icon_state = "3" + + //Ensure flow temperature is higher than minimum fire temperatures. flow.temperature = max(PLASMA_MINIMUM_BURN_TEMPERATURE+0.1,flow.temperature) + + //Burn the gas mixture. flow.zburn(liquid) else + del src - S.assume_air(flow) + S.assume_air(flow) //Then put it back where you found it. + else - //world << "No air at all." del src else del src else - //world << "Insufficient fire level for ignition: [firelevel]/[IgnitionLevel]" del src for(var/mob/living/carbon/human/M in loc) - M.FireBurn(min(max(0.1,firelevel / 20),10)) + M.FireBurn(min(max(0.1,firelevel / 20),10)) //Burn the humans! New(newLoc,fl) @@ -235,7 +144,7 @@ obj sd_SetLuminosity(3) firelevel = fl for(var/mob/living/carbon/human/M in loc) - M.FireBurn(min(max(0.1,firelevel / 20),10)) + M.FireBurn(min(max(0.1,firelevel / 20),10)) //Burn the humans! Del() if (istype(loc, /turf/simulated)) @@ -246,23 +155,29 @@ obj ..() obj/liquid_fuel + //Liquid fuel is used for things that used to rely on volatile fuels or plasma being contained to a couple tiles. icon = 'icons/effects/effects.dmi' icon_state = "fuel" layer = TURF_LAYER+0.2 anchored = 1 - var/amount = 1 + var/amount = 1 //Basically moles. New(newLoc,amt=1) src.amount = amt + + //Be absorbed by any other liquid fuel in the tile. for(var/obj/liquid_fuel/other in newLoc) if(other != src) other.amount += src.amount spawn other.Spread() del src return + Spread() . = ..() + proc/Spread() + //Allows liquid fuels to sometimes flow into other tiles. if(amount < 0.5) return var/turf/simulated/S = loc if(!istype(S)) return @@ -277,22 +192,23 @@ obj/liquid_fuel icon_state = "mustard" anchored = 0 New(newLoc, amt = 1, d = 0) - dir = d + dir = d //Setting this direction means you won't get torched by your own flamethrower. . = ..() Spread() + //The spread for flamethrower fuel is much more precise, to create a wide fire pattern. if(amount < 0.1) return var/turf/simulated/S = loc if(!istype(S)) return + for(var/d in list(turn(dir,90),turn(dir,-90))) if(S.air_check_directions & d) var/turf/simulated/O = get_step(S,d) new/obj/liquid_fuel/flamethrower_fuel(O,amount*0.25,d) - O.hotspot_expose((T20C*2) + 380,500) + O.hotspot_expose((T20C*2) + 380,500) //Light flamethrower fuel on fire immediately. + amount *= 0.5 -vs_control/var/switch_fire = 1 - -turf/simulated/var/fire_protection = 0 +turf/simulated/var/fire_protection = 0 //Protects newly extinguished tiles from being overrun again. turf/proc/apply_fire_protection() turf/simulated/apply_fire_protection() @@ -300,50 +216,72 @@ turf/simulated/apply_fire_protection() datum/gas_mixture/proc zburn(obj/liquid_fuel/liquid) + //This proc is similar to fire(), but uses a simple logarithm to calculate temp, and is thus more stable with ZAS. if(temperature > PLASMA_MINIMUM_BURN_TEMPERATURE) var total_fuel = toxins - fuel_sources = 0 + fuel_sources = 0 //We'll divide by this later so that fuel is consumed evenly. datum/gas/volatile_fuel/fuel = locate() in trace_gases + if(fuel) + //Volatile Fuel total_fuel += fuel.moles fuel_sources++ + if(liquid) + //Liquid Fuel if(liquid.amount <= 0) del liquid else total_fuel += liquid.amount fuel_sources++ + + //Toxins if(toxins > 0.3) fuel_sources++ - if(!fuel_sources) return 0 - if(oxygen > 0.3 && total_fuel) + if(!fuel_sources) return 0 //If there's no fuel, there's no burn. Can't divide by zero anyway. + + if(oxygen > 0.3) + + //Calculate the firelevel. var/firelevel = calculate_firelevel(liquid) - //f(x) = 1000ln(0.01x + 1.45) + + //Reaches a maximum practical temperature of around 2750. + temperature = 1000*log(0.016*firelevel + 1.45) + + //Consume some gas. var/consumed_gas = min(oxygen,0.002*firelevel,total_fuel) / fuel_sources + oxygen -= consumed_gas + toxins = max(0,toxins-consumed_gas) + if(fuel) fuel.moles -= consumed_gas if(fuel.moles <= 0) del fuel + if(liquid) liquid.amount -= consumed_gas if(liquid.amount <= 0) del liquid + update_values() return consumed_gas*fuel_sources return 0 + calculate_firelevel(obj/liquid_fuel/liquid) + //Calculates the firelevel based on one equation instead of having to do this multiple times in different areas. var datum/gas/volatile_fuel/fuel = locate() in trace_gases fuel_level = 0 liquid_level = 0 + if(fuel) fuel_level = fuel.moles if(liquid) liquid_level = liquid.amount return oxygen + toxins + liquid_level*15 + fuel_level*5 /mob/living/carbon/human/proc/FireBurn(mx as num) - //NO! NOT INTO THE PIT! IT BURRRRRNS! + //Burns mobs due to fire. Respects heat transfer coefficients on various body parts. var head_exposure = 1 @@ -352,6 +290,7 @@ datum/gas_mixture/proc legs_exposure = 1 arms_exposure = 1 + //Get heat transfer coefficients for clothing. for(var/obj/item/clothing/C in src) if(l_hand == C || r_hand == C) continue if(C.body_parts_covered & HEAD) @@ -365,8 +304,6 @@ datum/gas_mixture/proc if(C.body_parts_covered & ARMS) arms_exposure *= C.heat_transfer_coefficient - mx *= 1 - //Always check these damage procs first if fire damage isn't working. They're probably what's wrong. apply_damage(2.5*mx*head_exposure, BURN, "head", 0, 0, "Fire") diff --git a/code/ZAS/Functions.dm b/code/ZAS/Functions.dm index 548289ade0..b9d88a84f2 100644 --- a/code/ZAS/Functions.dm +++ b/code/ZAS/Functions.dm @@ -1,43 +1,34 @@ zone proc AddTurf(turf/T) + //Adds the turf to contents, increases the size of the zone, and sets the zone var. if(T in contents) return contents += T air.group_multiplier++ T.zone = src RemoveTurf(turf/T) + //Same, but in reverse. if(!(T in contents)) return contents -= T air.group_multiplier-- T.zone = null - DivideAir(ratio) - ratio = min(1,max(0,ratio)) - air.oxygen *= ratio - air.oxygen = QUANTIZE(air.oxygen) - air.nitrogen *= ratio - air.nitrogen = QUANTIZE(air.nitrogen) - air.toxins *= ratio - air.toxins = QUANTIZE(air.toxins) - air.carbon_dioxide *= ratio - air.carbon_dioxide = QUANTIZE(air.carbon_dioxide) - if(air.trace_gases.len) - for(var/datum/gas/trace_gas in air.trace_gases) - trace_gas.moles *= ratio - trace_gas.moles = QUANTIZE(trace_gas.moles) - air.temperature = air.temperature*ratio + TCMB*(1-ratio) - air.temperature = QUANTIZE(air.temperature) - AddSpace(turf/space/S) + //Adds a space tile to the list, and creates the list if null. if(istype(S,/turf/space)) if(!space_tiles) space_tiles = list() space_tiles += S + RemoveSpace(turf/space/S) + //Removes a space tile from the list, and deletes the list if length is 0. if(space_tiles) space_tiles -= S if(!space_tiles.len) space_tiles = null turf/proc/HasDoor(turf/O) + //Checks for the presence of doors, used for zone spreading and connection. + //A positive numerical argument checks only for closed doors. + //Another turf as an argument checks for windoors between here and there. for(var/obj/machinery/door/D in src) if(isnum(O) && O) if(!D.density) continue @@ -48,6 +39,7 @@ turf/proc/HasDoor(turf/O) return 1 turf/proc/find_zone() + //Allows newly generated turfs to join up with a nearby zone. if(world.time < 10) return for(var/d in cardinal) var/turf/T = get_step(src,d) @@ -59,6 +51,7 @@ turf/proc/find_zone() ZConnect(src,T) turf/proc/check_connections() + //Checks for new connections that can be made. for(var/d in cardinal) var/turf/T = get_step(src,d) if(!T || !T.zone || !T.CanPass(0,src,0,0)) continue @@ -66,6 +59,7 @@ turf/proc/check_connections() ZConnect(src,T) turf/proc/check_for_space() + //Checks for space around the turf. for(var/d in cardinal) var/turf/T = get_step(src,d) if(istype(T,/turf/space) && T.CanPass(0,src,0,0)) @@ -73,97 +67,125 @@ turf/proc/check_for_space() proc ZMerge(zone/A,zone/B) - //world << "Merge occured." + //Merges two zones so that they are one. var a_size = A.air.group_multiplier b_size = B.air.group_multiplier c_size = a_size + b_size new_contents = A.contents + B.contents + //Set air multipliers to one so air represents gas per tile. A.air.group_multiplier = 1 B.air.group_multiplier = 1 + //Remove some air proportional to the size of this zone. A.air.remove_ratio(a_size/c_size) B.air.remove_ratio(b_size/c_size) + + //Merge the gases and set the multiplier to the sum of the old ones. A.air.merge(B.air) A.air.group_multiplier = c_size + //Check for connections to merge into the new zone. for(var/connection/C in B.connections) if((C.A in new_contents) && (C.B in new_contents)) del C continue if(!A.connections) A.connections = list() A.connections += C + + //Add space tiles. A.space_tiles += B.space_tiles + + //Add contents. A.contents = new_contents + + //Set all the zone vars. for(var/turf/T in B.contents) T.zone = A + del B ZConnect(turf/A,turf/B) + //Connects two zones by forming a connection object representing turfs A and B. + + //Make sure that if it's space, it gets added to space_tiles instead. if(istype(B,/turf/space)) if(A.zone) A.zone.AddSpace(B) - //world << "Space added." return if(istype(A,/turf/space)) if(B.zone) B.zone.AddSpace(A) - //world << "Space added." return + + //Make some preliminary checks to see if the connection is valid. if(!A.zone || !B.zone) return if(A.zone == B.zone) return if(!A.CanPass(0,B,0,0)) return + + //Ensure the connection isn't already made. for(var/connection/C in A.zone.connections) if((C.A == A && C.B == B) || (C.A == B && C.B == A)) return - var/connection/C = new(A,B) - if(A.HasDoor(B) || B.HasDoor(A)) C.indirect = 1 - //world << "Connection Formed: [A] --> [B] [(C.indirect?"Indirect":"Direct")]" - //A.overlays += 'zone_connection_A.dmi' - //B.overlays += 'zone_connection_B.dmi' - //spawn(10) - // A.overlays -= 'zone_connection_A.dmi' - // B.overlays -= 'zone_connection_B.dmi' + var/connection/C = new(A,B) + + //Ensure zones separated by doors do not merge. + if(A.HasDoor(B) || B.HasDoor(A)) C.indirect = 1 ZDisconnect(turf/A,turf/B) + //Removes a zone connection. Can split zones in the case of a permanent barrier. + + //If one of them doesn't have a zone, it might be space, so check for that. if(A.zone && B.zone) + //If the two zones are different, just remove a connection. if(A.zone != B.zone) for(var/connection/C in A.zone.connections) if((C.A == A && C.B == B) || (C.A == B && C.B == A)) - //world << "Connection Dissolved: [A] -/-> [B] [(C.indirect?"Indirect":"Direct")]" - /*A.overlays += 'zone_connection_A.dmi' - B.overlays += 'zone_connection_B.dmi' - spawn(10) - A.overlays -= 'zone_connection_A.dmi' - B.overlays -= 'zone_connection_B.dmi'*/ del C + //If they're the same, split the zone at this line. else + //Preliminary checks to prevent stupidity. if(A == B) return if(A.CanPass(0,B,0,0)) return if(A.HasDoor(B) || B.HasDoor(A)) return + + //Do a test fill. If turf B is still in the floodfill, then the zone isn't really split. var/zone/oldzone = A.zone var/list/test = FloodFill(A) if(B in test) return + else - var/zone/Z = new(test,oldzone.air) + var/zone/Z = new(test,oldzone.air) //Create a new zone based on the old air and the test fill. + + //Add connections from the old zone. for(var/connection/C in oldzone.connections) if((A in Z.contents) || (B in Z.contents)) if(!Z.connections) Z.connections = list() Z.connections += C + + //Check for space. for(var/turf/T in test) T.check_for_space() + + //Make a new, identical air mixture for the other zone. var/datum/gas_mixture/Y_Air = new Y_Air.copy_from(oldzone.air) - var/zone/Y = new(B,Y_Air) + + var/zone/Y = new(B,Y_Air) //Make a new zone starting at B and using Y_Air. + + //Add relevant connections from old zone. for(var/connection/C in oldzone.connections) if((A in Y.contents) || (B in Y.contents)) if(!Y.connections) Y.connections = list() Y.connections += C + + //Add the remaining space tiles to this zone. for(var/turf/space/T in oldzone.space_tiles) if(!(T in Z.space_tiles)) Y.AddSpace(T) + oldzone.air = null del oldzone else diff --git a/code/ZAS/Plasma.dm b/code/ZAS/Plasma.dm index ab7f452fa9..858799a272 100644 --- a/code/ZAS/Plasma.dm +++ b/code/ZAS/Plasma.dm @@ -1,94 +1,35 @@ pl_control/var PLASMA_DMG = 3 - PLASMA_DMG_NAME = "Plasma Damage Multiplier" - PLASMA_DMG_DESC = "Multiplier on how much damage inhaling plasma can do." CLOTH_CONTAMINATION = 0 //If this is on, plasma does damage by getting into cloth. - CLOTH_CONTAMINATION_NAME = "Plasma - Cloth Contamination" - CLOTH_CONTAMINATION_RANDOM = 60 - CLOTH_CONTAMINATION_METHOD = "Toggle" - CLOTH_CONTAMINATION_DESC = "If set to nonzero, plasma will contaminate cloth items (uniforms, backpacks, etc.)\ - and cause a small amount of damage over time to anyone carrying or wearing them. Contamination can be washed off in the washer." - ALL_ITEM_CONTAMINATION = 0 //If this is on, any item can be contaminated, so suits and tools must be discarded or - //decontaminated. - ALL_ITEM_CONTAMINATION_NAME = "Plasma - Full Contamination" - ALL_ITEM_CONTAMINATION_RANDOM = 10 - ALL_ITEM_CONTAMINATION_METHOD = "Toggle" - ALL_ITEM_CONTAMINATION_DESC = "Like Cloth Contamination, but all item types are susceptible." - - PLASMAGUARD_ONLY = 0 - PLASMAGUARD_ONLY_NAME = "Plasma - Biosuits/Spacesuits Only" - PLASMAGUARD_ONLY_RANDOM = 20 - PLASMAGUARD_ONLY_METHOD = "Toggle" - PLASMAGUARD_ONLY_DESC = "If on, any suits that are not biosuits or space suits will not protect against contamination." - - //CANISTER_CORROSION = 0 //If this is on, plasma must be stored in orange tanks and canisters, - //CANISTER_CORROSION_RANDOM = 20 //or it will corrode the tank. - //CANISTER_CORROSION_METHOD = "Toggle" + PLASMAGUARD_ONLY = 0 //If this is on, only biosuits and spacesuits protect against contamination and ill effects. GENETIC_CORRUPTION = 0 //Chance of genetic corruption as well as toxic damage, X in 10,000. - GENETIC_CORRUPTION_NAME = "Plasma - Genetic Corruption" - GENETIC_CORRUPTION_RANDOM = "PROB10/3d6" - GENETIC_CORRUPTION_METHOD = "Numeric" - GENETIC_CORRUPTION_DESC = "When set to a probability in 1000, any humans in plasma will have this chance to develop a random mutation." SKIN_BURNS = 1 //Plasma has an effect similar to mustard gas on the un-suited. - SKIN_BURNS_NAME = "Plasma - Skin Burns" - SKIN_BURNS_RANDOM = 10 - SKIN_BURNS_METHOD = "Toggle" - SKIN_BURNS_DESC = "When toggled, humans with exposed skin will suffer burns (similar to mustard gas) in plasma." - - //PLASMA_INJECTS_TOXINS = 0 //Plasma damage injects the toxins chemical to do damage over time. - //PLASMA_INJECTS_TOXINS_RANDOM = 30 - //PLASMA_INJECTS_TOXINS_METHOD = "Toggle" EYE_BURNS = 1 //Plasma burns the eyes of anyone not wearing eye protection. - EYE_BURNS_NAME = "Plasma - Eye Burns" - EYE_BURNS_RANDOM = 30 - EYE_BURNS_METHOD = "Toggle" - EYE_BURNS_DESC = "When toggled, humans without masks that cover the eyes will suffer temporary blurriness and sight loss,\ - and may need glasses to see again if exposed for long durations." - - //N2O_REACTION = 0 //Plasma can react with N2O, making sparks and starting a fire if levels are high. - //N2O_REACTION_RANDOM = 5 - - //PLASMA_COLOR = "onturf" //Plasma can change colors yaaaay! - //PLASMA_COLOR_RANDOM = "PICKonturf,onturf" - - //PLASMA_DMG_OFFSET = 1 - //PLASMA_DMG_OFFSET_RANDOM = "1d5" - //PLASMA_DMG_QUOTIENT = 10 - //PLASMA_DMG_QUOTIENT_RANDOM = "1d10+4" CONTAMINATION_LOSS = 0.01 - CONTAMINATION_LOSS_NAME = "Plasma - Contamination Damage" - CONTAMINATION_LOSS_DESC = "A number representing the damage done per life cycle by contaminated items." - PLASMA_HALLUCINATION = 1 - PLASMA_HALLUCINATION_NAME = "Plasma - Hallucination" - PLASMA_HALLUCINATION_METHOD = "Toggle" - PLASMA_HALLUCINATION_DESC = "If toggled, uses the remnants of the hallucination code to induce visions in those\ - who breathe plasma." + PLASMA_HALLUCINATION = 0 + N2O_HALLUCINATION = 1 - N2O_HALLUCINATION_NAME = "Nitrous Oxide - Hallucination" - N2O_HALLUCINATION_METHOD = "Toggle" - N2O_HALLUCINATION_DESC = "If toggled, uses the remnants of the hallucination code to induce visions in those\ - who breathe N2O." - //CONTAMINATION_LOSS_RANDOM = "5d5" -//Plasma has a chance to be a different color. + obj/var/contaminated = 0 obj/item/proc can_contaminate() + //Clothing and backpacks can be contaminated. if(flags & PLASMAGUARD) return 0 - if((flags & SUITSPACE) && !vsc.plc.PLASMAGUARD_ONLY) return 1 - if(vsc.plc.ALL_ITEM_CONTAMINATION) return 1 + if(flags & SUITSPACE) return 0 else if(istype(src,/obj/item/clothing)) return 1 else if(istype(src,/obj/item/weapon/storage/backpack)) return 1 contaminate() + //Do a contamination overlay? Temporary measure to keep contamination less deadly than it was. if(!contaminated) contaminated = 1 overlays += 'icons/effects/contamination.dmi' @@ -100,6 +41,8 @@ obj/item/proc /mob/proc/contaminate() /mob/living/carbon/human/contaminate() + //See if anything can be contaminated. + if(!pl_suit_protected()) suit_contamination() @@ -109,25 +52,26 @@ obj/item/proc if(istype(back,/obj/item/weapon/storage/backpack)) back.contaminate() - /*if(l_hand) - if(l_hand.can_contaminate()) l_hand.contaminate() - if(r_hand) - if(r_hand.can_contaminate()) r_hand.contaminate() - if(belt) - if(belt.can_contaminate()) belt.contaminate()*/ - /mob/proc/pl_effects() /mob/living/carbon/human/pl_effects() + //Handles all the bad things plasma can do. + + //Contamination if(vsc.plc.CLOTH_CONTAMINATION) contaminate() + + //Anything else requires them to not be dead. if(stat >= 2) return + + //Burn skin if exposed. if(vsc.plc.SKIN_BURNS) if(!pl_head_protected() || !pl_suit_protected()) burn_skin(0.75) if(prob(20)) src << "\red Your skin burns!" updatehealth() + //Burn eyes if exposed. if(vsc.plc.EYE_BURNS) if(!head) if(!wear_mask) @@ -136,13 +80,14 @@ obj/item/proc if(!(wear_mask.flags & MASKCOVERSEYES)) burn_eyes() else - if(!(head.flags & MASKCOVERSEYES)) + if(!(head.flags & HEADCOVERSEYES)) if(!wear_mask) burn_eyes() else if(!(wear_mask.flags & MASKCOVERSEYES)) burn_eyes() + //Genetic Corruption if(vsc.plc.GENETIC_CORRUPTION) if(rand(1,10000) < vsc.plc.GENETIC_CORRUPTION) randmutb(src) @@ -150,6 +95,7 @@ obj/item/proc domutcheck(src,null) /mob/living/carbon/human/proc/burn_eyes() + //The proc that handles eye burning. if(prob(20)) src << "\red Your eyes burn!" eye_stat += 2.5 eye_blurry = min(eye_blurry+1.5,50) @@ -159,6 +105,7 @@ obj/item/proc eye_stat = 0 /mob/living/carbon/human/proc/pl_head_protected() + //Checks if the head is adequately sealed. if(head) if(vsc.plc.PLASMAGUARD_ONLY) if(head.flags & PLASMAGUARD || head.flags & HEADSPACE) return 1 @@ -167,6 +114,7 @@ obj/item/proc return 0 /mob/living/carbon/human/proc/pl_suit_protected() + //Checks if the suit is adequately sealed. if(wear_suit) if(vsc.plc.PLASMAGUARD_ONLY) if(wear_suit.flags & PLASMAGUARD || wear_suit.flags & SUITSPACE) return 1 @@ -175,6 +123,7 @@ obj/item/proc return 0 /mob/living/carbon/human/proc/suit_contamination() + //Runs over the things that can be contaminated and does so. if(w_uniform) w_uniform.contaminate() if(shoes) shoes.contaminate() if(gloves) gloves.contaminate() @@ -182,6 +131,7 @@ obj/item/proc turf/Entered(obj/item/I) . = ..() + //Items that are in plasma, but not on a mob, can still be contaminated. if(istype(I) && vsc.plc.CLOTH_CONTAMINATION) var/datum/gas_mixture/env = return_air(1) if(env.toxins > MOLES_PLASMA_VISIBLE + 1) diff --git a/code/ZAS/Processing.dm b/code/ZAS/Processing.dm index 8423ae46af..d80048cbb1 100644 --- a/code/ZAS/Processing.dm +++ b/code/ZAS/Processing.dm @@ -2,19 +2,26 @@ var/explosion_halt = 0 zone proc/process() + //Does rebuilding stuff. Not sure if used. if(rebuild) + //Deletes zone if empty. if(!contents.len) del src return 0 + + //Choose a random turf and regenerate the zone from it. var turf/sample = pick(contents) list/new_contents = FloodFill(sample) problem = 0 + + //If something isn't carried over, there was a complication. for(var/turf/T in contents) if(!(T in new_contents)) problem = 1 if(problem) + //Build some new zones for stuff that wasn't included. var/list/rebuild_turfs = list() for(var/turf/T in contents - new_contents) contents -= T @@ -26,11 +33,13 @@ zone Z.air.copy_from(air) rebuild = 0 + //Sometimes explosions will cause the air to be deleted for some reason. if(!air) air = new() air.adjustGases(MOLES_O2STANDARD, 0, MOLES_N2STANDARD, 0, list()) world.log << "Air object lost in zone. Regenerating." + //Counting up space. var/total_space = 0 if(space_tiles) @@ -38,44 +47,60 @@ zone if(!istype(T,/turf/space)) space_tiles -= T total_space = length(space_tiles) - if(total_space) // SPAAAAAAAAAACE - //var/old_pressure = air.pressure + //Add checks to ensure that we're not sucking air out of an empty room. + if(total_space && air.total_moles > 0.1 && air.temperature > TCMB+0.5) + //If there is space, air should flow out of the zone. ShareSpace(air,total_space*(vsc.zone_share_percent/100)) - //var/p_diff = old_pressure - air.pressure - //if(p_diff > vsc.AF_TINY_MOVEMENT_THRESHOLD) AirflowSpace(src,p_diff) + //React the air here. air.react(null,0) + + //Check the graphic. var/check = air.check_tile_graphic() + //Only run through the individual turfs if there's reason to. if(check || air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST) + for(var/turf/simulated/S in contents) + //Update overlays. if(check) if(S.HasDoor(1)) S.update_visuals() else S.update_visuals(air) + //Expose stuff to extreme heat. if(air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST) for(var/atom/movable/item in S) item.temperature_expose(air, air.temperature, CELL_VOLUME) S.temperature_expose(air, air.temperature, CELL_VOLUME) + //Archive graphic so we can know if it's different. air.graphic_archived = air.graphic + //Ensure temperature does not reach absolute zero. air.temperature = max(TCMB,air.temperature) + //Handle connections to other zones. if(length(connections)) for(var/connection/C in connections) + //Check if the connection is valid first. C.Cleanup() + //Do merging if conditions are met. Specifically, if there's a non-door connection + //to somewhere with space, the zones are merged regardless of equilibrium, to speed + //up spacing in areas with double-plated windows. if(C && !C.indirect && C.A.zone && C.B.zone) if(C.A.zone.air.compare(C.B.zone.air) || total_space) ZMerge(C.A.zone,C.B.zone) + + //Share some for(var/zone/Z in connected_zones) - //var/p_diff = (air.return_pressure()-Z.air.return_pressure())*connected_zones[Z]*(vsc.zone_share_percent/100) - //if(p_diff > vsc.AF_TINY_MOVEMENT_THRESHOLD) Airflow(src,Z,p_diff) - ShareRatio(air,Z.air,connected_zones[Z]*(vsc.zone_share_percent/100)) + //Ensure we're not doing pointless calculations on equilibrium zones. + if(abs(air.total_moles - Z.air.total_moles) > 0.1 || abs(air.temperature - Z.air.temperature) > 0.1) + ShareRatio(air,Z.air,connected_zones[Z]*(vsc.zone_share_percent/100)) proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, ratio) + //Shares a specific ratio of gas between mixtures using simple weighted averages. var size = max(1,A.group_multiplier) share_size = max(1,B.group_multiplier) @@ -138,9 +163,8 @@ proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, ratio) if(A.compare(B)) return 1 else return 0 - /* See? Now that's how it's done. */ - proc/ShareSpace(datum/gas_mixture/A, ratio) + //A modified version of ShareRatio for spacing gas at the same rate as if it were going into a huge airless room. var size = max(1,A.group_multiplier) share_size = 2000 //A huge value because space is huge. @@ -179,6 +203,7 @@ proc/ShareSpace(datum/gas_mixture/A, ratio) zone/proc connected_zones() + //A legacy proc for getting connected zones. . = list() for(var/connection/C in connections) var/zone/Z diff --git a/html/changelog.html b/html/changelog.html index ec5d41f73d..c099a42b9e 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,6 +56,17 @@ Stuff which is in development and not yet visible to players or just code relate should be listed in the changelog upon commit though. Thanks. --> + +
+

5/26/2012

+

Aryn updated:

+ +
+

26 May 2012

Erthilo updated: