/
githubmirror
/
vgstation13
Обзор
Документация
Войти
/
githubmirror
/
vgstation13
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
Bleeding-Edge
code/modules/ZAS/Zone.dm
322 строки
10 KB
SECBATON GRIFFON
Gas overlay varied sprites (#38855)
01 фев 2026, 06:17
Не верифицирован
01 фев 2026, 06:17
fc92f92
Код
Авторство
О чём код?
/* Overview: Each zone is a self-contained area where gas values would be the same if tile-based equalization were run indefinitely. If you're unfamiliar with ZAS, FEA's air groups would have similar functionality if they didn't break in a stiff breeze. Class Vars: name - A name of the format "Zone [#]", used for debugging. invalid - True if the zone has been erased and is no longer eligible for processing. needs_update - True if the zone has been added to the update list. edges - A list of edges that connect to this zone. air - The gas mixture that any turfs in this zone will return. Values are per-tile with a group multiplier. Class Procs: add(turf/simulated/T) Adds a turf to the contents, sets its zone and merges its air. remove(turf/simulated/T) Removes a turf, sets its zone to null and erases any gas graphics. Invalidates the zone if it has no more tiles. c_merge(zone/into) Invalidates this zone and adds all its former contents to into. c_invalidate() Marks this zone as invalid and removes it from processing. rebuild() Invalidates the zone and marks all its former tiles for updates. tick() Called only when the gas content is changed. Changes gas graphics. dbg_data(mob/M) Sends M a printout of important figures for the zone. */ //Colors the turfs in each zone to make zone boundaries, changes, rebuilds, etc. visible. //Do not expect it to play nice with anything else that changes turf color. //It specifically behaves like gas tile_overlays with regards to when the color is added and removed. //#define ZAS_COLOR /zone var/name var/invalid = 0 var/list/contents = list() var/needs_update = 0 var/list/edges = list() var/datum/gas_mixture/air = new //Flags of active tile overlays for this zone. Updated by check_tile_graphic() var/graphic = 0 var/graphic_add = 0 var/graphic_remove = 0 #ifdef ZAS_COLOR var/turf_color #endif // Hardcoded-event specific variables. var/ice_puddle_list var/list/atom/burnable_atoms = list() /zone/New() SSair.add_zone(src) air.temperature = TCMB air.volume = 0 #ifdef ZAS_COLOR turf_color = rgb(rand(255), rand(255), rand(255)) #endif /zone/proc/add(turf/simulated/T) #ifdef ZASDBG ASSERT(!invalid) ASSERT(istype(T)) ASSERT(!SSair.has_valid_zone(T)) #endif var/datum/gas_mixture/turf_air = T.return_air() air.volume += turf_air.volume air.merge(turf_air) T.zone = src contents += T T.update_graphic(graphic) #ifdef ZAS_COLOR T.color = turf_color #endif handle_events_add(T) /zone/proc/remove(turf/simulated/T) #ifdef ZASDBG ASSERT(!invalid) ASSERT(istype(T)) ASSERT(T.zone == src) #endif T.c_copy_air() T.zone = null var/datum/gas_mixture/turf_air = T.return_air() air.multiply(1 - turf_air.volume / air.volume) air.volume -= turf_air.volume air.update_values() contents -= T T.update_graphic(graphic_remove = graphic) #ifdef ZAS_COLOR T.color = null #endif if(!contents.len) c_invalidate() handle_events_remove(T) /zone/proc/c_merge(zone/into) #ifdef ZASDBG ASSERT(!invalid) ASSERT(istype(into)) ASSERT(into != src) ASSERT(!into.invalid) #endif c_invalidate() for(var/turf/simulated/T in contents) T.update_graphic(graphic_remove = graphic) into.add(T) #ifdef ZASDBG T.dbg(merged) #endif //Rebuild the old zone's edges so that they will be possessed by the new zone for(var/connection_edge/E in edges) if(E.contains_zone(into)) E.erase() //Don't need to connect the new zone to itself for(var/turf/T in E.connecting_turfs) SSair.mark_for_update(T) /zone/proc/c_invalidate() invalid = 1 SSair.remove_zone(src) for(var/turf/simulated/T in contents) handle_events_remove(T) #ifdef ZASDBG for(var/turf/simulated/T in contents) T.dbg(invalid_zone) #endif /zone/proc/rebuild() if(invalid) return //Short circuit for explosions where rebuild is called many times over. c_invalidate() for(var/turf/simulated/T in contents) T.update_graphic(graphic_remove = graphic) //we need to remove the overlays so they're not doubled when the zone is rebuilt #ifdef ZAS_COLOR T.color = null #endif //T.dbg(invalid_zone) T.needs_air_update = 0 //Reset the marker so that it will be added to the list. SSair.mark_for_update(T) //Gets a list of the gas_mixtures of all zones connected to this one through arbitrarily many sleeping edges. //This is to cut down somewhat on differentials across open doors. //Yes, recursion is slow, but this will generally not be called very often, and will rarely have to recurse more than a few levels deep. //That said, feel free to optimize it if you want. // //At the top level, just call it with no arg. The arg generally is for internal use. /zone/proc/get_equalized_zone_air(list/found = list()) found += air . = found //I want to minimize the call stack left over after the recursive call. Honestly the implicit return is probably the same as an explicit one, but I'd rather play it safe. for(var/connection_edge/zone/E in edges) if(E.sleeping) var/zone/Z = E.get_connected_zone(src) if(!(Z.air in found)) Z.get_equalized_zone_air(found) /zone/proc/tick() check_for_events() air.reaction_tick() if(check_tile_graphic()) for(var/turf/simulated/T in contents) T.update_graphic(graphic_add, graphic_remove) graphic_add = 0 graphic_remove = 0 for(var/connection_edge/E in edges) if(E.sleeping) E.recheck() //Rechecks the gas_mixture and adjusts the graphic list if needed. /zone/proc/check_tile_graphic() for(var/g in XGM.overlay_limit) if(g in gas2show) if(graphic & gas2show[g]) //Overlay is already applied for this gas, check if it's still valid. if(air.molar_density(g) <= XGM.overlay_limit[g]) graphic_remove |= gas2show[g] else //Overlay isn't applied for this gas, check if it's valid and needs to be added. if(air.molar_density(g) > XGM.overlay_limit[g]) graphic_add |= gas2show[g] . = 0 //Apply changes if(graphic_add) graphic |= graphic_add . = 1 if(graphic_remove) graphic &= ~graphic_remove . = 1 /zone/proc/dbg_data(mob/M) to_chat(M, name) to_chat(M, "O2: [air[GAS_OXYGEN]] N2: [air[GAS_NITROGEN]] CO2: [air[GAS_CARBON]] P: [air[GAS_PLASMA]]") to_chat(M, "P: [air.pressure] kPa V: [air.volume]L T: [air.temperature]�K ([air.temperature - T0C]�C)") to_chat(M, "O2 per N2: [(air[GAS_NITROGEN] ? air[GAS_OXYGEN]/air[GAS_NITROGEN] : "N/A")] Moles: [air.total_moles]") to_chat(M, "Simulated: [contents.len] ([air.volume / CELL_VOLUME])") // to_chat(M, "Unsimulated: [unsimulated_contents.len]") // to_chat(M, "Edges: [edges.len]") if(invalid) to_chat(M, "Invalid!") var/zone_edges = 0 var/space_edges = 0 var/space_coefficient = 0 for(var/connection_edge/E in edges) if(E.type == /connection_edge/zone) zone_edges++ else space_edges++ space_coefficient += E.coefficient to_chat(M, "[E:air:return_pressure()]kPa") to_chat(M, "Zone Edges: [zone_edges]") to_chat(M, "Space Edges: [space_edges] ([space_coefficient] connections)") //for(var/turf/T in unsimulated_contents) // to_chat(M, "[T] at ([T.x],[T.y])") // There are some behaviors that we want to happen upon certain thresholds. For instance, if slippery ice is spread across many turfs that melts upon a certain temperature, // we want to know when the zone's temperature is raised above that threshold. // In an ideal non-BYOND environment we could use something like events to hookup each ice tile to. However, our in-house implementation of events suck for performance. So you // can just hardcode the check here. /zone/proc/check_for_events() // Only initialize ice_puddle_list and check for ice-related temperature events after cryotheum has been introduced to the zone. if( ice_puddle_list != null ) for(var/obj/effect/overlay/puddle/ice/existing_ice in ice_puddle_list) existing_ice.current_temp = air.temperature // Below freezing and cryotheum in the air, create ice. if( air.temperature <= T0C && air.molar_density(GAS_CRYOTHEUM) > MOLES_CRYOTHEUM_VISIBLE / CELL_VOLUME ) for(var/turf/simulated/T in contents) var/found = FALSE for(var/obj/effect/overlay/puddle/ice/puddle in T) found = TRUE break if(!found) var/obj/effect/overlay/puddle/ice/new_ice = new /obj/effect/overlay/puddle/ice(T, T.zone) new_ice.wet = TURF_WET_ICE else if(air.temperature >= T0C+5 && isemptylist(ice_puddle_list)) ice_puddle_list = null else if ( air.molar_density(GAS_CRYOTHEUM) > MOLES_CRYOTHEUM_VISIBLE / CELL_VOLUME ) ice_puddle_list = list() if(air.temperature >= AUTOIGNITION_TRIGGER) burnable_zones_processing |= src else burnable_zones_processing -= src /zone/proc/handle_events_add(turf/simulated/T) for(var/obj/effect/overlay/puddle/ice/ice_puddle in T) if(ice_puddle_list == null) ice_puddle_list = list() ice_puddle_list |= ice_puddle if(T.flammable) burnable_atoms |= T for(var/obj/O in T) if(O.flammable) burnable_atoms |= O /zone/proc/handle_events_remove(turf/simulated/T) if(ice_puddle_list != null) for(var/obj/effect/overlay/puddle/ice/ice_puddle in T) ice_puddle_list -= ice_puddle burnable_atoms -= T for(var/obj/O in T) burnable_atoms -= O /zone/proc/checkzoneburn() for(var/atom/A in burnable_atoms) A.checkburn() /zone/proc/blow_dust_motes(var/connection_edge/edge, var/differential) if (!edge) return var/dust_differential = log(abs(differential) * 3) var/list/my_turfs = contents.Copy() var/i = ZAS_DUST_TURFS_PER_TICK while (my_turfs.len > 0 && i > 0) var/turf/T = pick(my_turfs) my_turfs.Remove(T) i-- var/turf/closest_turf = null var/closest_dist = 999 for(var/turf/U in edge.connecting_turfs) var/dist = get_dist(T,U) if(dist > 0 && dist < closest_dist) closest_dist = dist closest_turf = U if (closest_turf) if (differential > 0) T.flying_dust(closest_turf,dust_differential,min(99,abs(differential*2))) else T.flying_dust(closest_turf,-dust_differential,min(99,abs(differential*2))) /zone/proc/blow_dust_motes_but_with_turf(var/turf/target_turf, var/differential) if (!target_turf) return var/dust_differential = log(abs(differential) * 3) for (var/turf/T in contents) if (differential > 0) T.flying_dust(target_turf,dust_differential,min(99,abs(differential*2))) else T.flying_dust(target_turf,-dust_differential,min(99,abs(differential*2))) #ifdef ZAS_COLOR #undef ZAS_COLOR #endif