mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 18:22:39 +00:00
Several ZAS fixes.
Adds insulation to doors, modifiable by admins from the ZAS setting panel. Fixes a logic error with connections. (I am dumb some days) Improves the runtime detection and reporting. Improves "zone info" debug verb.
This commit is contained in:
@@ -367,6 +367,7 @@ Indirect connections will not merge the two zones after they reach equilibrium.
|
|||||||
if(zone_A && zone_B)
|
if(zone_A && zone_B)
|
||||||
DisconnectZones(zone_A, zone_B)
|
DisconnectZones(zone_A, zone_B)
|
||||||
ConnectZones(A.zone, B.zone, indirect)
|
ConnectZones(A.zone, B.zone, indirect)
|
||||||
|
zone_A = A.zone
|
||||||
|
|
||||||
//The "B" zone changed.
|
//The "B" zone changed.
|
||||||
else if(B.zone && B.zone != zone_B)
|
else if(B.zone && B.zone != zone_B)
|
||||||
@@ -394,6 +395,7 @@ Indirect connections will not merge the two zones after they reach equilibrium.
|
|||||||
if(zone_A && zone_B)
|
if(zone_A && zone_B)
|
||||||
DisconnectZones(zone_A, zone_B)
|
DisconnectZones(zone_A, zone_B)
|
||||||
ConnectZones(A.zone, B.zone, indirect)
|
ConnectZones(A.zone, B.zone, indirect)
|
||||||
|
zone_B = B.zone
|
||||||
|
|
||||||
|
|
||||||
#undef CONNECTION_DIRECT
|
#undef CONNECTION_DIRECT
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ client/proc/Zone_Info(turf/T as null|turf)
|
|||||||
mob << "No zone here."
|
mob << "No zone here."
|
||||||
else
|
else
|
||||||
if(zone_debug_images)
|
if(zone_debug_images)
|
||||||
images -= zone_debug_images
|
for(var/zone in zone_debug_images)
|
||||||
|
images -= zone_debug_images[zone]
|
||||||
zone_debug_images = null
|
zone_debug_images = null
|
||||||
|
|
||||||
client/var/list/zone_debug_images
|
client/var/list/zone_debug_images
|
||||||
@@ -23,12 +24,12 @@ client/proc/Test_ZAS_Connection(var/turf/simulated/T as turf)
|
|||||||
"South" = SOUTH,\
|
"South" = SOUTH,\
|
||||||
"East" = EAST,\
|
"East" = EAST,\
|
||||||
"West" = WEST,\
|
"West" = WEST,\
|
||||||
"None" = null)
|
"N/A" = null)
|
||||||
var/direction = input("What direction do you wish to test?","Set direction") as null|anything in direction_list
|
var/direction = input("What direction do you wish to test?","Set direction") as null|anything in direction_list
|
||||||
if(!direction)
|
if(!direction)
|
||||||
return
|
return
|
||||||
|
|
||||||
if(direction == "None")
|
if(direction == "N/A")
|
||||||
if(T.CanPass(null, T, 0,0))
|
if(T.CanPass(null, T, 0,0))
|
||||||
mob << "The turf can pass air! :D"
|
mob << "The turf can pass air! :D"
|
||||||
else
|
else
|
||||||
@@ -64,11 +65,14 @@ zone/proc/DebugDisplay(client/client)
|
|||||||
|
|
||||||
if(!client.zone_debug_images)
|
if(!client.zone_debug_images)
|
||||||
client.zone_debug_images = list()
|
client.zone_debug_images = list()
|
||||||
|
|
||||||
|
var/list/current_zone_images = list()
|
||||||
|
|
||||||
for(var/turf/T in contents)
|
for(var/turf/T in contents)
|
||||||
client.zone_debug_images += image('debug_group.dmi', T)
|
current_zone_images += image('debug_group.dmi', T, null, TURF_LAYER)
|
||||||
|
|
||||||
for(var/turf/space/S in unsimulated_tiles)
|
for(var/turf/space/S in unsimulated_tiles)
|
||||||
client.zone_debug_images += image('debug_space.dmi', S)
|
current_zone_images += image('debug_space.dmi', S, null, TURF_LAYER)
|
||||||
|
|
||||||
client << "<u>Zone Air Contents</u>"
|
client << "<u>Zone Air Contents</u>"
|
||||||
client << "Oxygen: [air.oxygen]"
|
client << "Oxygen: [air.oxygen]"
|
||||||
@@ -85,8 +89,8 @@ zone/proc/DebugDisplay(client/client)
|
|||||||
|
|
||||||
for(var/connection/C in connections)
|
for(var/connection/C in connections)
|
||||||
client << "\ref[C] [C.A] --> [C.B] [(C.indirect?"Open":"Closed")]"
|
client << "\ref[C] [C.A] --> [C.B] [(C.indirect?"Open":"Closed")]"
|
||||||
client.zone_debug_images += image('debug_connect.dmi', C.A)
|
current_zone_images += image('debug_connect.dmi', C.A, null, TURF_LAYER)
|
||||||
client.zone_debug_images += image('debug_connect.dmi', C.B)
|
current_zone_images += image('debug_connect.dmi', C.B, null, TURF_LAYER)
|
||||||
|
|
||||||
client << "Connected Zones:"
|
client << "Connected Zones:"
|
||||||
for(var/zone/zone in connected_zones)
|
for(var/zone/zone in connected_zones)
|
||||||
@@ -99,13 +103,17 @@ zone/proc/DebugDisplay(client/client)
|
|||||||
if(!istype(C,/connection))
|
if(!istype(C,/connection))
|
||||||
client << "[C] (Not Connection!)"
|
client << "[C] (Not Connection!)"
|
||||||
|
|
||||||
client.images += client.zone_debug_images
|
if(!client.zone_debug_images)
|
||||||
|
client.zone_debug_images = list()
|
||||||
|
client.zone_debug_images[src] = current_zone_images
|
||||||
|
|
||||||
|
client.images += client.zone_debug_images[src]
|
||||||
|
|
||||||
else
|
else
|
||||||
dbg_output = 0
|
dbg_output = 0
|
||||||
|
|
||||||
client.images -= client.zone_debug_images
|
client.images -= client.zone_debug_images[src]
|
||||||
client.zone_debug_images = null
|
client.zone_debug_images.Remove(src)
|
||||||
|
|
||||||
for(var/zone/Z in zones)
|
for(var/zone/Z in zones)
|
||||||
if(Z.air == air && Z != src)
|
if(Z.air == air && Z != src)
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ atom/proc/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
|
|||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
var/global/datum/controller/air_system/air_master
|
var/datum/controller/air_system/air_master
|
||||||
|
|
||||||
/datum/controller/air_system/
|
/datum/controller/air_system/
|
||||||
//Geoemetry lists
|
//Geoemetry lists
|
||||||
@@ -180,17 +180,20 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
|||||||
if(. && T && !T.update_air_properties())
|
if(. && T && !T.update_air_properties())
|
||||||
. = 0 //If a runtime occured, make sure we can sense it.
|
. = 0 //If a runtime occured, make sure we can sense it.
|
||||||
//message_admins("ZASALERT: Unable run turf/simualted/update_air_properties()")
|
//message_admins("ZASALERT: Unable run turf/simualted/update_air_properties()")
|
||||||
tiles_to_update = list()
|
if(.)
|
||||||
|
tiles_to_update = list()
|
||||||
|
|
||||||
//Check sanity on connection objects.
|
//Check sanity on connection objects.
|
||||||
tick_progress = "connections_to_check"
|
if(.)
|
||||||
|
tick_progress = "connections_to_check"
|
||||||
if(connections_to_check.len)
|
if(connections_to_check.len)
|
||||||
for(var/connection/C in connections_to_check)
|
for(var/connection/C in connections_to_check)
|
||||||
C.CheckPassSanity()
|
C.CheckPassSanity()
|
||||||
connections_to_check = list()
|
connections_to_check = list()
|
||||||
|
|
||||||
//Ensure tiles still have zones.
|
//Ensure tiles still have zones.
|
||||||
tick_progress = "tiles_to_reconsider_zones"
|
if(.)
|
||||||
|
tick_progress = "tiles_to_reconsider_zones"
|
||||||
if(tiles_to_reconsider_zones.len)
|
if(tiles_to_reconsider_zones.len)
|
||||||
for(var/turf/simulated/T in tiles_to_reconsider_zones)
|
for(var/turf/simulated/T in tiles_to_reconsider_zones)
|
||||||
if(!T.zone)
|
if(!T.zone)
|
||||||
@@ -198,7 +201,8 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
|||||||
tiles_to_reconsider_zones = list()
|
tiles_to_reconsider_zones = list()
|
||||||
|
|
||||||
//Process zones.
|
//Process zones.
|
||||||
tick_progress = "zone/process()"
|
if(.)
|
||||||
|
tick_progress = "zone/process()"
|
||||||
for(var/zone/Z in zones)
|
for(var/zone/Z in zones)
|
||||||
if(Z.last_update < current_cycle)
|
if(Z.last_update < current_cycle)
|
||||||
var/output = Z.process()
|
var/output = Z.process()
|
||||||
@@ -207,9 +211,11 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
|||||||
if(. && Z && !output)
|
if(. && Z && !output)
|
||||||
. = 0
|
. = 0
|
||||||
//Process fires.
|
//Process fires.
|
||||||
tick_progress = "active_hotspots (fire)"
|
if(.)
|
||||||
|
tick_progress = "active_hotspots (fire)"
|
||||||
for(var/obj/fire/F in active_hotspots)
|
for(var/obj/fire/F in active_hotspots)
|
||||||
if(. && F && !F.process())
|
if(. && F && !F.process())
|
||||||
. = 0
|
. = 0
|
||||||
|
|
||||||
tick_progress = "success"
|
if(.)
|
||||||
|
tick_progress = "success"
|
||||||
@@ -62,6 +62,13 @@ var/global/vs_control/vsc = new
|
|||||||
var/airflow_mob_slowdown_NAME = "Airflow Slowdown"
|
var/airflow_mob_slowdown_NAME = "Airflow Slowdown"
|
||||||
var/airflow_mob_slowdown_DESC = "Time in tenths of a second to add as a delay to each movement by a mob if they are fighting the pull of the airflow."
|
var/airflow_mob_slowdown_DESC = "Time in tenths of a second to add as a delay to each movement by a mob if they are fighting the pull of the airflow."
|
||||||
|
|
||||||
|
var/connection_insulation = 0.4
|
||||||
|
var/connection_insulation_NAME = "Connections - Insulation"
|
||||||
|
var/connection_insulation_DESC = "How insulative a connection is, in terms of heat transfer. 1 is perfectly insulative, and 0 is perfectly conductive."
|
||||||
|
|
||||||
|
var/connection_temperature_delta = 10
|
||||||
|
var/connection_temperature_delta_NAME = "Connections - Temperature Difference"
|
||||||
|
var/connection_temperature_delta_DESC = "The smallest temperature difference which will cause heat to travel through doors."
|
||||||
|
|
||||||
|
|
||||||
/vs_control/var/list/settings = list()
|
/vs_control/var/list/settings = list()
|
||||||
|
|||||||
@@ -36,14 +36,13 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
|||||||
//Generate the gas_mixture for use in txhis zone by using the average of the gases
|
//Generate the gas_mixture for use in txhis zone by using the average of the gases
|
||||||
//defined at startup.
|
//defined at startup.
|
||||||
air = new
|
air = new
|
||||||
var/members = contents.len
|
|
||||||
for(var/turf/simulated/T in contents)
|
|
||||||
air.oxygen += T.oxygen / members
|
|
||||||
air.nitrogen += T.nitrogen / members
|
|
||||||
air.carbon_dioxide += T.carbon_dioxide / members
|
|
||||||
air.toxins += T.toxins / members
|
|
||||||
air.temperature += T.temperature / members
|
|
||||||
air.group_multiplier = contents.len
|
air.group_multiplier = contents.len
|
||||||
|
for(var/turf/simulated/T in contents)
|
||||||
|
air.oxygen += T.oxygen / air.group_multiplier
|
||||||
|
air.nitrogen += T.nitrogen / air.group_multiplier
|
||||||
|
air.carbon_dioxide += T.carbon_dioxide / air.group_multiplier
|
||||||
|
air.toxins += T.toxins / air.group_multiplier
|
||||||
|
air.temperature += T.temperature / air.group_multiplier
|
||||||
air.update_values()
|
air.update_values()
|
||||||
|
|
||||||
//Add this zone to the global list.
|
//Add this zone to the global list.
|
||||||
@@ -80,8 +79,11 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
|||||||
for(var/zone/Z in connected_zones)
|
for(var/zone/Z in connected_zones)
|
||||||
if(src in Z.connected_zones)
|
if(src in Z.connected_zones)
|
||||||
Z.connected_zones.Remove(src)
|
Z.connected_zones.Remove(src)
|
||||||
|
connected_zones = null
|
||||||
|
|
||||||
for(var/connection/C in connections)
|
for(var/connection/C in connections)
|
||||||
air_master.connections_to_check += C
|
air_master.connections_to_check += C
|
||||||
|
connections = null
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@@ -108,12 +110,7 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
|||||||
|
|
||||||
/zone/proc/RemoveTurf(turf/T)
|
/zone/proc/RemoveTurf(turf/T)
|
||||||
//Same, but in reverse.
|
//Same, but in reverse.
|
||||||
if(istype(T, /turf/simulated) && T in unsimulated_tiles) //It happens. Gods know why.
|
if(istype(T, /turf/simulated))
|
||||||
unsimulated_tiles -= T
|
|
||||||
if(!unsimulated_tiles.len)
|
|
||||||
unsimulated_tiles = null
|
|
||||||
src.AddTurf(T) //Make sure it gets onto the simulated list.
|
|
||||||
else if(istype(T, /turf/simulated))
|
|
||||||
if(!(T in contents))
|
if(!(T in contents))
|
||||||
return
|
return
|
||||||
contents -= T
|
contents -= T
|
||||||
@@ -151,7 +148,7 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
|||||||
if(!contents.len) //If we got soft deleted.
|
if(!contents.len) //If we got soft deleted.
|
||||||
return
|
return
|
||||||
|
|
||||||
progress = "problem with: air.adjust()"
|
progress = "problem with: air regeneration"
|
||||||
|
|
||||||
//Sometimes explosions will cause the air to be deleted for some reason.
|
//Sometimes explosions will cause the air to be deleted for some reason.
|
||||||
if(!air)
|
if(!air)
|
||||||
@@ -162,26 +159,23 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
|||||||
air.total_moles()
|
air.total_moles()
|
||||||
world.log << "Air object lost in zone. Regenerating."
|
world.log << "Air object lost in zone. Regenerating."
|
||||||
|
|
||||||
|
|
||||||
progress = "problem with: ShareSpace()"
|
progress = "problem with: ShareSpace()"
|
||||||
|
|
||||||
|
if(unsimulated_tiles)
|
||||||
|
if(locate(/turf/simulated) in unsimulated_tiles)
|
||||||
|
for(var/turf/simulated/T in unsimulated_tiles)
|
||||||
|
unsimulated_tiles -= T
|
||||||
|
|
||||||
if(unsimulated_tiles && length(unsimulated_tiles))
|
if(unsimulated_tiles.len)
|
||||||
for(var/turf/simulated/T in unsimulated_tiles)
|
|
||||||
RemoveTurf(T)
|
|
||||||
if(unsimulated_tiles && length(unsimulated_tiles))
|
|
||||||
var/moved_air = ShareSpace(air,unsimulated_tiles)
|
var/moved_air = ShareSpace(air,unsimulated_tiles)
|
||||||
|
|
||||||
if(moved_air > vsc.airflow_lightest_pressure)
|
if(moved_air > vsc.airflow_lightest_pressure)
|
||||||
AirflowSpace(src)
|
AirflowSpace(src)
|
||||||
|
else
|
||||||
progress = "problem with: air.react()"
|
unsimulated_tiles = null
|
||||||
|
|
||||||
//React the air here.
|
|
||||||
//Handled by fire, no need for this.
|
|
||||||
// air.react(null,0)
|
|
||||||
|
|
||||||
//Check the graphic.
|
//Check the graphic.
|
||||||
|
|
||||||
progress = "problem with: modifying turf graphics"
|
progress = "problem with: modifying turf graphics"
|
||||||
|
|
||||||
air.graphic = 0
|
air.graphic = 0
|
||||||
@@ -236,12 +230,13 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
|||||||
//Check if the connection is valid first.
|
//Check if the connection is valid first.
|
||||||
if(!C.Cleanup())
|
if(!C.Cleanup())
|
||||||
continue
|
continue
|
||||||
|
|
||||||
//Do merging if conditions are met. Specifically, if there's a non-door connection
|
//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
|
//to somewhere with space, the zones are merged regardless of equilibrium, to speed
|
||||||
//up spacing in areas with double-plated windows.
|
//up spacing in areas with double-plated windows.
|
||||||
if(C && C.A.zone && C.B.zone)
|
if(C && C.A.zone && C.B.zone)
|
||||||
//indirect = 2 is a direct connection.
|
//indirect = 2 is a direct connection.
|
||||||
if(C.indirect == 2 )
|
if( C.indirect == 2 )
|
||||||
if(C.A.zone.air.compare(C.B.zone.air) || unsimulated_tiles)
|
if(C.A.zone.air.compare(C.B.zone.air) || unsimulated_tiles)
|
||||||
ZMerge(C.A.zone,C.B.zone)
|
ZMerge(C.A.zone,C.B.zone)
|
||||||
|
|
||||||
@@ -249,6 +244,10 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
|||||||
|
|
||||||
//Share some
|
//Share some
|
||||||
for(var/zone/Z in connected_zones)
|
for(var/zone/Z in connected_zones)
|
||||||
|
//If that zone has already processed, skip it.
|
||||||
|
if(Z.last_update > last_update)
|
||||||
|
continue
|
||||||
|
|
||||||
if(air && Z.air)
|
if(air && Z.air)
|
||||||
//Ensure we're not doing pointless calculations on equilibrium zones.
|
//Ensure we're not doing pointless calculations on equilibrium zones.
|
||||||
var/moles_delta = abs(air.total_moles() - Z.air.total_moles())
|
var/moles_delta = abs(air.total_moles() - Z.air.total_moles())
|
||||||
@@ -265,7 +264,7 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
|||||||
|
|
||||||
for(var/zone/Z in closed_connection_zones)
|
for(var/zone/Z in closed_connection_zones)
|
||||||
if(air && Z.air)
|
if(air && Z.air)
|
||||||
if( abs(air.temperature - Z.air.temperature) > 10 )
|
if( abs(air.temperature - Z.air.temperature) > vsc.connection_temperature_delta )
|
||||||
ShareHeat(air, Z.air, closed_connection_zones[Z])
|
ShareHeat(air, Z.air, closed_connection_zones[Z])
|
||||||
|
|
||||||
progress = "all components completed successfully, the problem is not here"
|
progress = "all components completed successfully, the problem is not here"
|
||||||
@@ -274,7 +273,7 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
|||||||
//Air Movement//
|
//Air Movement//
|
||||||
////////////////
|
////////////////
|
||||||
|
|
||||||
var/list/sharing_lookup_table = list(0.15, 0.20, 0.24, 0.27, 0.30, 0.33)
|
var/list/sharing_lookup_table = list(0.30, 0.40, 0.48, 0.54, 0.60, 0.66)
|
||||||
|
|
||||||
proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
|
proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
|
||||||
//Shares a specific ratio of gas between mixtures using simple weighted averages.
|
//Shares a specific ratio of gas between mixtures using simple weighted averages.
|
||||||
@@ -404,7 +403,9 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output)
|
|||||||
|
|
||||||
if(sharing_lookup_table.len >= unsimulated_tiles.len) //6 or more interconnecting tiles will max at 42% of air moved per tick.
|
if(sharing_lookup_table.len >= unsimulated_tiles.len) //6 or more interconnecting tiles will max at 42% of air moved per tick.
|
||||||
ratio = sharing_lookup_table[unsimulated_tiles.len]
|
ratio = sharing_lookup_table[unsimulated_tiles.len]
|
||||||
ratio *= 2
|
|
||||||
|
//We need to adjust it to account for the insulation settings.
|
||||||
|
ratio *= 1 - vsc.connection_insulation
|
||||||
|
|
||||||
A.oxygen = max(0, (A.oxygen - oxy_avg) * (1 - ratio) + oxy_avg )
|
A.oxygen = max(0, (A.oxygen - oxy_avg) * (1 - ratio) + oxy_avg )
|
||||||
A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1 - ratio) + nit_avg )
|
A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1 - ratio) + nit_avg )
|
||||||
|
|||||||
@@ -132,12 +132,12 @@ datum/controller/game_controller/proc/process()
|
|||||||
//src.set_debug_state("Air Master")
|
//src.set_debug_state("Air Master")
|
||||||
|
|
||||||
air_master.current_cycle++
|
air_master.current_cycle++
|
||||||
var/success = air_master.tick() //Changed so that a runtime does not crash the ticker.
|
if(!air_master.tick()) //Runtimed.
|
||||||
if(!success) //Runtimed.
|
|
||||||
air_master.failed_ticks++
|
air_master.failed_ticks++
|
||||||
if(air_master.failed_ticks > 5)
|
if(air_master.failed_ticks > 5)
|
||||||
world << "<font color='red'><b>RUNTIMES IN ATMOS TICKER. Killing air simulation!</font></b>"
|
world << "<font color='red'><b>RUNTIMES IN ATMOS TICKER. Killing air simulation!</font></b>"
|
||||||
message_admins("ZASALERT: unable run [air_master.tick_progress], tell someone about this!")
|
world.log << "### ZAS SHUTDOWN"
|
||||||
|
message_admins("ZASALERT: unable to run [air_master.tick_progress], shutting down!")
|
||||||
log_admin("ZASALERT: unable run zone/process() -- [air_master.tick_progress]")
|
log_admin("ZASALERT: unable run zone/process() -- [air_master.tick_progress]")
|
||||||
air_processing_killed = 1
|
air_processing_killed = 1
|
||||||
air_master.failed_ticks = 0
|
air_master.failed_ticks = 0
|
||||||
|
|||||||
@@ -77,7 +77,9 @@ mob/living/carbon/proc/handle_hallucinations()
|
|||||||
halitem.name = "Flashbang"
|
halitem.name = "Flashbang"
|
||||||
if(client) client.screen += halitem
|
if(client) client.screen += halitem
|
||||||
spawn(rand(100,250))
|
spawn(rand(100,250))
|
||||||
del halitem
|
if(client)
|
||||||
|
client.screen -= halitem
|
||||||
|
halitem = null
|
||||||
if(26 to 40)
|
if(26 to 40)
|
||||||
//Flashes of danger
|
//Flashes of danger
|
||||||
//src << "Danger Flash"
|
//src << "Danger Flash"
|
||||||
|
|||||||
Reference in New Issue
Block a user