Merge branch 'dev' of https://github.com/Baystation12/Baystation12 into medtweaks
@@ -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)
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]"
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 ..()
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
@@ -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" )
|
||||
|
||||
@@ -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)
|
||||
@@ -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")
|
||||
@@ -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]!")
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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!
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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, " ")
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
@@ -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;}
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 135 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 51 KiB |