This commit is contained in:
comma
2013-08-01 10:03:46 +04:00
85 changed files with 4012 additions and 2992 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ Click [here](https://github.com/Baystation12/Baystation12/archive/master.zip) to
The more complicated and easier to update method is using git. You'll need to download git or some client from [here](http://git-scm.com/). When that's installed, right click in any folder and click on "Git Bash". When that opens, type in:
git clone git@github.com:Baystation12/Baystation12.git
git clone https://github.com/Baystation12/Baystation12.git
(hint: hold down ctrl and press insert to paste into git bash)
+4 -1
View File
@@ -248,6 +248,7 @@
#include "code\game\gamemodes\events\holidays\Holidays.dm"
#include "code\game\gamemodes\events\holidays\Other.dm"
#include "code\game\gamemodes\extended\extended.dm"
#include "code\game\gamemodes\heist\heist.dm"
#include "code\game\gamemodes\malfunction\Malf_Modules.dm"
#include "code\game\gamemodes\malfunction\malfunction.dm"
#include "code\game\gamemodes\meteor\meteor.dm"
@@ -313,6 +314,7 @@
#include "code\game\machinery\newscaster.dm"
#include "code\game\machinery\OpTable.dm"
#include "code\game\machinery\overview.dm"
#include "code\game\machinery\podmen.dm"
#include "code\game\machinery\portable_turret.dm"
#include "code\game\machinery\recharger.dm"
#include "code\game\machinery\rechargestation.dm"
@@ -380,6 +382,7 @@
#include "code\game\machinery\computer\station_alert.dm"
#include "code\game\machinery\computer\syndicate_shuttle.dm"
#include "code\game\machinery\computer\syndicate_specops_shuttle.dm"
#include "code\game\machinery\computer\vox_shuttle.dm"
#include "code\game\machinery\doors\airlock.dm"
#include "code\game\machinery\doors\airlock_electronics.dm"
#include "code\game\machinery\doors\alarmlock.dm"
@@ -487,6 +490,7 @@
#include "code\game\objects\items\devices\lightreplacer.dm"
#include "code\game\objects\items\devices\multitool.dm"
#include "code\game\objects\items\devices\paicard.dm"
#include "code\game\objects\items\devices\pipe_painter.dm"
#include "code\game\objects\items\devices\powersink.dm"
#include "code\game\objects\items\devices\scanners.dm"
#include "code\game\objects\items\devices\taperecorder.dm"
@@ -1322,7 +1326,6 @@
#include "code\WorkInProgress\Cael_Aislinn\Supermatter\ZeroPointLaser.dm"
#include "code\WorkInProgress\Chinsky\ashtray.dm"
#include "code\WorkInProgress\Cib\MedicalSideEffects.dm"
#include "code\WorkInProgress\kilakk\responseteam.dm"
#include "code\WorkInProgress\Mini\ATM.dm"
#include "code\WorkInProgress\Mini\atmos_control.dm"
#include "code\WorkInProgress\Ported\policetape.dm"
+6 -25
View File
@@ -527,7 +527,7 @@ obj/machinery/atmospherics/pipe
var/build_killswitch = 1
var/obj/machinery/atmospherics/node1
New()
New()
initialize_directions = dir
..()
@@ -722,7 +722,7 @@ obj/machinery/atmospherics/pipe
icon_state = "manifold_[connected]_[unconnected]"
if(!connected)
if(!connected)
del(src)
return
@@ -951,7 +951,7 @@ obj/machinery/atmospherics/pipe
return
initialize()
for(var/obj/machinery/atmospherics/target in get_step(src,1))
if(target.initialize_directions & 2)
node1 = target
@@ -1028,7 +1028,7 @@ obj/machinery/atmospherics/pipe
manifold4w/general/hidden
level = 1
icon_state = "manifold4w-f"
cap
name = "pipe endcap"
desc = "An endcap for pipes"
@@ -1117,28 +1117,9 @@ obj/machinery/atmospherics/pipe/attackby(var/obj/item/weapon/W as obj, var/mob/u
if (istype(src, /obj/machinery/atmospherics/pipe/vent))
return ..()
// ===== Handle paints =====
if(istype(W, /obj/item/weapon/reagent_containers/glass/paint/red))
src.color = "red"
user << "\red You paint the pipe red."
update_icon()
if(istype(W,/obj/item/device/pipe_painter))
return 1
if(istype(W, /obj/item/weapon/reagent_containers/glass/paint/blue))
src.color = "blue"
user << "\red You paint the pipe blue."
update_icon()
return 1
if(istype(W, /obj/item/weapon/reagent_containers/glass/paint/green))
src.color = "green"
user << "\red You paint the pipe green."
update_icon()
return 1
if(istype(W, /obj/item/weapon/reagent_containers/glass/paint/yellow))
src.color = "yellow"
user << "\red You paint the pipe yellow."
update_icon()
return 1
if (!istype(W, /obj/item/weapon/wrench))
return ..()
var/turf/T = src.loc
+1 -1
View File
@@ -228,7 +228,7 @@ var/global/admin_emergency_team = 0 // Used for admin-spawned response teams
// Put stuff into their backpacks
equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid(src), slot_in_backpack) // Not sure about this
// equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/regular(src), slot_in_backpack) // Regular medkit
// Loyalty implants
var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(src)
+129 -129
View File
@@ -225,142 +225,142 @@ proc/AirflowSpace(zone/A)
if(M) M.GotoAirflowDest(n/10)
//Sometimes shit breaks, and M isn't there after the spawn.
atom/movable
var/tmp/turf/airflow_dest
var/tmp/airflow_speed = 0
var/tmp/airflow_time = 0
var/tmp/last_airflow = 0
proc/GotoAirflowDest(n)
if(!airflow_dest) return
if(airflow_speed < 0) return
if(last_airflow > world.time - vsc.airflow_delay) return
if(airflow_speed)
airflow_speed = n/max(get_dist(src,airflow_dest),1)
/atom/movable/var/tmp/turf/airflow_dest
/atom/movable/var/tmp/airflow_speed = 0
/atom/movable/var/tmp/airflow_time = 0
/atom/movable/var/tmp/last_airflow = 0
/atom/movable/proc/GotoAirflowDest(n)
if(!airflow_dest) return
if(airflow_speed < 0) return
if(last_airflow > world.time - vsc.airflow_delay) return
if(airflow_speed)
airflow_speed = n/max(get_dist(src,airflow_dest),1)
return
last_airflow = world.time
if(airflow_dest == loc)
step_away(src,loc)
if(ismob(src))
if(src:status_flags & GODMODE)
return
last_airflow = world.time
if(airflow_dest == loc)
step_away(src,loc)
if(ismob(src))
if(src:status_flags & GODMODE)
if(istype(src, /mob/living/carbon/human))
if(src:buckled)
return
if(istype(src, /mob/living/carbon/human))
if(src:buckled)
return
if(src:shoes)
if(istype(src:shoes, /obj/item/clothing/shoes/magboots))
if(src:shoes:magpulse)
return
src << "\red You are sucked away by airflow!"
var/airflow_falloff = 9 - ul_FalloffAmount(airflow_dest) //It's a fast falloff calc. Very useful.
if(airflow_falloff < 1)
airflow_dest = null
return
airflow_speed = min(max(n * (9/airflow_falloff),1),9)
var
xo = airflow_dest.x - src.x
yo = airflow_dest.y - src.y
od = 0
if(src:shoes)
if(istype(src:shoes, /obj/item/clothing/shoes/magboots))
if(src:shoes:magpulse)
return
src << "\red You are sucked away by airflow!"
var/airflow_falloff = 9 - ul_FalloffAmount(airflow_dest) //It's a fast falloff calc. Very useful.
if(airflow_falloff < 1)
airflow_dest = null
if(!density)
density = 1
od = 1
while(airflow_speed > 0)
if(airflow_speed <= 0) return
airflow_speed = min(airflow_speed,15)
airflow_speed -= vsc.airflow_speed_decay
if(airflow_speed > 7)
if(airflow_time++ >= airflow_speed - 7)
if(od)
density = 0
sleep(1 * tick_multiplier)
else
return
airflow_speed = min(max(n * (9/airflow_falloff),1),9)
var
xo = airflow_dest.x - src.x
yo = airflow_dest.y - src.y
od = 0
airflow_dest = null
if(!density)
density = 1
od = 1
while(airflow_speed > 0)
if(airflow_speed <= 0) return
airflow_speed = min(airflow_speed,15)
airflow_speed -= vsc.airflow_speed_decay
if(airflow_speed > 7)
if(airflow_time++ >= airflow_speed - 7)
if(od)
density = 0
sleep(max(1,10-(airflow_speed+3)) * tick_multiplier)
if(od)
density = 1
if ((!( src.airflow_dest ) || src.loc == src.airflow_dest))
src.airflow_dest = locate(min(max(src.x + xo, 1), world.maxx), min(max(src.y + yo, 1), world.maxy), src.z)
if ((src.x == 1 || src.x == world.maxx || src.y == 1 || src.y == world.maxy))
return
if(!istype(loc, /turf))
return
step_towards(src, src.airflow_dest)
if(ismob(src) && src:client)
src:client:move_delay = world.time + vsc.airflow_mob_slowdown
airflow_dest = null
airflow_speed = 0
airflow_time = 0
if(od)
density = 0
proc/RepelAirflowDest(n)
if(!airflow_dest) return
if(airflow_speed < 0) return
if(last_airflow > world.time - vsc.airflow_delay) return
if(airflow_speed)
airflow_speed = n/max(get_dist(src,airflow_dest),1)
return
if(airflow_dest == loc)
step_away(src,loc)
if(ismob(src))
if(src:status_flags & GODMODE)
return
if(istype(src, /mob/living/carbon/human))
if(src:buckled)
return
if(src:shoes)
if(src:shoes.type == /obj/item/clothing/shoes/magboots)
if(src:shoes.flags & NOSLIP)
return
src << "\red You are pushed away by airflow!"
last_airflow = world.time
var/airflow_falloff = 9 - ul_FalloffAmount(airflow_dest) //It's a fast falloff calc. Very useful.
if(airflow_falloff < 1)
airflow_dest = null
return
airflow_speed = min(max(n * (9/airflow_falloff),1),9)
var
xo = -(airflow_dest.x - src.x)
yo = -(airflow_dest.y - src.y)
od = 0
airflow_dest = null
if(!density)
density = 1
od = 1
while(airflow_speed > 0)
if(airflow_speed <= 0) return
airflow_speed = min(airflow_speed,15)
airflow_speed -= vsc.airflow_speed_decay
if(airflow_speed > 7)
if(airflow_time++ >= airflow_speed - 7)
sleep(1 * tick_multiplier)
else
sleep(max(1,10-(airflow_speed+3)) * tick_multiplier)
if ((!( src.airflow_dest ) || src.loc == src.airflow_dest))
src.airflow_dest = locate(min(max(src.x + xo, 1), world.maxx), min(max(src.y + yo, 1), world.maxy), src.z)
if ((src.x == 1 || src.x == world.maxx || src.y == 1 || src.y == world.maxy))
return
if(!istype(loc, /turf))
return
step_towards(src, src.airflow_dest)
if(ismob(src) && src:client)
src:client:move_delay = world.time + vsc.airflow_mob_slowdown
airflow_dest = null
airflow_speed = 0
airflow_time = 0
if(od)
density = 0
Bump(atom/A)
if(airflow_speed > 0 && airflow_dest)
airflow_hit(A)
sleep(1 * tick_multiplier)
else
airflow_speed = 0
airflow_time = 0
. = ..()
if(od)
density = 0
sleep(max(1,10-(airflow_speed+3)) * tick_multiplier)
if(od)
density = 1
if ((!( src.airflow_dest ) || src.loc == src.airflow_dest))
src.airflow_dest = locate(min(max(src.x + xo, 1), world.maxx), min(max(src.y + yo, 1), world.maxy), src.z)
if ((src.x == 1 || src.x == world.maxx || src.y == 1 || src.y == world.maxy))
return
if(!istype(loc, /turf))
return
step_towards(src, src.airflow_dest)
if(ismob(src) && src:client)
src:client:move_delay = world.time + vsc.airflow_mob_slowdown
airflow_dest = null
airflow_speed = 0
airflow_time = 0
if(od)
density = 0
/atom/movable/proc/RepelAirflowDest(n)
if(!airflow_dest) return
if(airflow_speed < 0) return
if(last_airflow > world.time - vsc.airflow_delay) return
if(airflow_speed)
airflow_speed = n/max(get_dist(src,airflow_dest),1)
return
if(airflow_dest == loc)
step_away(src,loc)
if(ismob(src))
if(src:status_flags & GODMODE)
return
if(istype(src, /mob/living/carbon/human))
if(src:buckled)
return
if(src:shoes)
if(istype(src:shoes, /obj/item/clothing/shoes/magboots))
if(src:shoes.flags & NOSLIP)
return
src << "\red You are pushed away by airflow!"
last_airflow = world.time
var/airflow_falloff = 9 - ul_FalloffAmount(airflow_dest) //It's a fast falloff calc. Very useful.
if(airflow_falloff < 1)
airflow_dest = null
return
airflow_speed = min(max(n * (9/airflow_falloff),1),9)
var
xo = -(airflow_dest.x - src.x)
yo = -(airflow_dest.y - src.y)
od = 0
airflow_dest = null
if(!density)
density = 1
od = 1
while(airflow_speed > 0)
if(airflow_speed <= 0) return
airflow_speed = min(airflow_speed,15)
airflow_speed -= vsc.airflow_speed_decay
if(airflow_speed > 7)
if(airflow_time++ >= airflow_speed - 7)
sleep(1 * tick_multiplier)
else
sleep(max(1,10-(airflow_speed+3)) * tick_multiplier)
if ((!( src.airflow_dest ) || src.loc == src.airflow_dest))
src.airflow_dest = locate(min(max(src.x + xo, 1), world.maxx), min(max(src.y + yo, 1), world.maxy), src.z)
if ((src.x == 1 || src.x == world.maxx || src.y == 1 || src.y == world.maxy))
return
if(!istype(loc, /turf))
return
step_towards(src, src.airflow_dest)
if(ismob(src) && src:client)
src:client:move_delay = world.time + vsc.airflow_mob_slowdown
airflow_dest = null
airflow_speed = 0
airflow_time = 0
if(od)
density = 0
/atom/movable/Bump(atom/A)
if(airflow_speed > 0 && airflow_dest)
airflow_hit(A)
else
airflow_speed = 0
airflow_time = 0
. = ..()
atom/movable/proc/airflow_hit(atom/A)
airflow_speed = 0
+364 -361
View File
@@ -6,393 +6,396 @@ Indirect connections will not merge the two zones after they reach equilibrium.
#define CONNECTION_INDIRECT 1
#define CONNECTION_CLOSED 0
/connection
var/turf/simulated/A
var/turf/simulated/B
connection
var
turf/simulated //The turfs involved in the connection.
A
B
zone
zone_A
zone_B
ref_A
ref_B
indirect = CONNECTION_DIRECT //If the connection is purely indirect, the zones should not join.
last_updated //The tick at which this was last updated.
no_zone_count = 0
var/zone/zone_A
var/zone/zone_B
var/ref_A
var/ref_B
var/indirect = CONNECTION_DIRECT //If the connection is purely indirect, the zones should not join.
var/last_updated //The tick at which this was last updated.
var/no_zone_count = 0
New(turf/T,turf/O)
A = T
B = O
if(A.zone && B.zone)
if(!A.zone.connections) A.zone.connections = list()
A.zone.connections += src
zone_A = A.zone
ref_A = "\ref[A]"
if(!B.zone.connections) B.zone.connections = list()
B.zone.connections += src
zone_B = B.zone
ref_B = "\ref[B]"
/connection/New(turf/T,turf/O)
A = T
B = O
if(A.zone && B.zone)
if(!A.zone.connections) A.zone.connections = list()
A.zone.connections += src
zone_A = A.zone
ref_A = "\ref[A]"
if(ref_A in air_master.turfs_with_connections)
var/list/connections = air_master.turfs_with_connections[ref_A]
connections.Add(src)
else
air_master.turfs_with_connections[ref_A] = list(src)
if(ref_B in air_master.turfs_with_connections)
var/list/connections = air_master.turfs_with_connections[ref_B]
connections.Add(src)
else
air_master.turfs_with_connections[ref_B] = list(src)
if(A.CanPass(null, B, 0, 0))
ConnectZones(A.zone, B.zone, 1)
if(A.HasDoor(B) || B.HasDoor(A))
indirect = CONNECTION_INDIRECT
else
ConnectZones(A.zone, B.zone)
indirect = CONNECTION_CLOSED
else
world.log << "Attempted to create connection object for non-zone tiles: [T] ([T.x],[T.y],[T.z]) -> [O] ([O.x],[O.y],[O.z])"
del(src)
Del()
//remove connections from master lists.
if(ref_B in air_master.turfs_with_connections)
var/list/connections = air_master.turfs_with_connections[ref_B]
connections.Remove(src)
if(!B.zone.connections) B.zone.connections = list()
B.zone.connections += src
zone_B = B.zone
ref_B = "\ref[B]"
if(ref_A in air_master.turfs_with_connections)
var/list/connections = air_master.turfs_with_connections[ref_A]
connections.Remove(src)
connections.Add(src)
else
air_master.turfs_with_connections[ref_A] = list(src)
//Remove connection from zones.
if(A)
if(A.zone && A.zone.connections)
A.zone.connections.Remove(src)
if(!A.zone.connections.len)
A.zone.connections = null
if(ref_B in air_master.turfs_with_connections)
var/list/connections = air_master.turfs_with_connections[ref_B]
connections.Add(src)
else
air_master.turfs_with_connections[ref_B] = list(src)
if(istype(zone_A) && (!A || A.zone != zone_A))
if(A.CanPass(null, B, 0, 0))
ConnectZones(A.zone, B.zone, 1)
if(A.HasDoor(B) || B.HasDoor(A))
indirect = CONNECTION_INDIRECT
else
ConnectZones(A.zone, B.zone)
indirect = CONNECTION_CLOSED
else
world.log << "Attempted to create connection object for non-zone tiles: [T] ([T.x],[T.y],[T.z]) -> [O] ([O.x],[O.y],[O.z])"
del(src)
/connection/Del()
//remove connections from master lists.
if(ref_B in air_master.turfs_with_connections)
var/list/connections = air_master.turfs_with_connections[ref_B]
connections.Remove(src)
if(ref_A in air_master.turfs_with_connections)
var/list/connections = air_master.turfs_with_connections[ref_A]
connections.Remove(src)
//Remove connection from zones.
if(A)
if(A.zone && A.zone.connections)
A.zone.connections.Remove(src)
if(!A.zone.connections.len)
A.zone.connections = null
if(istype(zone_A) && (!A || A.zone != zone_A))
if(zone_A.connections)
zone_A.connections.Remove(src)
if(!zone_A.connections.len)
zone_A.connections = null
if(B)
if(B.zone && B.zone.connections)
B.zone.connections.Remove(src)
if(!B.zone.connections.len)
B.zone.connections = null
if(istype(zone_B) && (!B || B.zone != zone_B))
if(zone_B.connections)
zone_B.connections.Remove(src)
if(!zone_B.connections.len)
zone_B.connections = null
//Disconnect zones while handling unusual conditions.
// e.g. loss of a zone on a turf
if(A && A.zone && B && B.zone)
DisconnectZones(A.zone, B.zone)
//Finally, preform actual deletion.
. = ..()
/connection/proc/ConnectZones(var/zone/zone_1, var/zone/zone_2, open = 0)
//Sanity checking
if(!istype(zone_1) || !istype(zone_2))
return
//Handle zones connecting indirectly/directly.
if(open)
//Create the lists if necessary.
if(!zone_1.connected_zones)
zone_1.connected_zones = list()
if(!zone_2.connected_zones)
zone_2.connected_zones = list()
//Increase the number of connections between zones.
if(zone_2 in zone_1.connected_zones)
zone_1.connected_zones[zone_2]++
else
zone_1.connected_zones += zone_2
zone_1.connected_zones[zone_2] = 1
if(zone_1 in zone_2.connected_zones)
zone_2.connected_zones[zone_1]++
else
zone_2.connected_zones += zone_1
zone_2.connected_zones[zone_1] = 1
//Handle closed connections.
else
//Create the lists
if(!zone_1.closed_connection_zones)
zone_1.closed_connection_zones = list()
if(!zone_2.closed_connection_zones)
zone_2.closed_connection_zones = list()
//Increment the connections.
if(zone_2 in zone_1.closed_connection_zones)
zone_1.closed_connection_zones[zone_2]++
else
zone_1.closed_connection_zones += zone_2
zone_1.closed_connection_zones[zone_2] = 1
if(zone_1 in zone_2.closed_connection_zones)
zone_2.closed_connection_zones[zone_1]++
else
zone_2.closed_connection_zones += zone_1
zone_2.closed_connection_zones[zone_1] = 1
/connection/proc/DisconnectZones(var/zone/zone_1, var/zone/zone_2)
//Sanity checking
if(!istype(zone_1) || !istype(zone_2))
return
if(indirect != CONNECTION_CLOSED)
//Handle disconnection of indirectly or directly connected zones.
if( (zone_1 in zone_2.connected_zones) || (zone_2 in zone_1.connected_zones) )
//If there are more than one connection, decrement the number of connections
//Otherwise, remove all connections between the zones.
if(zone_2 in zone_1.connected_zones)
if(zone_1.connected_zones[zone_2] > 1)
zone_1.connected_zones[zone_2]--
else
zone_1.connected_zones -= zone_2
//remove the list if it is empty
if(!zone_1.connected_zones.len)
zone_1.connected_zones = null
//Then do the same for the other zone.
if(zone_1 in zone_2.connected_zones)
if(zone_2.connected_zones[zone_1] > 1)
zone_2.connected_zones[zone_1]--
else
zone_2.connected_zones -= zone_1
if(!zone_2.connected_zones.len)
zone_2.connected_zones = null
else
//Handle disconnection of closed zones.
if( (zone_1 in zone_2.closed_connection_zones) || (zone_2 in zone_1.closed_connection_zones) )
//If there are more than one connection, decrement the number of connections
//Otherwise, remove all connections between the zones.
if(zone_2 in zone_1.closed_connection_zones)
if(zone_1.closed_connection_zones[zone_2] > 1)
zone_1.closed_connection_zones[zone_2]--
else
zone_1.closed_connection_zones -= zone_2
//remove the list if it is empty
if(!zone_1.closed_connection_zones.len)
zone_1.closed_connection_zones = null
//Then do the same for the other zone.
if(zone_1 in zone_2.closed_connection_zones)
if(zone_2.closed_connection_zones[zone_1] > 1)
zone_2.closed_connection_zones[zone_1]--
else
zone_2.closed_connection_zones -= zone_1
if(!zone_2.closed_connection_zones.len)
zone_2.closed_connection_zones = null
/connection/proc/Cleanup()
//Check sanity: existance of turfs
if(!A || !B)
del src
//Check sanity: zones are different
if(A.zone == B.zone)
del src
//Check sanity: same turfs as before.
if(ref_A != "\ref[A]" || ref_B != "\ref[B]")
del src
//Handle zones changing on a turf.
if((A.zone && A.zone != zone_A) || (B.zone && B.zone != zone_B))
Sanitize()
//Manage sudden loss of a turfs zone. (e.g. a wall being built)
if(!A.zone || !B.zone)
no_zone_count++
if(no_zone_count >= 5)
//world.log << "Connection removed: [A] or [B] missing a zone."
del src
return 0
return 1
/connection/proc/CheckPassSanity()
//Sanity check, first.
Cleanup()
if(A.zone && B.zone)
//If no walls are blocking us...
if(A.ZAirPass(B))
//...we check to see if there is a door in the way...
var/door_pass = A.CanPass(null,B,1.5,1)
//...and if it is opened.
if(door_pass || A.CanPass(null,B,0,0))
//Make and remove connections to let air pass.
if(indirect == CONNECTION_CLOSED)
DisconnectZones(A.zone, B.zone)
ConnectZones(A.zone, B.zone, 1)
if(door_pass)
indirect = CONNECTION_DIRECT
else if(!door_pass)
indirect = CONNECTION_INDIRECT
//The door is instead closed.
else if(indirect > CONNECTION_CLOSED)
DisconnectZones(A.zone, B.zone)
indirect = CONNECTION_CLOSED
ConnectZones(A.zone, B.zone)
//If I can no longer pass air, better delete
else
del src
/connection/proc/Sanitize()
//If the zones change on connected turfs, update it.
//Both zones changed (wat)
if(A.zone && A.zone != zone_A && B.zone && B.zone != zone_B)
//If the zones have gotten swapped
// (do not ask me how, I am just being anal retentive about sanity)
if(A.zone == zone_B && B.zone == zone_A)
var/turf/temp = B
B = A
A = temp
zone_B = B.zone
zone_A = A.zone
var/temp_ref = ref_A
ref_A = ref_B
ref_B = temp_ref
return
//Handle removal of connections from archived zones.
if(zone_A && zone_A.connections)
zone_A.connections.Remove(src)
if(!zone_A.connections.len)
zone_A.connections = null
if(zone_B && zone_B.connections)
zone_B.connections.Remove(src)
if(!zone_B.connections.len)
zone_B.connections = null
if(A.zone)
if(!A.zone.connections)
A.zone.connections = list()
A.zone.connections |= src
if(B.zone)
if(!B.zone.connections)
B.zone.connections = list()
B.zone.connections |= src
//If either zone is null, we disconnect the archived ones after cleaning up the connections.
if(!A.zone || !B.zone)
if(zone_A && zone_B)
DisconnectZones(zone_B, zone_A)
if(!A.zone)
zone_A = A.zone
if(!B.zone)
zone_B = B.zone
return
//Handle diconnection and reconnection of zones.
if(zone_A && zone_B)
DisconnectZones(zone_A, zone_B)
ConnectZones(A.zone, B.zone, indirect)
//resetting values of archived values.
zone_B = B.zone
zone_A = A.zone
//The "A" zone changed.
else if(A.zone && A.zone != zone_A)
//Handle connection cleanup
if(zone_A)
if(zone_A.connections)
zone_A.connections.Remove(src)
if(!zone_A.connections.len)
zone_A.connections = null
if(B)
if(B.zone && B.zone.connections)
B.zone.connections.Remove(src)
if(!B.zone.connections.len)
B.zone.connections = null
if(A.zone)
if(!A.zone.connections)
A.zone.connections = list()
A.zone.connections |= src
if(istype(zone_B) && (!B || B.zone != zone_B))
//If the "A" zone is null, we disconnect the archived ones after cleaning up the connections.
if(!A.zone)
if(zone_A && zone_B)
DisconnectZones(zone_A, zone_B)
zone_A = A.zone
return
//Handle diconnection and reconnection of zones.
if(zone_A && zone_B)
DisconnectZones(zone_A, zone_B)
ConnectZones(A.zone, B.zone, indirect)
zone_A = A.zone
//The "B" zone changed.
else if(B.zone && B.zone != zone_B)
//Handle connection cleanup
if(zone_B)
if(zone_B.connections)
zone_B.connections.Remove(src)
if(!zone_B.connections.len)
zone_B.connections = null
//Disconnect zones while handling unusual conditions.
// e.g. loss of a zone on a turf
if(A && A.zone && B && B.zone)
DisconnectZones(A.zone, B.zone)
if(B.zone)
if(!B.zone.connections)
B.zone.connections = list()
B.zone.connections |= src
//Finally, preform actual deletion.
. = ..()
proc/ConnectZones(var/zone/zone_1, var/zone/zone_2, open = 0)
//Sanity checking
if(!istype(zone_1) || !istype(zone_2))
return
//Handle zones connecting indirectly/directly.
if(open)
//Create the lists if necessary.
if(!zone_1.connected_zones)
zone_1.connected_zones = list()
if(!zone_2.connected_zones)
zone_2.connected_zones = list()
//Increase the number of connections between zones.
if(zone_2 in zone_1.connected_zones)
zone_1.connected_zones[zone_2]++
else
zone_1.connected_zones += zone_2
zone_1.connected_zones[zone_2] = 1
if(zone_1 in zone_2.connected_zones)
zone_2.connected_zones[zone_1]++
else
zone_2.connected_zones += zone_1
zone_2.connected_zones[zone_1] = 1
//Handle closed connections.
else
//Create the lists
if(!zone_1.closed_connection_zones)
zone_1.closed_connection_zones = list()
if(!zone_2.closed_connection_zones)
zone_2.closed_connection_zones = list()
//Increment the connections.
if(zone_2 in zone_1.closed_connection_zones)
zone_1.closed_connection_zones[zone_2]++
else
zone_1.closed_connection_zones += zone_2
zone_1.closed_connection_zones[zone_2] = 1
if(zone_1 in zone_2.closed_connection_zones)
zone_2.closed_connection_zones[zone_1]++
else
zone_2.closed_connection_zones += zone_1
zone_2.closed_connection_zones[zone_1] = 1
proc/DisconnectZones(var/zone/zone_1, var/zone/zone_2)
//Sanity checking
if(!istype(zone_1) || !istype(zone_2))
return
if(indirect != CONNECTION_CLOSED)
//Handle disconnection of indirectly or directly connected zones.
if( (zone_1 in zone_2.connected_zones) || (zone_2 in zone_1.connected_zones) )
//If there are more than one connection, decrement the number of connections
//Otherwise, remove all connections between the zones.
if(zone_2 in zone_1.connected_zones)
if(zone_1.connected_zones[zone_2] > 1)
zone_1.connected_zones[zone_2]--
else
zone_1.connected_zones -= zone_2
//remove the list if it is empty
if(!zone_1.connected_zones.len)
zone_1.connected_zones = null
//Then do the same for the other zone.
if(zone_1 in zone_2.connected_zones)
if(zone_2.connected_zones[zone_1] > 1)
zone_2.connected_zones[zone_1]--
else
zone_2.connected_zones -= zone_1
if(!zone_2.connected_zones.len)
zone_2.connected_zones = null
else
//Handle disconnection of closed zones.
if( (zone_1 in zone_2.closed_connection_zones) || (zone_2 in zone_1.closed_connection_zones) )
//If there are more than one connection, decrement the number of connections
//Otherwise, remove all connections between the zones.
if(zone_2 in zone_1.closed_connection_zones)
if(zone_1.closed_connection_zones[zone_2] > 1)
zone_1.closed_connection_zones[zone_2]--
else
zone_1.closed_connection_zones -= zone_2
//remove the list if it is empty
if(!zone_1.closed_connection_zones.len)
zone_1.closed_connection_zones = null
//Then do the same for the other zone.
if(zone_1 in zone_2.closed_connection_zones)
if(zone_2.closed_connection_zones[zone_1] > 1)
zone_2.closed_connection_zones[zone_1]--
else
zone_2.closed_connection_zones -= zone_1
if(!zone_2.closed_connection_zones.len)
zone_2.closed_connection_zones = null
proc/Cleanup()
//Check sanity: existance of turfs
if(!A || !B)
del src
//Check sanity: zones are different
if(A.zone == B.zone)
del src
//Check sanity: same turfs as before.
if(ref_A != "\ref[A]" || ref_B != "\ref[B]")
del src
//Handle zones changing on a turf.
if((A.zone && A.zone != zone_A) || (B.zone && B.zone != zone_B))
Sanitize()
//Manage sudden loss of a turfs zone. (e.g. a wall being built)
if(!A.zone || !B.zone)
no_zone_count++
if(no_zone_count >= 5)
//world.log << "Connection removed: [A] or [B] missing a zone."
del src
return 0
return 1
proc/CheckPassSanity()
//Sanity check, first.
Cleanup()
if(A.zone && B.zone)
//If no walls are blocking us...
if(A.ZAirPass(B))
//...we check to see if there is a door in the way...
var/door_pass = A.CanPass(null,B,1.5,1)
//...and if it is opened.
if(door_pass || A.CanPass(null,B,0,0))
//Make and remove connections to let air pass.
if(indirect == CONNECTION_CLOSED)
DisconnectZones(A.zone, B.zone)
ConnectZones(A.zone, B.zone, 1)
if(door_pass)
indirect = CONNECTION_DIRECT
else if(!door_pass)
indirect = CONNECTION_INDIRECT
//The door is instead closed.
else if(indirect > CONNECTION_CLOSED)
DisconnectZones(A.zone, B.zone)
indirect = CONNECTION_CLOSED
ConnectZones(A.zone, B.zone)
//If I can no longer pass air, better delete
else
del src
proc/Sanitize()
//If the zones change on connected turfs, update it.
//Both zones changed (wat)
if(A.zone && A.zone != zone_A && B.zone && B.zone != zone_B)
//If the zones have gotten swapped
// (do not ask me how, I am just being anal retentive about sanity)
if(A.zone == zone_B && B.zone == zone_A)
var/turf/temp = B
B = A
A = temp
zone_B = B.zone
zone_A = A.zone
var/temp_ref = ref_A
ref_A = ref_B
ref_B = temp_ref
return
//Handle removal of connections from archived zones.
if(zone_A && zone_A.connections)
zone_A.connections.Remove(src)
if(!zone_A.connections.len)
zone_A.connections = null
if(zone_B && zone_B.connections)
zone_B.connections.Remove(src)
if(!zone_B.connections.len)
zone_B.connections = null
if(A.zone)
if(!A.zone.connections)
A.zone.connections = list()
A.zone.connections |= src
if(B.zone)
if(!B.zone.connections)
B.zone.connections = list()
B.zone.connections |= src
//If either zone is null, we disconnect the archived ones after cleaning up the connections.
if(!A.zone || !B.zone)
if(zone_A && zone_B)
DisconnectZones(zone_B, zone_A)
if(!A.zone)
zone_A = A.zone
if(!B.zone)
zone_B = B.zone
return
//Handle diconnection and reconnection of zones.
//If the "B" zone is null, we disconnect the archived ones after cleaning up the connections.
if(!B.zone)
if(zone_A && zone_B)
DisconnectZones(zone_A, zone_B)
ConnectZones(A.zone, B.zone, indirect)
//resetting values of archived values.
zone_B = B.zone
zone_A = A.zone
return
//The "A" zone changed.
else if(A.zone && A.zone != zone_A)
//Handle connection cleanup
if(zone_A)
if(zone_A.connections)
zone_A.connections.Remove(src)
if(!zone_A.connections.len)
zone_A.connections = null
if(A.zone)
if(!A.zone.connections)
A.zone.connections = list()
A.zone.connections |= src
//If the "A" zone is null, we disconnect the archived ones after cleaning up the connections.
if(!A.zone)
if(zone_A && zone_B)
DisconnectZones(zone_A, zone_B)
zone_A = A.zone
return
//Handle diconnection and reconnection of zones.
if(zone_A && zone_B)
DisconnectZones(zone_A, zone_B)
ConnectZones(A.zone, B.zone, indirect)
//The "B" zone changed.
else if(B.zone && B.zone != zone_B)
//Handle connection cleanup
if(zone_B)
if(zone_B.connections)
zone_B.connections.Remove(src)
if(!zone_B.connections.len)
zone_B.connections = null
if(B.zone)
if(!B.zone.connections)
B.zone.connections = list()
B.zone.connections |= src
//If the "B" zone is null, we disconnect the archived ones after cleaning up the connections.
if(!B.zone)
if(zone_A && zone_B)
DisconnectZones(zone_A, zone_B)
zone_B = B.zone
return
//Handle diconnection and reconnection of zones.
if(zone_A && zone_B)
DisconnectZones(zone_A, zone_B)
ConnectZones(A.zone, B.zone, indirect)
//Handle diconnection and reconnection of zones.
if(zone_A && zone_B)
DisconnectZones(zone_A, zone_B)
ConnectZones(A.zone, B.zone, indirect)
zone_B = B.zone
#undef CONNECTION_DIRECT
+55 -48
View File
@@ -8,7 +8,8 @@ client/proc/Zone_Info(turf/T as null|turf)
mob << "No zone here."
else
if(zone_debug_images)
images -= zone_debug_images
for(var/zone in zone_debug_images)
images -= zone_debug_images[zone]
zone_debug_images = null
client/var/list/zone_debug_images
@@ -23,12 +24,12 @@ client/proc/Test_ZAS_Connection(var/turf/simulated/T as turf)
"South" = SOUTH,\
"East" = EAST,\
"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
if(!direction)
return
if(direction == "None")
if(direction == "N/A")
if(T.CanPass(null, T, 0,0))
mob << "The turf can pass air! :D"
else
@@ -55,61 +56,67 @@ client/proc/Test_ZAS_Connection(var/turf/simulated/T as turf)
mob << "Both turfs can connect! :)"
zone/proc
DebugDisplay(client/client)
if(!istype(client))
return
zone/proc/DebugDisplay(client/client)
if(!istype(client))
return
if(!dbg_output)
dbg_output = 1 //Don't want to be spammed when someone investigates a zone...
if(!dbg_output)
dbg_output = 1 //Don't want to be spammed when someone investigates a zone...
if(!client.zone_debug_images)
client.zone_debug_images = list()
for(var/turf/T in contents)
client.zone_debug_images += image('debug_group.dmi', T)
if(!client.zone_debug_images)
client.zone_debug_images = list()
for(var/turf/space/S in unsimulated_tiles)
client.zone_debug_images += image('debug_space.dmi', S)
var/list/current_zone_images = list()
client << "<u>Zone Air Contents</u>"
client << "Oxygen: [air.oxygen]"
client << "Nitrogen: [air.nitrogen]"
client << "Plasma: [air.toxins]"
client << "Carbon Dioxide: [air.carbon_dioxide]"
client << "Temperature: [air.temperature] K"
client << "Heat Energy: [air.temperature * air.heat_capacity()] J"
client << "Pressure: [air.return_pressure()] KPa"
client << ""
client << "Space Tiles: [length(unsimulated_tiles)]"
client << "Movable Objects: [length(movables())]"
client << "<u>Connections: [length(connections)]</u>"
for(var/turf/T in contents)
current_zone_images += image('debug_group.dmi', T, null, TURF_LAYER)
for(var/connection/C in connections)
client << "\ref[C] [C.A] --> [C.B] [(C.indirect?"Open":"Closed")]"
client.zone_debug_images += image('debug_connect.dmi', C.A)
client.zone_debug_images += image('debug_connect.dmi', C.B)
for(var/turf/space/S in unsimulated_tiles)
current_zone_images += image('debug_space.dmi', S, null, TURF_LAYER)
client << "Connected Zones:"
for(var/zone/zone in connected_zones)
client << "\ref[zone] [zone] - [connected_zones[zone]] (Connected)"
client << "<u>Zone Air Contents</u>"
client << "Oxygen: [air.oxygen]"
client << "Nitrogen: [air.nitrogen]"
client << "Plasma: [air.toxins]"
client << "Carbon Dioxide: [air.carbon_dioxide]"
client << "Temperature: [air.temperature] K"
client << "Heat Energy: [air.temperature * air.heat_capacity()] J"
client << "Pressure: [air.return_pressure()] KPa"
client << ""
client << "Space Tiles: [length(unsimulated_tiles)]"
client << "Movable Objects: [length(movables())]"
client << "<u>Connections: [length(connections)]</u>"
for(var/zone/zone in closed_connection_zones)
client << "\ref[zone] [zone] - [closed_connection_zones[zone]] (Unconnected)"
for(var/connection/C in connections)
client << "\ref[C] [C.A] --> [C.B] [(C.indirect?"Open":"Closed")]"
current_zone_images += image('debug_connect.dmi', C.A, null, TURF_LAYER)
current_zone_images += image('debug_connect.dmi', C.B, null, TURF_LAYER)
for(var/C in connections)
if(!istype(C,/connection))
client << "[C] (Not Connection!)"
client << "Connected Zones:"
for(var/zone/zone in connected_zones)
client << "\ref[zone] [zone] - [connected_zones[zone]] (Connected)"
client.images += client.zone_debug_images
for(var/zone/zone in closed_connection_zones)
client << "\ref[zone] [zone] - [closed_connection_zones[zone]] (Unconnected)"
else
dbg_output = 0
for(var/C in connections)
if(!istype(C,/connection))
client << "[C] (Not Connection!)"
client.images -= client.zone_debug_images
client.zone_debug_images = null
if(!client.zone_debug_images)
client.zone_debug_images = list()
client.zone_debug_images[src] = current_zone_images
for(var/zone/Z in zones)
if(Z.air == air && Z != src)
var/turf/zloc = pick(Z.contents)
client << "\red Illegal air datum shared by: [zloc.loc.name]"
client.images += client.zone_debug_images[src]
else
dbg_output = 0
client.images -= client.zone_debug_images[src]
client.zone_debug_images.Remove(src)
for(var/zone/Z in zones)
if(Z.air == air && Z != src)
var/turf/zloc = pick(Z.contents)
client << "\red Illegal air datum shared by: [zloc.loc.name]"
File diff suppressed because it is too large Load Diff
+112 -109
View File
@@ -64,49 +64,46 @@ 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
/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
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)
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 src)
if(!obstacle.CanPass(mover, target, height, air_group))
if(target != src)
for(var/obj/obstacle in target)
if(!obstacle.CanPass(mover, src, height, air_group))
return 0
if(target != src)
for(var/obj/obstacle in target)
if(!obstacle.CanPass(mover, src, height, air_group))
return 0
return 1
return 1
var/global/datum/controller/air_system/air_master
var/datum/controller/air_system/air_master
datum
controller
air_system
//Geoemetry lists
var/list/turfs_with_connections = list()
var/list/active_hotspots = list()
/datum/controller/air_system/
//Geoemetry lists
var/list/turfs_with_connections = list()
var/list/active_hotspots = list()
//Special functions lists
var/list/tiles_to_reconsider_zones = list()
//Special functions lists
var/list/tiles_to_reconsider_zones = list()
//Geometry updates lists
var/list/tiles_to_update = list()
var/list/connections_to_check = list()
//Geometry updates lists
var/list/tiles_to_update = list()
var/list/connections_to_check = list()
var/current_cycle = 0
var/update_delay = 5 //How long between check should it try to process atmos again.
var/failed_ticks = 0 //How many ticks have runtimed?
var/current_cycle = 0
var/update_delay = 5 //How long between check should it try to process atmos again.
var/failed_ticks = 0 //How many ticks have runtimed?
var/tick_progress = 0
var/tick_progress = 0
/* process()
@@ -122,97 +119,103 @@ datum
*/
proc/setup()
//Purpose: Call this at the start to setup air groups geometry
// (Warning: Very processor intensive but only must be done once per round)
//Called by: Gameticker/Master controller
//Inputs: None.
//Outputs: None.
/datum/controller/air_system/proc/setup()
//Purpose: Call this at the start to setup air groups geometry
// (Warning: Very processor intensive but only must be done once per round)
//Called by: Gameticker/Master controller
//Inputs: None.
//Outputs: None.
set background = 1
world << "\red \b Processing Geometry..."
sleep(-1)
set background = 1
world << "\red \b Processing Geometry..."
sleep(-1)
var/start_time = world.timeofday
var/start_time = world.timeofday
var/simulated_turf_count = 0
var/simulated_turf_count = 0
for(var/turf/simulated/S in world)
simulated_turf_count++
if(!S.zone && !S.blocks_air)
if(S.CanPass(null, S, 0, 0))
new/zone(S)
for(var/turf/simulated/S in world)
simulated_turf_count++
if(!S.zone && !S.blocks_air)
if(S.CanPass(null, S, 0, 0))
new/zone(S)
for(var/turf/simulated/S in world)
S.update_air_properties()
for(var/turf/simulated/S in world)
S.update_air_properties()
world << {"<font color='red'><b>Geometry initialized in [round(0.1*(world.timeofday-start_time),0.1)] seconds.</b>
Total Simulated Turfs: [simulated_turf_count]
Total Zones: [zones.len]
Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_count]</font>"}
/*
spawn start()
world << {"<font color='red'><b>Geometry initialized in [round(0.1*(world.timeofday-start_time),0.1)] seconds.</b>
Total Simulated Turfs: [simulated_turf_count]
Total Zones: [zones.len]
Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_count]</font>"}
/*
spawn start()
proc/start()
//Purpose: This is kicked off by the master controller, and controls the processing of all atmosphere.
//Called by: Master controller
//Inputs: None.
//Outputs: None.
/datum/controller/air_system/proc/start()
//Purpose: This is kicked off by the master controller, and controls the processing of all atmosphere.
//Called by: Master controller
//Inputs: None.
//Outputs: None.
set background = 1
set background = 1
while(1)
if(!kill_air)
current_cycle++
var/success = tick() //Changed so that a runtime does not crash the ticker.
if(!success) //Runtimed.
failed_ticks++
if(failed_ticks > 20)
world << "<font color='red'><b>ERROR IN ATMOS TICKER. Killing air simulation!</font></b>"
kill_air = 1
sleep(max(5,update_delay*tick_multiplier))
*/
while(1)
if(!kill_air)
current_cycle++
var/success = tick() //Changed so that a runtime does not crash the ticker.
if(!success) //Runtimed.
failed_ticks++
if(failed_ticks > 20)
world << "<font color='red'><b>ERROR IN ATMOS TICKER. Killing air simulation!</font></b>"
kill_air = 1
sleep(max(5,update_delay*tick_multiplier))
*/
proc/tick()
. = 1 //Set the default return value, for runtime detection.
/datum/controller/air_system/proc/tick()
. = 1 //Set the default return value, for runtime detection.
tick_progress = "update_air_properties"
if(tiles_to_update.len) //If there are tiles to update, do so.
for(var/turf/simulated/T in tiles_to_update)
if(. && T && !T.update_air_properties())
. = 0 //If a runtime occured, make sure we can sense it.
//message_admins("ZASALERT: Unable run turf/simualted/update_air_properties()")
tiles_to_update = list()
tick_progress = "update_air_properties"
if(tiles_to_update.len) //If there are tiles to update, do so.
for(var/turf/simulated/T in tiles_to_update)
if(. && T && !T.update_air_properties())
. = 0 //If a runtime occured, make sure we can sense it.
//message_admins("ZASALERT: Unable run turf/simualted/update_air_properties()")
if(.)
tiles_to_update = list()
//Check sanity on connection objects.
tick_progress = "connections_to_check"
if(connections_to_check.len)
for(var/connection/C in connections_to_check)
C.CheckPassSanity()
connections_to_check = list()
//Check sanity on connection objects.
if(.)
tick_progress = "connections_to_check"
if(connections_to_check.len)
for(var/connection/C in connections_to_check)
C.CheckPassSanity()
connections_to_check = list()
//Ensure tiles still have zones.
tick_progress = "tiles_to_reconsider_zones"
if(tiles_to_reconsider_zones.len)
for(var/turf/simulated/T in tiles_to_reconsider_zones)
if(!T.zone)
new /zone(T)
tiles_to_reconsider_zones = list()
//Ensure tiles still have zones.
if(.)
tick_progress = "tiles_to_reconsider_zones"
if(tiles_to_reconsider_zones.len)
for(var/turf/simulated/T in tiles_to_reconsider_zones)
if(!T.zone)
new /zone(T)
tiles_to_reconsider_zones = list()
//Process zones.
tick_progress = "zone/process()"
for(var/zone/Z in zones)
if(Z.last_update < current_cycle)
var/output = Z.process()
if(Z)
Z.last_update = current_cycle
if(. && Z && !output)
. = 0
//Process fires.
tick_progress = "active_hotspots (fire)"
for(var/obj/fire/F in active_hotspots)
if(. && F && !F.process())
. = 0
//Process zones.
if(.)
tick_progress = "zone/process()"
for(var/zone/Z in zones)
if(Z.last_update < current_cycle)
var/output = Z.process()
if(Z)
Z.last_update = current_cycle
if(. && Z && !output)
. = 0
//Process fires.
if(.)
tick_progress = "active_hotspots (fire)"
for(var/obj/fire/F in active_hotspots)
if(. && F && !F.process())
. = 0
tick_progress = "success"
if(.)
tick_progress = "success"
+119 -121
View File
@@ -30,7 +30,7 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh)
var/igniting = 0
var/obj/effect/decal/cleanable/liquid_fuel/liquid = locate() in src
if(air_contents.check_combustability(liquid))
igniting = 1
@@ -43,132 +43,130 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh)
return igniting
obj
fire
//Icon for fire on turfs.
/obj/fire
//Icon for fire on turfs.
anchored = 1
mouse_opacity = 0
anchored = 1
mouse_opacity = 0
//luminosity = 3
//luminosity = 3
icon = 'fire.dmi'
icon = 'fire.dmi'
icon_state = "1"
layer = TURF_LAYER
var/firelevel = 10000 //Calculated by gas_mixture.calculate_firelevel()
/obj/fire/process()
. = 1
//get location and check if it is in a proper ZAS zone
var/turf/simulated/floor/S = loc
if(!S.zone)
del src
if(!istype(S))
del src
var/datum/gas_mixture/air_contents = S.return_air()
//get liquid fuels on the ground.
var/obj/effect/decal/cleanable/liquid_fuel/liquid = locate() in S
//and the volatile stuff from the air
var/datum/gas/volatile_fuel/fuel = locate() in air_contents.trace_gases
//since the air is processed in fractions, we need to make sure not to have any minuscle residue or
//the amount of moles might get to low for some functions to catch them and thus result in wonky behaviour
if(air_contents.oxygen < 0.001)
air_contents.oxygen = 0
if(air_contents.toxins < 0.001)
air_contents.toxins = 0
if(fuel)
if(fuel.moles < 0.001)
air_contents.trace_gases.Remove(fuel)
//check if there is something to combust
if(!air_contents.check_combustability(liquid))
del src
//get a firelevel and set the icon
firelevel = air_contents.calculate_firelevel(liquid)
if(firelevel > 6)
icon_state = "3"
SetLuminosity(7)
else if(firelevel > 2.5)
icon_state = "2"
SetLuminosity(5)
else
icon_state = "1"
SetLuminosity(3)
layer = TURF_LAYER
//im not sure how to implement a version that works for every creature so for now monkeys are firesafe
for(var/mob/living/carbon/human/M in loc)
M.FireBurn(firelevel, air_contents.temperature, air_contents.return_pressure() ) //Burn the humans!
var
firelevel = 10000 //Calculated by gas_mixture.calculate_firelevel()
process()
. = 1
//get location and check if it is in a proper ZAS zone
var/turf/simulated/floor/S = loc
if(!S.zone)
del src
if(!istype(S))
del src
var/datum/gas_mixture/air_contents = S.return_air()
//get liquid fuels on the ground.
var/obj/effect/decal/cleanable/liquid_fuel/liquid = locate() in S
//and the volatile stuff from the air
var/datum/gas/volatile_fuel/fuel = locate() in air_contents.trace_gases
//since the air is processed in fractions, we need to make sure not to have any minuscle residue or
//the amount of moles might get to low for some functions to catch them and thus result in wonky behaviour
if(air_contents.oxygen < 0.001)
air_contents.oxygen = 0
if(air_contents.toxins < 0.001)
air_contents.toxins = 0
if(fuel)
if(fuel.moles < 0.001)
air_contents.trace_gases.Remove(fuel)
//check if there is something to combust
if(!air_contents.check_combustability(liquid))
del src
//get a firelevel and set the icon
firelevel = air_contents.calculate_firelevel(liquid)
if(firelevel > 6)
icon_state = "3"
SetLuminosity(7)
else if(firelevel > 2.5)
icon_state = "2"
SetLuminosity(5)
else
icon_state = "1"
SetLuminosity(3)
//im not sure how to implement a version that works for every creature so for now monkeys are firesafe
for(var/mob/living/carbon/human/M in loc)
M.FireBurn(firelevel, air_contents.temperature, air_contents.return_pressure() ) //Burn the humans!
//spread!
for(var/direction in cardinal)
if(S.air_check_directions&direction) //Grab all valid bordering tiles
//spread!
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)
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 -= 1.5
continue
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 -= 1.5
continue
//Spread the fire.
if(!(locate(/obj/fire) in enemy_tile))
if( prob( 50 + 50 * (firelevel/vsc.fire_firelevel_multiplier) ) && S.CanPass(null, enemy_tile, 0,0) && enemy_tile.CanPass(null, S, 0,0))
new/obj/fire(enemy_tile,firelevel)
//seperate part of the present gas
//this is done to prevent the fire burning all gases in a single pass
var/datum/gas_mixture/flow = air_contents.remove_ratio(vsc.fire_consuption_rate)
//Spread the fire.
if(!(locate(/obj/fire) in enemy_tile))
if( prob( 50 + 50 * (firelevel/vsc.fire_firelevel_multiplier) ) && S.CanPass(null, enemy_tile, 0,0) && enemy_tile.CanPass(null, S, 0,0))
new/obj/fire(enemy_tile,firelevel)
//seperate part of the present gas
//this is done to prevent the fire burning all gases in a single pass
var/datum/gas_mixture/flow = air_contents.remove_ratio(vsc.fire_consuption_rate)
///////////////////////////////// FLOW HAS BEEN CREATED /// DONT DELETE THE FIRE UNTIL IT IS MERGED BACK OR YOU WILL DELETE AIR ///////////////////////////////////////////////
if(flow)
if(flow.check_combustability(liquid))
//Ensure flow temperature is higher than minimum fire temperatures.
//this creates some energy ex nihilo but is necessary to get a fire started
//lets just pretend this energy comes from the ignition source and dont mention this again
//flow.temperature = max(PLASMA_MINIMUM_BURN_TEMPERATURE+0.1,flow.temperature)
//burn baby burn!
flow.zburn(liquid,1)
//merge the air back
S.assume_air(flow)
if(flow)
if(flow.check_combustability(liquid))
//Ensure flow temperature is higher than minimum fire temperatures.
//this creates some energy ex nihilo but is necessary to get a fire started
//lets just pretend this energy comes from the ignition source and dont mention this again
//flow.temperature = max(PLASMA_MINIMUM_BURN_TEMPERATURE+0.1,flow.temperature)
//burn baby burn!
flow.zburn(liquid,1)
//merge the air back
S.assume_air(flow)
///////////////////////////////// FLOW HAS BEEN REMERGED /// feel free to delete the fire again from here on //////////////////////////////////////////////////////////////////
New(newLoc,fl)
..()
if(!istype(loc, /turf))
del src
/obj/fire/New(newLoc,fl)
..()
dir = pick(cardinal)
SetLuminosity(3)
firelevel = fl
air_master.active_hotspots.Add(src)
if(!istype(loc, /turf))
del src
dir = pick(cardinal)
SetLuminosity(3)
firelevel = fl
air_master.active_hotspots.Add(src)
Del()
if (istype(loc, /turf/simulated))
SetLuminosity(0)
/obj/fire/Del()
if (istype(loc, /turf/simulated))
SetLuminosity(0)
loc = null
air_master.active_hotspots.Remove(src)
loc = null
air_master.active_hotspots.Remove(src)
..()
..()
@@ -180,13 +178,13 @@ turf/simulated/apply_fire_protection()
datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid,force_burn)
var/value = 0
if((temperature > PLASMA_MINIMUM_BURN_TEMPERATURE || force_burn) && check_combustability(liquid) )
var/total_fuel = 0
var/total_fuel = 0
var/datum/gas/volatile_fuel/fuel = locate() in trace_gases
total_fuel += toxins
if(fuel)
//Volatile Fuel
total_fuel += fuel.moles
@@ -207,7 +205,7 @@ datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid,force
//determine the amount of oxygen used
var/total_oxygen = min(oxygen, 2 * total_fuel)
//determine the amount of fuel actually used
var/used_fuel_ratio = min(oxygen / 2 , total_fuel) / total_fuel
total_fuel = total_fuel * used_fuel_ratio
@@ -234,31 +232,31 @@ datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid,force
//calculate the energy produced by the reaction and then set the new temperature of the mix
temperature = (starting_energy + vsc.fire_fuel_energy_release * total_fuel) / heat_capacity()
update_values()
value = total_reactants * used_reactants_ratio
return value
datum/gas_mixture/proc/check_combustability(obj/effect/decal/cleanable/liquid_fuel/liquid)
//this check comes up very often and is thus centralized here to ease adding stuff
var/datum/gas/volatile_fuel/fuel = locate() in trace_gases
var/datum/gas/volatile_fuel/fuel = locate() in trace_gases
var/value = 0
if(oxygen && (toxins || fuel || liquid))
value = 1
return value
datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/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
var/total_fuel = 0
var/firelevel = 0
if(check_combustability(liquid))
total_fuel += toxins
if(liquid)
@@ -268,16 +266,16 @@ datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fue
total_fuel += fuel.moles
var/total_combustables = (total_fuel + oxygen)
if(total_fuel > 0 && oxygen > 0)
//slows down the burning when the concentration of the reactants is low
var/dampening_multiplier = total_combustables / (total_combustables + nitrogen + carbon_dioxide)
//calculates how close the mixture of the reactants is to the optimum
var/mix_multiplier = 1 / (1 + (5 * ((oxygen / total_combustables) ^2)))
//toss everything together
firelevel = vsc.fire_firelevel_multiplier * mix_multiplier * dampening_multiplier
return max( 0, firelevel)
+42 -42
View File
@@ -1,61 +1,61 @@
var/image/contamination_overlay = image('icons/effects/contamination.dmi')
pl_control/var
PLASMA_DMG = 3
PLASMA_DMG_NAME = "Plasma Damage Amount"
PLASMA_DMG_DESC = "Self Descriptive"
/pl_control
var/PLASMA_DMG = 3
var/PLASMA_DMG_NAME = "Plasma Damage Amount"
var/PLASMA_DMG_DESC = "Self Descriptive"
CLOTH_CONTAMINATION = 1
CLOTH_CONTAMINATION_NAME = "Cloth Contamination"
CLOTH_CONTAMINATION_DESC = "If this is on, plasma does damage by getting into cloth."
var/CLOTH_CONTAMINATION = 1
var/CLOTH_CONTAMINATION_NAME = "Cloth Contamination"
var/CLOTH_CONTAMINATION_DESC = "If this is on, plasma does damage by getting into cloth."
PLASMAGUARD_ONLY = 0
PLASMAGUARD_ONLY_NAME = "\"PlasmaGuard Only\""
PLASMAGUARD_ONLY_DESC = "If this is on, only biosuits and spacesuits protect against contamination and ill effects."
var/PLASMAGUARD_ONLY = 0
var/PLASMAGUARD_ONLY_NAME = "\"PlasmaGuard Only\""
var/PLASMAGUARD_ONLY_DESC = "If this is on, only biosuits and spacesuits protect against contamination and ill effects."
GENETIC_CORRUPTION = 0
GENETIC_CORRUPTION_NAME = "Genetic Corruption Chance"
GENETIC_CORRUPTION_DESC = "Chance of genetic corruption as well as toxic damage, X in 10,000."
var/GENETIC_CORRUPTION = 0
var/GENETIC_CORRUPTION_NAME = "Genetic Corruption Chance"
var/GENETIC_CORRUPTION_DESC = "Chance of genetic corruption as well as toxic damage, X in 10,000."
SKIN_BURNS = 0
SKIN_BURNS_DESC = "Plasma has an effect similar to mustard gas on the un-suited."
SKIN_BURNS_NAME = "Skin Burns"
var/SKIN_BURNS = 0
var/SKIN_BURNS_DESC = "Plasma has an effect similar to mustard gas on the un-suited."
var/SKIN_BURNS_NAME = "Skin Burns"
EYE_BURNS = 1
EYE_BURNS_NAME = "Eye Burns"
EYE_BURNS_DESC = "Plasma burns the eyes of anyone not wearing eye protection."
var/EYE_BURNS = 1
var/EYE_BURNS_NAME = "Eye Burns"
var/EYE_BURNS_DESC = "Plasma burns the eyes of anyone not wearing eye protection."
CONTAMINATION_LOSS = 0.02
CONTAMINATION_LOSS_NAME = "Contamination Loss"
CONTAMINATION_LOSS_DESC = "How much toxin damage is dealt from contaminated clothing" //Per tick? ASK ARYN
var/CONTAMINATION_LOSS = 0.02
var/CONTAMINATION_LOSS_NAME = "Contamination Loss"
var/CONTAMINATION_LOSS_DESC = "How much toxin damage is dealt from contaminated clothing" //Per tick? ASK ARYN
PLASMA_HALLUCINATION = 0
PLASMA_HALLUCINATION_NAME = "Plasma Hallucination"
PLASMA_HALLUCINATION_DESC = "Does being in plasma cause you to hallucinate?"
var/PLASMA_HALLUCINATION = 0
var/PLASMA_HALLUCINATION_NAME = "Plasma Hallucination"
var/PLASMA_HALLUCINATION_DESC = "Does being in plasma cause you to hallucinate?"
N2O_HALLUCINATION = 1
N2O_HALLUCINATION_NAME = "N2O Hallucination"
N2O_HALLUCINATION_DESC = "Does being in sleeping gas cause you to hallucinate?"
var/N2O_HALLUCINATION = 1
var/N2O_HALLUCINATION_NAME = "N2O Hallucination"
var/N2O_HALLUCINATION_DESC = "Does being in sleeping gas cause you to hallucinate?"
obj/var/contaminated = 0
obj/item/proc
can_contaminate()
//Clothing and backpacks can be contaminated.
if(flags & PLASMAGUARD) return 0
else if(istype(src,/obj/item/weapon/storage/backpack)) return 0 //Cannot be washed :(
else if(istype(src,/obj/item/clothing)) return 1
contaminate()
//Do a contamination overlay? Temporary measure to keep contamination less deadly than it was.
if(!contaminated)
contaminated = 1
overlays += contamination_overlay
/obj/item/proc/can_contaminate()
//Clothing and backpacks can be contaminated.
if(flags & PLASMAGUARD) return 0
else if(istype(src,/obj/item/weapon/storage/backpack)) return 0 //Cannot be washed :(
else if(istype(src,/obj/item/clothing)) return 1
decontaminate()
contaminated = 0
overlays -= contamination_overlay
/obj/item/proc/contaminate()
//Do a contamination overlay? Temporary measure to keep contamination less deadly than it was.
if(!contaminated)
contaminated = 1
overlays += contamination_overlay
/obj/item/proc/decontaminate()
contaminated = 0
overlays -= contamination_overlay
/mob/proc/contaminate()
+306 -296
View File
@@ -1,322 +1,332 @@
var/global/vs_control/vsc = new
vs_control/var
fire_consuption_rate = 0.25
fire_consuption_rate_NAME = "Fire - Air Consumption Ratio"
fire_consuption_rate_DESC = "Ratio of air removed and combusted per tick."
/vs_control
var/fire_consuption_rate = 0.25
var/fire_consuption_rate_NAME = "Fire - Air Consumption Ratio"
var/fire_consuption_rate_DESC = "Ratio of air removed and combusted per tick."
fire_firelevel_multiplier = 25
fire_firelevel_multiplier_NAME = "Fire - Firelevel Constant"
fire_firelevel_multiplier_DESC = "Multiplied by the equation for firelevel, affects mainly the extingiushing of fires."
var/fire_firelevel_multiplier = 25
var/fire_firelevel_multiplier_NAME = "Fire - Firelevel Constant"
var/fire_firelevel_multiplier_DESC = "Multiplied by the equation for firelevel, affects mainly the extingiushing of fires."
fire_fuel_energy_release = 397000
fire_fuel_energy_release_NAME = "Fire - Fuel energy release"
fire_fuel_energy_release_DESC = "The energy in joule released when burning one mol of a burnable substance"
airflow_lightest_pressure = 20
airflow_lightest_pressure_NAME = "Airflow - Small Movement Threshold %"
airflow_lightest_pressure_DESC = "Percent of 1 Atm. at which items with the small weight classes will move."
airflow_light_pressure = 35
airflow_light_pressure_NAME = "Airflow - Medium Movement Threshold %"
airflow_light_pressure_DESC = "Percent of 1 Atm. at which items with the medium weight classes will move."
airflow_medium_pressure = 50
airflow_medium_pressure_NAME = "Airflow - Heavy Movement Threshold %"
airflow_medium_pressure_DESC = "Percent of 1 Atm. at which items with the largest weight classes will move."
airflow_heavy_pressure = 65
airflow_heavy_pressure_NAME = "Airflow - Mob Movement Threshold %"
airflow_heavy_pressure_DESC = "Percent of 1 Atm. at which mobs will move."
airflow_dense_pressure = 85
airflow_dense_pressure_NAME = "Airflow - Dense Movement Threshold %"
airflow_dense_pressure_DESC = "Percent of 1 Atm. at which items with canisters and closets will move."
airflow_stun_pressure = 60
airflow_stun_pressure_NAME = "Airflow - Mob Stunning Threshold %"
airflow_stun_pressure_DESC = "Percent of 1 Atm. at which mobs will be stunned by airflow."
airflow_stun_cooldown = 60
airflow_stun_cooldown_NAME = "Aiflow Stunning - Cooldown"
airflow_stun_cooldown_DESC = "How long, in tenths of a second, to wait before stunning them again."
airflow_stun = 1
airflow_stun_NAME = "Airflow Impact - Stunning"
airflow_stun_DESC = "How much a mob is stunned when hit by an object."
airflow_damage = 2
airflow_damage_NAME = "Airflow Impact - Damage"
airflow_damage_DESC = "Damage from airflow impacts."
airflow_speed_decay = 1.5
airflow_speed_decay_NAME = "Airflow Speed Decay"
airflow_speed_decay_DESC = "How rapidly the speed gained from airflow decays."
airflow_delay = 30
airflow_delay_NAME = "Airflow Retrigger Delay"
airflow_delay_DESC = "Time in deciseconds before things can be moved by airflow again."
airflow_mob_slowdown = 1
airflow_mob_slowdown_NAME = "Airflow Slowdown"
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/fire_fuel_energy_release = 397000
var/fire_fuel_energy_release_NAME = "Fire - Fuel energy release"
var/fire_fuel_energy_release_DESC = "The energy in joule released when burning one mol of a burnable substance"
vs_control
var
list/settings = list()
list/bitflags = list("1","2","4","8","16","32","64","128","256","512","1024")
pl_control/plc = new()
var/airflow_lightest_pressure = 20
var/airflow_lightest_pressure_NAME = "Airflow - Small Movement Threshold %"
var/airflow_lightest_pressure_DESC = "Percent of 1 Atm. at which items with the small weight classes will move."
New()
. = ..()
settings = vars.Copy()
var/airflow_light_pressure = 35
var/airflow_light_pressure_NAME = "Airflow - Medium Movement Threshold %"
var/airflow_light_pressure_DESC = "Percent of 1 Atm. at which items with the medium weight classes will move."
var/datum/D = new() //Ensure only unique vars are put through by making a datum and removing all common vars.
for(var/V in D.vars)
var/airflow_medium_pressure = 50
var/airflow_medium_pressure_NAME = "Airflow - Heavy Movement Threshold %"
var/airflow_medium_pressure_DESC = "Percent of 1 Atm. at which items with the largest weight classes will move."
var/airflow_heavy_pressure = 65
var/airflow_heavy_pressure_NAME = "Airflow - Mob Movement Threshold %"
var/airflow_heavy_pressure_DESC = "Percent of 1 Atm. at which mobs will move."
var/airflow_dense_pressure = 85
var/airflow_dense_pressure_NAME = "Airflow - Dense Movement Threshold %"
var/airflow_dense_pressure_DESC = "Percent of 1 Atm. at which items with canisters and closets will move."
var/airflow_stun_pressure = 60
var/airflow_stun_pressure_NAME = "Airflow - Mob Stunning Threshold %"
var/airflow_stun_pressure_DESC = "Percent of 1 Atm. at which mobs will be stunned by airflow."
var/airflow_stun_cooldown = 60
var/airflow_stun_cooldown_NAME = "Aiflow Stunning - Cooldown"
var/airflow_stun_cooldown_DESC = "How long, in tenths of a second, to wait before stunning them again."
var/airflow_stun = 1
var/airflow_stun_NAME = "Airflow Impact - Stunning"
var/airflow_stun_DESC = "How much a mob is stunned when hit by an object."
var/airflow_damage = 2
var/airflow_damage_NAME = "Airflow Impact - Damage"
var/airflow_damage_DESC = "Damage from airflow impacts."
var/airflow_speed_decay = 1.5
var/airflow_speed_decay_NAME = "Airflow Speed Decay"
var/airflow_speed_decay_DESC = "How rapidly the speed gained from airflow decays."
var/airflow_delay = 30
var/airflow_delay_NAME = "Airflow Retrigger Delay"
var/airflow_delay_DESC = "Time in deciseconds before things can be moved by airflow again."
var/airflow_mob_slowdown = 1
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/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/bitflags = list("1","2","4","8","16","32","64","128","256","512","1024")
/vs_control/var/pl_control/plc = new()
/vs_control/New()
. = ..()
settings = vars.Copy()
var/datum/D = new() //Ensure only unique vars are put through by making a datum and removing all common vars.
for(var/V in D.vars)
settings -= V
for(var/V in settings)
if(findtextEx(V,"_RANDOM") || findtextEx(V,"_DESC") || findtextEx(V,"_METHOD"))
settings -= V
for(var/V in settings)
if(findtextEx(V,"_RANDOM") || findtextEx(V,"_DESC") || findtextEx(V,"_METHOD"))
settings -= V
settings -= "settings"
settings -= "bitflags"
settings -= "plc"
settings -= "settings"
settings -= "bitflags"
settings -= "plc"
proc/ChangeSettingsDialog(mob/user,list/L)
//var/which = input(user,"Choose a setting:") in L
var/dat = ""
for(var/ch in L)
if(findtextEx(ch,"_RANDOM") || findtextEx(ch,"_DESC") || findtextEx(ch,"_METHOD") || findtextEx(ch,"_NAME")) continue
var/vw
var/vw_desc = "No Description."
var/vw_name = ch
if(ch in plc.settings)
vw = plc.vars[ch]
if("[ch]_DESC" in plc.vars) vw_desc = plc.vars["[ch]_DESC"]
if("[ch]_NAME" in plc.vars) vw_name = plc.vars["[ch]_NAME"]
else
vw = vars[ch]
if("[ch]_DESC" in vars) vw_desc = vars["[ch]_DESC"]
if("[ch]_NAME" in vars) vw_name = vars["[ch]_NAME"]
dat += "<b>[vw_name] = [vw]</b> <A href='?src=\ref[src];changevar=[ch]'>\[Change\]</A><br>"
dat += "<i>[vw_desc]</i><br><br>"
user << browse(dat,"window=settings")
Topic(href,href_list)
if("changevar" in href_list)
ChangeSetting(usr,href_list["changevar"])
proc/ChangeSetting(mob/user,ch)
/vs_control/proc/ChangeSettingsDialog(mob/user,list/L)
//var/which = input(user,"Choose a setting:") in L
var/dat = ""
for(var/ch in L)
if(findtextEx(ch,"_RANDOM") || findtextEx(ch,"_DESC") || findtextEx(ch,"_METHOD") || findtextEx(ch,"_NAME")) continue
var/vw
var/how = "Text"
var/display_description = ch
var/vw_desc = "No Description."
var/vw_name = ch
if(ch in plc.settings)
vw = plc.vars[ch]
if("[ch]_NAME" in plc.vars)
display_description = plc.vars["[ch]_NAME"]
if("[ch]_METHOD" in plc.vars)
how = plc.vars["[ch]_METHOD"]
else
if(isnum(vw))
how = "Numeric"
else
how = "Text"
if("[ch]_DESC" in plc.vars) vw_desc = plc.vars["[ch]_DESC"]
if("[ch]_NAME" in plc.vars) vw_name = plc.vars["[ch]_NAME"]
else
vw = vars[ch]
if("[ch]_NAME" in vars)
display_description = vars["[ch]_NAME"]
if("[ch]_METHOD" in vars)
how = vars["[ch]_METHOD"]
if("[ch]_DESC" in vars) vw_desc = vars["[ch]_DESC"]
if("[ch]_NAME" in vars) vw_name = vars["[ch]_NAME"]
dat += "<b>[vw_name] = [vw]</b> <A href='?src=\ref[src];changevar=[ch]'>\[Change\]</A><br>"
dat += "<i>[vw_desc]</i><br><br>"
user << browse(dat,"window=settings")
/vs_control/Topic(href,href_list)
if("changevar" in href_list)
ChangeSetting(usr,href_list["changevar"])
/vs_control/proc/ChangeSetting(mob/user,ch)
var/vw
var/how = "Text"
var/display_description = ch
if(ch in plc.settings)
vw = plc.vars[ch]
if("[ch]_NAME" in plc.vars)
display_description = plc.vars["[ch]_NAME"]
if("[ch]_METHOD" in plc.vars)
how = plc.vars["[ch]_METHOD"]
else
if(isnum(vw))
how = "Numeric"
else
if(isnum(vw))
how = "Numeric"
else
how = "Text"
var/newvar = vw
switch(how)
if("Numeric")
newvar = input(user,"Enter a number:","Settings",newvar) as num
if("Bit Flag")
var/flag = input(user,"Toggle which bit?","Settings") in bitflags
flag = text2num(flag)
if(newvar & flag)
newvar &= ~flag
else
newvar |= flag
if("Toggle")
newvar = !newvar
if("Text")
newvar = input(user,"Enter a string:","Settings",newvar) as text
if("Long Text")
newvar = input(user,"Enter text:","Settings",newvar) as message
vw = newvar
if(ch in plc.settings)
plc.vars[ch] = vw
how = "Text"
else
vw = vars[ch]
if("[ch]_NAME" in vars)
display_description = vars["[ch]_NAME"]
if("[ch]_METHOD" in vars)
how = vars["[ch]_METHOD"]
else
vars[ch] = vw
if(how == "Toggle")
newvar = (newvar?"ON":"OFF")
world << "\blue <b>[key_name(user)] changed the setting [display_description] to [newvar].</b>"
if(ch in plc.settings)
ChangeSettingsDialog(user,plc.settings)
else
ChangeSettingsDialog(user,settings)
proc/RandomizeWithProbability()
for(var/V in settings)
var/newvalue
if("[V]_RANDOM" in vars)
if(isnum(vars["[V]_RANDOM"]))
newvalue = prob(vars["[V]_RANDOM"])
else if(istext(vars["[V]_RANDOM"]))
newvalue = roll(vars["[V]_RANDOM"])
else
newvalue = vars[V]
V = newvalue
if(isnum(vw))
how = "Numeric"
else
how = "Text"
var/newvar = vw
switch(how)
if("Numeric")
newvar = input(user,"Enter a number:","Settings",newvar) as num
if("Bit Flag")
var/flag = input(user,"Toggle which bit?","Settings") in bitflags
flag = text2num(flag)
if(newvar & flag)
newvar &= ~flag
else
newvar |= flag
if("Toggle")
newvar = !newvar
if("Text")
newvar = input(user,"Enter a string:","Settings",newvar) as text
if("Long Text")
newvar = input(user,"Enter text:","Settings",newvar) as message
vw = newvar
if(ch in plc.settings)
plc.vars[ch] = vw
else
vars[ch] = vw
if(how == "Toggle")
newvar = (newvar?"ON":"OFF")
world << "\blue <b>[key_name(user)] changed the setting [display_description] to [newvar].</b>"
if(ch in plc.settings)
ChangeSettingsDialog(user,plc.settings)
else
ChangeSettingsDialog(user,settings)
proc/ChangePlasma()
for(var/V in plc.settings)
plc.Randomize(V)
proc/SetDefault(var/mob/user)
var/list/setting_choices = list("Plasma - Standard", "Plasma - Low Hazard", "Plasma - High Hazard", "Plasma - Oh Shit!",\
"ZAS - Normal", "ZAS - Forgiving", "ZAS - Dangerous", "ZAS - Hellish")
var/def = input(user, "Which of these presets should be used?") as null|anything in setting_choices
if(!def)
return
switch(def)
if("Plasma - Standard")
plc.CLOTH_CONTAMINATION = 1 //If this is on, plasma does damage by getting into cloth.
plc.PLASMAGUARD_ONLY = 0
plc.GENETIC_CORRUPTION = 0 //Chance of genetic corruption as well as toxic damage, X in 1000.
plc.SKIN_BURNS = 0 //Plasma has an effect similar to mustard gas on the un-suited.
plc.EYE_BURNS = 1 //Plasma burns the eyes of anyone not wearing eye protection.
plc.PLASMA_HALLUCINATION = 0
plc.CONTAMINATION_LOSS = 0.02
if("Plasma - Low Hazard")
plc.CLOTH_CONTAMINATION = 0 //If this is on, plasma does damage by getting into cloth.
plc.PLASMAGUARD_ONLY = 0
plc.GENETIC_CORRUPTION = 0 //Chance of genetic corruption as well as toxic damage, X in 1000
plc.SKIN_BURNS = 0 //Plasma has an effect similar to mustard gas on the un-suited.
plc.EYE_BURNS = 1 //Plasma burns the eyes of anyone not wearing eye protection.
plc.PLASMA_HALLUCINATION = 0
plc.CONTAMINATION_LOSS = 0.01
if("Plasma - High Hazard")
plc.CLOTH_CONTAMINATION = 1 //If this is on, plasma does damage by getting into cloth.
plc.PLASMAGUARD_ONLY = 0
plc.GENETIC_CORRUPTION = 0 //Chance of genetic corruption as well as toxic damage, X in 1000.
plc.SKIN_BURNS = 1 //Plasma has an effect similar to mustard gas on the un-suited.
plc.EYE_BURNS = 1 //Plasma burns the eyes of anyone not wearing eye protection.
plc.PLASMA_HALLUCINATION = 1
plc.CONTAMINATION_LOSS = 0.05
if("Plasma - Oh Shit!")
plc.CLOTH_CONTAMINATION = 1 //If this is on, plasma does damage by getting into cloth.
plc.PLASMAGUARD_ONLY = 1
plc.GENETIC_CORRUPTION = 5 //Chance of genetic corruption as well as toxic damage, X in 1000.
plc.SKIN_BURNS = 1 //Plasma has an effect similar to mustard gas on the un-suited.
plc.EYE_BURNS = 1 //Plasma burns the eyes of anyone not wearing eye protection.
plc.PLASMA_HALLUCINATION = 1
plc.CONTAMINATION_LOSS = 0.075
if("ZAS - Normal")
airflow_lightest_pressure = 20
airflow_light_pressure = 35
airflow_medium_pressure = 50
airflow_heavy_pressure = 65
airflow_dense_pressure = 85
airflow_stun_pressure = 60
airflow_stun_cooldown = 60
airflow_stun = 1
airflow_damage = 2
airflow_speed_decay = 1.5
airflow_delay = 30
airflow_mob_slowdown = 1
if("ZAS - Forgiving")
airflow_lightest_pressure = 45
airflow_light_pressure = 60
airflow_medium_pressure = 120
airflow_heavy_pressure = 110
airflow_dense_pressure = 200
airflow_stun_pressure = 150
airflow_stun_cooldown = 90
airflow_stun = 0.15
airflow_damage = 0.15
airflow_speed_decay = 1.5
airflow_delay = 50
airflow_mob_slowdown = 0
if("ZAS - Dangerous")
airflow_lightest_pressure = 15
airflow_light_pressure = 30
airflow_medium_pressure = 45
airflow_heavy_pressure = 55
airflow_dense_pressure = 70
airflow_stun_pressure = 50
airflow_stun_cooldown = 50
airflow_stun = 2
airflow_damage = 3
airflow_speed_decay = 1.2
airflow_delay = 25
airflow_mob_slowdown = 2
if("ZAS - Hellish")
airflow_lightest_pressure = 20
airflow_light_pressure = 30
airflow_medium_pressure = 40
airflow_heavy_pressure = 50
airflow_dense_pressure = 60
airflow_stun_pressure = 40
airflow_stun_cooldown = 40
airflow_stun = 3
airflow_damage = 4
airflow_speed_decay = 1
airflow_delay = 20
airflow_mob_slowdown = 3
world << "\blue <b>[key_name(user)] changed the global plasma/ZAS settings to \"[def]\"</b>"
pl_control
var/list/settings = list()
New()
. = ..()
settings = vars.Copy()
var/datum/D = new() //Ensure only unique vars are put through by making a datum and removing all common vars.
for(var/V in D.vars)
settings -= V
for(var/V in settings)
if(findtextEx(V,"_RANDOM") || findtextEx(V,"_DESC"))
settings -= V
settings -= "settings"
proc/Randomize(V)
/vs_control/proc/RandomizeWithProbability()
for(var/V in settings)
var/newvalue
if("[V]_RANDOM" in vars)
if(isnum(vars["[V]_RANDOM"]))
newvalue = prob(vars["[V]_RANDOM"])
else if(istext(vars["[V]_RANDOM"]))
var/txt = vars["[V]_RANDOM"]
if(findtextEx(txt,"PROB"))
txt = text2list(txt,"/")
txt[1] = replacetext(txt[1],"PROB","")
var/p = text2num(txt[1])
var/r = txt[2]
if(prob(p))
newvalue = roll(r)
else
newvalue = vars[V]
else if(findtextEx(txt,"PICK"))
txt = replacetext(txt,"PICK","")
txt = text2list(txt,",")
newvalue = pick(txt)
else
newvalue = roll(txt)
newvalue = roll(vars["[V]_RANDOM"])
else
newvalue = vars[V]
vars[V] = newvalue
V = newvalue
/vs_control/proc/ChangePlasma()
for(var/V in plc.settings)
plc.Randomize(V)
/vs_control/proc/SetDefault(var/mob/user)
var/list/setting_choices = list("Plasma - Standard", "Plasma - Low Hazard", "Plasma - High Hazard", "Plasma - Oh Shit!",\
"ZAS - Normal", "ZAS - Forgiving", "ZAS - Dangerous", "ZAS - Hellish")
var/def = input(user, "Which of these presets should be used?") as null|anything in setting_choices
if(!def)
return
switch(def)
if("Plasma - Standard")
plc.CLOTH_CONTAMINATION = 1 //If this is on, plasma does damage by getting into cloth.
plc.PLASMAGUARD_ONLY = 0
plc.GENETIC_CORRUPTION = 0 //Chance of genetic corruption as well as toxic damage, X in 1000.
plc.SKIN_BURNS = 0 //Plasma has an effect similar to mustard gas on the un-suited.
plc.EYE_BURNS = 1 //Plasma burns the eyes of anyone not wearing eye protection.
plc.PLASMA_HALLUCINATION = 0
plc.CONTAMINATION_LOSS = 0.02
if("Plasma - Low Hazard")
plc.CLOTH_CONTAMINATION = 0 //If this is on, plasma does damage by getting into cloth.
plc.PLASMAGUARD_ONLY = 0
plc.GENETIC_CORRUPTION = 0 //Chance of genetic corruption as well as toxic damage, X in 1000
plc.SKIN_BURNS = 0 //Plasma has an effect similar to mustard gas on the un-suited.
plc.EYE_BURNS = 1 //Plasma burns the eyes of anyone not wearing eye protection.
plc.PLASMA_HALLUCINATION = 0
plc.CONTAMINATION_LOSS = 0.01
if("Plasma - High Hazard")
plc.CLOTH_CONTAMINATION = 1 //If this is on, plasma does damage by getting into cloth.
plc.PLASMAGUARD_ONLY = 0
plc.GENETIC_CORRUPTION = 0 //Chance of genetic corruption as well as toxic damage, X in 1000.
plc.SKIN_BURNS = 1 //Plasma has an effect similar to mustard gas on the un-suited.
plc.EYE_BURNS = 1 //Plasma burns the eyes of anyone not wearing eye protection.
plc.PLASMA_HALLUCINATION = 1
plc.CONTAMINATION_LOSS = 0.05
if("Plasma - Oh Shit!")
plc.CLOTH_CONTAMINATION = 1 //If this is on, plasma does damage by getting into cloth.
plc.PLASMAGUARD_ONLY = 1
plc.GENETIC_CORRUPTION = 5 //Chance of genetic corruption as well as toxic damage, X in 1000.
plc.SKIN_BURNS = 1 //Plasma has an effect similar to mustard gas on the un-suited.
plc.EYE_BURNS = 1 //Plasma burns the eyes of anyone not wearing eye protection.
plc.PLASMA_HALLUCINATION = 1
plc.CONTAMINATION_LOSS = 0.075
if("ZAS - Normal")
airflow_lightest_pressure = 20
airflow_light_pressure = 35
airflow_medium_pressure = 50
airflow_heavy_pressure = 65
airflow_dense_pressure = 85
airflow_stun_pressure = 60
airflow_stun_cooldown = 60
airflow_stun = 1
airflow_damage = 2
airflow_speed_decay = 1.5
airflow_delay = 30
airflow_mob_slowdown = 1
if("ZAS - Forgiving")
airflow_lightest_pressure = 45
airflow_light_pressure = 60
airflow_medium_pressure = 120
airflow_heavy_pressure = 110
airflow_dense_pressure = 200
airflow_stun_pressure = 150
airflow_stun_cooldown = 90
airflow_stun = 0.15
airflow_damage = 0.15
airflow_speed_decay = 1.5
airflow_delay = 50
airflow_mob_slowdown = 0
if("ZAS - Dangerous")
airflow_lightest_pressure = 15
airflow_light_pressure = 30
airflow_medium_pressure = 45
airflow_heavy_pressure = 55
airflow_dense_pressure = 70
airflow_stun_pressure = 50
airflow_stun_cooldown = 50
airflow_stun = 2
airflow_damage = 3
airflow_speed_decay = 1.2
airflow_delay = 25
airflow_mob_slowdown = 2
if("ZAS - Hellish")
airflow_lightest_pressure = 20
airflow_light_pressure = 30
airflow_medium_pressure = 40
airflow_heavy_pressure = 50
airflow_dense_pressure = 60
airflow_stun_pressure = 40
airflow_stun_cooldown = 40
airflow_stun = 3
airflow_damage = 4
airflow_speed_decay = 1
airflow_delay = 20
airflow_mob_slowdown = 3
world << "\blue <b>[key_name(user)] changed the global plasma/ZAS settings to \"[def]\"</b>"
/pl_control/var/list/settings = list()
/pl_control/New()
. = ..()
settings = vars.Copy()
var/datum/D = new() //Ensure only unique vars are put through by making a datum and removing all common vars.
for(var/V in D.vars)
settings -= V
for(var/V in settings)
if(findtextEx(V,"_RANDOM") || findtextEx(V,"_DESC"))
settings -= V
settings -= "settings"
/pl_control/proc/Randomize(V)
var/newvalue
if("[V]_RANDOM" in vars)
if(isnum(vars["[V]_RANDOM"]))
newvalue = prob(vars["[V]_RANDOM"])
else if(istext(vars["[V]_RANDOM"]))
var/txt = vars["[V]_RANDOM"]
if(findtextEx(txt,"PROB"))
txt = text2list(txt,"/")
txt[1] = replacetext(txt[1],"PROB","")
var/p = text2num(txt[1])
var/r = txt[2]
if(prob(p))
newvalue = roll(r)
else
newvalue = vars[V]
else if(findtextEx(txt,"PICK"))
txt = replacetext(txt,"PICK","")
txt = text2list(txt,",")
newvalue = pick(txt)
else
newvalue = roll(txt)
else
newvalue = vars[V]
vars[V] = newvalue
+209 -222
View File
@@ -1,278 +1,266 @@
atom/var/pressure_resistance = ONE_ATMOSPHERE
turf
/atom/var/pressure_resistance = ONE_ATMOSPHERE
var/zone/zone
/turf/var/zone/zone
assume_air(datum/gas_mixture/giver) //use this for machines to adjust air
del(giver)
return 0
/turf/assume_air(datum/gas_mixture/giver) //use this for machines to adjust air
del(giver)
return 0
return_air()
//Create gas mixture to hold data for passing
var/datum/gas_mixture/GM = new
/turf/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.oxygen = oxygen
GM.carbon_dioxide = carbon_dioxide
GM.nitrogen = nitrogen
GM.toxins = toxins
GM.temperature = temperature
GM.update_values()
GM.temperature = temperature
GM.update_values()
return GM
return GM
remove_air(amount as num)
var/datum/gas_mixture/GM = new
/turf/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
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
GM.update_values()
GM.temperature = temperature
GM.update_values()
return GM
return GM
turf
simulated
/turf/simulated/var/current_graphic = null
var/current_graphic = null
/turf/simulated/var/tmp/datum/gas_mixture/air
var/tmp
datum/gas_mixture/air
/turf/simulated/var/tmp/processing = 1
processing = 1
/turf/simulated/var/tmp/air_check_directions = 0 //Do not modify this, just add turf to air_master.tiles_to_update
air_check_directions = 0 //Do not modify this, just add turf to air_master.tiles_to_update
/turf/simulated/var/tmp/obj/fire/active_hotspot
obj/fire/active_hotspot
/turf/simulated/proc/update_visuals()
overlays = null
var/siding_icon_state = return_siding_icon_state()
if(siding_icon_state)
overlays += image('floors.dmi',siding_icon_state)
var/datum/gas_mixture/model = return_air()
switch(model.graphic)
if(1)
overlays.Add(plmaster) //TODO: Make invisible plasma an option
if(2)
overlays.Add(slmaster)
proc/update_visuals()
overlays = null
/turf/simulated/New()
..()
var/siding_icon_state = return_siding_icon_state()
if(siding_icon_state)
overlays += image('floors.dmi',siding_icon_state)
var/datum/gas_mixture/model = return_air()
switch(model.graphic)
if(1)
overlays.Add(plmaster) //TODO: Make invisible plasma an option
if(2)
overlays.Add(slmaster)
if(!blocks_air)
air = new
air.oxygen = oxygen
air.carbon_dioxide = carbon_dioxide
air.nitrogen = nitrogen
air.toxins = toxins
air.temperature = temperature
air.update_values()
New()
..()
if(!blocks_air)
air = new
air.oxygen = oxygen
air.carbon_dioxide = carbon_dioxide
air.nitrogen = nitrogen
air.toxins = toxins
air.temperature = temperature
air.update_values()
if(air_master)
air_master.tiles_to_update.Add(src)
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 |= target
Del()
if(active_hotspot)
del(active_hotspot)
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
if(zone)
zone.air.merge(giver)
return 1
else
return ..()
return_air()
if(zone)
return zone.air
else if(air)
return air
else
return ..()
remove_air(amount as num)
if(zone)
var/datum/gas_mixture/removed = null
removed = zone.air.remove(amount)
return removed
else if(air)
var/datum/gas_mixture/removed = null
removed = air.remove(amount)
if(air.check_tile_graphic())
update_visuals(air)
return removed
else
return ..()
proc/update_air_properties()
var/air_directions_archived = air_check_directions
air_check_directions = 0
if(air_master)
air_master.tiles_to_update.Add(src)
else
if(air_master)
for(var/direction in cardinal)
if(ZAirPass(get_step(src,direction)))
air_check_directions |= direction
var/turf/simulated/floor/target = get_step(src,direction)
if(istype(target))
air_master.tiles_to_update |= target
if(!zone && !blocks_air) //No zone, but not a wall.
for(var/direction in DoorDirections) //Check door directions first.
if(air_check_directions&direction)
var/turf/simulated/T = get_step(src,direction)
if(!istype(T))
continue
if(T.zone)
T.zone.AddTurf(src)
break
if(!zone) //Still no zone
for(var/direction in CounterDoorDirections) //Check the others second.
if(air_check_directions&direction)
var/turf/simulated/T = get_step(src,direction)
if(!istype(T))
continue
if(T.zone)
T.zone.AddTurf(src)
break
if(!zone) //No zone found, new zone!
new/zone(src)
if(!zone) //Still no zone, the floodfill determined it is not part of a larger zone. Force a zone on it.
new/zone(list(src))
/turf/simulated/Del()
if(active_hotspot)
del(active_hotspot)
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)
..()
//Check pass sanity of the connections.
if("\ref[src]" in air_master.turfs_with_connections)
for(var/connection/C in air_master.turfs_with_connections["\ref[src]"])
air_master.connections_to_check |= C
/turf/simulated/assume_air(datum/gas_mixture/giver)
if(!giver) return 0
if(zone)
zone.air.merge(giver)
return 1
else
return ..()
if(zone && !zone.rebuild)
for(var/direction in cardinal)
var/turf/T = get_step(src,direction)
/turf/simulated/return_air()
if(zone)
return zone.air
else if(air)
return air
else
return ..()
/turf/simulated/remove_air(amount as num)
if(zone)
var/datum/gas_mixture/removed = null
removed = zone.air.remove(amount)
return removed
else if(air)
var/datum/gas_mixture/removed = null
removed = air.remove(amount)
if(air.check_tile_graphic())
update_visuals(air)
return removed
else
return ..()
/turf/simulated/proc/update_air_properties()
var/air_directions_archived = air_check_directions
air_check_directions = 0
for(var/direction in cardinal)
if(ZAirPass(get_step(src,direction)))
air_check_directions |= direction
if(!zone && !blocks_air) //No zone, but not a wall.
for(var/direction in DoorDirections) //Check door directions first.
if(air_check_directions&direction)
var/turf/simulated/T = get_step(src,direction)
if(!istype(T))
continue
if(T.zone)
T.zone.AddTurf(src)
break
if(!zone) //Still no zone
for(var/direction in CounterDoorDirections) //Check the others second.
if(air_check_directions&direction)
var/turf/simulated/T = get_step(src,direction)
if(!istype(T))
continue
if(T.zone)
T.zone.AddTurf(src)
break
if(!zone) //No zone found, new zone!
new/zone(src)
if(!zone) //Still no zone, the floodfill determined it is not part of a larger zone. Force a zone on it.
new/zone(list(src))
//I can connect to air in this direction
if(air_check_directions&direction)
//Check pass sanity of the connections.
if("\ref[src]" in air_master.turfs_with_connections)
for(var/connection/C in air_master.turfs_with_connections["\ref[src]"])
air_master.connections_to_check |= C
//If either block air, we must look to see if the adjacent turfs need rebuilt.
if(!CanPass(null, T, 0, 0))
if(zone && !zone.rebuild)
for(var/direction in cardinal)
var/turf/T = get_step(src,direction)
if(!istype(T))
continue
//Target blocks air
if(!T.CanPass(null, T, 0, 0))
var/turf/NT = get_step(T, direction)
//I can connect to air in this direction
if(air_check_directions&direction)
//If that turf is in my zone still, rebuild.
if(istype(NT,/turf/simulated) && NT in zone.contents)
zone.rebuild = 1
//If either block air, we must look to see if the adjacent turfs need rebuilt.
if(!CanPass(null, T, 0, 0))
//If that is an unsimulated tile in my zone, see if we need to rebuild or just remove.
else if(istype(NT) && NT in zone.unsimulated_tiles)
var/consider_rebuild = 0
for(var/d in cardinal)
var/turf/UT = get_step(NT,d)
if(istype(UT, /turf/simulated) && UT.zone == zone && UT.CanPass(null, NT, 0, 0)) //If we find a neighboring tile that is in the same zone, check if we need to rebuild
consider_rebuild = 1
break
if(consider_rebuild)
zone.rebuild = 1 //Gotta check if we need to rebuild, dammit
else
zone.RemoveTurf(NT) //Not adjacent to anything, and unsimulated. Goodbye~
//To make a closed connection through closed door.
ZConnect(T, src)
//If I block air.
else if(T.zone && !T.zone.rebuild)
var/turf/NT = get_step(src, reverse_direction(direction))
//If I am splitting a zone, rebuild.
if(istype(NT,/turf/simulated) && (NT in T.zone.contents || (NT.zone && T in NT.zone.contents)))
T.zone.rebuild = 1
//If NT is unsimulated, parse if I should remove it or rebuild.
else if(istype(NT) && NT in T.zone.unsimulated_tiles)
var/consider_rebuild = 0
for(var/d in cardinal)
var/turf/UT = get_step(NT,d)
if(istype(UT, /turf/simulated) && UT.zone == T.zone && UT.CanPass(null, NT, 0, 0)) //If we find a neighboring tile that is in the same zone, check if we need to rebuild
consider_rebuild = 1
break
//Needs rebuilt.
if(consider_rebuild)
T.zone.rebuild = 1
//Not adjacent to anything, and unsimulated. Goodbye~
else
T.zone.RemoveTurf(NT)
else
//Produce connection through open door.
ZConnect(src,T)
//Something like a wall was built, changing the geometry.
else if(air_directions_archived&direction)
//Target blocks air
if(!T.CanPass(null, T, 0, 0))
var/turf/NT = get_step(T, direction)
//If the tile is in our own zone, and we cannot connect to it, better rebuild.
//If that turf is in my zone still, rebuild.
if(istype(NT,/turf/simulated) && NT in zone.contents)
zone.rebuild = 1
//Parse if we need to remove the tile, or rebuild the zone.
//If that is an unsimulated tile in my zone, see if we need to rebuild or just remove.
else if(istype(NT) && NT in zone.unsimulated_tiles)
var/consider_rebuild = 0
//Loop through all neighboring turfs to see if we should remove the turf or just rebuild.
for(var/d in cardinal)
var/turf/UT = get_step(NT,d)
if(istype(UT, /turf/simulated) && UT.zone == zone && UT.CanPass(null, NT, 0, 0)) //If we find a neighboring tile that is in the same zone, check if we need to rebuild
consider_rebuild = 1
break
if(consider_rebuild)
zone.rebuild = 1 //Gotta check if we need to rebuild, dammit
else
zone.RemoveTurf(NT) //Not adjacent to anything, and unsimulated. Goodbye~
//If we find a neighboring tile that is in the same zone, rebuild
if(istype(UT, /turf/simulated) && UT.zone == zone && UT.CanPass(null, NT, 0, 0))
//To make a closed connection through closed door.
ZConnect(T, src)
//If I block air.
else if(T.zone && !T.zone.rebuild)
var/turf/NT = get_step(src, reverse_direction(direction))
//If I am splitting a zone, rebuild.
if(istype(NT,/turf/simulated) && (NT in T.zone.contents || (NT.zone && T in NT.zone.contents)))
T.zone.rebuild = 1
//If NT is unsimulated, parse if I should remove it or rebuild.
else if(istype(NT) && NT in T.zone.unsimulated_tiles)
var/consider_rebuild = 0
for(var/d in cardinal)
var/turf/UT = get_step(NT,d)
if(istype(UT, /turf/simulated) && UT.zone == T.zone && UT.CanPass(null, NT, 0, 0)) //If we find a neighboring tile that is in the same zone, check if we need to rebuild
consider_rebuild = 1
break
//The unsimulated turf is adjacent to another one of our zone's turfs,
// better rebuild to be sure we didn't get cut in twain
//Needs rebuilt.
if(consider_rebuild)
zone.rebuild = 1
T.zone.rebuild = 1
//Not adjacent to anything, and unsimulated. Goodbye~
else
zone.RemoveTurf(NT)
T.zone.RemoveTurf(NT)
if(air_check_directions)
processing = 1
else
processing = 0
return 1
else
//Produce connection through open door.
ZConnect(src,T)
//Something like a wall was built, changing the geometry.
else if(air_directions_archived&direction)
var/turf/NT = get_step(T, direction)
//If the tile is in our own zone, and we cannot connect to it, better rebuild.
if(istype(NT,/turf/simulated) && NT in zone.contents)
zone.rebuild = 1
//Parse if we need to remove the tile, or rebuild the zone.
else if(istype(NT) && NT in zone.unsimulated_tiles)
var/consider_rebuild = 0
//Loop through all neighboring turfs to see if we should remove the turf or just rebuild.
for(var/d in cardinal)
var/turf/UT = get_step(NT,d)
//If we find a neighboring tile that is in the same zone, rebuild
if(istype(UT, /turf/simulated) && UT.zone == zone && UT.CanPass(null, NT, 0, 0))
consider_rebuild = 1
break
//The unsimulated turf is adjacent to another one of our zone's turfs,
// better rebuild to be sure we didn't get cut in twain
if(consider_rebuild)
zone.rebuild = 1
//Not adjacent to anything, and unsimulated. Goodbye~
else
zone.RemoveTurf(NT)
if(air_check_directions)
processing = 1
else
processing = 0
return 1
/turf/proc/HasDoor(turf/O)
//Checks for the presence of doors, used for zone spreading and connection.
@@ -289,7 +277,7 @@ turf
else
return 1
turf/proc/ZCanPass(turf/simulated/T, var/include_space = 0)
/turf/proc/ZCanPass(turf/simulated/T, var/include_space = 0)
//Fairly standard pass checks for turfs, objects and directional windows. Also stops at the edge of space.
if(!istype(T))
return 0
@@ -314,7 +302,7 @@ turf/proc/ZCanPass(turf/simulated/T, var/include_space = 0)
return 1
turf/proc/ZAirPass(turf/T)
/turf/proc/ZAirPass(turf/T)
//Fairly standard pass checks for turfs, objects and directional windows.
if(!istype(T))
return 0
@@ -336,7 +324,6 @@ turf/proc/ZAirPass(turf/T)
return 1
/*UNUSED
/turf/proc/check_connections()
//Checks for new connections that can be made.
+122 -153
View File
@@ -2,129 +2,126 @@ var/list/zones = list()
var/list/DoorDirections = list(NORTH,WEST) //Which directions doors turfs can connect to zones
var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs can connect to zones
zone
var
dbg_output = 0 //Enables debug output.
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.
list/connected_zones //Parallels connections, but lists zones to which this one is connected and the number
/zone
var/dbg_output = 0 //Enables debug output.
var/rebuild = 0 //If 1, zone will be rebuilt on next process. Not sure if used.
var/datum/gas_mixture/air //The air contents of the zone.
var/list/contents //All the tiles that are contained in this zone.
var/list/connections // /connection objects which refer to connections with other zones, e.g. through a door.
var/list/connected_zones //Parallels connections, but lists zones to which this one is connected and the number
//of points they're connected at.
list/closed_connection_zones //Same as connected_zones, but for zones where the door or whatever is closed.
list/unsimulated_tiles // Any space tiles in this list will cause air to flow out.
last_update = 0
progress = "nothing"
// To make sure you're not spammed to death by airflow sound effects
tmp/playsound_cooldown = 0
var/list/closed_connection_zones //Same as connected_zones, but for zones where the door or whatever is closed.
var/list/unsimulated_tiles // Any space tiles in this list will cause air to flow out.
var/last_update = 0
var/progress = "nothing"
//CREATION AND DELETION
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)
/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 unsimulated_tiles.
for(var/turf/T in contents)
if(T.zone && T.zone != src)
T.zone.RemoveTurf(T)
T.zone = src
if(!istype(T,/turf/simulated))
AddTurf(T)
//Change all the zone vars of the turfs, check for space to be added to unsimulated_tiles.
for(var/turf/T in contents)
if(T.zone && T.zone != src)
T.zone.RemoveTurf(T)
T.zone = src
if(!istype(T,/turf/simulated))
AddTurf(T)
//Generate the gas_mixture for use in txhis zone by using the average of the gases
//defined at startup.
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.update_values()
//Generate the gas_mixture for use in txhis zone by using the average of the gases
//defined at startup.
air = new
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()
//Add this zone to the global list.
zones.Add(src)
//Add this zone to the global list.
zones.Add(src)
//LEGACY, DO NOT USE. Use the SoftDelete proc.
Del()
//Ensuring the zone list doesn't get clogged with null values.
for(var/turf/simulated/T in contents)
RemoveTurf(T)
air_master.tiles_to_reconsider_zones += T
for(var/zone/Z in connected_zones)
if(src in Z.connected_zones)
Z.connected_zones.Remove(src)
for(var/connection/C in connections)
air_master.connections_to_check += C
zones.Remove(src)
air = null
. = ..()
/zone/Del()
//Ensuring the zone list doesn't get clogged with null values.
for(var/turf/simulated/T in contents)
RemoveTurf(T)
air_master.tiles_to_reconsider_zones += T
for(var/zone/Z in connected_zones)
if(src in Z.connected_zones)
Z.connected_zones.Remove(src)
for(var/connection/C in connections)
air_master.connections_to_check += C
zones.Remove(src)
air = null
. = ..()
//Handles deletion via garbage collection.
proc/SoftDelete()
zones.Remove(src)
air = null
/zone/proc/SoftDelete()
zones.Remove(src)
air = null
//Ensuring the zone list doesn't get clogged with null values.
for(var/turf/simulated/T in contents)
RemoveTurf(T)
air_master.tiles_to_reconsider_zones += T
//Ensuring the zone list doesn't get clogged with null values.
for(var/turf/simulated/T in contents)
RemoveTurf(T)
air_master.tiles_to_reconsider_zones += T
//Removing zone connections and scheduling connection cleanup
for(var/zone/Z in connected_zones)
if(src in Z.connected_zones)
Z.connected_zones.Remove(src)
for(var/connection/C in connections)
air_master.connections_to_check += C
//Removing zone connections and scheduling connection cleanup
for(var/zone/Z in connected_zones)
if(src in Z.connected_zones)
Z.connected_zones.Remove(src)
connected_zones = null
return 1
for(var/connection/C in connections)
air_master.connections_to_check += C
connections = null
return 1
//ZONE MANAGEMENT FUNCTIONS
proc/AddTurf(turf/T)
//Adds the turf to contents, increases the size of the zone, and sets the zone var.
if(istype(T, /turf/simulated))
if(T in contents)
return
if(T.zone)
T.zone.RemoveTurf(T)
contents += T
if(air)
air.group_multiplier++
T.zone = src
else
if(!unsimulated_tiles)
unsimulated_tiles = list()
else if(T in unsimulated_tiles)
return
unsimulated_tiles += T
contents -= T
/zone/proc/AddTurf(turf/T)
//Adds the turf to contents, increases the size of the zone, and sets the zone var.
if(istype(T, /turf/simulated))
if(T in contents)
return
if(T.zone)
T.zone.RemoveTurf(T)
contents += T
if(air)
air.group_multiplier++
T.zone = src
else
if(!unsimulated_tiles)
unsimulated_tiles = list()
else if(T in unsimulated_tiles)
return
unsimulated_tiles += T
contents -= T
proc/RemoveTurf(turf/T)
//Same, but in reverse.
if(istype(T, /turf/simulated))
if(!(T in contents))
return
contents -= T
if(air)
air.group_multiplier--
if(T.zone == src)
T.zone = null
else if(unsimulated_tiles)
unsimulated_tiles -= T
if(!unsimulated_tiles.len)
unsimulated_tiles = null
/zone/proc/RemoveTurf(turf/T)
//Same, but in reverse.
if(istype(T, /turf/simulated))
if(!(T in contents))
return
contents -= T
if(air)
air.group_multiplier--
if(T.zone == src)
T.zone = null
else if(unsimulated_tiles)
unsimulated_tiles -= T
if(!unsimulated_tiles.len)
unsimulated_tiles = null
//////////////
//PROCESSING//
@@ -132,7 +129,7 @@ zone
#define QUANTIZE(variable) (round(variable,0.0001))
zone/proc/process()
/zone/proc/process()
. = 1
progress = "problem with: SoftDelete()"
@@ -151,7 +148,7 @@ zone/proc/process()
if(!contents.len) //If we got soft deleted.
return
progress = "problem with: air.adjust()"
progress = "problem with: air regeneration"
//Sometimes explosions will cause the air to be deleted for some reason.
if(!air)
@@ -162,36 +159,23 @@ zone/proc/process()
air.total_moles()
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)
RemoveTurf(T)
if(unsimulated_tiles)
unsimulated_tiles -= T
if(unsimulated_tiles.len)
var/moved_air = ShareSpace(air,unsimulated_tiles)
// Only play a sound effect every once in a while
if(playsound_cooldown <= world.time)
// Play a nice sound effect at one of the bordering turfs
playsound_cooldown = world.time + rand(30, 70)
var/turf/random_border = pick(contents)
play_wind_sound(random_border, abs(moved_air))
if(moved_air > vsc.airflow_lightest_pressure)
AirflowSpace(src)
progress = "problem with: air.react()"
//React the air here.
//Handled by fire, no need for this.
// air.react(null,0)
else
unsimulated_tiles = null
//Check the graphic.
progress = "problem with: modifying turf graphics"
air.graphic = 0
@@ -246,12 +230,13 @@ zone/proc/process()
//Check if the connection is valid first.
if(!C.Cleanup())
continue
//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.A.zone && C.B.zone)
//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)
ZMerge(C.A.zone,C.B.zone)
@@ -259,18 +244,13 @@ zone/proc/process()
//Share some
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)
//Ensure we're not doing pointless calculations on equilibrium zones.
var/moles_delta = abs(air.total_moles() - Z.air.total_moles())
if(moles_delta > 0.1)
// Only play a sound effect every once in a while
if(playsound_cooldown <= world.time)
// Play a nice sound effect at one of the bordering turfs
playsound_cooldown = world.time + rand(30, 70)
var/turf/random_border = pick(contents)
play_wind_sound(random_border, abs(moles_delta))
if(moles_delta > 0.1 || abs(air.temperature - Z.air.temperature) > 0.1)
if(abs(Z.air.return_pressure() - air.return_pressure()) > vsc.airflow_lightest_pressure)
Airflow(src,Z)
@@ -283,8 +263,11 @@ zone/proc/process()
ShareRatio( air , Z.air , connected_zones[Z] + unsimulated_boost)
for(var/zone/Z in closed_connection_zones)
//If that zone has already processed, skip it.
if(Z.last_update > last_update)
continue
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])
progress = "all components completed successfully, the problem is not here"
@@ -293,7 +276,7 @@ zone/proc/process()
//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)
//Shares a specific ratio of gas between mixtures using simple weighted averages.
@@ -423,7 +406,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.
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.nitrogen = max(0, (A.nitrogen - nit_avg) * (1 - ratio) + nit_avg )
@@ -543,22 +528,6 @@ zone/proc/Rebuild()
if(istype(T) && T.zone && S.CanPass(null, T, 0, 0))
T.zone.AddTurf(S)
proc/play_wind_sound(var/turf/random_border, var/n)
if(random_border)
var/windsound = 'sound/effects/wind/wind_2_1.ogg'
switch(n)
if(31 to 40)
windsound = pick('sound/effects/wind/wind_2_1.ogg', 'sound/effects/wind/wind_2_2.ogg')
if(41 to 50)
windsound = pick('sound/effects/wind/wind_3_1.ogg')
if(51 to 60)
windsound = pick('sound/effects/wind/wind_4_1.ogg', 'sound/effects/wind/wind_4_2.ogg')
if(61 to 1000000)
windsound = pick('sound/effects/wind/wind_5_1.ogg')
playsound(random_border, windsound, 50, 1, 1)
//UNUSED
/*
zone/proc/connected_zones()
+3 -3
View File
@@ -132,12 +132,12 @@ datum/controller/game_controller/proc/process()
//src.set_debug_state("Air Master")
air_master.current_cycle++
var/success = air_master.tick() //Changed so that a runtime does not crash the ticker.
if(!success) //Runtimed.
if(!air_master.tick()) //Runtimed.
air_master.failed_ticks++
if(air_master.failed_ticks > 5)
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]")
air_processing_killed = 1
air_master.failed_ticks = 0
-24
View File
@@ -81,30 +81,6 @@
plant_type = 2
growthstages = 3
/obj/item/seeds/replicapod
name = "pack of replica pod seeds"
desc = "These seeds grow into replica pods. They say these are used to harvest humans."
icon_state = "seed-replicapod"
mypath = "/obj/item/seeds/replicapod"
species = "replicapod"
plantname = "Replica Pod"
productname = "/mob/living/carbon/human" //verrry special -- Urist
lifespan = 50 //no idea what those do
endurance = 8
maturation = 10
production = 10
yield = 1 //seeds if there isn't a dna inside
oneharvest = 1
potency = 30
plant_type = 0
growthstages = 6
var/ui = null //for storing the guy
var/se = null
var/ckey = null
var/realName = null
var/datum/mind/mind = null
gender = MALE
/obj/item/seeds/grapeseed
name = "pack of grape seeds"
desc = "These seeds grow into grape vines."
+24
View File
@@ -309,6 +309,11 @@ proc/process_ghost_teleport_locs()
/area/shuttle/research/outpost
icon_state = "shuttle"
/area/shuttle/vox/station
name = "\improper Vox Skipjack"
icon_state = "yellow"
requires_power = 0
/area/airtunnel1/ // referenced in airtunnel.dm:759
/area/dummy/ // Referenced in engine.dm:261
@@ -489,10 +494,29 @@ proc/process_ghost_teleport_locs()
icon_state = "yellow"
requires_power = 0
/area/vox_station/transit
name = "\improper hyperspace"
icon_state = "shuttle"
/area/vox_station/southwest_solars
name = "\improper aft port solars"
icon_state = "southwest"
/area/vox_station/northwest_solars
name = "\improper fore port solars"
icon_state = "northwest"
/area/vox_station/northeast_solars
name = "\improper fore starboard solars"
icon_state = "northeast"
/area/vox_station/southeast_solars
name = "\improper aft starboard solars"
icon_state = "southeast"
/area/vox_station/mining
name = "\improper nearby mining asteroid"
icon_state = "north"
//PRISON
/area/prison
+15 -2
View File
@@ -47,6 +47,10 @@
var/list/cameras = list()
for (var/obj/machinery/camera/C in src)
cameras += C
if(state == 1)
C.network.Remove("Power Alarms")
else
C.network.Add("Power Alarms")
for (var/mob/living/silicon/aiPlayer in player_list)
if(aiPlayer.z == source.z)
if (state == 1)
@@ -73,11 +77,15 @@
//updateicon()
for(var/obj/machinery/camera/C in RA)
cameras += C
C.network.Add("Atmosphere Alarms")
for(var/mob/living/silicon/aiPlayer in player_list)
aiPlayer.triggerAlarm("Atmosphere", src, cameras, src)
for(var/obj/machinery/computer/station_alert/a in machines)
a.triggerAlarm("Atmosphere", src, cameras, src)
else if (atmosalm == 2)
for(var/area/RA in related)
for(var/obj/machinery/camera/C in RA)
C.network.Remove("Atmosphere Alarms")
for(var/mob/living/silicon/aiPlayer in player_list)
aiPlayer.cancelAlarm("Atmosphere", src, src)
for(var/obj/machinery/computer/station_alert/a in machines)
@@ -101,8 +109,10 @@
spawn()
D.close()
var/list/cameras = list()
for (var/obj/machinery/camera/C in src)
cameras += C
for(var/area/RA in related)
for (var/obj/machinery/camera/C in RA)
cameras.Add(C)
C.network.Add("Fire Alarms")
for (var/mob/living/silicon/ai/aiPlayer in player_list)
aiPlayer.triggerAlarm("Fire", src, cameras, src)
for (var/obj/machinery/computer/station_alert/a in machines)
@@ -120,6 +130,9 @@
else if(D.density)
spawn(0)
D.open()
for(var/area/RA in related)
for (var/obj/machinery/camera/C in RA)
C.network.Remove("Fire Alarms")
for (var/mob/living/silicon/ai/aiPlayer in player_list)
aiPlayer.cancelAlarm("Fire", src, src)
for (var/obj/machinery/computer/station_alert/a in machines)
+12 -2
View File
@@ -74,7 +74,6 @@ Radio:
1359 - Security
1441 - death squad
1443 - Confession Intercom
1349 - Miners
1347 - Cargo techs
Devices:
@@ -110,10 +109,21 @@ var/list/radiochannels = list(
"Supply" = 1347,
)
//depenging helpers
var/list/DEPT_FREQS = list(1351,1355,1357,1359,1213, 1443, 1441,1347)
var/list/DEPT_FREQS = list(1351, 1355, 1357, 1359, 1213, 1443, 1441, 1347)
// central command channels, i.e deathsquid & response teams
var/list/CENT_FREQS = list(1441, 1443)
var/const/COMM_FREQ = 1353 //command, colored gold in chat window
var/const/SYND_FREQ = 1213
// department channels
var/const/SEC_FREQ = 1359
var/const/ENG_FREQ = 1357
var/const/SCI_FREQ = 1351
var/const/MED_FREQ = 1355
var/const/SUP_FREQ = 1347
#define TRANSMISSION_WIRE 0
#define TRANSMISSION_RADIO 1
+1
View File
@@ -278,6 +278,7 @@ Implants;
if(BE_REV) roletext="revolutionary"
if(BE_CULTIST) roletext="cultist"
if(BE_NINJA) roletext="ninja"
if(BE_RAIDER) roletext="raider"
// Assemble a list of active players without jobbans.
for(var/mob/new_player/player in player_list)
+251
View File
@@ -0,0 +1,251 @@
/*
VOX HEIST ROUNDTYPE
*/
#define MAX_VOX_KILLS 10 //Number of kills during the round before the Inviolate is broken.
//Would be nice to use vox-specific kills but is currently not feasible.
var/global/vox_kills = 0 //Used to check the Inviolate.
/datum/game_mode/heist
name = "heist"
config_tag = "heist"
required_players = 15
required_players_secret = 25
required_enemies = 4
recommended_enemies = 6
var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds)
var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds)
var/list/raid_objectives = list() //Raid objectives.
var/list/datum/mind/raiders = list() //Antags.
var/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' objective.
/datum/game_mode/heist/announce()
world << "<B>The current game mode is - Heist!</B>"
world << "<B>An unidentified bluespace signature has slipped past the Icarus and is approaching [station_name()]!</B>"
world << "Whoever they are, they're likely up to no good. Protect the crew and station resources against this dastardly threat!"
world << "<B>Raiders:</B> Loot [station_name()] for anything and everything you need."
world << "<B>Personnel:</B> Repel the raiders and their low, low prices and/or crossbows."
/datum/game_mode/heist/can_start()
if(!..())
return 0
var/list/candidates = get_players_for_role(BE_RAIDER)
var/raider_num = 0
//Check that we have enough vox.
if(candidates.len < required_enemies)
return 0
else if(candidates.len < recommended_enemies)
raider_num = candidates.len
else
raider_num = recommended_enemies
//Grab candidates randomly until we have enough.
while(raider_num > 0)
var/datum/mind/new_raider = pick(candidates)
raiders += new_raider
candidates -= new_raider
raider_num--
for(var/datum/mind/raider in raiders)
raider.assigned_role = "MODE"
raider.special_role = "Vox Raider"
return 1
/datum/game_mode/heist/pre_setup()
return 1
/datum/game_mode/heist/post_setup()
//Build a list of spawn points.
var/list/turf/raider_spawn = list()
for(var/obj/effect/landmark/L in landmarks_list)
if(L.name == "voxstart")
raider_spawn += get_turf(L)
del(L)
continue
//Generate objectives for the group.
raid_objectives = forge_vox_objectives()
var/index = 1
//Spawn the vox!
for(var/datum/mind/raider in raiders)
if(index > raider_spawn.len)
index = 1
raider.current.loc = raider_spawn[index]
index++
var/sounds = rand(2,8)
var/i = 0
var/newname = ""
while(i<=sounds)
i++
newname += pick(list("ti","hi","ki","ya","ta","ha","ka","ya","chi","cha","kah"))
var/mob/living/carbon/human/vox = raider.current
vox.vox_talk_understand = 1
vox.real_name = capitalize(newname)
vox.name = vox.real_name
vox.age = rand(12,20)
vox.dna.mutantrace = "vox"
vox.h_style = "Short Vox Quills"
vox.equip_vox_raider()
vox.regenerate_icons()
raider.objectives = raid_objectives
greet_vox(raider)
spawn (rand(waittime_l, waittime_h))
send_intercept()
/datum/game_mode/heist/proc/is_raider_crew_safe()
if(cortical_stacks.len == 0)
return 0
for(var/obj/stack in cortical_stacks)
if (get_area(stack) != locate(/area/shuttle/vox/station))
return 0
return 1
/datum/game_mode/heist/proc/is_raider_crew_alive()
for(var/datum/mind/raider in raiders)
if(raider.current)
if(istype(raider.current,/mob/living/carbon/human) && raider.current.stat != 2)
return 1
return 0
/datum/game_mode/heist/proc/forge_vox_objectives()
//Commented out for testing.
/* var/i = 1
var/max_objectives = pick(2,2,2,3,3)
var/list/objs = list()
while(i<= max_objectives)
var/list/goals = list("kidnap","loot","salvage")
var/goal = pick(goals)
var/datum/objective/heist/O
if(goal == "kidnap")
goals -= "kidnap"
O = new /datum/objective/heist/kidnap()
else if(goal == "loot")
O = new /datum/objective/heist/loot()
else
O = new /datum/objective/heist/salvage()
O.choose_target()
objs += O
i++
//-All- vox raids have these two objectives. Failing them loses the game.
objs += new /datum/objective/heist/inviolate_crew
objs += new /datum/objective/heist/inviolate_death */
raid_objectives += new /datum/objective/heist/kidnap
raid_objectives += new /datum/objective/heist/loot
raid_objectives += new /datum/objective/heist/salvage
raid_objectives += new /datum/objective/heist/inviolate_crew
raid_objectives += new /datum/objective/heist/inviolate_death
for(var/datum/objective/heist/O in raid_objectives)
O.choose_target()
return raid_objectives
/datum/game_mode/heist/proc/greet_vox(var/datum/mind/raider)
raider.current << "\blue <B>You are a Vox Raider, fresh from the Shoal!</b>"
raider.current << "\blue The Vox are a race of cunning, sharp-eyed nomadic raiders and traders endemic to Tau Ceti and much of the unexplored galaxy. You and the crew have come to the Exodus for plunder, trade or both."
raider.current << "\blue Vox are cowardly and will flee from larger groups, but corner one or find them en masse and they are vicious."
raider.current << "\blue Use :V to voxtalk, :H to talk on your encrypted channel, and don't forget to turn on your nitrogen internals!"
var/obj_count = 1
for(var/datum/objective/objective in raider.objectives)
raider.current << "<B>Objective #[obj_count]</B>: [objective.explanation_text]"
obj_count++
/datum/game_mode/heist/declare_completion()
//No objectives, go straight to the feedback.
if(!(raid_objectives.len)) return ..()
var/win_type = "Major"
var/win_group = "Crew"
var/win_msg = ""
var/success = raid_objectives.len
//Decrease success for failed objectives.
for(var/datum/objective/O in raid_objectives)
if(!(O.check_completion())) success--
//Set result by objectives.
if(success == raid_objectives.len)
win_type = "Major"
win_group = "Vox"
else if(success > 2)
win_type = "Minor"
win_group = "Vox"
else
win_type = "Minor"
win_group = "Crew"
//Now we modify that result by the state of the vox crew.
if(!is_raider_crew_alive())
win_type = "Major"
win_group = "Crew"
win_msg += "<B>The Vox Raiders have been wiped out!</B>"
else if(!is_raider_crew_safe())
if(win_group == "Crew" && win_type == "Minor")
win_type = "Major"
win_group = "Crew"
win_msg += "<B>The Vox Raiders have left someone behind!</B>"
else
if(win_group == "Vox")
if(win_type == "Minor")
win_type = "Major"
win_msg += "<B>The Vox Raiders escaped the station!</B>"
else
win_msg += "<B>The Vox Raiders were repelled!</B>"
world << "\red <FONT size = 3><B>[win_type] [win_group] victory!</B></FONT>"
world << "[win_msg]"
feedback_set_details("round_end_result","heist - [win_type] [win_group]")
var/count = 1
for(var/datum/objective/objective in raid_objectives)
if(objective.check_completion())
world << "<br><B>Objective #[count]</B>: [objective.explanation_text] <font color='green'><B>Success!</B></font>"
feedback_add_details("traitor_objective","[objective.type]|SUCCESS")
else
world << "<br><B>Objective #[count]</B>: [objective.explanation_text] <font color='red'>Fail.</font>"
feedback_add_details("traitor_objective","[objective.type]|FAIL")
count++
..()
/datum/game_mode/heist/check_finished()
if (!(is_raider_crew_alive()) || (vox_shuttle_location && (vox_shuttle_location == "start")))
return 1
return ..()
+93 -5
View File
@@ -15,6 +15,8 @@ var/bomb_set
var/yes_code = 0.0
var/safety = 1.0
var/obj/item/weapon/disk/nuclear/auth = null
var/removal_stage = 0 // 0 is no removal, 1 is covers removed, 2 is covers open,
// 3 is sealant open, 4 is unwrenched, 5 is removed from bolts.
flags = FPRINT
use_power = 0
@@ -33,14 +35,83 @@ var/bomb_set
src.attack_hand(M)
return
/obj/machinery/nuclearbomb/attackby(obj/item/weapon/I as obj, mob/user as mob)
/obj/machinery/nuclearbomb/attackby(obj/item/weapon/O as obj, mob/user as mob)
if (src.extended)
if (istype(I, /obj/item/weapon/disk/nuclear))
if (istype(O, /obj/item/weapon/disk/nuclear))
usr.drop_item()
I.loc = src
src.auth = I
O.loc = src
src.auth = O
src.add_fingerprint(user)
return
if (src.anchored)
switch(removal_stage)
if(0)
if(istype(O,/obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = O
if(!WT.isOn()) return
if (WT.get_fuel() < 5) // uses up 5 fuel.
user << "\red You need more fuel to complete this task."
return
user.visible_message("[user] starts cutting loose the anchoring bolt covers on [src].", "You start cutting loose the anchoring bolt covers with [O]...")
if(do_after(user,40))
if(!src || !user || !WT.remove_fuel(5, user)) return
user.visible_message("[user] cuts through the bolt covers on [src].", "You cut through the bolt cover.")
removal_stage = 1
return
if(1)
if(istype(O,/obj/item/weapon/crowbar))
user.visible_message("[user] starts forcing open the bolt covers on [src].", "You start forcing open the anchoring bolt covers with [O]...")
if(do_after(user,15))
if(!src || !user) return
user.visible_message("[user] forces open the bolt covers on [src].", "You force open the bolt covers.")
removal_stage = 2
return
if(2)
if(istype(O,/obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = O
if(!WT.isOn()) return
if (WT.get_fuel() < 5) // uses up 5 fuel.
user << "\red You need more fuel to complete this task."
return
user.visible_message("[user] starts cutting apart the anchoring system sealant on [src].", "You start cutting apart the anchoring system's sealant with [O]...")
if(do_after(user,40))
if(!src || !user || !WT.remove_fuel(5, user)) return
user.visible_message("[user] cuts apart the anchoring system sealant on [src].", "You cut apart the anchoring system's sealant.")
removal_stage = 3
return
if(3)
if(istype(O,/obj/item/weapon/wrench))
user.visible_message("[user] begins unwrenching the anchoring bolts on [src].", "You begin unwrenching the anchoring bolts...")
if(do_after(user,50))
if(!src || !user) return
user.visible_message("[user] unwrenches the anchoring bolts on [src].", "You unwrench the anchoring bolts.")
removal_stage = 4
return
if(4)
if(istype(O,/obj/item/weapon/crowbar))
user.visible_message("[user] begins lifting [src] off of the anchors.", "You begin lifting the device off the anchors...")
if(do_after(user,80))
if(!src || !user) return
user.visible_message("[user] crowbars [src] off of the anchors. It can now be moved.", "You jam the crowbar under the nuclear device and lift it off its anchors. You can now move it!")
anchored = 0
removal_stage = 5
return
..()
/obj/machinery/nuclearbomb/attack_paw(mob/user as mob)
@@ -69,7 +140,11 @@ var/bomb_set
user << browse(dat, "window=nuclearbomb;size=300x400")
onclose(user, "nuclearbomb")
else if (src.deployable)
src.anchored = 1
if(removal_stage < 5)
src.anchored = 1
visible_message("\red With a steely snap, bolts slide out of [src] and anchor it to the flooring!")
else
visible_message("\red \The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.")
flick("nuclearbombc", src)
src.icon_state = "nuclearbomb1"
src.extended = 1
@@ -81,8 +156,10 @@ var/bomb_set
set src in oview(1)
if (src.deployable)
usr << "\red You close several panels to make [src] undeployable."
src.deployable = 0
else
usr << "\red You adjust some panels to make [src] deployable."
src.deployable = 1
/obj/machinery/nuclearbomb/Topic(href, href_list)
@@ -148,7 +225,18 @@ var/bomb_set
src.timing = 0
bomb_set = 0
if (href_list["anchor"])
if(removal_stage == 5)
src.anchored = 0
visible_message("\red \The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.")
return
src.anchored = !( src.anchored )
if(src.anchored)
visible_message("\red With a steely snap, bolts slide out of [src] and anchor it to the flooring.")
else
visible_message("\red The anchoring bolts slide back into the depths of [src].")
src.add_fingerprint(usr)
for(var/mob/M in viewers(1, src))
if ((M.client && M.machine == src))
+169
View File
@@ -742,3 +742,172 @@ datum/objective/absorb
/*-------ENDOF CULTIST------*/
*/
//Vox heist objectives.
datum/objective/heist
proc/choose_target()
return
datum/objective/heist/kidnap
choose_target()
var/list/roles = list("Chief Engineer","Research Director","Roboticist","Chemist","Station Engineer")
var/list/possible_targets = list()
var/list/priority_targets = list()
for(var/datum/mind/possible_target in ticker.minds)
if(possible_target != owner && ishuman(possible_target.current) && (possible_target.current.stat != 2) && (possible_target.assigned_role != "MODE"))
possible_targets += possible_target
for(var/role in roles)
if(possible_target.assigned_role == role)
priority_targets += possible_target
continue
if(priority_targets.len > 0)
target = pick(priority_targets)
else if(possible_targets.len > 0)
target = pick(possible_targets)
if(target && target.current)
explanation_text = "The Shoal has a need for [target.current.real_name], the [target.assigned_role]. Take them alive."
else
explanation_text = "Free Objective"
return target
check_completion()
if(target && target.current)
if (target.current.stat == 2)
return 0 // They're dead. Fail.
//if (!target.current.restrained())
// return 0 // They're loose. Close but no cigar.
var/area/shuttle/vox/station/A = locate()
for(var/mob/living/carbon/human/M in A)
if(target.current == M)
return 1 //They're restrained on the shuttle. Success.
else
return 0
datum/objective/heist/loot
choose_target()
if(pick("hardware","weapons") == "hardware")
target = pick("a complete particle accelerator","a gravitational generator","four emitters","a nuclear bomb")
else
target = pick("six guns","four energy guns","two laser guns","an ion gun")
explanation_text = "We are lacking in hardware. Steal [target]."
switch(target)
if("a complete particle accelerator")
target = /obj/structure/particle_accelerator
target_amount = 6
if("a gravitational generator")
target = /obj/machinery/the_singularitygen
target_amount = 1
if("four emitters")
target = /obj/machinery/power/emitter
target_amount = 4
if("a nuclear bomb")
target = /obj/machinery/nuclearbomb
target_amount = 1
if("six guns")
target = /obj/item/weapon/gun
target_amount = 6
if("four energy guns")
target = /obj/item/weapon/gun/energy
target_amount = 4
if("two laser guns")
target = /obj/item/weapon/gun/energy/laser
target_amount = 2
if("an ion gun")
target = /obj/item/weapon/gun/energy/ionrifle
target_amount = 1
check_completion()
var/total_amount = 0
for(var/obj/O in locate(/area/shuttle/vox/station))
if(istype(O,target)) total_amount++
if(total_amount >= target_amount) return 1
var/datum/game_mode/heist/H = ticker.mode
for(var/datum/mind/raider in H.raiders)
if(raider.current)
for(var/obj/O in raider.current.get_contents())
if(istype(O,target)) total_amount++
if(total_amount >= target_amount) return 1
return 0
datum/objective/heist/salvage
choose_target()
var/list/possible_items = list("300 metal sheets","200 glass sheets","100 plasteel sheets","100 units of solid plasma","50 silver bars","20 gold bars","20 uranium bars","20 diamonds")
target = pick(possible_items)
explanation_text = "Ransack the station and escape with [target]."
switch(target)
if("300 metal sheets")
target = "metal"
target_amount = 300
if("200 glass sheets")
target = "glass"
target_amount = 200
if("100 plasteel sheets")
target = "plasteel"
target_amount = 100
if("100 units of solid plasma")
target = "plasma"
target_amount = 100
if("50 silver bars")
target = "silver"
target_amount = 50
if("20 gold bars")
target = "gold"
target_amount = 20
if("20 uranium bars")
target = "uranium"
target_amount = 20
if("20 diamonds")
target = "diamond"
target_amount = 20
check_completion()
var/total_amount = 0
for(var/obj/item/O in locate(/area/shuttle/vox/station))
if(istype(O,/obj/item/stack/sheet))
if(O.name == target)
var/obj/item/stack/sheet/S = O
total_amount += S.amount
var/datum/game_mode/heist/H = ticker.mode
for(var/datum/mind/raider in H.raiders)
if(raider.current)
for(var/obj/item/O in raider.current.get_contents())
if(istype(O,/obj/item/stack/sheet))
if(O.name == target)
var/obj/item/stack/sheet/S = O
total_amount += S.amount
if(total_amount >= target_amount) return 1
return 0
datum/objective/heist/inviolate_crew
explanation_text = "Do not leave any Vox behind, alive or dead."
check_completion()
var/datum/game_mode/heist/H = ticker.mode
if(H.is_raider_crew_safe()) return 1
return 0
datum/objective/heist/inviolate_death
explanation_text = "Follow the Inviolate. Minimise death and loss of resources."
check_completion()
if(vox_kills>5) return 0
return 1
+2 -4
View File
@@ -1479,8 +1479,7 @@ FIRE ALARM
A = A.loc
if (!( istype(A, /area) ))
return
for(var/area/RA in A.related)
RA.firereset()
A.firereset()
update_icon()
return
@@ -1491,8 +1490,7 @@ FIRE ALARM
A = A.loc
if (!( istype(A, /area) ))
return
for(var/area/RA in A.related)
RA.firealert()
A.firealert()
update_icon()
//playsound(src.loc, 'sound/ambience/signal.ogg', 75, 0)
return
@@ -87,6 +87,9 @@
usr << "No network found please hang up and try your call again."
return
var/temptag = "[get_area(src)] ([rand(1, 999)])"
input = strip_html(input(usr, "How would you like to name the camera?", "Set Camera Name", temptag))
state = 4
var/obj/machinery/camera/C = new(src.loc)
src.loc = C
@@ -94,9 +97,12 @@
C.auto_turn()
C.network = tempnetwork
C.network = uniquelist(tempnetwork)
tempnetwork = difflist(C.network,RESTRICTED_CAMERA_NETWORKS)
if(!tempnetwork.len)//Camera isn't on any open network - remove its chunk from AI visibility.
cameranet.removeCamera(C)
C.c_tag = "[get_area_name(src)] ([rand(1, 999)]"
C.c_tag = input
for(var/i = 5; i >= 0; i -= 1)
var/direct = input(user, "Direction?", "Assembling Camera", null) in list("LEAVE IT", "NORTH", "EAST", "SOUTH", "WEST" )
+43 -5
View File
@@ -37,6 +37,10 @@
/obj/item/weapon/circuitboard/security
name = "Circuit board (Security)"
build_path = "/obj/machinery/computer/security"
var/network = list("SS13")
req_access = list(access_security)
var/locked = 1
var/emagged = 0
/obj/item/weapon/circuitboard/aicore
name = "Circuit board (AI core)"
origin_tech = "programming=4;biotech=2"
@@ -169,10 +173,6 @@
name = "Circuit board (Operating Computer)"
build_path = "/obj/machinery/computer/operating"
origin_tech = "programming=2;biotech=2"
/obj/item/weapon/circuitboard/mining
name = "Circuit board (Outpost Status Display)"
build_path = "/obj/machinery/computer/security/mining"
origin_tech = "programming=2"
/obj/item/weapon/circuitboard/comm_monitor
name = "Circuit board (Telecommunications Monitor)"
build_path = "/obj/machinery/computer/telecomms/monitor"
@@ -241,6 +241,40 @@
user << "DERP! BUG! Report this (And what you were doing to cause it) to Agouri"
return
/obj/item/weapon/circuitboard/security/attackby(obj/item/I as obj, mob/user as mob)
if(istype(I,/obj/item/weapon/card/emag))
if(emagged)
user << "Circuit lock is already removed."
return
user << "\blue You override the circuit lock and open controls."
emagged = 1
locked = 0
else if(istype(I,/obj/item/weapon/card/id))
if(emagged)
user << "\red Circuit lock does not respond."
return
if(check_access(I))
locked = !locked
user << "\blue You [locked ? "" : "un"]lock the circuit controls."
else
user << "\red Access denied."
else if(istype(I,/obj/item/device/multitool))
if(locked)
user << "\red Circuit controls are locked."
return
var/existing_networks = dd_list2text(network,",")
var/input = strip_html(input(usr, "Which networks would you like to connect this camera console circuit to? Seperate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Multitool-Circuitboard interface", existing_networks))
if(!input)
usr << "No input found please hang up and try your call again."
return
var/list/tempnetwork = text2list(input, ",")
tempnetwork = difflist(tempnetwork,RESTRICTED_CAMERA_NETWORKS,1)
if(tempnetwork.len < 1)
usr << "No network found please hang up and try your call again."
return
network = tempnetwork
return
/obj/item/weapon/circuitboard/rdconsole/attackby(obj/item/I as obj, mob/user as mob)
if(istype(I,/obj/item/weapon/screwdriver))
if(src.build_path == "/obj/machinery/computer/rdconsole/core")
@@ -356,4 +390,8 @@
var/obj/machinery/computer/supplycomp/SC = B
var/obj/item/weapon/circuitboard/supplycomp/C = circuit
SC.can_order_contraband = C.contraband_enabled
del(src)
if(istype(circuit,/obj/item/weapon/circuitboard/security))
var/obj/machinery/computer/security/C = B
var/obj/item/weapon/circuitboard/security/CB = circuit
C.network = CB.network
del(src)
+38 -8
View File
@@ -5,7 +5,6 @@
name = "Security Cameras"
desc = "Used to access the various cameras on the station."
icon_state = "cameras"
circuit = "/obj/item/weapon/circuitboard/security"
var/obj/machinery/camera/current = null
var/last_pic = 1.0
var/list/network = list("SS13")
@@ -78,7 +77,38 @@
attack_hand(user)
return
attackby(I as obj, user as mob)
if(istype(I, /obj/item/weapon/screwdriver))
playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1)
if(do_after(user, 20))
if (stat & BROKEN)
user << "\blue The broken glass falls out."
var/obj/structure/computerframe/CF = new /obj/structure/computerframe(loc)
new /obj/item/weapon/shard(loc)
var/obj/item/weapon/circuitboard/security/CB = new /obj/item/weapon/circuitboard/security(CF)
CB.network = network
for (var/obj/C in src)
C.loc = loc
CF.circuit = CB
CF.state = 3
CF.icon_state = "3"
CF.anchored = 1
del(src)
else
user << "\blue You disconnect the monitor."
var/obj/structure/computerframe/CF = new /obj/structure/computerframe( loc )
var/obj/item/weapon/circuitboard/security/CB = new /obj/item/weapon/circuitboard/security(CF)
CB.network = network
for (var/obj/C in src)
C.loc = loc
CF.circuit = CB
CF.state = 4
CF.icon_state = "4"
CF.anchored = 1
del(src)
else
attack_hand(user)
return
/obj/machinery/computer/security/telescreen
name = "Telescreen"
@@ -87,7 +117,6 @@
icon_state = "telescreen"
network = list("thunder")
density = 0
circuit = null
/obj/machinery/computer/security/telescreen/update_icon()
icon_state = initial(icon_state)
@@ -100,10 +129,6 @@
desc = "Damn, they better have /tg/thechannel on these things."
icon = 'icons/obj/status_display.dmi'
icon_state = "entertainment"
network = list("thunder")
density = 0
circuit = null
/obj/machinery/computer/security/wooden_tv
name = "Security Cameras"
@@ -116,4 +141,9 @@
desc = "Used to access the various cameras on the outpost."
icon_state = "miningcameras"
network = list("MINE")
circuit = "/obj/item/weapon/circuitboard/mining"
/obj/machinery/computer/security/engineering
name = "Engineering Cameras"
desc = "Used to monitor fires and breaches."
icon_state = "engineeringcameras"
network = list("Power Alarms","Atmosphere Alarms","Fire Alarms")
+106
View File
@@ -0,0 +1,106 @@
#define VOX_SHUTTLE_MOVE_TIME 260
#define VOX_SHUTTLE_COOLDOWN 460
//Copied from Syndicate shuttle.
var/global/vox_shuttle_location
/obj/machinery/computer/vox_station
name = "vox skipjack terminal"
icon = 'icons/obj/computer.dmi'
icon_state = "syndishuttle"
req_access = list(access_syndicate)
var/area/curr_location
var/moving = 0
var/lastMove = 0
var/warning //Warning about the end of the round.
/obj/machinery/computer/vox_station/New()
curr_location= locate(/area/shuttle/vox/station)
/obj/machinery/computer/vox_station/proc/vox_move_to(area/destination as area)
if(moving) return
if(lastMove + VOX_SHUTTLE_COOLDOWN > world.time) return
var/area/dest_location = locate(destination)
if(curr_location == dest_location) return
moving = 1
lastMove = world.time
if(curr_location.z != dest_location.z)
var/area/transit_location = locate(/area/vox_station/transit)
curr_location.move_contents_to(transit_location)
curr_location = transit_location
sleep(VOX_SHUTTLE_MOVE_TIME)
curr_location.move_contents_to(dest_location)
curr_location = dest_location
moving = 0
return 1
/obj/machinery/computer/vox_station/attackby(obj/item/I as obj, mob/user as mob)
return attack_hand(user)
/obj/machinery/computer/vox_station/attack_ai(mob/user as mob)
return attack_hand(user)
/obj/machinery/computer/vox_station/attack_paw(mob/user as mob)
return attack_hand(user)
/obj/machinery/computer/vox_station/attack_hand(mob/user as mob)
if(!allowed(user))
user << "\red Access Denied"
return
user.set_machine(src)
var/dat = {"Location: [curr_location]<br>
Ready to move[max(lastMove + VOX_SHUTTLE_COOLDOWN - world.time, 0) ? " in [max(round((lastMove + VOX_SHUTTLE_COOLDOWN - world.time) * 0.1), 0)] seconds" : ": now"]<br>
<a href='?src=\ref[src];start=1'>Return to dark space</a><br>
<a href='?src=\ref[src];solars_fore_port=1'>Fore port solar</a> |
<a href='?src=\ref[src];solars_aft_port=1'>Aft port solar</a> |
<a href='?src=\ref[src];solars_fore_starboard=1'>Fore starboard solar</a><br>
<a href='?src=\ref[src];solars_aft_starboard=1'>Aft starboard solar</a> |
<a href='?src=\ref[src];mining=1'>Mining Asteroid</a><br>
<a href='?src=\ref[user];mach_close=computer'>Close</a>"}
user << browse(dat, "window=computer;size=575x450")
onclose(user, "computer")
return
/obj/machinery/computer/vox_station/Topic(href, href_list)
if(!isliving(usr)) return
var/mob/living/user = usr
if(in_range(src, user) || istype(user, /mob/living/silicon))
user.set_machine(src)
vox_shuttle_location = "station"
if(href_list["start"])
if(ticker && (istype(ticker.mode,/datum/game_mode/heist)))
if(!warning)
user << "\red Returning to dark space will end your raid and report your success or failure. If you are sure, press the button again."
warning = 1
return
vox_move_to(/area/shuttle/vox/station)
vox_shuttle_location = "start"
else if(href_list["solars_fore_starboard"])
vox_move_to(/area/vox_station/northeast_solars)
else if(href_list["solars_fore_port"])
vox_move_to(/area/vox_station/northwest_solars)
else if(href_list["solars_aft_starboard"])
vox_move_to(/area/vox_station/southeast_solars)
else if(href_list["solars_aft_port"])
vox_move_to(/area/vox_station/southwest_solars)
else if(href_list["mining"])
vox_move_to(/area/vox_station/mining)
add_fingerprint(usr)
updateUsrDialog()
return
/obj/machinery/computer/vox_station/bullet_act(var/obj/item/projectile/Proj)
visible_message("[Proj] ricochets off [src]!")
+2 -104
View File
@@ -915,115 +915,13 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob)
parent.update_tray()
/obj/item/seeds/replicapod/harvest(mob/user = usr) //now that one is fun -- Urist
var/obj/machinery/hydroponics/parent = loc
var/make_podman = 0
var/mob/ghost
if(ckey && config.revival_pod_plants)
ghost = find_dead_player("[ckey]")
if(ismob(ghost))
if(istype(ghost,/mob/dead/observer))
var/mob/dead/observer/O = ghost
if(istype(mind,/datum/mind))
if(O.can_reenter_corpse)
make_podman = 1
else
make_podman = 1
if(make_podman) //all conditions met!
var/mob/living/carbon/human/podman = new /mob/living/carbon/human(parent.loc)
if(realName)
podman.real_name = realName
else
podman.real_name = "Pod Person [rand(0,999)]"
var/oldactive = mind.active
mind.active = 1
mind.transfer_to(podman)
mind.active = oldactive
// -- Mode/mind specific stuff goes here. TODO! Broken :( Should be merged into mob/living/Login
switch(ticker.mode.name)
if ("revolution")
if (podman.mind in ticker.mode:revolutionaries)
ticker.mode:add_revolutionary(podman.mind)
ticker.mode:update_all_rev_icons() //So the icon actually appears
if (podman.mind in ticker.mode:head_revolutionaries)
ticker.mode:update_all_rev_icons()
if ("nuclear emergency")
if (podman.mind in ticker.mode:syndicates)
ticker.mode:update_all_synd_icons()
if ("cult")
if (podman.mind in ticker.mode:cult)
ticker.mode:add_cultist(podman.mind)
ticker.mode:update_all_cult_icons() //So the icon actually appears
// -- End mode specific stuff
podman.gender = ghost.gender
if(podman.gender in list(NEUTER, PLURAL)) //Sanity check, which should never actually happen.
podman.gender = pick(MALE,FEMALE)
if(!podman.dna)
podman.dna = new /datum/dna()
podman.dna.real_name = podman.real_name
if(ui)
podman.dna.uni_identity = ui
updateappearance(podman, ui)
if(se)
podman.dna.struc_enzymes = se
if(!prob(potency)) //if it fails, plantman!
if(podman)
// podman.dna.mutantrace = "plant"
podman.mutations.Add(PLANT)
podman.update_mutantrace()
else //else, one packet of seeds. maybe two
var/seed_count = 1
if(prob(yield * parent.yieldmod * 20))
seed_count++
for(var/i=0,i<seed_count,i++)
var/obj/item/seeds/replicapod/harvestseeds = new /obj/item/seeds/replicapod(user.loc)
harvestseeds.lifespan = lifespan
harvestseeds.endurance = endurance
harvestseeds.maturation = maturation
harvestseeds.production = production
harvestseeds.yield = yield
harvestseeds.potency = potency
parent.update_tray()
/obj/item/seeds/replicapod/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W,/obj/item/weapon/reagent_containers))
user << "You inject the contents of the syringe into the seeds."
for(var/datum/reagent/blood/bloodSample in W:reagents.reagent_list)
var/mob/living/carbon/human/source = bloodSample.data["donor"] //hacky, since it gets the CURRENT condition of the mob, not how it was when the blood sample was taken
if (!istype(source))
continue
//ui = bloodSample.data["blood_dna"] doesn't work for whatever reason
ui = source.dna.uni_identity
se = source.dna.struc_enzymes
if(source.ckey)
ckey = source.ckey
else if(source.mind)
ckey = ckey(source.mind.key)
realName = source.real_name
gender = source.gender
if (!isnull(source.mind))
mind = source.mind
W:reagents.clear_reagents()
else
return ..()
/obj/machinery/hydroponics/proc/update_tray(mob/user = usr)
harvest = 0
lastproduce = age
if((yieldmod * myseed.yield) <= 0)
if((yieldmod * myseed.yield) <= 0 || istype(myseed,/obj/item/seeds/replicapod))
user << text("\red You fail to harvest anything useful.")
else
user << text("You harvest from the [myseed.plantname]")
user << text("You harvest from the [myseed.plantname].")
if(myseed.oneharvest)
del(myseed)
planted = 0
+153
View File
@@ -0,0 +1,153 @@
/* Moved all the plant people code here for ease of reference and coherency.
Injecting a pod person with a blood sample will grow a pod person with the memories and persona of that mob.
Growing it to term with nothing injected will grab a ghost from the observers. */
/obj/item/seeds/replicapod
name = "pack of dionaea-replicant seeds"
desc = "These seeds grow into 'replica pods' or 'dionaea', a form of strange sapient plantlife."
icon_state = "seed-replicapod"
mypath = "/obj/item/seeds/replicapod"
species = "replicapod"
plantname = "Dionaea"
productname = "/mob/living/carbon/human" //verrry special -- Urist
lifespan = 50 //no idea what those do
endurance = 8
maturation = 10
production = 10
yield = 1 //seeds if there isn't a dna inside
oneharvest = 1
potency = 30
plant_type = 0
growthstages = 6
var/ckey = null
var/realName = null
var/mob/living/carbon/human/source //Donor of blood, if any.
gender = MALE
/obj/item/seeds/replicapod/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W,/obj/item/weapon/reagent_containers))
user << "You inject the contents of the syringe into the seeds."
var/datum/reagent/blood/B
//Find a blood sample to inject.
for(var/datum/reagent/R in W:reagents.reagent_list)
if(istype(R,/datum/reagent/blood))
B = R
break
if(B)
source = B.data["donor"]
user << "The strange, sluglike seeds quiver gently and swell with blood."
if(!source.client && source.mind)
for(var/mob/dead/observer/O in player_list)
if(O.mind == source.mind && config.revival_pod_plants)
O << "<b><font color = #330033><font size = 3>Your blood has been placed into a replica pod seed. Return to your body if you want to be returned to life as a pod person!</b> (Verbs -> Ghost -> Re-enter corpse)</font color>"
break
else
user << "Nothing happens."
return
if (!istype(source))
return
if(source.ckey)
realName = source.real_name
ckey = source.ckey
W:reagents.clear_reagents()
return
return ..()
/obj/item/seeds/replicapod/harvest(mob/user = usr)
var/obj/machinery/hydroponics/parent = loc
var/mob/ghost
var/list/candidates = list()
user.visible_message("\blue You carefully begin to open the pod...","[user] carefully begins to open the pod...")
//If a sample is injected (and revival is allowed) the plant will be controlled by the original donor.
if(source && source.mind && source.ckey && config.revival_pod_plants)
ghost = source
else // If no sample was injected or revival is not allowed, we grab an interested observer.
for(var/mob/dead/observer/O in player_list)
if(O.client)
var/response = alert(O, "Someone is harvesting a replica pod. Would you like to play as a Dionaea?", "Replica pod harvest", "Yes", "No")
if(response == "Yes")
candidates += O
if(!do_after(user, 100))
return
if(!src || !user)
return
if(candidates.len)
ghost = pick(candidates)
//If we don't have a ghost or the ghost is now unplayed, we just give the harvester some seeds.
if(!ghost || !(ghost.ckey))
user << "The pod has formed badly, and all you can do is salvage some of the seeds."
var/seed_count = 1
if(prob(yield * parent.yieldmod * 20))
seed_count++
for(var/i=0,i<seed_count,i++)
new /obj/item/seeds/replicapod(user.loc)
parent.update_tray()
return
var/mob/living/carbon/human/podman = new /mob/living/carbon/human(parent.loc)
podman.ckey = ghost.ckey
if(ghost.mind)
ghost.mind.transfer_to(podman)
if(realName)
podman.real_name = realName
else
podman.real_name = "Diona [rand(0,999)]"
podman.gender = NEUTER
podman.dna = new /datum/dna()
podman.dna.real_name = podman.real_name
podman.dna.mutantrace = "plant"
podman.update_mutantrace()
// Update mode specific HUD icons.
switch(ticker.mode.name)
if ("revolution")
if (podman.mind in ticker.mode:revolutionaries)
ticker.mode:add_revolutionary(podman.mind)
ticker.mode:update_all_rev_icons() //So the icon actually appears
if (podman.mind in ticker.mode:head_revolutionaries)
ticker.mode:update_all_rev_icons()
if ("nuclear emergency")
if (podman.mind in ticker.mode:syndicates)
ticker.mode:update_all_synd_icons()
if ("cult")
if (podman.mind in ticker.mode:cult)
ticker.mode:add_cultist(podman.mind)
ticker.mode:update_all_cult_icons() //So the icon actually appears
// -- End mode specific stuff
visible_message("\blue The pod disgorges a fully-formed plant person!")
spawn(0)
podman << "\green <B>You awaken slowly, feeling your sap stir into sluggish motion as the warm air caresses your bark.</B>"
if(source && ckey && podman.ckey == ckey)
podman << "<B>Memories of a life as [source] drift oddly through a mind unsuited for them, like a skin of oil over a fathomless lake.</B>"
podman << "<B>You are now one of the Dionaea, a race of drifting interstellar plantlike creatures that sometimes share their seeds with human traders.</B>"
podman << "<B>Too much darkness will send you into shock and starve you, but light will help you heal.</B>"
if(!realName)
var/newname = input(podman,"Enter a name, or leave blank for the default name.", "Name change","") as text
if (newname != "")
podman.real_name = newname
parent.update_tray()
+28 -11
View File
@@ -341,12 +341,10 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
freq_text = "Engineering"
if(1359)
freq_text = "Security"
// if(1349)
// freq_text = "Mining"
if(1347)
freq_text = "Supply"
if(1441)
freq_text = "Death Squad"
freq_text = "Special Ops"
if(1443)
freq_text = "Response Team"
//There's probably a way to use the list var of channels in code\game\communications.dm to make the dept channels non-hardcoded, but I wasn't in an experimentive mood. --NEO
@@ -365,10 +363,35 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
var/part_b = "</span><b> \icon[radio]\[[freq_text]\][part_b_extra]</b> <span class='message'>" // Tweaked for security headsets -- TLE
var/part_c = "</span></span>"
if (display_freq==SYND_FREQ)
// syndies!
if (display_freq == SYND_FREQ)
part_a = "<span class='syndradio'><span class='name'>"
else if (display_freq==COMM_FREQ)
// centcomm channels (deathsquid and ert)
else if (display_freq in CENT_FREQS)
part_a = "<span class='centradio'><span class='name'>"
// command channel
else if (display_freq == COMM_FREQ)
part_a = "<span class='comradio'><span class='name'>"
// department radio formatting (poorly optimized, ugh)
else if (display_freq == SEC_FREQ)
part_a = "<span class='secradio'><span class='name'>"
else if (display_freq == ENG_FREQ)
part_a = "<span class='engradio'><span class='name'>"
else if (display_freq == SCI_FREQ)
part_a = "<span class='sciradio'><span class='name'>"
else if (display_freq == MED_FREQ)
part_a = "<span class='medradio'><span class='name'>"
else if (display_freq == SUP_FREQ) // cargo
part_a = "<span class='supradio'><span class='name'>"
// If all else fails and it's a dept_freq, color me purple!
else if (display_freq in DEPT_FREQS)
part_a = "<span class='deptradio'><span class='name'>"
@@ -406,8 +429,6 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
blackbox.msg_deathsquad += blackbox_msg
if(1213)
blackbox.msg_syndicate += blackbox_msg
// if(1349)
// blackbox.msg_mining += blackbox_msg
if(1347)
blackbox.msg_cargo += blackbox_msg
else
@@ -629,8 +650,6 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
freq_text = "Engineering"
if(1359)
freq_text = "Security"
// if(1349)
// freq_text = "Mining"
if(1347)
freq_text = "Supply"
//There's probably a way to use the list var of channels in code\game\communications.dm to make the dept channels non-hardcoded, but I wasn't in an experimentive mood. --NEO
@@ -685,8 +704,6 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
blackbox.msg_deathsquad += blackbox_msg
if(1213)
blackbox.msg_syndicate += blackbox_msg
// if(1349)
// blackbox.msg_mining += blackbox_msg
if(1347)
blackbox.msg_cargo += blackbox_msg
else
+1 -6
View File
@@ -142,12 +142,7 @@
id = "Supply Server"
freq_listening = list(1347)
autolinkers = list("supply")
/*
/obj/machinery/telecomms/server/presets/mining
id = "Mining Server"
freq_listening = list(1349)
autolinkers = list("mining")
*/
/obj/machinery/telecomms/server/presets/common
id = "Common Server"
freq_listening = list()
+2 -1
View File
@@ -49,7 +49,8 @@
/obj/item/robot_parts/robot_component/radio,
/obj/item/robot_parts/robot_component/actuator,
/obj/item/robot_parts/robot_component/diagnosis_unit,
/obj/item/robot_parts/robot_component/camera
/obj/item/robot_parts/robot_component/camera,
/obj/item/robot_parts/robot_component/armour
),
"Ripley"=list(
/obj/item/mecha_parts/chassis/ripley,
@@ -0,0 +1,22 @@
/obj/item/device/pipe_painter
name = "pipe painter"
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "labeler1"
item_state = "flight"
var/list/modes = list("grey","red","blue","cyan","green","yellow","purple")
var/mode = "grey"
/obj/item/device/pipe_painter/afterattack(atom/A, mob/user as mob)
if(!istype(A,/obj/machinery/atmospherics/pipe) || istype(A,/obj/machinery/atmospherics/pipe/tank) || istype(A,/obj/machinery/atmospherics/pipe/vent) || istype(A,/obj/machinery/atmospherics/pipe/simple/heat_exchanging) || istype(A,/obj/machinery/atmospherics/pipe/simple/insulated))
return
var/obj/machinery/atmospherics/pipe/P = A
P.color = mode
user.visible_message("<span class='notice'>[user] paints \the [P] [mode].</span>","<span class='notice'>You paint \the [P] [mode].</span>")
P.update_icon()
/obj/item/device/pipe_painter/attack_self(mob/user as mob)
mode = input("Which colour do you want to use?","Pipe painter") in modes
/obj/item/device/pipe_painter/examine()
..()
usr << "It is in [mode] mode."
@@ -121,7 +121,8 @@
desc = "An encyption key for a radio headset. Contains cypherkeys."
icon_state = "cargo_cypherkey"
channels = list("Supply" = 1)
/obj/item/device/encryptionkey/ert
name = "NanoTrasen ERT Radio Encryption Key"
desc = "An encyption key for a radio headset. Contains cypherkeys."
channels = list("Response Team" = 1, "Science" = 1, "Command" = 1, "Medical" = 1, "Engineering" = 1, "Security" = 1, "Mining" = 1, "Cargo" = 1,)
channels = list("Response Team" = 1, "Science" = 1, "Command" = 1, "Medical" = 1, "Engineering" = 1, "Security" = 1, "Supply" = 1)
@@ -499,8 +499,6 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
freq_text = "Engineering"
if(1359)
freq_text = "Security"
// if(1349)
// freq_text = "Mining"
if(1347)
freq_text = "Supply"
//There's probably a way to use the list var of channels in code\game\communications.dm to make the dept channels non-hardcoded, but I wasn't in an experimentive mood. --NEO
@@ -32,6 +32,7 @@
R.icon_state = "robot"
del(R.module)
R.module = null
R.camera.network.Remove(list("Medical","MINE"))
R.updatename("Default")
R.status_flags |= CANPUSH
R.updateicon()
@@ -461,3 +461,7 @@ the implant may become unstable and either pre-maturely inject the subject or si
islegal()
return 0
/obj/item/weapon/implant/cortical
name = "cortical stack"
desc = "A fist-sized mass of biocircuits and chips."
@@ -29,7 +29,7 @@
..()
if(air_contents.oxygen < 10)
usr << text("\red <B>The meter on the [src.name] indicates you are almost out of air!</B>")
playsound(usr, 'sound/effects/alert.ogg', 50, 1)
//playsound(usr, 'sound/effects/alert.ogg', 50, 1)
/obj/item/weapon/tank/oxygen/yellow
@@ -186,4 +186,4 @@
..()
if(air_contents.nitrogen < 10)
usr << text("\red <B>The meter on the [src.name] indicates you are almost out of air!</B>")
playsound(usr, 'sound/effects/alert.ogg', 50, 1)
//playsound(usr, 'sound/effects/alert.ogg', 50, 1)
+39 -10
View File
@@ -1,9 +1,43 @@
//STRIKE TEAMS
//Thanks to Kilakk for the admin-button portion of this code.
var/list/response_team_members = list()
var/global/send_emergency_team = 0 // Used for automagic response teams
// 'admin_emergency_team' for admin-spawned response teams
/client/proc/response_team()
set name = "Dispatch Emergency Response Team"
set category = "Special Verbs"
set desc = "Send an emergency response team to the station"
if(!holder)
usr << "\red Only administrators may use this command."
return
if(!ticker)
usr << "\red The game hasn't started yet!"
return
if(ticker.current_state == 1)
usr << "\red The round hasn't started yet!"
return
if(send_emergency_team)
usr << "\red Central Command has already dispatched an emergency response team!"
return
if(alert("Do you want to dispatch an Emergency Response Team?",,"Yes","No") != "Yes")
return
if(get_security_level() != "red") // Allow admins to reconsider if the alert level isn't Red
switch(alert("The station has not entered code red recently. Do you still want to dispatch a response team?",,"Yes","No"))
if("No")
return
if(send_emergency_team)
usr << "\red Looks like somebody beat you to it!"
return
message_admins("[key_name_admin(usr)] is dispatching an Emergency Response Team.", 1)
log_admin("[key_name(usr)] used Dispatch Response Team.")
trigger_armed_response_team(1)
client/verb/JoinResponseTeam()
set category = "IC"
@@ -11,9 +45,9 @@ client/verb/JoinResponseTeam()
if(!send_emergency_team)
usr << "No emergency response team is currently being sent."
return
if(admin_emergency_team)
/* if(admin_emergency_team)
usr << "An emergency response team has already been sent."
return
return */
if(jobban_isbanned(usr, "Syndicate") || jobban_isbanned(usr, "Emergency Response Team") || jobban_isbanned(usr, "Security Officer"))
usr << "<font color=red><b>You are jobbanned from the emergency reponse team!"
return
@@ -69,10 +103,10 @@ proc/percentage_antagonists()
proc/trigger_armed_response_team(var/force = 0)
if(send_emergency_team || admin_emergency_team)
if(send_emergency_team)
return
var/send_team_chance = 20 // base chance that a team will be sent
var/send_team_chance = 50 // base chance that a team will be sent
send_team_chance += 2*percentage_dead() // the more people are dead, the higher the chance
send_team_chance += percentage_antagonists() // the more antagonists, the higher the chance
send_team_chance = min(send_team_chance, 100)
@@ -82,7 +116,7 @@ proc/trigger_armed_response_team(var/force = 0)
// there's only a certain chance a team will be sent
if(!prob(send_team_chance)) return
command_alert("Sensors indicate that [station_name()] has entered Code Red and is in need of assistance. We will prepare and dispatch an emergency response team to deal with the situation.", "NMV Icarus Command")
command_alert("Sensors indicate that [station_name()] has entered Code Red and is in need of assistance. We will prepare and dispatch an emergency response team to deal with the situation.", "Central Command")
send_emergency_team = 1
@@ -224,11 +258,6 @@ proc/trigger_armed_response_team(var/force = 0)
//Special radio setup
equip_to_slot_or_del(new /obj/item/device/radio/headset/ert(src), slot_ears)
//Adding Camera Network
var/obj/machinery/camera/camera = new /obj/machinery/camera(src) //Gives all the commandos internals cameras.
camera.network = "CREED"
camera.c_tag = real_name
//Replaced with new ERT uniform
equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(src), slot_w_uniform)
equip_to_slot_or_del(new /obj/item/clothing/shoes/swat(src), slot_shoes)
+3 -3
View File
@@ -6,8 +6,8 @@ var/list/admin_verbs_default = list(
/client/proc/hide_verbs, /*hides all our adminverbs*/
/client/proc/hide_most_verbs, /*hides all our hideable adminverbs*/
/client/proc/debug_variables, /*allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify*/
/client/proc/check_antagonists, /*shows all antags*/
/client/proc/deadchat /*toggles deadchat on/off*/
/client/proc/check_antagonists /*shows all antags*/
// /client/proc/deadchat /*toggles deadchat on/off*/
)
var/list/admin_verbs_admin = list(
/client/proc/player_panel, /*shows an interface for all players, with links to various panels (old style)*/
@@ -156,7 +156,7 @@ var/list/admin_verbs_rejuv = list(
var/list/admin_verbs_hideable = list(
/client/proc/set_ooc,
/client/proc/deadmin_self,
/client/proc/deadchat,
// /client/proc/deadchat,
/client/proc/toggleprayers,
/client/proc/toggle_hear_radio,
/datum/admins/proc/show_traitor_panel,
+9 -1
View File
@@ -11,6 +11,10 @@
src << "\red You cannot send DSAY messages (muted)."
return
if(!(prefs.toggles & CHAT_DEAD))
src << "\red You have deadchat muted."
return
if (src.handle_spam_prevention(msg,MUTE_DEADCHAT))
return
@@ -25,7 +29,11 @@
for (var/mob/M in player_list)
if (istype(M, /mob/new_player))
continue
if (M.stat == DEAD || (M.client && M.client.holder && (M.client.prefs.toggles & CHAT_DEAD))) //admins can toggle deadchat on and off. This is a proc in admin.dm and is only give to Administrators and above
if(M.client && M.client.holder && (M.client.prefs.toggles & CHAT_DEAD)) // show the message to admins who have deadchat toggled on
M.show_message(rendered, 2)
else if(M.stat == DEAD && (M.client.prefs.toggles & CHAT_DEAD)) // show the message to regular ghosts who have deadchat toggled on
M.show_message(rendered, 2)
feedback_add_details("admin_verb","D") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+2 -2
View File
@@ -462,11 +462,11 @@ client/proc/one_click_antag()
candidates.Remove(G)
if(candidates.len)
var/max_raiders = 4
var/max_raiders = 1
var/raiders = max_raiders
//Spawns vox raiders and equips them.
for (var/obj/effect/landmark/L in world)
if(L.name == "Response Team")
if(L.name == "voxstart")
if(raiders<=0)
break
+22 -10
View File
@@ -18,7 +18,14 @@ var/global/vox_tick = 1
equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(src), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE.
equip_to_slot_or_del(new /obj/item/device/chameleon(src), slot_l_store)
equip_to_slot_or_del(new /obj/item/weapon/gun/dartgun/vox/raider, slot_r_hand)
var/obj/item/weapon/crossbow/W = new(src)
W.cell = new /obj/item/weapon/cell/crap(W)
W.cell.charge = 500
equip_to_slot_or_del(W, slot_r_hand)
var/obj/item/stack/rods/A = new(src)
A.amount = 20
equip_to_slot_or_del(A, slot_l_hand)
if(2) // Vox engineer!
equip_to_slot_or_del(new /obj/item/clothing/suit/space/vox/pressure(src), slot_wear_suit)
@@ -26,6 +33,7 @@ var/global/vox_tick = 1
equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full(src), slot_belt)
equip_to_slot_or_del(new /obj/item/clothing/glasses/meson(src), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE.
equip_to_slot_or_del(new /obj/item/weapon/storage/box/emps(src), slot_l_store)
equip_to_slot_or_del(new /obj/item/device/multitool(src), slot_l_hand)
var/obj/item/weapon/storage/pneumatic/W = new(src)
W.tank = new /obj/item/weapon/tank/nitrogen(W)
@@ -37,15 +45,8 @@ var/global/vox_tick = 1
equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full(src), slot_belt)
equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(src), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE.
equip_to_slot_or_del(new /obj/item/weapon/card/emag(src), slot_l_store)
var/obj/item/weapon/crossbow/W = new(src)
W.cell = new /obj/item/weapon/cell/crap(W)
W.cell.charge = 500
equip_to_slot_or_del(W, slot_r_hand)
var/obj/item/stack/rods/A = new(src)
A.amount = 20
equip_to_slot_or_del(A, slot_l_hand)
equip_to_slot_or_del(new /obj/item/weapon/gun/dartgun/vox/raider(src), slot_r_hand)
equip_to_slot_or_del(new /obj/item/device/multitool(src), slot_l_hand)
if(4) // Vox medic!
equip_to_slot_or_del(new /obj/item/clothing/suit/space/vox/pressure(src), slot_wear_suit)
@@ -67,6 +68,17 @@ var/global/vox_tick = 1
W.registered_name = real_name
equip_to_slot_or_del(W, slot_wear_id)
var/obj/item/weapon/implant/cortical/I = new(src)
I.imp_in = src
I.implanted = 1
var/datum/organ/external/affected = src.get_organ("head")
affected.implants += I
I.part = affected
if(ticker.mode && ( istype( ticker.mode,/datum/game_mode/heist ) ) )
var/datum/game_mode/heist/M = ticker.mode
M.cortical_stacks += I
vox_tick++
if (vox_tick > 4) vox_tick = 1
+2 -1
View File
@@ -15,6 +15,7 @@ var/global/list/special_roles = list( //keep synced with the defines BE_* in set
"cultist" = IS_MODE_COMPILED("cult"), // 8
"infested monkey" = IS_MODE_COMPILED("monkey"), // 9
"ninja" = "true", // 10
"vox raider" = IS_MODE_COMPILED("heist"), // 11
)
var/const/MAX_SAVE_SLOTS = 10
@@ -1135,7 +1136,7 @@ datum/preferences
proc/copy_to(mob/living/carbon/human/character, safety = 0)
if(be_random_name)
real_name = random_name()
real_name = random_name(gender)
if(config.humans_need_surnames)
var/firstspace = findtext(real_name, " ")
+1 -1
View File
@@ -156,7 +156,7 @@
if(isnull(species)) species = "Human"
if(isnull(language)) language = "None"
if(isnull(nanotrasen_relation)) nanotrasen_relation = initial(nanotrasen_relation)
if(!real_name) real_name = random_name()
if(!real_name) real_name = random_name(gender)
be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name))
gender = sanitize_gender(gender)
age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age))
+7 -2
View File
@@ -37,13 +37,18 @@
usr << "You will [(prefs.toggles & SOUND_ADMINHELP) ? "now" : "no longer"] hear a sound when adminhelps arrive."
feedback_add_details("admin_verb","AHS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/deadchat()
/client/verb/deadchat() // Deadchat toggle is usable by anyone.
set name = "Show/Hide Deadchat"
set category = "Preferences"
set desc ="Toggles seeing deadchat"
prefs.toggles ^= CHAT_DEAD
prefs.save_preferences()
src << "You will [(prefs.toggles & CHAT_DEAD) ? "now" : "no longer"] see deadchat."
if(src.holder)
src << "You will [(prefs.toggles & CHAT_DEAD) ? "now" : "no longer"] see deadchat."
else
src << "As a ghost, you will [(prefs.toggles & CHAT_DEAD) ? "now" : "no longer"] see deadchat."
feedback_add_details("admin_verb","TDV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/toggleprayers()
+3 -2
View File
@@ -130,8 +130,9 @@
icon_state = "boots-vox"
toggle()
name = "Toggle Floor Grip"
//set name = "Toggle Floor Grip"
if(usr.stat)
return
if(src.magpulse)
src.flags &= ~NOSLIP
src.magpulse = 0
+36 -16
View File
@@ -1,14 +1,30 @@
/obj/item/clothing/head/helmet/space/ert
/obj/item/clothing/head/helmet/space/rig/ert
name = "emergency response team helmet"
desc = "A helmet worn by members of the NanoTrasen Emergency Response Team. Armoured and space ready."
icon_state = "ert_commander"
icon_state = "rig0-ert_commander"
item_state = "helm-command"
armor = list(melee = 50, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 60)
siemens_coefficient = 0.6
var/obj/machinery/camera/camera
/obj/item/clothing/suit/space/ert
/obj/item/clothing/head/helmet/space/rig/ert/attack_self(mob/user)
if(camera)
..(user)
else
camera = new /obj/machinery/camera(src)
camera.network = list("ERT")
cameranet.removeCamera(camera)
camera.c_tag = user.name
user << "\blue User scanned as [camera.c_tag]. Camera activated."
/obj/item/clothing/head/helmet/space/rig/ert/examine()
..()
if(get_dist(usr,src) <= 1)
usr << "This helmet has a built-in camera. It's [camera ? "" : "in"]active."
/obj/item/clothing/suit/space/rig/ert
name = "emergency response team suit"
desc = "A suit worn by members of the NanoTrasen Emergency Response Team. Armoured, space ready, and fire resistant."
desc = "A suit worn by members of the NanoTrasen Emaergency Response Team. Armoured, space ready, and fire resistant."
icon_state = "ert_commander"
item_state = "suit-command"
w_class = 3
@@ -22,49 +38,53 @@
siemens_coefficient = 0.6
//Commander
/obj/item/clothing/head/helmet/space/ert/commander
/obj/item/clothing/head/helmet/space/rig/ert/commander
name = "emergency response team commander helmet"
desc = "A helmet worn by the commander of a NanoTrasen Emergency Response Team. Has blue highlights. Armoured and space ready."
icon_state = "ert_commander"
icon_state = "rig0-ert_commander"
item_state = "helm-command"
color = "ert_commander"
/obj/item/clothing/suit/space/ert/commander
/obj/item/clothing/suit/space/rig/ert/commander
name = "emergency response team commander suit"
desc = "A suit worn by the commander of a NanoTrasen Emergency Response Team. Has blue highlights. Armoured, space ready, and fire resistant."
icon_state = "ert_commander"
item_state = "suit-command"
//Security
/obj/item/clothing/head/helmet/space/ert/security
/obj/item/clothing/head/helmet/space/rig/ert/security
name = "emergency response team security helmet"
desc = "A helmet worn by security members of a NanoTrasen Emergency Response Team. Has red highlights. Armoured and space ready."
icon_state = "ert_security"
icon_state = "rig0-ert_security"
item_state = "syndicate-helm-black-red"
color = "ert_security"
/obj/item/clothing/suit/space/ert/security
/obj/item/clothing/suit/space/rig/ert/security
name = "emergency response team security suit"
desc = "A suit worn by security members of a NanoTrasen Emergency Response Team. Has red highlights. Armoured, space ready, and fire resistant."
icon_state = "ert_security"
item_state = "syndicate-black-red"
//Engineer
/obj/item/clothing/head/helmet/space/ert/engineer
/obj/item/clothing/head/helmet/space/rig/ert/engineer
name = "emergency response team engineer helmet"
desc = "A helmet worn by engineering members of a NanoTrasen Emergency Response Team. Has blue highlights. Armoured and space ready."
icon_state = "ert_engineer"
icon_state = "rig0-ert_engineer"
color = "ert_engineer"
/obj/item/clothing/suit/space/ert/engineer
/obj/item/clothing/suit/space/rig/ert/engineer
name = "emergency response team engineer suit"
desc = "A suit worn by the engineering of a NanoTrasen Emergency Response Team. Has blue highlights. Armoured, space ready, and fire resistant."
icon_state = "ert_engineer"
//Medical
/obj/item/clothing/head/helmet/space/ert/medical
/obj/item/clothing/head/helmet/space/rig/ert/medical
name = "emergency response team medical helmet"
desc = "A helmet worn by medical members of a NanoTrasen Emergency Response Team. Has white highlights. Armoured and space ready."
icon_state = "ert_medical"
icon_state = "rig0-ert_medical"
color = "ert_medical"
/obj/item/clothing/suit/space/ert/medical
/obj/item/clothing/suit/space/rig/ert/medical
name = "emergency response team medical suit"
desc = "A suit worn by medical members of a NanoTrasen Emergency Response Team. Has white highlights. Armoured and space ready."
icon_state = "ert_medical"
+15
View File
@@ -87,7 +87,22 @@
color = "syndi"
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 35, bio = 100, rad = 60)
siemens_coefficient = 0.6
var/obj/machinery/camera/camera
/obj/item/clothing/head/helmet/space/rig/syndi/attack_self(mob/user)
if(camera)
..(user)
else
camera = new /obj/machinery/camera(src)
camera.network = list("NUKE")
cameranet.removeCamera(camera)
camera.c_tag = user.name
user << "\blue User scanned as [camera.c_tag]. Camera activated."
/obj/item/clothing/head/helmet/space/rig/syndi/examine()
..()
if(get_dist(usr,src) <= 1)
usr << "This helmet has a built-in camera. It's [camera ? "" : "in"]active."
/obj/item/clothing/suit/space/rig/syndi
icon_state = "rig-syndi"
+2 -3
View File
@@ -103,9 +103,8 @@
icon_state = "hazard"
item_state = "hazard"
blood_overlay_type = "armor"
allowed = list (/obj/item/device/analyzer, /obj/item/device/flashlight, /obj/item/device/multitool, /obj/item/device/radio, /obj/item/device/t_scanner, \
/obj/item/weapon/crowbar, /obj/item/weapon/screwdriver, /obj/item/weapon/weldingtool, /obj/item/weapon/wirecutters, /obj/item/weapon/wrench, \
/obj/item/weapon/tank/emergency_oxygen)
allowed = list (/obj/item/device/analyzer, /obj/item/device/flashlight, /obj/item/device/multitool, /obj/item/device/pipe_painter, /obj/item/device/radio, /obj/item/device/t_scanner, \
/obj/item/weapon/crowbar, /obj/item/weapon/screwdriver, /obj/item/weapon/weldingtool, /obj/item/weapon/wirecutters, /obj/item/weapon/wrench, /obj/item/weapon/tank/emergency_oxygen)
//Lawyer
/obj/item/clothing/suit/storage/lawyer/bluejacket
+1 -1
View File
@@ -222,7 +222,7 @@
slots = 5
/obj/item/clothing/tie/storage/brown_vest
name = "black webbing vest"
name = "brown webbing vest"
desc = "Worn brownish synthcotton vest with lots of pockets to unload your hands."
icon_state = "vest_brown"
color = "vest_brown"
+3 -1
View File
@@ -77,7 +77,9 @@ mob/living/carbon/proc/handle_hallucinations()
halitem.name = "Flashbang"
if(client) client.screen += halitem
spawn(rand(100,250))
del halitem
if(client)
client.screen -= halitem
halitem = null
if(26 to 40)
//Flashes of danger
//src << "Danger Flash"
+23
View File
@@ -18,6 +18,29 @@
return
. = src.say_dead(message)
/mob/dead/observer/emote(var/act, var/type, var/message)
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
if(!message)
return
if(act != "me")
return
log_emote("Ghost/[src.key] : [message]")
if(src.client)
if(src.client.prefs.muted & MUTE_DEADCHAT)
src << "\red You cannot emote in deadchat (muted)."
return
if(src.client.handle_spam_prevention(message, MUTE_DEADCHAT))
return
. = src.emote_dead(message)
/*
for (var/mob/M in hearers(null, null))
if (!M.stat)
+37 -2
View File
@@ -1,5 +1,5 @@
// All mobs should have custom emote, really..
mob/proc/custom_emote(var/m_type=1,var/message = null)
/mob/proc/custom_emote(var/m_type=1,var/message = null)
if(!use_me && usr == src)
usr << "You are unable to emote."
@@ -25,7 +25,7 @@ mob/proc/custom_emote(var/m_type=1,var/message = null)
//Hearing gasp and such every five seconds is not good emotes were not global for a reason.
// Maybe some people are okay with that.
for(var/mob/M in world)
for(var/mob/M in player_list)
if (!M.client)
continue //skip monkeys and leavers
if (istype(M, /mob/new_player))
@@ -42,3 +42,38 @@ mob/proc/custom_emote(var/m_type=1,var/message = null)
else if (m_type & 2)
for (var/mob/O in hearers(src.loc, null))
O.show_message(message, m_type)
/mob/proc/emote_dead(var/message)
if(client.prefs.muted & MUTE_DEADCHAT)
src << "\red You cannot send deadchat emotes (muted)."
return
if(!(client.prefs.toggles & CHAT_DEAD))
src << "\red You have deadchat muted."
return
var/input
if(!message)
input = copytext(sanitize(input(src, "Choose an emote to display.") as text|null), 1, MAX_MESSAGE_LEN)
else
input = message
if(input)
message = "<span class='game deadsay'><span class='prefix'>DEAD:</span> <b>[src]</b> [message]</span>"
else
return
if(message)
log_emote("Ghost/[src.key] : [message]")
for(var/mob/M in player_list)
if(istype(M, /mob/new_player))
continue
if(M.client && M.client.holder && (M.client.holder.rights & R_ADMIN|R_MOD) && (M.client.prefs.toggles & CHAT_DEAD)) // Show the emote to admins/mods
M << message
else if(M.stat == DEAD && (M.client.prefs.toggles & CHAT_DEAD)) // Show the emote to regular ghosts with deadchat toggled on
M.show_message(message, 2)
@@ -54,6 +54,15 @@
dizziness = 0
jitteriness = 0
//Check for heist mode kill count.
if(ticker.mode && ( istype( ticker.mode,/datum/game_mode/heist) ) )
//Check for last assailant's mutantrace.
/*if( LAssailant && ( istype( LAssailant,/mob/living/carbon/human ) ) )
var/mob/living/carbon/human/V = LAssailant
if (V.dna && (V.dna.mutantrace == "vox"))*/ //Not currently feasible due to terrible LAssailant tracking.
//world << "Vox kills: [vox_kills]"
vox_kills++ //Bad vox. Shouldn't be killing humans.
if(!gibbed)
emote("deathgasp") //let the world KNOW WE ARE DEAD
@@ -205,19 +205,15 @@
var/distance = get_dist(usr,src)
if(istype(usr, /mob/dead/observer) || usr.stat == 2) // ghosts can see anything
distance = 1
if (src.stat == 1 || stat == 2)
if (src.stat)
msg += "<span class='warning'>[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.</span>\n"
if((stat == 2 || src.health < config.health_threshold_crit) && distance <= 3)
msg += "<span class='warning'>[t_He] does not appear to be breathing.</span>\n"
if(istype(usr, /mob/living/carbon/human) && usr.stat == 0 && src.stat == 1 && distance <= 1)
if(istype(usr, /mob/living/carbon/human) && !usr.stat && distance <= 1)
for(var/mob/O in viewers(usr.loc, null))
O.show_message("[usr] checks [src]'s pulse.", 1)
spawn(15)
usr << "\blue [t_He] has a pulse!"
if(distance <= 1)
if(istype(usr, /mob/living/carbon/human) && usr.stat == 0)
spawn(15)
spawn(15)
if(distance <= 1 && usr.stat != 1)
if(pulse == PULSE_NONE)
usr << "<span class='deadsay'>[t_He] has no pulse[src.client ? "" : " and [t_his] soul has departed"]...</span>"
else
@@ -1115,7 +1115,7 @@ mob/living/carbon/human/yank_out_object()
set desc = "Remove an embedded item at the cost of bleeding and pain."
set src in view(1)
if(!isliving(usr) || usr.last_click + usr.click_delay < world.time)
if(!isliving(usr) || usr.last_click + usr.click_delay > world.time)
return
usr.delay_click(20)
@@ -11,21 +11,6 @@ emp_act
/mob/living/carbon/human/bullet_act(var/obj/item/projectile/P, var/def_zone)
// BEGIN TASER NERF
if(istype(P, /obj/item/projectile/energy/electrode))
var/datum/organ/external/select_area = get_organ(def_zone) // We're checking the outside, buddy!
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes) // What all are we checking?
// var/deflectchance=90 //Is it a CRITICAL HIT with that taser?
for(var/bp in body_parts) //Make an unregulated var to pass around.
if(!bp)
continue //Does this thing we're shooting even exist?
if(bp && istype(bp ,/obj/item/clothing)) // If it exists, and it's clothed
var/obj/item/clothing/C = bp // Then call an argument C to be that clothing!
if(C.body_parts_covered & select_area.body_part) // Is that body part being targeted covered?
P.agony=P.agony*C.siemens_coefficient
apply_effect(P.agony,AGONY,0)
flash_pain()
src <<"\red You have been shot!"
del P
/* Commenting out new-old taser nerf.
if(C.siemens_coefficient == 0) //If so, is that clothing shock proof?
if(prob(deflectchance))
@@ -43,7 +28,7 @@ emp_act
// END TASER NERF
if(wear_suit && istype(wear_suit, /obj/item/clothing/suit/armor/laserproof))
if(istype(P, /obj/item/projectile/energy) || !(istype(P, /obj/item/projectile/energy/electrode)) || istype(P, /obj/item/projectile/beam))
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
var/reflectchance = 40 - round(P.damage/3)
if(!(def_zone in list("chest", "groin")))
reflectchance /= 2
@@ -66,6 +51,23 @@ emp_act
return -1 // complete projectile permutation
//BEGIN BOOK'S TASER NERF.
if(istype(P, /obj/item/projectile/energy/electrode))
var/datum/organ/external/select_area = get_organ(def_zone) // We're checking the outside, buddy!
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes) // What all are we checking?
// var/deflectchance=90 //Is it a CRITICAL HIT with that taser?
for(var/bp in body_parts) //Make an unregulated var to pass around.
if(!bp)
continue //Does this thing we're shooting even exist?
if(bp && istype(bp ,/obj/item/clothing)) // If it exists, and it's clothed
var/obj/item/clothing/C = bp // Then call an argument C to be that clothing!
if(C.body_parts_covered & select_area.body_part) // Is that body part being targeted covered?
P.agony=P.agony*C.siemens_coefficient
apply_effect(P.agony,AGONY,0)
flash_pain()
src <<"\red You have been shot!"
//END TASER NERF
if(check_shields(P.damage, "the [P.name]"))
P.on_hit(src, 2)
return 2
+3 -5
View File
@@ -841,8 +841,7 @@
if(status_flags & GODMODE) return 0 //godmode
adjustToxLoss(total_plasmaloss)
// if(dna && dna.mutantrace == "plant") //couldn't think of a better place to place it, since it handles nutrition -- Urist
if(PLANT in mutations)
if(PLANT in mutations || (dna && dna.mutantrace == "plant"))
var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing
if(isturf(loc)) //else, there's considered to be no light
var/turf/T = loc
@@ -900,8 +899,7 @@
if(overeatduration > 1)
overeatduration -= 2 //doubled the unfat rate
// if(dna && dna.mutantrace == "plant")
if(PLANT in mutations)
if(PLANT in mutations || (dna && dna.mutantrace == "plant"))
if(nutrition < 200)
take_overall_damage(2,0)
@@ -998,7 +996,7 @@
sleeping = max(sleeping-1, 0)
blinded = 1
stat = UNCONSCIOUS
if( prob(10) && health && !hal_crit )
if( prob(2) && health && !hal_crit )
spawn(0)
emote("snore")
else if(resting)
@@ -220,14 +220,14 @@ proc/get_damage_icon_part(damage_state, body_part)
var/husk_color_mod = rgb(96,88,80)
var/hulk_color_mod = rgb(48,224,40)
var/plant_color_mod = rgb(144,224,144)
//var/plant_color_mod = rgb(144,224,144)
var/necrosis_color_mod = rgb(10,50,0)
var/husk = (HUSK in src.mutations) //100% unnecessary -Agouri //nope, do you really want to iterate through src.mutations repeatedly? -Pete
var/fat = (FAT in src.mutations)
var/hulk = (HULK in src.mutations)
var/skeleton = (SKELETON in src.mutations)
var/plant = (PLANT in src.mutations)
var/plant = (PLANT in src.mutations || (dna && dna.mutantrace == "plant"))
var/g = "m"
if(gender == FEMALE) g = "f"
@@ -240,8 +240,8 @@ proc/get_damage_icon_part(damage_state, body_part)
else if(hulk)
var/list/TONE = ReadRGB(hulk_color_mod)
stand_icon.MapColors(rgb(TONE[1],0,0),rgb(0,TONE[2],0),rgb(0,0,TONE[3]))
else if(plant)
stand_icon.ColorTone(plant_color_mod)
//else if(plant)
// stand_icon.ColorTone(plant_color_mod)
var/datum/organ/external/head = get_organ("head")
var/has_head = 0
@@ -269,8 +269,8 @@ proc/get_damage_icon_part(damage_state, body_part)
else if(hulk)
var/list/TONE = ReadRGB(hulk_color_mod)
temp.MapColors(rgb(TONE[1],0,0),rgb(0,TONE[2],0),rgb(0,0,TONE[3]))
else if(plant)
temp.ColorTone(plant_color_mod)
//else if(plant)
// temp.ColorTone(plant_color_mod)
//That part makes left and right legs drawn topmost and lowermost when human looks WEST or EAST
//And no change in rendering for other parts (they icon_position is 0, so goes to 'else' part)
@@ -320,7 +320,7 @@ proc/get_damage_icon_part(damage_state, body_part)
stand_icon.Blend(new/icon('icons/mob/human_face.dmi', "lips_[lip_style]_s"), ICON_OVERLAY)
//Underwear
if(underwear >0 && underwear < 12 && (src.dna.mutantrace != "vox" && src.dna.mutantrace != "kidan"))
if(underwear >0 && underwear < 12 && (src.dna.mutantrace != "vox" && src.dna.mutantrace != "plant" && src.dna.mutantrace != "kidan"))
if(!fat && !skeleton)
stand_icon.Blend(new /icon('icons/mob/human.dmi', "underwear[underwear]_[g]_s"), ICON_OVERLAY)
@@ -440,11 +440,12 @@ proc/get_damage_icon_part(damage_state, body_part)
if("skrell")
race_icon = 'icons/mob/human_races/r_skrell.dmi'
deform_icon = 'icons/mob/human_races/r_def_skrell.dmi'
if("vox")
race_icon = 'icons/mob/human_races/r_vox.dmi'
deform_icon = 'icons/mob/human_races/r_def_vox.dmi'
if("plant")
race_icon = 'icons/mob/human_races/r_plant.dmi'
deform_icon = 'icons/mob/human_races/r_def_plant.dmi'
else
race_icon = 'icons/mob/human_races/r_human.dmi'
deform_icon = 'icons/mob/human_races/r_def_human.dmi'
@@ -459,12 +460,12 @@ proc/get_damage_icon_part(damage_state, body_part)
// if("lizard","tajaran","skrell")
// overlays_lying[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.mutantrace]_[gender]_l")
// overlays_standing[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.mutantrace]_[gender]_s")
if("plant")
if(stat == DEAD) //TODO
overlays_lying[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/genetics.dmi', "icon_state" = "[dna.mutantrace]_d")
else
overlays_lying[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/genetics.dmi', "icon_state" = "[dna.mutantrace][fat]_[gender]_l")
overlays_standing[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/genetics.dmi', "icon_state" = "[dna.mutantrace][fat]_[gender]_s")
// if("plant")
// if(stat == DEAD) //TODO
// overlays_lying[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/genetics.dmi', "icon_state" = "[dna.mutantrace]_d")
// else
// overlays_lying[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/genetics.dmi', "icon_state" = "[dna.mutantrace][fat]_[gender]_l")
// overlays_standing[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/genetics.dmi', "icon_state" = "[dna.mutantrace][fat]_[gender]_s")
else
overlays_lying[MUTANTRACE_LAYER] = null
overlays_standing[MUTANTRACE_LAYER] = null
+3 -4
View File
@@ -340,7 +340,7 @@ var/list/ai_list = list()
if(href_list["say_word"])
src.announcement(href_list["say_word"])
return
if (href_list["lawi"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite
var/L = text2num(href_list["lawi"])
switch(ioncheck[L])
@@ -561,10 +561,9 @@ var/list/ai_list = list()
if(!C.can_use())
continue
var/list/tempnetwork = C.network
tempnetwork.Remove("CREED", "thunder", "RD", "toxins", "Prison")
var/list/tempnetwork = difflist(C.network,RESTRICTED_CAMERA_NETWORKS,1)
if(tempnetwork.len)
for(var/i in C.network)
for(var/i in tempnetwork)
cameralist[i] = i
var/old_network = network
network = input(U, "Which network would you like to view?") as null|anything in cameralist
@@ -67,7 +67,7 @@
var/oldLoc = src.loc
. = ..()
if(.)
if(src.camera)
if(src.camera && src.camera.network.len)
if(!updating)
updating = 1
spawn(BORG_CAMERA_BUFFER)
@@ -89,12 +89,16 @@
/obj/machinery/camera/New()
..()
cameranet.cameras += src
cameranet.addCamera(src)
cameranet.cameras += src //Camera must be added to global list of all cameras no matter what...
var/list/open_networks = difflist(network,RESTRICTED_CAMERA_NETWORKS) //...but if all of camera's networks are restricted, it only works for specific camera consoles.
if(open_networks.len) //If there is at least one open network, chunk is available for AI usage.
cameranet.addCamera(src)
/obj/machinery/camera/Del()
cameranet.cameras -= src
cameranet.removeCamera(src)
var/list/open_networks = difflist(network,RESTRICTED_CAMERA_NETWORKS)
if(open_networks.len)
cameranet.removeCamera(src)
..()
#undef BORG_CAMERA_BUFFER
+10 -8
View File
@@ -102,7 +102,7 @@
if(!scrambledcodes && !camera)
camera = new /obj/machinery/camera(src)
camera.c_tag = real_name
camera.network = list("SS13")
camera.network = list("SS13","Robots")
if(isWireCut(5)) // 5 = BORG CAMERA
camera.status = 0
@@ -148,7 +148,7 @@
if(module)
return
var/list/modules = list("Standard", "Engineering", "Medical", "Miner", "Janitor", "Service", "Security")
if(emagged || security_level > SEC_LEVEL_BLUE)
if(crisis && security_level == SEC_LEVEL_RED) //Leaving this in until it's balanced appropriately.
src << "\red Crisis mode active. Combat module available."
modules+="Combat"
modtype = input("Please, select a module!", "Robot", null, null) in modules
@@ -177,6 +177,8 @@
if("Miner")
module = new /obj/item/weapon/robot_module/miner(src)
channels = list("Supply" = 1)
if(camera && "Robots" in camera.network)
camera.network.Add("MINE")
module_sprites["Basic"] = "Miner_old"
module_sprites["Advanced Droid"] = "droid-miner"
module_sprites["Treadhead"] = "Miner"
@@ -184,6 +186,8 @@
if("Medical")
module = new /obj/item/weapon/robot_module/medical(src)
channels = list("Medical" = 1)
if(camera && "Robots" in camera.network)
camera.network.Add("Medical")
module_sprites["Basic"] = "Medbot"
module_sprites["Advanced Droid"] = "droid-medical"
module_sprites["Needles"] = "medicalrobot"
@@ -1175,12 +1179,8 @@
scrambledcodes = 1
//Disconnect it's camera so it's not so easily tracked.
if(src.camera)
del(src.camera)
src.camera = null
// I'm trying to get the Cyborg to not be listed in the camera list
// Instead of being listed as "deactivated". The downside is that I'm going
// to have to check if every camera is null or not before doing anything, to prevent runtime errors.
// I could change the network to null but I don't know what would happen, and it seems too hacky for me.
src.camera.network = list()
cameranet.removeCamera(src.camera)
/mob/living/silicon/robot/proc/ResetSecurityCodes()
@@ -1240,9 +1240,11 @@
else
src << "Something is badly wrong with the sprite selection. Harass a coder."
icon_state = module_sprites[1]
base_icon = icon_state
return
overlays -= "eyes"
base_icon = icon_state
updateicon()
if (triesleft >= 1)
@@ -223,13 +223,12 @@
/obj/item/weapon/robot_module/combat
name = "combat robot module"
New()
src.modules += new /obj/item/borg/sight/thermal(src)
src.modules += new /obj/item/weapon/gun/energy/lasercannon/cyborg(src)
src.modules += new /obj/item/weapon/gun/energy/laser/cyborg(src)
src.modules += new /obj/item/weapon/pickaxe/plasmacutter(src)
src.modules += new /obj/item/borg/combat/shield(src)
src.modules += new /obj/item/borg/combat/mobility(src)
src.modules += new /obj/item/weapon/wrench(src) //Is a combat android really going to be stopped by a chair?
src.emag = new /obj/item/weapon/gun/energy/pulse_rifle/cyborg(src)
src.emag = new /obj/item/weapon/gun/energy/lasercannon/cyborg(src)
return
@@ -24,14 +24,15 @@
/obj/item/borg/upgrade/reset/action(var/mob/living/silicon/robot/R)
R.uneq_all()
R.hands.icon_state = "nomod"
R.icon_state = "robot"
del(R.module)
R.module = null
R.modtype = "robot"
R.real_name = "Cyborg [R.ident]"
R.name = R.real_name
R.nopush = 0
R.hands.icon_state = "nomod"
R.base_icon = "robot"
R.icon_state = "robot"
R.updateicon()
return 1
+1 -1
View File
@@ -70,7 +70,7 @@
var/obj/item/weapon/arrow/quill/Q = new(loc)
Q.fingerprintslast = src.ckey
Q.throw_at(target,10,20)
Q.throw_at(target,10,30)
quills--
spawn(100)
+1 -1
View File
@@ -900,7 +900,7 @@ mob/verb/yank_out_object()
set desc = "Remove an embedded item at the cost of bleeding and pain."
set src in view(1)
if(!isliving(usr) || usr.last_click + usr.click_delay < world.time)
if(!isliving(usr) || usr.last_click + usr.click_delay > world.time)
return
usr.delay_click(20)
+1 -1
View File
@@ -128,7 +128,7 @@
return
if(killing)
return
if (assailant.last_click + assailant.click_delay < world.time)
if (assailant.last_click + assailant.click_delay > world.time)
return
if ((!( assailant.canmove ) || assailant.lying))
//SN src = null
+2 -2
View File
@@ -119,7 +119,7 @@
src << "\blue Now teleporting."
observer.loc = O.loc
if(client.prefs.be_random_name)
client.prefs.real_name = random_name()
client.prefs.real_name = random_name(client.prefs.gender)
observer.real_name = client.prefs.real_name
observer.name = observer.real_name
observer.key = key
@@ -377,7 +377,7 @@
if(ticker.random_players)
new_character.gender = pick(MALE, FEMALE)
client.prefs.real_name = random_name()
client.prefs.real_name = random_name(new_character.gender)
client.prefs.randomize_appearance_for(new_character)
else
client.prefs.copy_to(new_character)
+7 -2
View File
@@ -37,6 +37,10 @@
usr << "\red Speech is currently admin-disabled."
return
if(!(client.prefs.toggles & CHAT_DEAD))
usr << "\red You have deadchat muted."
return
if(mind && mind.name)
name = "[mind.name]"
else
@@ -50,9 +54,10 @@
for(var/mob/M in player_list)
if(istype(M, /mob/new_player))
continue
if(M.client && M.client.holder && (M.client.holder.rights & R_ADMIN|R_MOD) && (M.client.prefs.toggles & CHAT_DEAD)) //admins can toggle deadchat on and off. This is a proc in admin.dm and is only give to Administrators and above
if(M.client && M.client.holder && (M.client.holder.rights & R_ADMIN|R_MOD) && (M.client.prefs.toggles & CHAT_DEAD)) // Show the message to admins/mods with deadchat toggled on
M << rendered //Admins can hear deadchat, if they choose to, no matter if they're blind/deaf or not.
else if(M.stat == DEAD)
else if(M.stat == DEAD && (M.client.prefs.toggles & CHAT_DEAD)) // Show the message to regular ghosts with deadchat toggled on.
M.show_message(rendered, 2) //Takes into account blindness and such.
return
+1 -1
View File
@@ -600,7 +600,7 @@
set name = "Resist"
set category = "IC"
if(!isliving(usr) || usr.last_click + usr.click_delay < world.time)
if(!isliving(usr) || usr.last_click + usr.click_delay > world.time)
return
usr.delay_click(20)
+2 -2
View File
@@ -28,7 +28,7 @@
var/list/mixing = list() //Containers being used for mixing.
var/obj/item/weapon/dart_cartridge/cartridge = null //Container of darts.
var/max_beakers = 3
var/dart_reagent_amount = 5
var/dart_reagent_amount = 15
var/container_type = /obj/item/weapon/reagent_containers/glass/beaker/vial
var/list/starting_chems = null
@@ -52,7 +52,7 @@
if(starting_chems)
for(var/chem in starting_chems)
var/obj/item/weapon/reagent_containers/glass/beaker/vial/B = new(src)
B.reagents.add_reagent(chem, 25)
B.reagents.add_reagent(chem, 50)
beakers += B
cartridge = new /obj/item/weapon/dart_cartridge(src)
update_icon()
-9
View File
@@ -331,15 +331,6 @@ datum/design/supplycomp
materials = list("$glass" = 2000, "sacid" = 20)
build_path = "/obj/item/weapon/circuitboard/supplycomp"
datum/design/mining
name = "Circuit Design (Outpost Status Display)"
desc = "Allows for the construction of circuit boards used to build an outpost status display console."
id = "mining"
req_tech = list("programming" = 2)
build_type = IMPRINTER
materials = list("$glass" = 2000, "sacid" = 20)
build_path = "/obj/item/weapon/circuitboard/mining"
datum/design/comm_monitor
name = "Circuit Design (Telecommunications Monitoring Console)"
desc = "Allows for the construction of circuit boards used to build a telecommunications monitor."
+2 -2
View File
@@ -86,7 +86,7 @@
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\red [user]'s hand slips, tearing blood vessals and causing massive bleeding in [target]'s [affected.display_name] with the \[tool]!", \
user.visible_message("\red [user]'s hand slips, tearing blood vessals and causing massive bleeding in [target]'s [affected.display_name] with \the [tool]!", \
"\red Your hand slips, tearing blood vessels and causing massive bleeding in [target]'s [affected.display_name] with \the [tool]!",)
affected.createwound(CUT, 10)
@@ -102,7 +102,7 @@
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
return ..() && affected.open < 2 && !(affected.status & ORGAN_BLEEDING)
return ..() && affected.open == 1 && !(affected.status & ORGAN_BLEEDING)
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
+11 -3
View File
@@ -627,7 +627,7 @@ var/list/TAGGERLOCATIONS = list("Disposals",
#define CHAT_LOOC 4096
#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_ATTACKLOGS)
#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_ATTACKLOGS|CHAT_LOOC)
#define BE_TRAITOR 1
#define BE_OPERATIVE 2
@@ -640,6 +640,7 @@ var/list/TAGGERLOCATIONS = list("Disposals",
#define BE_CULTIST 256
#define BE_MONKEY 512
#define BE_NINJA 1024
#define BE_RAIDER 2048
var/list/be_special_flags = list(
"Traitor" = BE_TRAITOR,
@@ -652,7 +653,8 @@ var/list/be_special_flags = list(
"pAI" = BE_PAI,
"Cultist" = BE_CULTIST,
"Monkey" = BE_MONKEY,
"Ninja" = BE_NINJA
"Ninja" = BE_NINJA,
"Raider" = BE_RAIDER
)
#define AGE_MIN 17 //youngest a character can be
@@ -693,4 +695,10 @@ var/list/bradycardics = list("neurotoxin", "cryoxadone", "clonexadone", "space_d
//proc/get_pulse methods
#define GETPULSE_HAND 0 //less accurate (hand)
#define GETPULSE_TOOL 1 //more accurate (med scanner, sleeper, etc)
#define GETPULSE_TOOL 1 //more accurate (med scanner, sleeper, etc)
var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accessed by preexisting terminals. AIs and new terminals can't use them.
"thunder",
"ERT",
"NUKE"
)
+8 -1
View File
@@ -26,8 +26,15 @@ em {font-style: normal; font-weight: bold;}
.deadsay {color: #5c00e6;}
.radio {color: #008000;}
.deptradio {color: #993399;}
.comradio {color: #885500;}
.comradio {color: #193A7A;}
.syndradio {color: #6D3F40;}
.centradio {color: #5C5C8A;}
.secradio {color: #A30000;}
.engradio {color: #A66300;}
.medradio {color: #008160;}
.sciradio {color: #993399;}
.supradio {color: #5F4519;}
.alert {color: #ff0000;}
h1.alert, h2.alert {color: #000000;}
+28
View File
@@ -56,6 +56,34 @@ Changelog Section
Stuff which is in development and not yet visible to players or just code related
(ie. code improvements for expandability, etc.) should not be listed here. They
should be listed in the changelog upon commit though. Thanks. -->
<div class="commit sansserif">
<h2 class="date">July 30th, 2013</h2>
<h3 class="author">Erthilo updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">EFTPOS and ATM machines should now connect to databases.</li>
<li class="bugfix">Gravitational Catapults can now be removed from mechs.</li>
<li class="bugfix">Ghost manifest rune paper naming now works correctly.</li>
<li class="bugfix">Fix for newscaster special characters. Still not recommended.</li>
</ul>
</div>
<div class="commit sansserif">
<h2 class="date">30.07.2013</h2>
<h3 class="author">Kilakk updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">Added colored department radio channels.</li>
</ul>
</div>
<div class="commit sansserif">
<h2 class="date">28.07.2013</h2>
<h3 class="author">Segrain updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">Camera console circuits can be adjusted for different networks.</li>
<li class="rscadd">Nuclear operatives and ERT members have built-in cameras in their helmets. Activate helmet to initialize it.</li>
</ul>
</div>
<div class="commit sansserif">
<h2 class="date">26.07.2013</h2>
<h3 class="author">Kilakk updated:</h3>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 51 KiB

File diff suppressed because it is too large Load Diff