mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2026-07-20 12:44:04 +01:00
Merge branch 'master' of https://github.com/VOREStation/VOREStation
# Conflicts: # code/modules/mob/living/carbon/human/species/station/station.dm # code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm # code/modules/vore/weight/fitness_machines_vr.dm # config/custom_items.txt
This commit is contained in:
@@ -6,6 +6,7 @@ Thumbs.db
|
||||
*.dmb
|
||||
*.lk
|
||||
*.backup
|
||||
*.pyc
|
||||
data/
|
||||
cfg/
|
||||
|
||||
|
||||
+12
-12
@@ -3,9 +3,14 @@ language: c
|
||||
sudo: false
|
||||
|
||||
env:
|
||||
BYOND_MAJOR="512"
|
||||
BYOND_MINOR="1403"
|
||||
MACRO_COUNT=4
|
||||
global:
|
||||
- BYOND_MAJOR="512"
|
||||
- BYOND_MINOR="1403"
|
||||
- MACRO_COUNT=4
|
||||
matrix:
|
||||
- TEST_DEFINE="MAP_TEST" TEST_FILE="code/_map_tests.dm" RUN="0"
|
||||
- TEST_DEFINE="AWAY_MISSION_TEST" TEST_FILE="code/_away_mission_tests.dm" RUN="0"
|
||||
- TEST_DEFINE="UNIT_TEST" TEST_FILE="code/_unit_tests.dm" RUN="1"
|
||||
|
||||
cache:
|
||||
directories:
|
||||
@@ -37,14 +42,9 @@ script:
|
||||
- (num=`grep -E '\\\\(red|blue|green|black|b|i[^mc])' **/*.dm | wc -l`; echo "$num escapes (expecting ${MACRO_COUNT} or less)"; [ $num -le ${MACRO_COUNT} ])
|
||||
- source $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}/byond/bin/byondsetup
|
||||
- python tools/TagMatcher/tag-matcher.py ../..
|
||||
#First compile is to ensure maps are valid.
|
||||
- echo "#define MAP_TEST 1" > code/_map_tests.dm
|
||||
# Run our test
|
||||
- cp config/example/* config/
|
||||
- echo "#define ${TEST_DEFINE} 1" > ${TEST_FILE}
|
||||
- DreamMaker vorestation.dme
|
||||
- echo "#define MAP_TEST 0" > code/_map_tests.dm
|
||||
#Second compile is for the unit tests. Compiling a second time to exclude the validated maps is actually faster than waiting for startup with them compiled.
|
||||
- echo "#define UNIT_TEST 1" > code/_unit_tests.dm
|
||||
- DreamMaker vorestation.dme
|
||||
- DreamDaemon vorestation.dmb -invisible -trusted -core 2>&1 | tee log.txt
|
||||
- grep "All Unit Tests Passed" log.txt
|
||||
|
||||
- if [ $RUN -eq 1 ]; then DreamDaemon vorestation.dmb -invisible -trusted -core 2>&1 | tee log.txt; fi
|
||||
- if [ $RUN -eq 1 ]; then grep "All Unit Tests Passed" log.txt; fi
|
||||
@@ -117,4 +117,11 @@ CREATE TABLE `erro_privacy` (
|
||||
`ckey` varchar(32) NOT NULL,
|
||||
`option` varchar(128) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
|
||||
|
||||
CREATE TABLE `vr_player_hours` (
|
||||
`ckey` varchar(32) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
|
||||
`department` varchar(64) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
|
||||
`hours` double NOT NULL,
|
||||
PRIMARY KEY (`ckey`,`department`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
@@ -52,7 +52,7 @@
|
||||
/obj/machinery/atmospherics/omni/mixer/Destroy()
|
||||
inputs.Cut()
|
||||
output = null
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/sort_ports()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
|
||||
@@ -244,7 +244,7 @@
|
||||
P.node.disconnect(src)
|
||||
qdel(P.network)
|
||||
P.node = null
|
||||
|
||||
ports = null
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/atmospherics/omni/atmos_init()
|
||||
|
||||
+15
-118
@@ -26,15 +26,17 @@ mob/living/simple_animal/slime/airflow_stun()
|
||||
return
|
||||
|
||||
mob/living/carbon/human/airflow_stun()
|
||||
if(shoes)
|
||||
if(shoes.item_flags & NOSLIP) return 0
|
||||
if(shoes && (shoes.item_flags & NOSLIP))
|
||||
to_chat(src, "<span class='notice'>Air suddenly rushes past you!</span>")
|
||||
return 0
|
||||
..()
|
||||
|
||||
atom/movable/proc/check_airflow_movable(n)
|
||||
if(!simulated) return 0
|
||||
|
||||
if(anchored && !ismob(src)) return 0
|
||||
|
||||
if(!istype(src,/obj/item) && n < vsc.airflow_dense_pressure) return 0
|
||||
if(!isobj(src) && n < vsc.airflow_dense_pressure) return 0
|
||||
|
||||
return 1
|
||||
|
||||
@@ -50,15 +52,20 @@ mob/living/silicon/check_airflow_movable()
|
||||
return 0
|
||||
|
||||
|
||||
obj/item/check_airflow_movable(n)
|
||||
. = ..()
|
||||
obj/check_airflow_movable(n)
|
||||
if (!(. = ..()))
|
||||
return 0
|
||||
if(isnull(w_class))
|
||||
if(n < vsc.airflow_dense_pressure) return 0 //most non-item objs don't have a w_class yet
|
||||
switch(w_class)
|
||||
if(2)
|
||||
if(ITEMSIZE_TINY,ITEMSIZE_SMALL)
|
||||
if(n < vsc.airflow_lightest_pressure) return 0
|
||||
if(3)
|
||||
if(ITEMSIZE_NORMAL)
|
||||
if(n < vsc.airflow_light_pressure) return 0
|
||||
if(4,5)
|
||||
if(ITEMSIZE_LARGE,ITEMSIZE_HUGE)
|
||||
if(n < vsc.airflow_medium_pressure) return 0
|
||||
else
|
||||
if(n < vsc.airflow_dense_pressure) return 0
|
||||
|
||||
/atom/movable/var/tmp/turf/airflow_dest
|
||||
/atom/movable/var/tmp/airflow_speed = 0
|
||||
@@ -78,116 +85,6 @@ obj/item/check_airflow_movable(n)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/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
|
||||
if(airflow_dest == loc)
|
||||
step_away(src,loc)
|
||||
if(!src.AirflowCanMove(n))
|
||||
return
|
||||
if(ismob(src))
|
||||
src << "<span class='danger'>You are sucked away by airflow!</span>"
|
||||
last_airflow = world.time
|
||||
var/airflow_falloff = 9 - sqrt((x - airflow_dest.x) ** 2 + (y - airflow_dest.y) ** 2)
|
||||
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) break
|
||||
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
|
||||
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))
|
||||
break
|
||||
if(!istype(loc, /turf))
|
||||
break
|
||||
step_towards(src, src.airflow_dest)
|
||||
var/mob/M = src
|
||||
if(istype(M) && M.client)
|
||||
M.setMoveCooldown(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(!src.AirflowCanMove(n))
|
||||
return
|
||||
if(ismob(src))
|
||||
src << "<span clas='danger'>You are pushed away by airflow!</span>"
|
||||
last_airflow = world.time
|
||||
var/airflow_falloff = 9 - sqrt((x - airflow_dest.x) ** 2 + (y - airflow_dest.y) ** 2)
|
||||
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)
|
||||
|
||||
+2
-1
@@ -76,7 +76,8 @@ turf/c_airblock(turf/other)
|
||||
return AIR_BLOCKED
|
||||
|
||||
var/result = 0
|
||||
for(var/atom/movable/M in contents)
|
||||
for(var/mm in contents)
|
||||
var/atom/movable/M = mm
|
||||
result |= M.c_airblock(other)
|
||||
if(result == BLOCKED) return BLOCKED
|
||||
return result
|
||||
|
||||
+31
-197
@@ -1,4 +1,4 @@
|
||||
var/datum/controller/air_system/air_master
|
||||
var/datum/controller/subsystem/air/air_master
|
||||
|
||||
var/tick_multiplier = 2
|
||||
|
||||
@@ -65,201 +65,35 @@ Class Procs:
|
||||
|
||||
*/
|
||||
|
||||
//
|
||||
// The rest of the air subsystem is defined in air.dm
|
||||
//
|
||||
|
||||
//Geometry lists
|
||||
/datum/controller/air_system/var/list/zones = list()
|
||||
/datum/controller/air_system/var/list/edges = list()
|
||||
/datum/controller/subsystem/air
|
||||
//Geometry lists
|
||||
var/list/zones = list()
|
||||
var/list/edges = list()
|
||||
//Geometry updates lists
|
||||
var/list/tiles_to_update = list()
|
||||
var/list/zones_to_update = list()
|
||||
var/list/active_fire_zones = list()
|
||||
var/list/active_hotspots = list()
|
||||
var/list/active_edges = list()
|
||||
|
||||
//Geometry updates lists
|
||||
/datum/controller/air_system/var/list/tiles_to_update = list()
|
||||
/datum/controller/air_system/var/list/zones_to_update = list()
|
||||
/datum/controller/air_system/var/list/active_fire_zones = list()
|
||||
/datum/controller/air_system/var/list/active_hotspots = list()
|
||||
/datum/controller/air_system/var/list/active_edges = list()
|
||||
var/active_zones = 0
|
||||
var/current_cycle = 0
|
||||
var/next_id = 1 //Used to keep track of zone UIDs.
|
||||
|
||||
/datum/controller/air_system/var/active_zones = 0
|
||||
|
||||
/datum/controller/air_system/var/current_cycle = 0
|
||||
/datum/controller/air_system/var/update_delay = 5 //How long between check should it try to process atmos again.
|
||||
/datum/controller/air_system/var/failed_ticks = 0 //How many ticks have runtimed?
|
||||
|
||||
/datum/controller/air_system/var/tick_progress = 0
|
||||
|
||||
/datum/controller/air_system/var/next_id = 1 //Used to keep track of zone UIDs.
|
||||
|
||||
|
||||
#if UNIT_TEST
|
||||
#define CHECK_SLEEP_ZAS_SETUP // For unit tests we don't care about a smooth lobby screen experience. We care about speed.
|
||||
#else
|
||||
#define CHECK_SLEEP_ZAS_SETUP if(++done_turfs > 10000) { done_turfs=0;sleep(world.tick_lag); }
|
||||
#endif
|
||||
/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.
|
||||
|
||||
#if !UNIT_TEST
|
||||
var/done_turfs = 0
|
||||
#endif
|
||||
#ifndef ZASDBG
|
||||
set background = 1
|
||||
#endif
|
||||
|
||||
admin_notice("<span class='danger'>Processing Geometry...</span>", R_DEBUG)
|
||||
sleep(-1)
|
||||
|
||||
var/start_time = world.timeofday
|
||||
|
||||
var/simulated_turf_count = 0
|
||||
|
||||
for(var/turf/simulated/S in world)
|
||||
simulated_turf_count++
|
||||
S.update_air_properties()
|
||||
CHECK_SLEEP_ZAS_SETUP
|
||||
|
||||
admin_notice({"<span class='danger'>Geometry initialized in [round(0.1*(world.timeofday-start_time),0.1)] seconds.</span>
|
||||
<span class='info'>
|
||||
Total Simulated Turfs: [simulated_turf_count]
|
||||
Total Zones: [zones.len]
|
||||
Total Edges: [edges.len]
|
||||
Total Active Edges: [active_edges.len ? "<span class='danger'>[active_edges.len]</span>" : "None"]
|
||||
Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_count]
|
||||
</span>"}, R_DEBUG)
|
||||
|
||||
// Uncomment this if you're having problems finding where active edges are.
|
||||
/*
|
||||
for(var/connection_edge/E in active_edges)
|
||||
world << "Edge became active: [E]."
|
||||
var/i = 1
|
||||
for(var/turf/T in E.connecting_turfs)
|
||||
world << "[i] [T]:[T.x],[T.y],[T.z]"
|
||||
i++
|
||||
*/
|
||||
|
||||
|
||||
// spawn Start()
|
||||
|
||||
|
||||
/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.
|
||||
|
||||
#ifndef ZASDBG
|
||||
set background = 1
|
||||
#endif
|
||||
|
||||
while(1)
|
||||
Tick()
|
||||
sleep(max(5,update_delay*tick_multiplier))
|
||||
|
||||
|
||||
/datum/controller/air_system/proc/Tick()
|
||||
. = 1 //Set the default return value, for runtime detection.
|
||||
|
||||
current_cycle++
|
||||
|
||||
//If there are tiles to update, do so.
|
||||
tick_progress = "updating turf properties"
|
||||
|
||||
var/list/updating
|
||||
|
||||
if(tiles_to_update.len)
|
||||
updating = tiles_to_update
|
||||
tiles_to_update = list()
|
||||
|
||||
#ifdef ZASDBG
|
||||
var/updated = 0
|
||||
#endif
|
||||
|
||||
//defer updating of self-zone-blocked turfs until after all other turfs have been updated.
|
||||
//this hopefully ensures that non-self-zone-blocked turfs adjacent to self-zone-blocked ones
|
||||
//have valid zones when the self-zone-blocked turfs update.
|
||||
|
||||
//This ensures that doorways don't form their own single-turf zones, since doorways are self-zone-blocked and
|
||||
//can merge with an adjacent zone, whereas zones that are formed on adjacent turfs cannot merge with the doorway.
|
||||
var/list/deferred = list()
|
||||
|
||||
for(var/turf/T in updating)
|
||||
//check if the turf is self-zone-blocked
|
||||
if(T.c_airblock(T) & ZONE_BLOCKED)
|
||||
deferred += T
|
||||
continue
|
||||
|
||||
T.update_air_properties()
|
||||
T.post_update_air_properties()
|
||||
T.needs_air_update = 0
|
||||
#ifdef ZASDBG
|
||||
T.overlays -= mark
|
||||
updated++
|
||||
#endif
|
||||
//sleep(1)
|
||||
|
||||
for(var/turf/T in deferred)
|
||||
T.update_air_properties()
|
||||
T.post_update_air_properties()
|
||||
T.needs_air_update = 0
|
||||
#ifdef ZASDBG
|
||||
T.overlays -= mark
|
||||
updated++
|
||||
#endif
|
||||
|
||||
#ifdef ZASDBG
|
||||
if(updated != updating.len)
|
||||
tick_progress = "[updating.len - updated] tiles left unupdated."
|
||||
world << "<span class='danger'>[tick_progress]</span>"
|
||||
. = 0
|
||||
#endif
|
||||
|
||||
//Where gas exchange happens.
|
||||
if(.)
|
||||
tick_progress = "processing edges"
|
||||
|
||||
for(var/connection_edge/edge in active_edges)
|
||||
edge.tick()
|
||||
|
||||
//Process fire zones.
|
||||
if(.)
|
||||
tick_progress = "processing fire zones"
|
||||
|
||||
for(var/zone/Z in active_fire_zones)
|
||||
Z.process_fire()
|
||||
|
||||
//Process hotspots.
|
||||
if(.)
|
||||
tick_progress = "processing hotspots"
|
||||
|
||||
for(var/obj/fire/fire in active_hotspots)
|
||||
fire.process()
|
||||
|
||||
//Process zones.
|
||||
if(.)
|
||||
tick_progress = "updating zones"
|
||||
|
||||
active_zones = zones_to_update.len
|
||||
if(zones_to_update.len)
|
||||
updating = zones_to_update
|
||||
zones_to_update = list()
|
||||
for(var/zone/zone in updating)
|
||||
zone.tick()
|
||||
zone.needs_update = 0
|
||||
|
||||
if(.)
|
||||
tick_progress = "success"
|
||||
|
||||
/datum/controller/air_system/proc/add_zone(zone/z)
|
||||
/datum/controller/subsystem/air/proc/add_zone(zone/z)
|
||||
zones.Add(z)
|
||||
z.name = "Zone [next_id++]"
|
||||
mark_zone_update(z)
|
||||
|
||||
/datum/controller/air_system/proc/remove_zone(zone/z)
|
||||
/datum/controller/subsystem/air/proc/remove_zone(zone/z)
|
||||
zones.Remove(z)
|
||||
zones_to_update.Remove(z)
|
||||
|
||||
/datum/controller/air_system/proc/air_blocked(turf/A, turf/B)
|
||||
/datum/controller/subsystem/air/proc/air_blocked(turf/A, turf/B)
|
||||
#ifdef ZASDBG
|
||||
ASSERT(isturf(A))
|
||||
ASSERT(isturf(B))
|
||||
@@ -268,13 +102,13 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
if(ablock == BLOCKED) return BLOCKED
|
||||
return ablock | B.c_airblock(A)
|
||||
|
||||
/datum/controller/air_system/proc/has_valid_zone(turf/simulated/T)
|
||||
/datum/controller/subsystem/air/proc/has_valid_zone(turf/simulated/T)
|
||||
#ifdef ZASDBG
|
||||
ASSERT(istype(T))
|
||||
#endif
|
||||
return istype(T) && T.zone && !T.zone.invalid
|
||||
|
||||
/datum/controller/air_system/proc/merge(zone/A, zone/B)
|
||||
/datum/controller/subsystem/air/proc/merge(zone/A, zone/B)
|
||||
#ifdef ZASDBG
|
||||
ASSERT(istype(A))
|
||||
ASSERT(istype(B))
|
||||
@@ -289,7 +123,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
B.c_merge(A)
|
||||
mark_zone_update(A)
|
||||
|
||||
/datum/controller/air_system/proc/connect(turf/simulated/A, turf/simulated/B)
|
||||
/datum/controller/subsystem/air/proc/connect(turf/simulated/A, turf/simulated/B)
|
||||
#ifdef ZASDBG
|
||||
ASSERT(istype(A))
|
||||
ASSERT(isturf(B))
|
||||
@@ -330,7 +164,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
|
||||
if(direct) c.mark_direct()
|
||||
|
||||
/datum/controller/air_system/proc/mark_for_update(turf/T)
|
||||
/datum/controller/subsystem/air/proc/mark_for_update(turf/T)
|
||||
#ifdef ZASDBG
|
||||
ASSERT(isturf(T))
|
||||
#endif
|
||||
@@ -341,7 +175,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
#endif
|
||||
T.needs_air_update = 1
|
||||
|
||||
/datum/controller/air_system/proc/mark_zone_update(zone/Z)
|
||||
/datum/controller/subsystem/air/proc/mark_zone_update(zone/Z)
|
||||
#ifdef ZASDBG
|
||||
ASSERT(istype(Z))
|
||||
#endif
|
||||
@@ -349,7 +183,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
zones_to_update.Add(Z)
|
||||
Z.needs_update = 1
|
||||
|
||||
/datum/controller/air_system/proc/mark_edge_sleeping(connection_edge/E)
|
||||
/datum/controller/subsystem/air/proc/mark_edge_sleeping(connection_edge/E)
|
||||
#ifdef ZASDBG
|
||||
ASSERT(istype(E))
|
||||
#endif
|
||||
@@ -357,7 +191,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
active_edges.Remove(E)
|
||||
E.sleeping = 1
|
||||
|
||||
/datum/controller/air_system/proc/mark_edge_active(connection_edge/E)
|
||||
/datum/controller/subsystem/air/proc/mark_edge_active(connection_edge/E)
|
||||
#ifdef ZASDBG
|
||||
ASSERT(istype(E))
|
||||
#endif
|
||||
@@ -365,10 +199,10 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
active_edges.Add(E)
|
||||
E.sleeping = 0
|
||||
|
||||
/datum/controller/air_system/proc/equivalent_pressure(zone/A, zone/B)
|
||||
/datum/controller/subsystem/air/proc/equivalent_pressure(zone/A, zone/B)
|
||||
return A.air.compare(B.air)
|
||||
|
||||
/datum/controller/air_system/proc/get_edge(zone/A, zone/B)
|
||||
/datum/controller/subsystem/air/proc/get_edge(zone/A, zone/B)
|
||||
|
||||
if(istype(B))
|
||||
for(var/connection_edge/zone/edge in A.edges)
|
||||
@@ -385,7 +219,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
edge.recheck()
|
||||
return edge
|
||||
|
||||
/datum/controller/air_system/proc/has_same_air(turf/A, turf/B)
|
||||
/datum/controller/subsystem/air/proc/has_same_air(turf/A, turf/B)
|
||||
if(A.oxygen != B.oxygen) return 0
|
||||
if(A.nitrogen != B.nitrogen) return 0
|
||||
if(A.phoron != B.phoron) return 0
|
||||
@@ -393,6 +227,6 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun
|
||||
if(A.temperature != B.temperature) return 0
|
||||
return 1
|
||||
|
||||
/datum/controller/air_system/proc/remove_edge(connection_edge/E)
|
||||
/datum/controller/subsystem/air/proc/remove_edge(connection_edge/E)
|
||||
edges.Remove(E)
|
||||
if(!E.sleeping) active_edges.Remove(E)
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
client/proc/ZoneTick()
|
||||
set category = "Debug"
|
||||
set name = "Process Atmos"
|
||||
set desc = "Manually run a single tick of the air subsystem"
|
||||
|
||||
// TODO - This might be a useful diagnostic tool. However its complicated to do with StonedMC
|
||||
// Therefore it is left unimplemented for now until its use actually becomes required. ~Leshana
|
||||
/*
|
||||
if(!check_rights(R_DEBUG)) return
|
||||
|
||||
var/result = air_master.Tick()
|
||||
if(result)
|
||||
@@ -8,7 +14,7 @@ client/proc/ZoneTick()
|
||||
|
||||
else
|
||||
src << "Failed to process! ([air_master.tick_progress])"
|
||||
|
||||
*/
|
||||
|
||||
client/proc/Zone_Info(turf/T as null|turf)
|
||||
set category = "Debug"
|
||||
|
||||
@@ -26,11 +26,3 @@ Notes for people who used ZAS before:
|
||||
var/zone/connected_zone = edge.get_connected_zone(zone)
|
||||
|
||||
*/
|
||||
|
||||
//#define ZASDBG
|
||||
#define MULTIZAS
|
||||
#define AIR_BLOCKED 1
|
||||
#define ZONE_BLOCKED 2
|
||||
#define BLOCKED 3
|
||||
|
||||
#define ZONE_MIN_SIZE 14 //zones with less than this many turfs will always merge, even if the connection is not direct
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
// Bitflag values for c_airblock()
|
||||
#define AIR_BLOCKED 1 // Blocked
|
||||
#define ZONE_BLOCKED 2 // Not blocked, but zone boundaries will not cross.
|
||||
#define BLOCKED 3 // Blocked, zone boundaries will not cross even if opened.
|
||||
|
||||
#define ZONE_MIN_SIZE 14 // Zones with less than this many turfs will always merge, even if the connection is not direct
|
||||
@@ -7,6 +7,10 @@
|
||||
2 for preloading absolutely everything;
|
||||
*/
|
||||
|
||||
// ZAS Compile Options
|
||||
//#define ZASDBG // Uncomment to turn on super detailed ZAS debugging that probably won't even compile.
|
||||
#define MULTIZAS // Uncomment to turn on Multi-Z ZAS Support!
|
||||
|
||||
// If we are doing the map test build, do not include the main maps, only the submaps.
|
||||
#if MAP_TEST
|
||||
#define USING_MAP_DATUM /datum/map
|
||||
|
||||
@@ -58,6 +58,8 @@ What is the naming convention for planes or layers?
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define
|
||||
#define DECALS_LAYER 2.01
|
||||
#define OVERTURF_LAYER 2.1
|
||||
#define DOOR_OPEN_LAYER 2.7 //Under all objects if opened. 2.7 due to tables being at 2.6
|
||||
//#define OBJ_LAYER 3 //For easy recordkeeping; this is a byond define
|
||||
#define DOOR_CLOSED_LAYER 3.1 //Above most items if closed
|
||||
@@ -70,7 +72,6 @@ What is the naming convention for planes or layers?
|
||||
//#define FLY_LAYER 5 //For easy recordkeeping; this is a byond define
|
||||
#define LIGHTING_LAYER 11 //Layer that lighting used to be on (now it's on a plane)
|
||||
#define HUD_LAYER 20 //Above lighting, but below obfuscation. For in-game HUD effects (whereas SCREEN_LAYER is for abstract/OOC things like inventory slots)
|
||||
#define OBFUSCATION_LAYER 21 //Where images covering the view for eyes are put
|
||||
#define SCREEN_LAYER 22 //Mob HUD/effects layer
|
||||
|
||||
#define PLANE_LIGHTING 5 //Where the lighting (and darkness) lives
|
||||
@@ -91,9 +92,11 @@ What is the naming convention for planes or layers?
|
||||
#define PLANE_CH_SPECIAL 23 //Special role icon (revhead or w/e)
|
||||
#define PLANE_CH_STATUS_OOC 24 //OOC status hud for spooks
|
||||
|
||||
#define PLANE_MESONS 30 //Stuff seen with mesons, like open ceilings. This is 30 for downstreams.
|
||||
|
||||
//Fullscreen overlays under inventory
|
||||
#define PLANE_FULLSCREEN 90 //Blindness, mesons, druggy, etc
|
||||
#define PLANE_FULLSCREEN 90 //Blindness, mesons, druggy, etc
|
||||
#define OBFUSCATION_LAYER 5 //Where images covering the view for eyes are put
|
||||
#define FULLSCREEN_LAYER 18
|
||||
#define DAMAGE_LAYER 18.1
|
||||
#define BLIND_LAYER 18.2
|
||||
|
||||
@@ -53,7 +53,7 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called
|
||||
#define NETWORK_PRISON "Prison"
|
||||
#define NETWORK_SECURITY "Security"
|
||||
#define NETWORK_INTERROGATION "Interrogation"
|
||||
#define NETWORK_TELECOM "Tcomsat"
|
||||
#define NETWORK_TELECOM "Tcomms"
|
||||
#define NETWORK_THUNDER "Thunderdome"
|
||||
#define NETWORK_COMMUNICATORS "Communicators"
|
||||
|
||||
|
||||
@@ -29,3 +29,6 @@
|
||||
#define SHUTTLE_CRASHED 3 // Yup that can happen now
|
||||
|
||||
#define BLUE_SHIELDED 2 // Shield from bluespace teleportation (telescience)
|
||||
|
||||
//Assistant/Visitor/Whatever
|
||||
#define USELESS_JOB "Visitor"
|
||||
+21
-18
@@ -231,25 +231,28 @@
|
||||
|
||||
//Vision flags, for dealing with plane visibility
|
||||
#define VIS_FULLBRIGHT 1
|
||||
#define VIS_GHOSTS 2
|
||||
#define VIS_AI_EYE 3
|
||||
#define VIS_LIGHTING 2
|
||||
#define VIS_GHOSTS 3
|
||||
#define VIS_AI_EYE 4
|
||||
|
||||
#define VIS_CH_STATUS 4
|
||||
#define VIS_CH_HEALTH 5
|
||||
#define VIS_CH_LIFE 6
|
||||
#define VIS_CH_ID 7
|
||||
#define VIS_CH_WANTED 8
|
||||
#define VIS_CH_IMPLOYAL 9
|
||||
#define VIS_CH_IMPTRACK 10
|
||||
#define VIS_CH_IMPCHEM 11
|
||||
#define VIS_CH_SPECIAL 12
|
||||
#define VIS_CH_STATUS_OOC 13
|
||||
#define VIS_CH_STATUS 5
|
||||
#define VIS_CH_HEALTH 6
|
||||
#define VIS_CH_LIFE 7
|
||||
#define VIS_CH_ID 8
|
||||
#define VIS_CH_WANTED 9
|
||||
#define VIS_CH_IMPLOYAL 10
|
||||
#define VIS_CH_IMPTRACK 11
|
||||
#define VIS_CH_IMPCHEM 12
|
||||
#define VIS_CH_SPECIAL 13
|
||||
#define VIS_CH_STATUS_OOC 14
|
||||
|
||||
#define VIS_D_COLORBLIND 14
|
||||
#define VIS_D_COLORBLINDI 15
|
||||
#define VIS_D_COLORBLIND 15
|
||||
#define VIS_D_COLORBLINDI 16
|
||||
|
||||
#define VIS_ADMIN1 16
|
||||
#define VIS_ADMIN2 17
|
||||
#define VIS_ADMIN3 18
|
||||
#define VIS_ADMIN1 17
|
||||
#define VIS_ADMIN2 18
|
||||
#define VIS_ADMIN3 19
|
||||
|
||||
#define VIS_COUNT 18 //Must be highest number from above.
|
||||
#define VIS_MESONS 20
|
||||
|
||||
#define VIS_COUNT 20 //Must be highest number from above.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#undef VIS_COUNT
|
||||
|
||||
#define VIS_CH_STATUS_R 18
|
||||
#define VIS_CH_HEALTH_VR 19
|
||||
#define VIS_CH_BACKUP 20
|
||||
#define VIS_CH_VANTAG 21
|
||||
#define VIS_CH_STATUS_R 21
|
||||
#define VIS_CH_HEALTH_VR 22
|
||||
#define VIS_CH_BACKUP 23
|
||||
#define VIS_CH_VANTAG 24
|
||||
|
||||
#define VIS_AUGMENTED 22
|
||||
#define VIS_AUGMENTED 25
|
||||
|
||||
#define VIS_COUNT 22
|
||||
#define VIS_COUNT 25
|
||||
|
||||
@@ -18,3 +18,4 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
|
||||
#define INIT_ORDER_MAPPING 20 // VOREStation Edit
|
||||
#define INIT_ORDER_MACHINES 10
|
||||
#define INIT_ORDER_LIGHTING 0
|
||||
#define INIT_ORDER_AIR -1
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
*
|
||||
* This file is used by Travis to indicate that additional maps need to be compiled to look for errors such as missing paths.
|
||||
* Do not add anything but the AWAY_MISSION_TEST definition here as it will be overwritten by Travis when running tests.
|
||||
*
|
||||
*
|
||||
* Should you wish to edit set AWAY_MISSION_TEST to 1 like so:
|
||||
* #define AWAY_MISSION_TEST 1
|
||||
*/
|
||||
#define AWAY_MISSION_TEST 0
|
||||
@@ -817,6 +817,11 @@ proc // Creates a single icon from a given /atom or /image. Only the first argu
|
||||
qdel(west)
|
||||
return full
|
||||
|
||||
/proc/downloadImage(atom/A, dir)
|
||||
var/icon/this_icon = getFlatIcon(A,defdir=dir||A.dir,always_use_defdir=1)
|
||||
|
||||
usr << ftp(this_icon,"[A.name].png")
|
||||
|
||||
/mob/proc/AddCamoOverlay(atom/A)//A is the atom which we are using as the overlay.
|
||||
var/icon/opacity_icon = new(A.icon, A.icon_state)//Don't really care for overlays/underlays.
|
||||
//Now we need to culculate overlays+underlays and add them together to form an image for a mask.
|
||||
|
||||
@@ -88,6 +88,10 @@
|
||||
/proc/log_unit_test(text)
|
||||
world.log << "## UNIT_TEST: [text]"
|
||||
|
||||
/proc/report_progress(var/progress_message)
|
||||
admin_notice("<span class='boldannounce'>[progress_message]</span>", R_DEBUG)
|
||||
to_world_log(progress_message)
|
||||
|
||||
//pretty print a direction bitflag, can be useful for debugging.
|
||||
/proc/print_dir(var/dir)
|
||||
var/list/comps = list()
|
||||
|
||||
@@ -248,3 +248,19 @@ Proc for attack log creation, because really why not
|
||||
|
||||
if (progbar)
|
||||
qdel(progbar)
|
||||
|
||||
/atom/proc/living_mobs(var/range = world.view)
|
||||
var/list/viewers = oviewers(src,range)
|
||||
var/list/living = list()
|
||||
for(var/mob/living/L in viewers)
|
||||
living += L
|
||||
|
||||
return living
|
||||
|
||||
/atom/proc/human_mobs(var/range = world.view)
|
||||
var/list/viewers = oviewers(src,range)
|
||||
var/list/humans = list()
|
||||
for(var/mob/living/carbon/human/H in viewers)
|
||||
humans += H
|
||||
|
||||
return humans
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
/atom/proc/living_mobs(var/range = world.view)
|
||||
var/list/viewers = oviewers(src,range)
|
||||
var/list/living = list()
|
||||
for(var/mob/living/L in viewers)
|
||||
living += L
|
||||
|
||||
return living
|
||||
@@ -28,3 +28,11 @@
|
||||
. = B.failures - A.failures
|
||||
if (!.)
|
||||
. = B.qdels - A.qdels
|
||||
|
||||
// Sorts jobs by department, and then by flag within department
|
||||
/proc/cmp_job_datums(var/datum/job/a, var/datum/job/b)
|
||||
. = sorttext(b.department, a.department)
|
||||
if (. == 0) //Same department, push up if they're a head
|
||||
. = b.head_position - a.head_position
|
||||
if (. == 0) //Already in head/nothead spot, sort by name
|
||||
. = sorttext(b.title, a.title)
|
||||
|
||||
@@ -792,6 +792,7 @@ proc/GaussRandRound(var/sigma,var/roundto)
|
||||
var/old_icon1 = T.icon
|
||||
var/old_overlays = T.overlays.Copy()
|
||||
var/old_underlays = T.underlays.Copy()
|
||||
var/old_decals = T.decals ? T.decals.Copy() : null
|
||||
|
||||
X = B.ChangeTurf(T.type)
|
||||
X.set_dir(old_dir1)
|
||||
@@ -799,6 +800,9 @@ proc/GaussRandRound(var/sigma,var/roundto)
|
||||
X.icon = old_icon1
|
||||
X.overlays = old_overlays
|
||||
X.underlays = old_underlays
|
||||
X.decals = old_decals
|
||||
if(old_decals)
|
||||
X.apply_decals()
|
||||
|
||||
//Move the air from source to dest
|
||||
var/turf/simulated/ST = T
|
||||
@@ -824,9 +828,11 @@ proc/GaussRandRound(var/sigma,var/roundto)
|
||||
|
||||
else if(turftoleave)
|
||||
T.ChangeTurf(turftoleave)
|
||||
T.apply_decals()
|
||||
|
||||
else
|
||||
T.ChangeTurf(get_base_turf_by_area(T))
|
||||
T.apply_decals()
|
||||
|
||||
refined_src -= T
|
||||
refined_trg -= B
|
||||
|
||||
@@ -28,6 +28,7 @@ var/list/global_huds = list(
|
||||
var/obj/screen/whitense
|
||||
var/list/vimpaired
|
||||
var/list/darkMask
|
||||
var/obj/screen/darksight
|
||||
var/obj/screen/nvg
|
||||
var/obj/screen/thermal
|
||||
var/obj/screen/meson
|
||||
@@ -66,6 +67,13 @@ var/list/global_huds = list(
|
||||
whitense.icon = 'icons/effects/static.dmi'
|
||||
whitense.icon_state = "1 light"
|
||||
|
||||
//darksight 'hanger' for attached icons
|
||||
darksight = new /obj/screen()
|
||||
darksight.icon = null
|
||||
darksight.screen_loc = "1,1"
|
||||
darksight.plane = PLANE_LIGHTING
|
||||
darksight.plane = LIGHTING_LAYER + 0.1
|
||||
|
||||
nvg = setup_overlay("nvg_hud")
|
||||
thermal = setup_overlay("thermal_hud")
|
||||
meson = setup_overlay("meson_hud")
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
|
||||
/datum/configuration
|
||||
var/list/engine_map // Comma separated list of engines to choose from. Blank means fully random.
|
||||
var/assistants_ratio
|
||||
var/assistants_assured = 15 // Default 15, only used if the ratio is set though.
|
||||
var/time_off = FALSE
|
||||
var/limit_interns = -1 //Unlimited by default
|
||||
var/limit_visitors = -1 //Unlimited by default
|
||||
var/pto_cap = 100 //Hours
|
||||
|
||||
/hook/startup/proc/read_vs_config()
|
||||
var/list/Lines = file2list("config/config.txt")
|
||||
@@ -32,10 +34,6 @@
|
||||
continue
|
||||
|
||||
switch (name)
|
||||
if ("assistants_ratio")
|
||||
config.assistants_ratio = text2num(value)
|
||||
if ("assistants_assured")
|
||||
config.assistants_assured = text2num(value)
|
||||
if ("chat_webhook_url")
|
||||
config.chat_webhook_url = value
|
||||
if ("chat_webhook_key")
|
||||
@@ -46,5 +44,13 @@
|
||||
config.fax_export_dir = value
|
||||
if ("items_survive_digestion")
|
||||
config.items_survive_digestion = 1
|
||||
if ("limit_interns")
|
||||
config.limit_interns = text2num(value)
|
||||
if ("limit_visitors")
|
||||
config.limit_visitors = text2num(value)
|
||||
if ("pto_cap")
|
||||
config.pto_cap = text2num(value)
|
||||
if ("time_off")
|
||||
config.time_off = TRUE
|
||||
|
||||
return 1
|
||||
|
||||
@@ -573,14 +573,11 @@ var/datum/controller/master/Master = new()
|
||||
var/datum/controller/subsystem/SS = S
|
||||
SS.StartLoadingMap()
|
||||
|
||||
// ZAS might displace objects as the map loads if an air tick is processed mid-load.
|
||||
air_processing_killed = TRUE
|
||||
map_loading = TRUE
|
||||
|
||||
/datum/controller/master/StopLoadingMap(var/quiet = TRUE)
|
||||
if(!quiet)
|
||||
admin_notice("<span class='danger'>Map is finished. Unlocking.</span>", R_DEBUG)
|
||||
air_processing_killed = FALSE
|
||||
map_loading = FALSE
|
||||
for(var/S in subsystems)
|
||||
var/datum/controller/subsystem/SS = S
|
||||
|
||||
@@ -11,7 +11,6 @@ var/global/datum/controller/game_controller/master_controller //Set in world.New
|
||||
var/global/controller_iteration = 0
|
||||
var/global/last_tick_duration = 0
|
||||
|
||||
var/global/air_processing_killed = 0
|
||||
var/global/pipe_processing_killed = 0
|
||||
|
||||
datum/controller/game_controller
|
||||
|
||||
@@ -0,0 +1,271 @@
|
||||
// Air update stages
|
||||
#define SSAIR_TURFS 1
|
||||
#define SSAIR_EDGES 2
|
||||
#define SSAIR_FIREZONES 3
|
||||
#define SSAIR_HOTSPOTS 4
|
||||
#define SSAIR_ZONES 5
|
||||
#define SSAIR_DONE 6
|
||||
|
||||
SUBSYSTEM_DEF(air)
|
||||
name = "Air"
|
||||
init_order = INIT_ORDER_AIR
|
||||
priority = 20
|
||||
wait = 2 SECONDS // seconds (We probably can speed this up actually)
|
||||
flags = SS_BACKGROUND // TODO - Should this really be background? It might be important.
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
var/static/list/part_names = list("turfs", "edges", "fire zones", "hotspots", "zones")
|
||||
|
||||
var/cost_turfs = 0
|
||||
var/cost_edges = 0
|
||||
var/cost_firezones = 0
|
||||
var/cost_hotspots = 0
|
||||
var/cost_zones = 0
|
||||
|
||||
var/list/currentrun = null
|
||||
var/current_step = null
|
||||
|
||||
// Updating zone tiles requires temporary storage location of self-zone-blocked turfs across resumes. Used only by process_tiles_to_update.
|
||||
var/list/selfblock_deferred = null
|
||||
|
||||
/datum/controller/subsystem/air/PreInit()
|
||||
air_master = src
|
||||
|
||||
/datum/controller/subsystem/air/Initialize(timeofday)
|
||||
report_progress("Processing Geometry...")
|
||||
|
||||
current_cycle = 0
|
||||
var/simulated_turf_count = 0
|
||||
for(var/turf/simulated/S in world)
|
||||
simulated_turf_count++
|
||||
S.update_air_properties()
|
||||
CHECK_TICK
|
||||
|
||||
admin_notice({"<span class='danger'>Geometry initialized in [round(0.1*(REALTIMEOFDAY-timeofday),0.1)] seconds.</span>
|
||||
<span class='info'>
|
||||
Total Simulated Turfs: [simulated_turf_count]
|
||||
Total Zones: [zones.len]
|
||||
Total Edges: [edges.len]
|
||||
Total Active Edges: [active_edges.len ? "<span class='danger'>[active_edges.len]</span>" : "None"]
|
||||
Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_count]
|
||||
</span>"}, R_DEBUG)
|
||||
|
||||
// Note - Baystation settles the air by running for one tick. We prefer to not have active edges.
|
||||
// Maps should not have active edges on boot. If we've got some, log it so it can get fixed.
|
||||
if(active_edges.len)
|
||||
var/list/edge_log = list()
|
||||
for(var/connection_edge/E in active_edges)
|
||||
edge_log += "Active Edge [E] ([E.type])"
|
||||
for(var/turf/T in E.connecting_turfs)
|
||||
edge_log += "+--- Connecting Turf [T] @ [T.x], [T.y], [T.z]"
|
||||
log_debug("Active Edges on ZAS Startup\n" + edge_log.Join("\n"))
|
||||
|
||||
..()
|
||||
|
||||
/datum/controller/subsystem/air/fire(resumed = 0)
|
||||
var/timer
|
||||
if(!resumed)
|
||||
ASSERT(LAZYLEN(currentrun) == 0) // Santity checks to make sure we don't somehow have items left over from last cycle
|
||||
ASSERT(current_step == null) // Or somehow didn't finish all the steps from last cycle
|
||||
current_cycle++ // Begin a new air_master cycle!
|
||||
current_step = SSAIR_TURFS // Start with Step 1 of course
|
||||
|
||||
INTERNAL_PROCESS_STEP(SSAIR_TURFS, TRUE, process_tiles_to_update, cost_turfs, SSAIR_EDGES)
|
||||
INTERNAL_PROCESS_STEP(SSAIR_EDGES, FALSE, process_active_edges, cost_edges, SSAIR_FIREZONES)
|
||||
INTERNAL_PROCESS_STEP(SSAIR_FIREZONES, FALSE, process_active_fire_zones, cost_firezones, SSAIR_HOTSPOTS)
|
||||
INTERNAL_PROCESS_STEP(SSAIR_HOTSPOTS, FALSE, process_active_hotspots, cost_hotspots, SSAIR_ZONES)
|
||||
INTERNAL_PROCESS_STEP(SSAIR_ZONES, FALSE, process_zones_to_update, cost_zones, SSAIR_DONE)
|
||||
|
||||
// Okay, we're done! Woo! Got thru a whole air_master cycle!
|
||||
ASSERT(LAZYLEN(currentrun) == 0) // Sanity checks to make sure there are really none left
|
||||
ASSERT(current_step == SSAIR_DONE) // And that we didn't somehow skip past the last step
|
||||
currentrun = null
|
||||
current_step = null
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_tiles_to_update(resumed = 0)
|
||||
if (!resumed)
|
||||
// NOT a copy, because we are supposed to drain active turfs each cycle anyway, so just replace with empty list.
|
||||
// We still use a separate list tho, to ensure we don't process a turf twice during a single cycle!
|
||||
src.currentrun = tiles_to_update
|
||||
tiles_to_update = list()
|
||||
|
||||
//defer updating of self-zone-blocked turfs until after all other turfs have been updated.
|
||||
//this hopefully ensures that non-self-zone-blocked turfs adjacent to self-zone-blocked ones
|
||||
//have valid zones when the self-zone-blocked turfs update.
|
||||
//This ensures that doorways don't form their own single-turf zones, since doorways are self-zone-blocked and
|
||||
//can merge with an adjacent zone, whereas zones that are formed on adjacent turfs cannot merge with the doorway.
|
||||
ASSERT(src.selfblock_deferred == null) // Sanity check to make sure it was not remaining from last cycle somehow.
|
||||
src.selfblock_deferred = list()
|
||||
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
var/list/selfblock_deferred = src.selfblock_deferred
|
||||
|
||||
// Run thru the list, processing non-self-zone-blocked and deferring self-zone-blocked
|
||||
while(currentrun.len)
|
||||
var/turf/T = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
//check if the turf is self-zone-blocked
|
||||
if(T.c_airblock(T) & ZONE_BLOCKED)
|
||||
selfblock_deferred += T
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
else
|
||||
continue
|
||||
T.update_air_properties()
|
||||
T.post_update_air_properties()
|
||||
T.needs_air_update = 0
|
||||
#ifdef ZASDBG
|
||||
T.overlays -= mark
|
||||
#endif
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
ASSERT(LAZYLEN(currentrun) == 0)
|
||||
|
||||
// Run thru the deferred list and processing them
|
||||
while(selfblock_deferred.len)
|
||||
var/turf/T = selfblock_deferred[selfblock_deferred.len]
|
||||
selfblock_deferred.len--
|
||||
T.update_air_properties()
|
||||
T.post_update_air_properties()
|
||||
T.needs_air_update = 0
|
||||
#ifdef ZASDBG
|
||||
T.overlays -= mark
|
||||
#endif
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
ASSERT(LAZYLEN(selfblock_deferred) == 0)
|
||||
src.selfblock_deferred = null
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_active_edges(resumed = 0)
|
||||
if (!resumed)
|
||||
src.currentrun = active_edges.Copy()
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
while(currentrun.len)
|
||||
var/connection_edge/edge = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if(edge) // TODO - Do we need to check this? Old one didn't, but old one was single-threaded.
|
||||
edge.tick()
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_active_fire_zones(resumed = 0)
|
||||
if (!resumed)
|
||||
src.currentrun = active_fire_zones.Copy()
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
while(currentrun.len)
|
||||
var/zone/Z = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if(Z) // TODO - Do we need to check this? Old one didn't, but old one was single-threaded.
|
||||
Z.process_fire()
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_active_hotspots(resumed = 0)
|
||||
if (!resumed)
|
||||
src.currentrun = active_hotspots.Copy()
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
while(currentrun.len)
|
||||
var/obj/fire/fire = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if(fire) // TODO - Do we need to check this? Old one didn't, but old one was single-threaded.
|
||||
fire.process()
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_zones_to_update(resumed = 0)
|
||||
if (!resumed)
|
||||
active_zones = zones_to_update.len // Save how many zones there were to update this cycle (used by some debugging stuff)
|
||||
if(!zones_to_update.len)
|
||||
return // Nothing to do here this cycle!
|
||||
// NOT a copy, because we are supposed to drain active turfs each cycle anyway, so just replace with empty list.
|
||||
// Blanking the public list means we actually are removing processed ones from the list! Maybe we could we use zones_for_update directly?
|
||||
// But if we dom any zones added to zones_to_update DURING this step will get processed again during this step.
|
||||
// I don't know if that actually happens? But if it does, it could lead to an infinate loop. Better preserve original semantics.
|
||||
src.currentrun = zones_to_update
|
||||
zones_to_update = list()
|
||||
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
while(currentrun.len)
|
||||
var/zone/zone = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if(zone) // TODO - Do we need to check this? Old one didn't, but old one was single-threaded.
|
||||
zone.tick()
|
||||
zone.needs_update = 0
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/air/stat_entry(msg_prefix)
|
||||
var/list/msg = list(msg_prefix)
|
||||
msg += "S:[current_step ? part_names[current_step] : ""] "
|
||||
msg += "C:{"
|
||||
msg += "T [round(cost_turfs, 1)] | "
|
||||
msg += "E [round(cost_edges, 1)] | "
|
||||
msg += "F [round(cost_firezones, 1)] | "
|
||||
msg += "H [round(cost_hotspots, 1)] | "
|
||||
msg += "Z [round(cost_zones, 1)] "
|
||||
msg += "}"
|
||||
msg += "Z: [zones.len] "
|
||||
msg += "E: [edges.len] "
|
||||
msg += "Cycle: [current_cycle] {"
|
||||
msg += "T [tiles_to_update.len] | "
|
||||
msg += "E [active_edges.len] | "
|
||||
msg += "F [active_fire_zones.len] | "
|
||||
msg += "H [active_hotspots.len] | "
|
||||
msg += "Z [zones_to_update.len] "
|
||||
msg += "}"
|
||||
..(msg.Join())
|
||||
|
||||
// ZAS might displace objects as the map loads if an air tick is processed mid-load.
|
||||
/datum/controller/subsystem/air/StartLoadingMap(var/quiet = TRUE)
|
||||
can_fire = FALSE
|
||||
. = ..()
|
||||
|
||||
/datum/controller/subsystem/air/StopLoadingMap(var/quiet = TRUE)
|
||||
can_fire = TRUE
|
||||
. = ..()
|
||||
|
||||
// Reboot the air master. A bit hacky right now, but sometimes necessary still.
|
||||
/datum/controller/subsystem/air/proc/RebootZAS()
|
||||
can_fire = FALSE // Pause processing while we reboot
|
||||
// If we should happen to be in the middle of processing... wait until that finishes.
|
||||
if (state != SS_IDLE)
|
||||
report_progress("ZAS Rebuild initiated. Waiting for current air tick to complete before continuing.")
|
||||
while (state != SS_IDLE)
|
||||
stoplag()
|
||||
|
||||
// Invalidate all zones
|
||||
for(var/zone/zone in zones)
|
||||
zone.c_invalidate()
|
||||
|
||||
// Reset all the lists
|
||||
zones.Cut()
|
||||
edges.Cut()
|
||||
tiles_to_update.Cut()
|
||||
zones_to_update.Cut()
|
||||
active_fire_zones.Cut()
|
||||
active_hotspots.Cut()
|
||||
active_edges.Cut()
|
||||
|
||||
// Start it up again
|
||||
Initialize(REALTIMEOFDAY)
|
||||
|
||||
// Update next_fire so the MC doesn't try to make up for missed ticks.
|
||||
next_fire = world.time + wait
|
||||
can_fire = TRUE // Unpause
|
||||
|
||||
//
|
||||
// The procs from the ZAS Air Controller are in ZAS/Controller.dm
|
||||
//
|
||||
|
||||
#undef SSAIR_TURFS
|
||||
#undef SSAIR_EDGES
|
||||
#undef SSAIR_FIREZONES
|
||||
#undef SSAIR_HOTSPOTS
|
||||
#undef SSAIR_ZONES
|
||||
#undef SSAIR_DONE
|
||||
@@ -0,0 +1,163 @@
|
||||
#define CLEAR_OBJECT(TARGET) \
|
||||
processing -= TARGET; \
|
||||
TARGET.airflow_dest = null; \
|
||||
TARGET.airflow_speed = 0; \
|
||||
TARGET.airflow_time = 0; \
|
||||
TARGET.airflow_skip_speedcheck = FALSE; \
|
||||
if (TARGET.airflow_od) { \
|
||||
TARGET.density = 0; \
|
||||
}
|
||||
|
||||
// No point in making this a processing substem, it overrides fire() and handles its own processing list!
|
||||
SUBSYSTEM_DEF(airflow)
|
||||
name = "Airflow"
|
||||
wait = 2
|
||||
flags = SS_NO_INIT
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
priority = 15
|
||||
|
||||
var/list/processing = list()
|
||||
var/list/currentrun = list()
|
||||
|
||||
/datum/controller/subsystem/airflow/fire(resumed = FALSE)
|
||||
if (!resumed)
|
||||
currentrun = processing.Copy()
|
||||
|
||||
var/mywait = wait
|
||||
var/list/curr = currentrun // Cache for sanic speed
|
||||
while (curr.len)
|
||||
var/atom/movable/target = curr[curr.len]
|
||||
curr.len--
|
||||
if(QDELETED(target))
|
||||
processing -= target
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
|
||||
if (target.airflow_speed <= 0)
|
||||
CLEAR_OBJECT(target)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
|
||||
if (target.airflow_process_delay > 0)
|
||||
target.airflow_process_delay -= mywait
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
else if (target.airflow_process_delay)
|
||||
target.airflow_process_delay = 0
|
||||
|
||||
target.airflow_speed = min(target.airflow_speed, 15)
|
||||
target.airflow_speed -= vsc.airflow_speed_decay
|
||||
if (!target.airflow_skip_speedcheck)
|
||||
if (target.airflow_speed > 7)
|
||||
if (target.airflow_time++ >= target.airflow_speed - 7)
|
||||
if (target.airflow_od)
|
||||
target.density = 0
|
||||
target.airflow_skip_speedcheck = TRUE
|
||||
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
else
|
||||
if (target.airflow_od)
|
||||
target.density = 0
|
||||
target.airflow_process_delay = max(1, 10 - (target.airflow_speed + 3))
|
||||
target.airflow_skip_speedcheck = TRUE
|
||||
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
|
||||
target.airflow_skip_speedcheck = FALSE
|
||||
|
||||
if (target.airflow_od)
|
||||
target.density = 1
|
||||
|
||||
if (!target.airflow_dest || target.loc == target.airflow_dest)
|
||||
target.airflow_dest = locate(min(max(target.x + target.airflow_xo, 1), world.maxx), min(max(target.y + target.airflow_yo, 1), world.maxy), target.z)
|
||||
|
||||
if ((target.x == 1) || (target.x == world.maxx) || (target.y == 1) || (target.y == world.maxy))
|
||||
CLEAR_OBJECT(target)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
|
||||
if (!isturf(target.loc))
|
||||
CLEAR_OBJECT(target)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
|
||||
step_towards(target, target.airflow_dest)
|
||||
var/mob/M = target
|
||||
if (ismob(target) && M.client)
|
||||
M.setMoveCooldown(vsc.airflow_mob_slowdown)
|
||||
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
#undef CLEAR_OBJECT
|
||||
|
||||
/atom/movable
|
||||
var/tmp/airflow_xo
|
||||
var/tmp/airflow_yo
|
||||
var/tmp/airflow_od
|
||||
var/tmp/airflow_process_delay
|
||||
var/tmp/airflow_skip_speedcheck
|
||||
|
||||
/atom/movable/proc/prepare_airflow(n)
|
||||
if (!airflow_dest || airflow_speed < 0 || last_airflow > world.time - vsc.airflow_delay)
|
||||
return FALSE
|
||||
if (airflow_speed)
|
||||
airflow_speed = n / max(get_dist(src, airflow_dest), 1)
|
||||
return FALSE
|
||||
|
||||
if (airflow_dest == loc)
|
||||
step_away(src, loc)
|
||||
|
||||
if (!src.AirflowCanMove(n))
|
||||
return FALSE
|
||||
|
||||
if (ismob(src))
|
||||
to_chat(src,"<span class='danger'>You are pushed away by airflow!</span>")
|
||||
|
||||
last_airflow = world.time
|
||||
var/airflow_falloff = 9 - sqrt((x - airflow_dest.x) ** 2 + (y - airflow_dest.y) ** 2)
|
||||
|
||||
if (airflow_falloff < 1)
|
||||
airflow_dest = null
|
||||
return FALSE
|
||||
|
||||
airflow_speed = min(max(n * (9 / airflow_falloff), 1), 9)
|
||||
|
||||
airflow_od = 0
|
||||
|
||||
if (!density)
|
||||
density = 1
|
||||
airflow_od = 1
|
||||
|
||||
return TRUE
|
||||
|
||||
/atom/movable/proc/GotoAirflowDest(n)
|
||||
if (!prepare_airflow(n))
|
||||
return
|
||||
|
||||
airflow_xo = airflow_dest.x - src.x
|
||||
airflow_yo = airflow_dest.y - src.y
|
||||
|
||||
airflow_dest = null
|
||||
|
||||
SSairflow.processing += src
|
||||
|
||||
/atom/movable/proc/RepelAirflowDest(n)
|
||||
if (!prepare_airflow(n))
|
||||
return
|
||||
|
||||
airflow_xo = -(airflow_dest.x - src.x)
|
||||
airflow_yo = -(airflow_dest.y - src.y)
|
||||
|
||||
airflow_dest = null
|
||||
|
||||
SSairflow.processing += src
|
||||
@@ -169,7 +169,7 @@ SUBSYSTEM_DEF(garbage)
|
||||
#endif
|
||||
var/type = D.type
|
||||
var/datum/qdel_item/I = items[type]
|
||||
testing("GC: -- \ref[src] | [type] was unable to be GC'd --")
|
||||
testing("GC: -- \ref[D] | [type] was unable to be GC'd --")
|
||||
I.failures++
|
||||
if (GC_QUEUE_HARDDELETE)
|
||||
HardDelete(D)
|
||||
|
||||
@@ -19,6 +19,8 @@ SUBSYSTEM_DEF(mapping)
|
||||
// createRandomZlevel()
|
||||
// Mining generation probably should be here too
|
||||
// TODO - Other stuff related to maps and areas could be moved here too. Look at /tg
|
||||
if(using_map)
|
||||
loadLateMaps()
|
||||
..()
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/loadEngine()
|
||||
@@ -49,10 +51,38 @@ SUBSYSTEM_DEF(mapping)
|
||||
|
||||
// Annihilate movable atoms
|
||||
engine_loader.annihilate_bounds()
|
||||
CHECK_TICK
|
||||
//CHECK_TICK //Don't let anything else happen for now
|
||||
// Actually load it
|
||||
chosen_type.load(T)
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/loadLateMaps()
|
||||
var/list/deffo_load = using_map.lateload_z_levels
|
||||
var/list/maybe_load = using_map.lateload_single_pick
|
||||
|
||||
for(var/mapname in deffo_load)
|
||||
var/datum/map_template/MT = map_templates[mapname]
|
||||
if(!istype(MT))
|
||||
error("Lateload Z level \"[mapname]\" is not a valid map!")
|
||||
continue
|
||||
MT.load_new_z(centered = FALSE, dont_init = TRUE)
|
||||
//CHECK_TICK //Can't deal with this until SSAtoms
|
||||
|
||||
if(LAZYLEN(maybe_load))
|
||||
var/picked = pick(maybe_load)
|
||||
var/list/picklist
|
||||
|
||||
if(islist(picked)) //So you can have a 'chain' of z-levels that make up one away mission
|
||||
picklist = picked
|
||||
else
|
||||
picklist = list(picked)
|
||||
|
||||
for(var/map in picklist)
|
||||
var/datum/map_template/MT = map_templates[map]
|
||||
if(!istype(MT))
|
||||
error("Randompick Z level \"[map]\" is not a valid map!")
|
||||
else
|
||||
MT.load_new_z(centered = FALSE, dont_init = TRUE)
|
||||
|
||||
/datum/controller/subsystem/mapping/stat_entry(msg)
|
||||
if (!Debug2)
|
||||
return // Only show up in stat panel if debugging is enabled.
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
////////////////////////////////
|
||||
//// Paid Leave Subsystem
|
||||
//// For tracking how much department PTO time players have accured
|
||||
////////////////////////////////
|
||||
|
||||
SUBSYSTEM_DEF(persist)
|
||||
name = "Persist"
|
||||
priority = 20
|
||||
wait = 15 MINUTES
|
||||
flags = SS_BACKGROUND|SS_NO_INIT|SS_KEEP_TIMING
|
||||
runlevels = RUNLEVEL_GAME|RUNLEVEL_POSTGAME
|
||||
var/list/currentrun = list()
|
||||
|
||||
/datum/controller/subsystem/persist/fire(var/resumed = FALSE)
|
||||
update_department_hours(resumed)
|
||||
|
||||
// Do PTO Accruals
|
||||
/datum/controller/subsystem/persist/proc/update_department_hours(var/resumed = FALSE)
|
||||
if(!config.time_off)
|
||||
return
|
||||
|
||||
establish_db_connection()
|
||||
if(!dbcon.IsConnected())
|
||||
src.currentrun.Cut()
|
||||
return
|
||||
if(!resumed)
|
||||
src.currentrun = human_mob_list.Copy()
|
||||
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
while (currentrun.len)
|
||||
var/mob/M = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if (QDELETED(M) || !istype(M) || !M.mind || !M.client || TICKS2DS(M.client.inactivity) > wait)
|
||||
continue
|
||||
|
||||
// Try and detect job and department of mob
|
||||
var/datum/job/J = detect_job(M)
|
||||
if(!istype(J) || !J.department || !J.timeoff_factor)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
|
||||
// Update client whatever
|
||||
var/client/C = M.client
|
||||
var/wait_in_hours = (wait / (1 HOUR)) * J.timeoff_factor
|
||||
LAZYINITLIST(C.department_hours)
|
||||
var/dept_hours = C.department_hours
|
||||
if(isnum(C.department_hours[J.department]))
|
||||
dept_hours[J.department] += wait_in_hours
|
||||
else
|
||||
dept_hours[J.department] = wait_in_hours
|
||||
|
||||
//Cap it
|
||||
dept_hours[J.department] = min(config.pto_cap, dept_hours[J.department])
|
||||
|
||||
|
||||
// Okay we figured it out, lets update database!
|
||||
var/sql_ckey = sql_sanitize_text(C.ckey)
|
||||
var/sql_dpt = sql_sanitize_text(J.department)
|
||||
var/sql_bal = text2num("[C.department_hours[J.department]]")
|
||||
var/DBQuery/query = dbcon.NewQuery("INSERT INTO vr_player_hours (ckey, department, hours) VALUES ('[sql_ckey]', '[sql_dpt]', [sql_bal]) ON DUPLICATE KEY UPDATE hours = VALUES(hours)")
|
||||
query.Execute()
|
||||
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
// This proc tries to find the job datum of an arbitrary mob.
|
||||
/datum/controller/subsystem/persist/proc/detect_job(var/mob/M)
|
||||
// Records are usually the most reliable way to get what job someone is.
|
||||
var/datum/data/record/R = find_general_record("name", M.real_name)
|
||||
if(R) // We found someone with a record.
|
||||
var/recorded_rank = R.fields["real_rank"]
|
||||
if(recorded_rank)
|
||||
. = job_master.GetJob(recorded_rank)
|
||||
if(.) return
|
||||
|
||||
// They have a custom title, aren't crew, or someone deleted their record, so we need a fallback method.
|
||||
// Let's check the mind.
|
||||
if(M.mind && M.mind.assigned_role)
|
||||
. = job_master.GetJob(M.mind.assigned_role)
|
||||
+1
-1
@@ -499,7 +499,7 @@
|
||||
//HUMAN
|
||||
/mob/living/carbon/human/mind_initialize()
|
||||
..()
|
||||
if(!mind.assigned_role) mind.assigned_role = "Assistant" //defualt
|
||||
if(!mind.assigned_role) mind.assigned_role = USELESS_JOB //defualt //VOREStation Edit - Visitor not Assistant
|
||||
|
||||
//slime
|
||||
/mob/living/simple_animal/slime/mind_initialize()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/decl/hierarchy/outfit/job/assistant
|
||||
name = OUTFIT_JOB_NAME("Assistant")
|
||||
name = OUTFIT_JOB_NAME(USELESS_JOB) //VOREStation Edit - Visitor not Assistant
|
||||
id_type = /obj/item/weapon/card/id/assistant
|
||||
|
||||
/decl/hierarchy/outfit/job/assistant/visitor
|
||||
@@ -11,7 +11,11 @@
|
||||
name = OUTFIT_JOB_NAME("Resident")
|
||||
id_pda_assignment = "Resident"
|
||||
uniform = /obj/item/clothing/under/color/white
|
||||
|
||||
//VOREStation Add - Interns
|
||||
/decl/hierarchy/outfit/job/assistant/intern
|
||||
name = OUTFIT_JOB_NAME("Intern")
|
||||
id_type = /obj/item/weapon/card/id/civilian
|
||||
//VOREStation Add End - Interns
|
||||
/decl/hierarchy/outfit/job/service
|
||||
l_ear = /obj/item/device/radio/headset/headset_service
|
||||
hierarchy_type = /decl/hierarchy/outfit/job/service
|
||||
|
||||
@@ -11,4 +11,24 @@
|
||||
cost = 50
|
||||
containertype = /obj/structure/closet/crate/secure/gear
|
||||
containername = "Belt-miner gear crate"
|
||||
access = access_mining
|
||||
|
||||
/datum/supply_packs/misc/eva_rig
|
||||
name = "eva hardsuit (empty)"
|
||||
contains = list(
|
||||
/obj/item/weapon/rig/eva = 1
|
||||
)
|
||||
cost = 150
|
||||
containertype = /obj/structure/closet/crate/secure/gear
|
||||
containername = "eva hardsuit crate"
|
||||
access = access_mining
|
||||
|
||||
/datum/supply_packs/misc/mining_rig
|
||||
name = "industrial hardsuit (empty)"
|
||||
contains = list(
|
||||
/obj/item/weapon/rig/industrial = 1
|
||||
)
|
||||
cost = 150
|
||||
containertype = /obj/structure/closet/crate/secure/gear
|
||||
containername = "industrial hardsuit crate"
|
||||
access = access_mining
|
||||
@@ -20,7 +20,8 @@
|
||||
/obj/item/clothing/suit/straight_jacket,
|
||||
/obj/item/weapon/handcuffs/legcuffs,
|
||||
/obj/item/weapon/melee/fluff/holochain/mass,
|
||||
/obj/item/weapon/material/twohanded/fluff/riding_crop
|
||||
/obj/item/weapon/material/twohanded/fluff/riding_crop,
|
||||
/obj/item/clothing/under/fluff/latexmaid
|
||||
)
|
||||
containertype = /obj/structure/closet/crate
|
||||
containername = "Restraints crate"
|
||||
|
||||
@@ -66,3 +66,10 @@
|
||||
containertype = /obj/structure/largecrate/animal/otie
|
||||
containername = "VARMAcorp adoptable reject (Dangerous!)"
|
||||
access = access_xenobiology
|
||||
|
||||
/datum/supply_packs/sci/phoronotie
|
||||
name = "VARMAcorp adaptive beta subject (Experimental)"
|
||||
cost = 200
|
||||
containertype = /obj/structure/largecrate/animal/otie/phoron
|
||||
containername = "VARMAcorp adaptive beta subject (Experimental)"
|
||||
access = access_xenobiology
|
||||
@@ -7,6 +7,15 @@
|
||||
access_security,
|
||||
access_xenobiology)
|
||||
|
||||
/datum/supply_packs/security/guardmutant
|
||||
name = "VARMAcorp autoNOMous security solution for hostile environments"
|
||||
cost = 250
|
||||
containertype = /obj/structure/largecrate/animal/guardmutant
|
||||
containername = "VARMAcorp autoNOMous security phoron-proof solution crate"
|
||||
access = list(
|
||||
access_security,
|
||||
access_xenobiology)
|
||||
|
||||
/datum/supply_packs/security/biosuit
|
||||
contains = list(
|
||||
/obj/item/clothing/head/bio_hood/security = 3,
|
||||
|
||||
@@ -137,6 +137,18 @@ var/global/list/PDA_Manifest = list()
|
||||
if(!department && !(name in heads))
|
||||
misc[++misc.len] = list("name" = name, "rank" = rank, "active" = isactive)
|
||||
|
||||
// Synthetics don't have actual records, so we will pull them from here.
|
||||
// Synths don't have records, which is the means by which isactive is retrieved, so I'm hardcoding it to active, don't really have any better means
|
||||
for(var/mob/living/silicon/ai/ai in mob_list)
|
||||
bot[++bot.len] = list("name" = ai.real_name, "rank" = "Artificial Intelligence", "active" = "Active")
|
||||
|
||||
for(var/mob/living/silicon/robot/robot in mob_list)
|
||||
// No combat/syndicate cyborgs, no drones.
|
||||
if(robot.module && robot.module.hide_on_manifest)
|
||||
continue
|
||||
|
||||
bot[++bot.len] = list("name" = robot.real_name, "rank" = "[robot.modtype] [robot.braintype]", "active" = "Active")
|
||||
|
||||
|
||||
PDA_Manifest = list(
|
||||
list("cat" = "Command", "elems" = heads),
|
||||
|
||||
@@ -1646,7 +1646,6 @@ area/space/atmosalert()
|
||||
requires_power = 1
|
||||
always_unpowered = 1
|
||||
dynamic_lighting = 0
|
||||
base_turf = /turf/space
|
||||
|
||||
auxport
|
||||
name = "\improper Fore Port Solar Array"
|
||||
|
||||
@@ -322,3 +322,9 @@ var/list/mob/living/forced_ambiance_list = new
|
||||
if(A && A.has_gravity())
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/area/proc/shuttle_arrived()
|
||||
return TRUE
|
||||
|
||||
/area/proc/shuttle_departed()
|
||||
return TRUE
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
/obj/machinery/dna_scannernew/attackby(var/obj/item/weapon/item as obj, var/mob/user as mob)
|
||||
if(istype(item, /obj/item/weapon/reagent_containers/glass))
|
||||
if(beaker)
|
||||
user << "<span class='warning'>A beaker is already loaded into the machine.</span>"
|
||||
to_chat(user, "<span class='warning'>A beaker is already loaded into the machine.</span>")
|
||||
return
|
||||
|
||||
beaker = item
|
||||
@@ -134,16 +134,32 @@
|
||||
item.loc = src
|
||||
user.visible_message("\The [user] adds \a [item] to \the [src]!", "You add \a [item] to \the [src]!")
|
||||
return
|
||||
|
||||
else if(istype(item, /obj/item/organ/internal/brain))
|
||||
if (src.occupant)
|
||||
to_chat(user, "<span class='warning'>The scanner is already occupied!</span>")
|
||||
return
|
||||
var/obj/item/organ/internal/brain/brain = item
|
||||
if(brain.clone_source)
|
||||
user.drop_item()
|
||||
brain.loc = src
|
||||
put_in(brain.brainmob)
|
||||
src.add_fingerprint(user)
|
||||
user.visible_message("\The [user] adds \a [item] to \the [src]!", "You add \a [item] to \the [src]!")
|
||||
return
|
||||
else
|
||||
to_chat(user,"\The [brain] is not acceptable for genetic sampling!")
|
||||
|
||||
else if (!istype(item, /obj/item/weapon/grab))
|
||||
return
|
||||
var/obj/item/weapon/grab/G = item
|
||||
if (!ismob(G.affecting))
|
||||
return
|
||||
if (src.occupant)
|
||||
user << "<span class='warning'>The scanner is already occupied!</span>"
|
||||
to_chat(user, "<span class='warning'>The scanner is already occupied!</span>")
|
||||
return
|
||||
if (G.affecting.abiotic())
|
||||
user << "<span class='warning'>The subject cannot have abiotic items on.</span>"
|
||||
to_chat(user, "<span class='warning'>The subject cannot have abiotic items on.</span>")
|
||||
return
|
||||
put_in(G.affecting)
|
||||
src.add_fingerprint(user)
|
||||
@@ -167,7 +183,7 @@
|
||||
if(!M.client && M.mind)
|
||||
for(var/mob/observer/dead/ghost in player_list)
|
||||
if(ghost.mind == M.mind)
|
||||
ghost << "<b><font color = #330033><font size = 3>Your corpse has been placed into a cloning scanner. Return to your body if you want to be resurrected/cloned!</b> (Verbs -> Ghost -> Re-enter corpse)</font></font>"
|
||||
to_chat(ghost, "<b><font color = #330033><font size = 3>Your corpse has been placed into a cloning scanner. Return to your body if you want to be resurrected/cloned!</b> (Verbs -> Ghost -> Re-enter corpse)</font></font>")
|
||||
break
|
||||
return
|
||||
|
||||
@@ -177,7 +193,14 @@
|
||||
if (src.occupant.client)
|
||||
src.occupant.client.eye = src.occupant.client.mob
|
||||
src.occupant.client.perspective = MOB_PERSPECTIVE
|
||||
src.occupant.loc = src.loc
|
||||
if(istype(occupant,/mob/living/carbon/brain))
|
||||
for(var/obj/O in src)
|
||||
if(istype(O,/obj/item/organ/internal/brain))
|
||||
O.loc = get_turf(src)
|
||||
src.occupant.loc = O
|
||||
break
|
||||
else
|
||||
src.occupant.loc = src.loc
|
||||
src.occupant = null
|
||||
src.icon_state = "scanner_0"
|
||||
return
|
||||
|
||||
@@ -149,7 +149,7 @@ datum/objective/anti_revolution/demote
|
||||
|
||||
if(!istype(I)) return 1
|
||||
|
||||
if(I.assignment == "Assistant")
|
||||
if(I.assignment == USELESS_JOB) //VOREStation Edit - Visitor not Assistant
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
@@ -1,23 +1,50 @@
|
||||
//VOREStation Edit - Basically this whole file
|
||||
/datum/job/intern
|
||||
title = "Intern"
|
||||
flag = INTERN
|
||||
department = "Civilian"
|
||||
department_flag = ENGSEC // VOREStation Edit - Ran out of bits
|
||||
faction = "Station"
|
||||
total_positions = -1
|
||||
spawn_positions = -1
|
||||
supervisors = "the staff from the departmen you're interning in"
|
||||
selection_color = "#555555"
|
||||
economic_modifier = 2
|
||||
access = list() //See /datum/job/assistant/get_access()
|
||||
minimal_access = list() //See /datum/job/assistant/get_access()
|
||||
outfit_type = /decl/hierarchy/outfit/job/assistant/intern
|
||||
alt_titles = list("Apprentice Engineer","Medical Intern","Lab Assistant","Security Cadet","Jr. Cargo Tech") //VOREStation Edit
|
||||
//VOREStation Add
|
||||
/datum/job/intern/New()
|
||||
..()
|
||||
if(config)
|
||||
total_positions = config.limit_interns
|
||||
spawn_positions = config.limit_interns
|
||||
//VOREStation Add End
|
||||
|
||||
// VOREStation Add
|
||||
/datum/job/assistant
|
||||
title = "Assistant"
|
||||
title = USELESS_JOB
|
||||
flag = ASSISTANT
|
||||
department = "Civilian"
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
total_positions = -1
|
||||
spawn_positions = -1
|
||||
supervisors = "absolutely everyone"
|
||||
supervisors = "nobody! You don't work here"
|
||||
selection_color = "#515151"
|
||||
economic_modifier = 1
|
||||
access = list() //See /datum/job/assistant/get_access()
|
||||
minimal_access = list() //See /datum/job/assistant/get_access()
|
||||
access = list()
|
||||
minimal_access = list()
|
||||
outfit_type = /decl/hierarchy/outfit/job/assistant
|
||||
alt_titles = list("Technical Assistant","Test Subject","Medical Intern","Research Assistant",
|
||||
"Visitor" = /decl/hierarchy/outfit/job/assistant/visitor,
|
||||
"Resident" = /decl/hierarchy/outfit/job/assistant/resident) //Test Subject is a VOREStation edit
|
||||
|
||||
/datum/job/assistant/New()
|
||||
..()
|
||||
if(config)
|
||||
total_positions = config.limit_visitors
|
||||
spawn_positions = config.limit_visitors
|
||||
/datum/job/assistant/get_access()
|
||||
if(config.assistant_maint)
|
||||
return list(access_maint_tunnels)
|
||||
else
|
||||
return list()
|
||||
//VOREStation Add End
|
||||
|
||||
@@ -36,7 +36,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
|
||||
/datum/job/hop
|
||||
title = "Head of Personnel"
|
||||
flag = HOP
|
||||
department = "Civilian"
|
||||
department = "Command"
|
||||
head_position = 1
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
@@ -71,7 +71,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
|
||||
/datum/job/secretary
|
||||
title = "Command Secretary"
|
||||
flag = BRIDGE
|
||||
department = "Civilian"
|
||||
department = "Command"
|
||||
head_position = 1
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
@@ -83,8 +83,8 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
|
||||
minimal_player_age = 5
|
||||
economic_modifier = 7
|
||||
|
||||
access = list(access_heads)
|
||||
minimal_access = list(access_heads)
|
||||
access = list(access_heads, access_keycard_auth)
|
||||
minimal_access = list(access_heads, access_keycard_auth)
|
||||
|
||||
outfit_type = /decl/hierarchy/outfit/job/secretary
|
||||
alt_titles = list("Command Liaison", "Bridge Secretary")
|
||||
alt_titles = list("Command Liaison", "Bridge Secretary")
|
||||
|
||||
@@ -56,12 +56,13 @@
|
||||
title = "Quartermaster"
|
||||
flag = QUARTERMASTER
|
||||
department = "Cargo"
|
||||
head_position = 1
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
total_positions = 1
|
||||
spawn_positions = 1
|
||||
supervisors = "the head of personnel"
|
||||
selection_color = "#515151"
|
||||
selection_color = "#7a4f33"
|
||||
idtype = /obj/item/weapon/card/id/cargo/head
|
||||
economic_modifier = 5
|
||||
access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_qm, access_mining, access_mining_station)
|
||||
@@ -81,7 +82,7 @@
|
||||
total_positions = 2
|
||||
spawn_positions = 2
|
||||
supervisors = "the quartermaster and the head of personnel"
|
||||
selection_color = "#515151"
|
||||
selection_color = "#9b633e"
|
||||
idtype = /obj/item/weapon/card/id/cargo/cargo_tech
|
||||
access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_mining, access_mining_station)
|
||||
minimal_access = list(access_maint_tunnels, access_cargo, access_cargo_bot, access_mailsorting)
|
||||
@@ -97,7 +98,7 @@
|
||||
total_positions = 3
|
||||
spawn_positions = 3
|
||||
supervisors = "the quartermaster and the head of personnel"
|
||||
selection_color = "#515151"
|
||||
selection_color = "#9b633e"
|
||||
idtype = /obj/item/weapon/card/id/cargo/mining
|
||||
economic_modifier = 5
|
||||
access = list(access_maint_tunnels, access_mailsorting, access_cargo, access_cargo_bot, access_mining, access_mining_station)
|
||||
|
||||
@@ -3,4 +3,11 @@
|
||||
var/whitelist_only = 0
|
||||
|
||||
//Does not display this job on the occupation setup screen
|
||||
var/latejoin_only = 0
|
||||
var/latejoin_only = 0
|
||||
|
||||
//Every hour playing this role gains this much time off. (Can be negative for off duty jobs!)
|
||||
var/timeoff_factor = 3
|
||||
|
||||
// Check client-specific availability rules.
|
||||
/datum/job/proc/player_has_enough_pto(client/C)
|
||||
return timeoff_factor >= 0 || (C && LAZYACCESS(C.department_hours, department) > 0)
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
//
|
||||
// "Off-duty" jobs are for people who want to do nothing and have earned it.
|
||||
//
|
||||
|
||||
/datum/job/offduty_civilian
|
||||
title = "Off-Duty Worker"
|
||||
latejoin_only = TRUE
|
||||
timeoff_factor = -1
|
||||
total_positions = -1
|
||||
faction = "Station"
|
||||
department = "Civilian"
|
||||
supervisors = "nobody! Enjoy your time off"
|
||||
selection_color = "#9b633e"
|
||||
access = list(access_maint_tunnels)
|
||||
minimal_access = list(access_maint_tunnels)
|
||||
outfit_type = /decl/hierarchy/outfit/job/assistant
|
||||
|
||||
/datum/job/offduty_cargo
|
||||
title = "Off-duty Cargo"
|
||||
latejoin_only = TRUE
|
||||
timeoff_factor = -1
|
||||
total_positions = -1
|
||||
faction = "Station"
|
||||
department = "Cargo"
|
||||
supervisors = "nobody! Enjoy your time off"
|
||||
selection_color = "#9b633e"
|
||||
access = list(access_maint_tunnels)
|
||||
minimal_access = list(access_maint_tunnels)
|
||||
outfit_type = /decl/hierarchy/outfit/job/assistant
|
||||
|
||||
/datum/job/offduty_engineering
|
||||
title = "Off-duty Engineer"
|
||||
latejoin_only = TRUE
|
||||
timeoff_factor = -1
|
||||
total_positions = -1
|
||||
faction = "Station"
|
||||
department = "Engineering"
|
||||
supervisors = "nobody! Enjoy your time off"
|
||||
selection_color = "#5B4D20"
|
||||
access = list(access_maint_tunnels, access_external_airlocks, access_construction)
|
||||
minimal_access = list(access_maint_tunnels, access_external_airlocks)
|
||||
outfit_type = /decl/hierarchy/outfit/job/assistant
|
||||
|
||||
/datum/job/offduty_medical
|
||||
title = "Off-duty Medic"
|
||||
latejoin_only = TRUE
|
||||
timeoff_factor = -1
|
||||
total_positions = -1
|
||||
faction = "Station"
|
||||
department = "Medical"
|
||||
supervisors = "nobody! Enjoy your time off"
|
||||
selection_color = "#013D3B"
|
||||
access = list(access_maint_tunnels, access_external_airlocks)
|
||||
minimal_access = list(access_maint_tunnels, access_external_airlocks)
|
||||
outfit_type = /decl/hierarchy/outfit/job/assistant
|
||||
|
||||
/datum/job/offduty_science
|
||||
title = "Off-duty Scientist"
|
||||
latejoin_only = TRUE
|
||||
timeoff_factor = -1
|
||||
total_positions = -1
|
||||
faction = "Station"
|
||||
department = "Science"
|
||||
supervisors = "nobody! Enjoy your time off"
|
||||
selection_color = "#633D63"
|
||||
access = list(access_maint_tunnels)
|
||||
minimal_access = list(access_maint_tunnels)
|
||||
outfit_type = /decl/hierarchy/outfit/job/assistant
|
||||
|
||||
/datum/job/offduty_security
|
||||
title = "Off-duty Officer"
|
||||
latejoin_only = TRUE
|
||||
timeoff_factor = -1
|
||||
total_positions = -1
|
||||
faction = "Station"
|
||||
department = "Security"
|
||||
supervisors = "nobody! Enjoy your time off"
|
||||
selection_color = "#601C1C"
|
||||
access = list(access_maint_tunnels)
|
||||
minimal_access = list(access_maint_tunnels)
|
||||
outfit_type = /decl/hierarchy/outfit/job/assistant
|
||||
@@ -1,194 +0,0 @@
|
||||
//These are a copy of Polaris' Southern Cross jobs
|
||||
|
||||
var/const/access_pilot = 67
|
||||
var/const/access_explorer = 43
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/access/pilot
|
||||
id = access_pilot
|
||||
desc = "Pilot"
|
||||
region = ACCESS_REGION_SUPPLY
|
||||
|
||||
/datum/access/explorer
|
||||
id = access_explorer
|
||||
desc = "Explorer"
|
||||
region = ACCESS_REGION_GENERAL
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
/obj/item/weapon/card/id/medical/sar
|
||||
assignment = "Search and Rescue"
|
||||
rank = "Search and Rescue"
|
||||
job_access_type = /datum/job/sar
|
||||
|
||||
/obj/item/weapon/card/id/civilian/pilot
|
||||
assignment = "Pilot"
|
||||
rank = "Pilot"
|
||||
job_access_type = /datum/job/pilot
|
||||
|
||||
/obj/item/weapon/card/id/civilian/explorer
|
||||
assignment = "Explorer"
|
||||
rank = "Explorer"
|
||||
job_access_type = /datum/job/explorer
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/job/pilot
|
||||
title = "Pilot"
|
||||
flag = PILOT
|
||||
department = "Civilian"
|
||||
department_flag = MEDSCI
|
||||
faction = "Station"
|
||||
total_positions = 2
|
||||
spawn_positions = 2
|
||||
supervisors = "the head of personnel"
|
||||
selection_color = "#515151"
|
||||
idtype = /obj/item/weapon/card/id/civilian/pilot
|
||||
economic_modifier = 4
|
||||
whitelist_only = 1
|
||||
latejoin_only = 1
|
||||
access = list(access_pilot, access_cargo, access_mining, access_mining_station)
|
||||
minimal_access = list(access_pilot, access_cargo, access_mining, access_mining_station)
|
||||
outfit_type = /decl/hierarchy/outfit/job/pilot
|
||||
|
||||
/datum/job/explorer
|
||||
title = "Explorer"
|
||||
flag = EXPLORER
|
||||
department = "Science"
|
||||
department_flag = MEDSCI
|
||||
faction = "Station"
|
||||
total_positions = 4
|
||||
spawn_positions = 4
|
||||
supervisors = "the explorer leader and the head of personnel"
|
||||
selection_color = "#515151"
|
||||
idtype = /obj/item/weapon/card/id/civilian/explorer
|
||||
economic_modifier = 4
|
||||
whitelist_only = 1
|
||||
latejoin_only = 1
|
||||
access = list(access_pilot, access_explorer)
|
||||
minimal_access = list(access_pilot, access_explorer)
|
||||
outfit_type = /decl/hierarchy/outfit/job/explorer2
|
||||
/* I split this into multiple jobs because it's set to latejoin_only, which means you can't see it to select alt titles.
|
||||
alt_titles = list(
|
||||
"Explorer Technician" = /decl/hierarchy/outfit/job/explorer2/technician,
|
||||
"Explorer Medic" = /decl/hierarchy/outfit/job/explorer2/medic)
|
||||
*/
|
||||
|
||||
/datum/job/explorer/technician
|
||||
title = "Explorer Technician"
|
||||
flag = EXPLORER_T
|
||||
outfit_type = /decl/hierarchy/outfit/job/explorer2/technician
|
||||
|
||||
/datum/job/explorer/medic
|
||||
title = "Explorer Medic"
|
||||
flag = EXPLORER_M
|
||||
outfit_type = /decl/hierarchy/outfit/job/explorer2/medic
|
||||
|
||||
/datum/job/sar
|
||||
title = "Search and Rescue"
|
||||
flag = SAR
|
||||
department = "Medical"
|
||||
department_flag = MEDSCI
|
||||
faction = "Station"
|
||||
total_positions = 2
|
||||
spawn_positions = 2
|
||||
supervisors = "the chief medical officer"
|
||||
selection_color = "#515151"
|
||||
idtype = /obj/item/weapon/card/id/medical
|
||||
economic_modifier = 4
|
||||
whitelist_only = 1
|
||||
latejoin_only = 1
|
||||
access = list(access_medical, access_medical_equip, access_morgue, access_surgery, access_chemistry, access_virology, access_eva, access_maint_tunnels, access_external_airlocks, access_psychiatrist, access_explorer)
|
||||
minimal_access = list(access_medical, access_medical_equip, access_morgue, access_explorer)
|
||||
outfit_type = /decl/hierarchy/outfit/job/medical/sar
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
/decl/hierarchy/outfit/job/explorer2
|
||||
name = OUTFIT_JOB_NAME("Explorer")
|
||||
shoes = /obj/item/clothing/shoes/boots/winter/explorer
|
||||
uniform = /obj/item/clothing/under/explorer
|
||||
l_ear = /obj/item/device/radio/headset/explorer
|
||||
id_slot = slot_wear_id
|
||||
pda_slot = slot_l_store
|
||||
pda_type = /obj/item/device/pda/cargo // Brown looks more rugged
|
||||
id_type = /obj/item/weapon/card/id/civilian/explorer
|
||||
id_pda_assignment = "Explorer"
|
||||
|
||||
/decl/hierarchy/outfit/job/explorer2/technician
|
||||
name = OUTFIT_JOB_NAME("Explorer Technician")
|
||||
belt = /obj/item/weapon/storage/belt/utility/full
|
||||
pda_slot = slot_l_store
|
||||
id_pda_assignment = "Explorer Technician"
|
||||
|
||||
/decl/hierarchy/outfit/job/explorer2/medic
|
||||
name = OUTFIT_JOB_NAME("Explorer Medic")
|
||||
l_hand = /obj/item/weapon/storage/firstaid/regular
|
||||
pda_slot = slot_l_store
|
||||
id_pda_assignment = "Explorer Medic"
|
||||
|
||||
/decl/hierarchy/outfit/job/pilot
|
||||
name = OUTFIT_JOB_NAME("Pilot")
|
||||
shoes = /obj/item/clothing/shoes/black
|
||||
uniform = /obj/item/clothing/under/color/black
|
||||
suit = /obj/item/clothing/suit/storage/toggle/bomber
|
||||
gloves = /obj/item/clothing/gloves/fingerless
|
||||
glasses = /obj/item/clothing/glasses/fakesunglasses/aviator
|
||||
l_ear = /obj/item/device/radio/headset/pilot
|
||||
id_slot = slot_wear_id
|
||||
pda_slot = slot_belt
|
||||
pda_type = /obj/item/device/pda/cargo // Brown looks more rugged
|
||||
id_type = /obj/item/weapon/card/id/civilian/pilot
|
||||
id_pda_assignment = "Pilot"
|
||||
|
||||
/decl/hierarchy/outfit/job/medical/sar
|
||||
name = OUTFIT_JOB_NAME("Search and Rescue")
|
||||
uniform = /obj/item/clothing/under/utility/blue
|
||||
suit = /obj/item/clothing/suit/storage/hooded/wintercoat/medical/sar
|
||||
shoes = /obj/item/clothing/shoes/boots/winter/explorer
|
||||
l_hand = /obj/item/weapon/storage/firstaid/adv
|
||||
belt = /obj/item/weapon/storage/belt/medical/emt
|
||||
pda_slot = slot_l_store
|
||||
id_type = /obj/item/weapon/card/id/medical/sar
|
||||
id_pda_assignment = "Search and Rescue"
|
||||
flags = OUTFIT_HAS_BACKPACK|OUTFIT_EXTENDED_SURVIVAL
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
/obj/item/device/encryptionkey/pilot
|
||||
name = "pilot's encryption key"
|
||||
icon_state = "com_cypherkey"
|
||||
channels = list("Supply" = 1, "Explorer" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/explorer
|
||||
name = "explorer radio encryption key"
|
||||
icon_state = "com_cypherkey"
|
||||
channels = list("Explorer" = 1)
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
/obj/item/device/radio/headset/pilot
|
||||
name = "pilot's headset"
|
||||
desc = "A bowman headset used by pilots, has access to supply and explorer channels."
|
||||
icon_state = "cargo_headset_alt"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/device/encryptionkey/pilot
|
||||
|
||||
/obj/item/device/radio/headset/explorer
|
||||
name = "explorer's headset"
|
||||
desc = "Headset used by explorers for exploring. Access to the explorer channel."
|
||||
icon_state = "mine_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/device/encryptionkey/explorer
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
/obj/item/clothing/suit/storage/hooded/wintercoat/medical/sar
|
||||
name = "search and rescue winter coat"
|
||||
desc = "A heavy winter jacket. A white star of life is emblazoned on the back, with the words search and rescue written underneath."
|
||||
icon_state = "coatsar"
|
||||
item_icons = list(slot_wear_suit_str = 'maps/southern_cross/icons/mob/sc_suit.dmi')
|
||||
icon = 'maps/southern_cross/icons/obj/sc_suit.dmi'
|
||||
armor = list(melee = 15, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 50, rad = 5)
|
||||
valid_accessory_slots = list(ACCESSORY_SLOT_INSIGNIA)
|
||||
@@ -25,6 +25,7 @@ var/global/datum/controller/occupations/job_master
|
||||
if(!job) continue
|
||||
if(job.faction != faction) continue
|
||||
occupations += job
|
||||
sortTim(occupations, /proc/cmp_job_datums)
|
||||
|
||||
|
||||
return 1
|
||||
@@ -116,7 +117,7 @@ var/global/datum/controller/occupations/job_master
|
||||
if(job.minimum_character_age && (player.client.prefs.age < job.minimum_character_age))
|
||||
continue
|
||||
|
||||
if(istype(job, GetJob("Assistant"))) // We don't want to give him assistant, that's boring!
|
||||
if(istype(job, GetJob(USELESS_JOB))) // We don't want to give him assistant, that's boring! //VOREStation Edit - Visitor not Assistant
|
||||
continue
|
||||
|
||||
if(job.title in command_positions) //If you want a command position, select it!
|
||||
@@ -241,7 +242,7 @@ var/global/datum/controller/occupations/job_master
|
||||
Debug("AC1, Candidates: [assistant_candidates.len]")
|
||||
for(var/mob/new_player/player in assistant_candidates)
|
||||
Debug("AC1 pass, Player: [player]")
|
||||
AssignRole(player, "Assistant")
|
||||
AssignRole(player, USELESS_JOB) //VOREStation Edit - Visitor not Assistant
|
||||
assistant_candidates -= player
|
||||
Debug("DO, AC1 end")
|
||||
|
||||
@@ -322,7 +323,7 @@ var/global/datum/controller/occupations/job_master
|
||||
for(var/mob/new_player/player in unassigned)
|
||||
if(player.client.prefs.alternate_option == BE_ASSISTANT)
|
||||
Debug("AC2 Assistant located, Player: [player]")
|
||||
AssignRole(player, "Assistant")
|
||||
AssignRole(player, USELESS_JOB) //VOREStation Edit - Visitor not Assistant
|
||||
|
||||
//For ones returning to lobby
|
||||
for(var/mob/new_player/player in unassigned)
|
||||
@@ -480,10 +481,9 @@ var/global/datum/controller/occupations/job_master
|
||||
R = locate() in S.contents
|
||||
if(!l_foot || !r_foot || R)
|
||||
var/obj/structure/bed/chair/wheelchair/W = new /obj/structure/bed/chair/wheelchair(H.loc)
|
||||
H.buckled = W
|
||||
W.buckle_mob(H)
|
||||
H.update_canmove()
|
||||
W.set_dir(H.dir)
|
||||
W.buckled_mobs |= H
|
||||
W.add_fingerprint(H)
|
||||
if(R)
|
||||
W.color = R.color
|
||||
|
||||
@@ -11,7 +11,7 @@ var/const/ENGINEER =(1<<6)
|
||||
var/const/ATMOSTECH =(1<<7)
|
||||
var/const/AI =(1<<8)
|
||||
var/const/CYBORG =(1<<9)
|
||||
|
||||
var/const/INTERN =(1<<15) //VOREStation Add
|
||||
|
||||
var/const/MEDSCI =(1<<1)
|
||||
|
||||
@@ -26,11 +26,6 @@ var/const/PSYCHIATRIST =(1<<7)
|
||||
var/const/ROBOTICIST =(1<<8)
|
||||
var/const/XENOBIOLOGIST =(1<<9)
|
||||
var/const/PARAMEDIC =(1<<10)
|
||||
var/const/SAR =(1<<11) //VOREStation THEFT
|
||||
var/const/PILOT =(1<<12) //VOREStation THEFT
|
||||
var/const/EXPLORER =(1<<13) //VOREStation THEFT
|
||||
var/const/EXPLORER_T =(1<<14) //VOREStation THEFT
|
||||
var/const/EXPLORER_M =(1<<15) //VOREStation THEFT
|
||||
|
||||
var/const/CIVILIAN =(1<<2)
|
||||
|
||||
@@ -109,7 +104,8 @@ var/list/civilian_positions = list(
|
||||
"Lawyer",
|
||||
"Chaplain",
|
||||
"Pilot", // VOREStation Edit - Moved Pilot from planetary -> civ
|
||||
"Assistant"
|
||||
USELESS_JOB, //VOREStation Edit - Visitor not Assistant
|
||||
"Intern" //VOREStation Edit - Intern
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ var/list/job_whitelist = list()
|
||||
var/datum/job/job = job_master.GetJob(rank)
|
||||
if(!job.whitelist_only)
|
||||
return 1
|
||||
if(rank == "assistant" || rank == "Assistant")
|
||||
if(rank == USELESS_JOB) //VOREStation Edit - Visitor not Assistant
|
||||
return 1
|
||||
if(check_rights(R_ADMIN, 0))
|
||||
return 1
|
||||
|
||||
@@ -103,6 +103,9 @@
|
||||
unregister_radio(src, frequency)
|
||||
qdel(wires)
|
||||
wires = null
|
||||
if(alarm_area && alarm_area.master_air_alarm == src)
|
||||
alarm_area.master_air_alarm = null
|
||||
elect_master(exclude_self = TRUE)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/alarm/New()
|
||||
@@ -272,8 +275,10 @@
|
||||
/obj/machinery/alarm/proc/master_is_operating()
|
||||
return alarm_area && alarm_area.master_air_alarm && !(alarm_area.master_air_alarm.stat & (NOPOWER | BROKEN))
|
||||
|
||||
/obj/machinery/alarm/proc/elect_master()
|
||||
/obj/machinery/alarm/proc/elect_master(exclude_self = FALSE)
|
||||
for(var/obj/machinery/alarm/AA in alarm_area)
|
||||
if(exclude_self && AA == src)
|
||||
continue
|
||||
if(!(AA.stat & (NOPOWER|BROKEN)))
|
||||
alarm_area.master_air_alarm = AA
|
||||
return 1
|
||||
|
||||
@@ -153,7 +153,7 @@
|
||||
modifier_lower_bound = round(modifier_lower_bound * clone_sickness_length, 1)
|
||||
modifier_upper_bound = round(modifier_upper_bound * clone_sickness_length, 1)
|
||||
|
||||
H.add_modifier(/datum/modifier/cloning_sickness, rand(modifier_lower_bound, modifier_upper_bound))
|
||||
H.add_modifier(H.species.cloning_modifier, rand(modifier_lower_bound, modifier_upper_bound))
|
||||
|
||||
// Modifier that doesn't do anything.
|
||||
H.add_modifier(/datum/modifier/cloned)
|
||||
@@ -342,7 +342,10 @@
|
||||
occupant.client.perspective = MOB_PERSPECTIVE
|
||||
occupant.loc = src.loc
|
||||
eject_wait = 0 //If it's still set somehow.
|
||||
domutcheck(occupant) //Waiting until they're out before possible transforming.
|
||||
if(ishuman(occupant)) //Need to be safe.
|
||||
var/mob/living/carbon/human/patient = occupant
|
||||
if(!(patient.species.flags & NO_SCAN)) //If, for some reason, someone makes a genetically-unalterable clone, let's not make them permanently disabled.
|
||||
domutcheck(occupant) //Waiting until they're out before possible transforming.
|
||||
occupant = null
|
||||
|
||||
biomass -= CLONE_BIOMASS
|
||||
|
||||
@@ -40,19 +40,19 @@
|
||||
if(!usr || usr.stat || usr.lying) return
|
||||
|
||||
if(scan)
|
||||
usr << "You remove \the [scan] from \the [src]."
|
||||
to_chat(usr, "You remove \the [scan] from \the [src].")
|
||||
scan.forceMove(get_turf(src))
|
||||
if(!usr.get_active_hand() && istype(usr,/mob/living/carbon/human))
|
||||
usr.put_in_hands(scan)
|
||||
scan = null
|
||||
else if(modify)
|
||||
usr << "You remove \the [modify] from \the [src]."
|
||||
to_chat(usr, "You remove \the [modify] from \the [src].")
|
||||
modify.forceMove(get_turf(src))
|
||||
if(!usr.get_active_hand() && istype(usr,/mob/living/carbon/human))
|
||||
usr.put_in_hands(modify)
|
||||
modify = null
|
||||
else
|
||||
usr << "There is nothing to remove from the console."
|
||||
to_chat(usr, "There is nothing to remove from the console.")
|
||||
return
|
||||
|
||||
/obj/machinery/computer/card/attackby(obj/item/weapon/card/id/id_card, mob/user)
|
||||
@@ -82,12 +82,15 @@
|
||||
/obj/machinery/computer/card/ui_interact(mob/user, ui_key="main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
user.set_machine(src)
|
||||
|
||||
if(data_core)
|
||||
data_core.get_manifest_list()
|
||||
|
||||
var/data[0]
|
||||
data["src"] = "\ref[src]"
|
||||
data["station_name"] = station_name()
|
||||
data["mode"] = mode
|
||||
data["printing"] = printing
|
||||
data["manifest"] = data_core ? data_core.get_manifest(0) : null
|
||||
data["manifest"] = PDA_Manifest
|
||||
data["target_name"] = modify ? modify.name : "-----"
|
||||
data["target_owner"] = modify && modify.registered_name ? modify.registered_name : "-----"
|
||||
data["target_rank"] = get_target_rank()
|
||||
@@ -99,13 +102,16 @@
|
||||
data["all_centcom_access"] = null
|
||||
data["regions"] = null
|
||||
|
||||
data["engineering_jobs"] = format_jobs(engineering_positions)
|
||||
data["medical_jobs"] = format_jobs(medical_positions)
|
||||
data["science_jobs"] = format_jobs(science_positions)
|
||||
data["security_jobs"] = format_jobs(security_positions)
|
||||
data["cargo_jobs"] = format_jobs(cargo_positions)
|
||||
data["civilian_jobs"] = format_jobs(civilian_positions)
|
||||
data["centcom_jobs"] = format_jobs(get_all_centcom_jobs())
|
||||
data["jobs"] = list(
|
||||
list("cat" = "Engineering", "jobs" = format_jobs(engineering_positions)),
|
||||
list("cat" = "Medical", "jobs" = format_jobs(medical_positions)),
|
||||
list("cat" = "Science", "jobs" = format_jobs(science_positions)),
|
||||
list("cat" = "Security", "jobs" = format_jobs(security_positions)),
|
||||
list("cat" = "Cargo", "jobs" = format_jobs(cargo_positions)),
|
||||
list("cat" = "Planetside", "jobs" = format_jobs(planet_positions)),
|
||||
list("cat" = "Civilian", "jobs" = format_jobs(civilian_positions)),
|
||||
list("cat" = "CentCom", "jobs" = format_jobs(get_all_centcom_jobs()))
|
||||
)
|
||||
|
||||
if (modify && is_centcom())
|
||||
var/list/all_centcom_access = list()
|
||||
@@ -209,7 +215,7 @@
|
||||
jobdatum = J
|
||||
break
|
||||
if(!jobdatum)
|
||||
usr << "<span class='warning'>No log exists for this job: [t1]</span>"
|
||||
to_chat(usr, "<span class='warning'>No log exists for this job: [t1]</span>")
|
||||
return
|
||||
|
||||
access = jobdatum.get_access()
|
||||
|
||||
@@ -289,10 +289,13 @@
|
||||
add_fingerprint(usr)
|
||||
|
||||
/obj/machinery/computer/cloning/proc/scan_mob(mob/living/carbon/human/subject as mob)
|
||||
if ((isnull(subject)) || (!(ishuman(subject))) || (!subject.dna))
|
||||
var/brain_skip = 0
|
||||
if (istype(subject, /mob/living/carbon/brain)) //Brain scans.
|
||||
brain_skip = 1
|
||||
if ((isnull(subject)) || (!(ishuman(subject)) && !brain_skip) || (!subject.dna))
|
||||
scantemp = "Error: Unable to locate valid genetic data."
|
||||
return
|
||||
if (!subject.has_brain())
|
||||
if (!subject.has_brain() && !brain_skip)
|
||||
if(istype(subject, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = subject
|
||||
if(H.should_have_organ("brain"))
|
||||
@@ -313,7 +316,7 @@
|
||||
if (NOCLONE in subject.mutations)
|
||||
scantemp = "Error: Mental interface failure."
|
||||
return
|
||||
if (subject.species && subject.species.flags & NO_SCAN)
|
||||
if (subject.species && subject.species.flags & NO_SCAN && !brain_skip)
|
||||
scantemp = "Error: Mental interface failure."
|
||||
return
|
||||
for(var/modifier_type in subject.modifiers) //Can't be cloned, even if they had a previous scan
|
||||
@@ -333,7 +336,10 @@
|
||||
R.name = R.dna.real_name
|
||||
R.types = DNA2_BUF_UI|DNA2_BUF_UE|DNA2_BUF_SE
|
||||
R.languages = subject.languages
|
||||
R.flavor = subject.flavor_texts.Copy()
|
||||
if(!brain_skip) //Brains don't have flavor text.
|
||||
R.flavor = subject.flavor_texts.Copy()
|
||||
else
|
||||
R.flavor = list()
|
||||
for(var/datum/modifier/mod in subject.modifiers)
|
||||
if(mod.flags & MODIFIER_GENETIC)
|
||||
R.genetic_modifiers.Add(mod.type)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
var/lit = 0
|
||||
var/id = null
|
||||
var/on_icon = "sign_on"
|
||||
var/off_icon = "sign_off"
|
||||
|
||||
/obj/machinery/holosign/proc/toggle()
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
@@ -22,7 +23,7 @@
|
||||
|
||||
/obj/machinery/holosign/update_icon()
|
||||
if(!lit)
|
||||
icon_state = "sign_off"
|
||||
icon_state = off_icon
|
||||
else
|
||||
icon_state = on_icon
|
||||
|
||||
@@ -40,7 +41,16 @@
|
||||
/obj/machinery/holosign/exit
|
||||
name = "exit holosign"
|
||||
desc = "Small wall-mounted holographic projector. This one reads EXIT."
|
||||
on_icon = "exit"
|
||||
on_icon = "emergencyexit"
|
||||
|
||||
/obj/machinery/holosign/bar
|
||||
name = "bar holosign"
|
||||
desc = "Small wall-mounted holographic projector. This one reads OPEN."
|
||||
icon_state = "barclosed"
|
||||
on_icon = "baropen"
|
||||
off_icon = "barclosed"
|
||||
|
||||
|
||||
////////////////////SWITCH///////////////////////////////////////
|
||||
|
||||
/obj/machinery/button/holosign
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
var/wrenching = 0
|
||||
var/last_target //last target fired at, prevents turrets from erratically firing at all valid targets in range
|
||||
var/timeout = 10 // When a turret pops up, then finds nothing to shoot at, this number decrements until 0, when it pops down.
|
||||
var/can_salvage = TRUE // If false, salvaging doesn't give you anything.
|
||||
|
||||
/obj/machinery/porta_turret/crescent
|
||||
enabled = 0
|
||||
@@ -102,6 +103,7 @@
|
||||
desc = "A very tough looking turret made by alien hands. This one looks destroyed, thankfully."
|
||||
icon_state = "destroyed_target_prism"
|
||||
stat = BROKEN
|
||||
can_salvage = FALSE // So you need to actually kill a turret to get the alien gun.
|
||||
|
||||
/obj/machinery/porta_turret/New()
|
||||
..()
|
||||
@@ -325,7 +327,7 @@ var/list/turret_icons
|
||||
//try and salvage its components
|
||||
user << "<span class='notice'>You begin prying the metal coverings off.</span>"
|
||||
if(do_after(user, 20))
|
||||
if(prob(70))
|
||||
if(can_salvage && prob(70))
|
||||
user << "<span class='notice'>You remove the turret and salvage some components.</span>"
|
||||
if(installation)
|
||||
var/obj/item/weapon/gun/energy/Gun = new installation(loc)
|
||||
|
||||
@@ -352,6 +352,18 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
|
||||
var/broadcasting = 1
|
||||
var/receiving = 1
|
||||
|
||||
// VOREStation Edit - Make sure constructed relays keep relaying for their current Z when moved by shuttles.
|
||||
/obj/machinery/telecomms/relay/proc/update_z()
|
||||
if (initial(listening_level) == 0)
|
||||
var/turf/T = get_turf(src)
|
||||
listening_level = T.z
|
||||
|
||||
/area/shuttle_arrived()
|
||||
. = ..()
|
||||
for(var/obj/machinery/telecomms/relay/R in contents)
|
||||
R.update_z()
|
||||
// VOREStation Edit End
|
||||
|
||||
/obj/machinery/telecomms/relay/receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from)
|
||||
|
||||
// Add our level and send it back
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
var/update = 0
|
||||
switch(damtype)
|
||||
if("brute")
|
||||
H.Paralyse(1)
|
||||
update |= temp.take_damage(rand(force/2, force), 0)
|
||||
if("fire")
|
||||
update |= temp.take_damage(0, rand(force/2, force))
|
||||
@@ -86,10 +85,7 @@
|
||||
src.visible_message("<font color='red'><b>[src.name] hits [target]</b></font>")
|
||||
if(!istype(target, /turf/simulated/wall))
|
||||
target:attackby(src,src.occupant)
|
||||
else if(prob(5))
|
||||
target:dismantle_wall(1)
|
||||
src.occupant_message("<span class='notice'>You smash through the wall.</span>")
|
||||
src.visible_message("<b>[src.name] smashes through the wall</b>")
|
||||
else
|
||||
playsound(src, 'sound/weapons/smash.ogg', 50, 1)
|
||||
melee_can_hit = 0
|
||||
if(do_after(melee_cooldown))
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
name = "APLU \"Ripley\""
|
||||
icon_state = "ripley"
|
||||
initial_icon = "ripley"
|
||||
step_in = 6
|
||||
step_in = 5 // vorestation edit, was 6 but that's PAINFULLY slow
|
||||
step_energy_drain = 5 // vorestation edit because 10 drained a significant chunk of its cell before you even got out the airlock
|
||||
max_temperature = 20000
|
||||
health = 200
|
||||
wreckage = /obj/effect/decal/mecha_wreckage/ripley
|
||||
cargo_capacity = 10
|
||||
var/obj/item/weapon/mining_scanner/orescanner // vorestation addition
|
||||
|
||||
/obj/mecha/working/ripley/Destroy()
|
||||
for(var/atom/movable/A in src.cargo)
|
||||
@@ -67,3 +69,19 @@
|
||||
qdel (B)
|
||||
|
||||
|
||||
// VORESTATION EDIT BEGIN
|
||||
|
||||
/obj/mecha/working/ripley/New()
|
||||
..()
|
||||
orescanner = new /obj/item/weapon/mining_scanner
|
||||
|
||||
/obj/mecha/working/ripley/verb/detect_ore()
|
||||
set category = "Exosuit Interface"
|
||||
set name = "Detect Ores"
|
||||
set src = usr.loc
|
||||
set popup_menu = 0
|
||||
|
||||
orescanner.attack_self(usr)
|
||||
|
||||
// VORESTATION EDIT END
|
||||
|
||||
|
||||
@@ -96,7 +96,18 @@
|
||||
Trigger(var/atom/movable/A)
|
||||
if(teleport_x && teleport_y && teleport_z)
|
||||
var/turf/T = locate(teleport_x, teleport_y, teleport_z)
|
||||
A.forceMove(T)
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
if(L.pulling)
|
||||
var/atom/movable/P = L.pulling
|
||||
L.stop_pulling()
|
||||
P.forceMove(T)
|
||||
L.forceMove(T)
|
||||
L.start_pulling(P)
|
||||
else
|
||||
A.forceMove(T)
|
||||
else
|
||||
A.forceMove(T)
|
||||
|
||||
/* Random teleporter, teleports atoms to locations ranging from teleport_x - teleport_x_offset, etc */
|
||||
|
||||
@@ -145,10 +156,7 @@ var/global/list/tele_landmarks = list() // Terrible, but the alternative is loop
|
||||
|
||||
/obj/effect/step_trigger/teleporter/planetary_fall
|
||||
var/datum/planet/planet = null
|
||||
/* //VOREStation Removal
|
||||
/obj/effect/step_trigger/teleporter/planetary_fall/sif/initialize()
|
||||
planet = planet_sif
|
||||
*/ //VOREStation Removal end
|
||||
|
||||
/obj/effect/step_trigger/teleporter/planetary_fall/Trigger(var/atom/movable/A)
|
||||
if(planet)
|
||||
if(!planet.planet_floors.len)
|
||||
@@ -158,7 +166,10 @@ var/global/list/tele_landmarks = list() // Terrible, but the alternative is loop
|
||||
var/safety = 100 // Infinite loop protection.
|
||||
while(!T && safety)
|
||||
var/turf/simulated/candidate = pick(planet.planet_floors)
|
||||
if(!istype(candidate) || istype(candidate, /turf/simulated/sky) || !T.outdoors)
|
||||
if(!istype(candidate) || istype(candidate, /turf/simulated/sky))
|
||||
safety--
|
||||
continue
|
||||
else if(candidate && !candidate.outdoors)
|
||||
safety--
|
||||
continue
|
||||
else
|
||||
|
||||
@@ -174,6 +174,11 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
// Description: Simple check to see if the exonet node is active.
|
||||
/obj/item/device/communicator/proc/get_connection_to_tcomms()
|
||||
if(node && node.on && node.allow_external_communicators && !is_jammed(src))
|
||||
// VOREStation Edit Start - Lose connection if too far from our exonet node.
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T || !is_on_same_plane_or_station(T.z, node.z))
|
||||
return 0
|
||||
// VOREStation Edit End
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
@@ -180,6 +180,13 @@
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/device/encryptionkey/heads/captain
|
||||
|
||||
/obj/item/device/radio/headset/heads/captain/sfr
|
||||
name = "SFR headset"
|
||||
desc = "A headset belonging to a Sif Free Radio DJ. SFR, best tunes in the wilderness."
|
||||
icon_state = "com_headset_alt"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/device/encryptionkey/heads/captain
|
||||
|
||||
/obj/item/device/radio/headset/heads/ai_integrated //No need to care about icons, it should be hidden inside the AI anyway.
|
||||
name = "\improper AI subspace transceiver"
|
||||
desc = "Integrated AI radio transceiver."
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
|
||||
/obj/item/poi
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
desc = "This is definitely something cool."
|
||||
|
||||
/obj/item/poi/pascalb
|
||||
icon_state = "pascalb"
|
||||
name = "misshapen manhole cover"
|
||||
desc = "The top of this twisted chunk of metal is faintly stamped with a five pointed star. 'Property of US Army, Pascal B - 1957'."
|
||||
|
||||
/obj/item/poi/pascalb/New()
|
||||
processing_objects += src
|
||||
return ..()
|
||||
|
||||
/obj/item/poi/pascalb/process()
|
||||
radiation_repository.radiate(src, 5)
|
||||
|
||||
/obj/item/poi/pascalb/Destroy()
|
||||
processing_objects -= src
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/crate/oldreactor
|
||||
name = "fission reactor rack"
|
||||
desc = "Used in older models of nuclear reactors, essentially a cooling rack for high volumes of radioactive material."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "poireactor"
|
||||
icon_opened = "poireactor_open"
|
||||
icon_closed = "poireactor"
|
||||
climbable = 0
|
||||
|
||||
/obj/structure/closet/crate/oldreactor/New()
|
||||
..()
|
||||
new /obj/item/weapon/fuel_assembly/deuterium(src)
|
||||
new /obj/item/weapon/fuel_assembly/deuterium(src)
|
||||
new /obj/item/weapon/fuel_assembly/deuterium(src)
|
||||
new /obj/item/weapon/fuel_assembly/deuterium(src)
|
||||
new /obj/item/weapon/fuel_assembly/deuterium(src)
|
||||
new /obj/item/weapon/fuel_assembly/deuterium(src)
|
||||
|
||||
/obj/item/poi/brokenoldreactor
|
||||
icon_state = "poireactor_broken"
|
||||
name = "ruptured fission reactor rack"
|
||||
desc = "This broken hunk of machinery looks extremely dangerous."
|
||||
|
||||
/obj/item/poi/brokenoldreactor/New()
|
||||
processing_objects += src
|
||||
return ..()
|
||||
|
||||
/obj/item/poi/brokenoldreactor/process()
|
||||
radiation_repository.radiate(src, 25)
|
||||
|
||||
/obj/item/poi/brokenoldreactor/Destroy()
|
||||
processing_objects -= src
|
||||
return ..()
|
||||
@@ -122,10 +122,7 @@
|
||||
build_delay = deconstruct ? 50 : 20
|
||||
build_cost = deconstruct ? 10 : 3
|
||||
build_type = deconstruct ? "floor" : "wall"
|
||||
if(F.check_destroy_override(F))
|
||||
build_turf = deconstruct ? destroy_floor_override_path : /turf/simulated/wall
|
||||
else
|
||||
build_turf = deconstruct ? /turf/space : /turf/simulated/wall
|
||||
build_turf = deconstruct ? get_base_turf_by_area(F) : /turf/simulated/wall
|
||||
|
||||
if(!build_type)
|
||||
working = 0
|
||||
|
||||
@@ -29,3 +29,13 @@
|
||||
board_type = new /datum/frame/frame_types/machine
|
||||
origin_tech = list(TECH_POWER = 4, TECH_ENGINEERING = 3)
|
||||
req_components = list(/obj/item/weapon/stock_parts/capacitor = 3, /obj/item/stack/cable_coil = 10)
|
||||
|
||||
/obj/item/weapon/circuitboard/breakerbox
|
||||
name = T_BOARD("breaker box")
|
||||
build_path = /obj/machinery/power/breakerbox
|
||||
board_type = new /datum/frame/frame_types/machine
|
||||
origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3)
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/spring = 1,
|
||||
/obj/item/weapon/stock_parts/manipulator = 1,
|
||||
/obj/item/stack/cable_coil = 10)
|
||||
|
||||
@@ -353,8 +353,8 @@
|
||||
job_access_type = /datum/job/qm
|
||||
|
||||
/obj/item/weapon/card/id/assistant
|
||||
assignment = "Assistant"
|
||||
rank = "Assistant"
|
||||
assignment = USELESS_JOB //VOREStation Edit - Visitor not Assistant
|
||||
rank = USELESS_JOB //VOREStation Edit - Visitor not Assistant
|
||||
job_access_type = /datum/job/assistant
|
||||
|
||||
/obj/item/weapon/card/id/civilian
|
||||
|
||||
@@ -399,28 +399,28 @@
|
||||
return
|
||||
|
||||
if(!parachute) //This packs the parachute
|
||||
visible_message("<span class='notice'>\The [H] starts to pack \the [src]!</span>", \
|
||||
H.visible_message("<span class='notice'>\The [H] starts to pack \the [src]!</span>", \
|
||||
"<span class='notice'>You start to pack \the [src]!</span>", \
|
||||
"You hear the shuffling of cloth.")
|
||||
if(do_after(H, 50))
|
||||
visible_message("<span class='notice'>\The [H] finishes packing \the [src]!</span>", \
|
||||
H.visible_message("<span class='notice'>\The [H] finishes packing \the [src]!</span>", \
|
||||
"<span class='notice'>You finish packing \the [src]!</span>", \
|
||||
"You hear the shuffling of cloth.")
|
||||
parachute = TRUE
|
||||
else
|
||||
visible_message("<span class='notice'>\The [src] gives up on packing \the [src]!</span>", \
|
||||
H.visible_message("<span class='notice'>\The [src] gives up on packing \the [src]!</span>", \
|
||||
"<span class='notice'>You give up on packing \the [src]!</span>")
|
||||
return
|
||||
else //This unpacks the parachute
|
||||
visible_message("<span class='notice'>\The [src] starts to unpack \the [src]!</span>", \
|
||||
H.visible_message("<span class='notice'>\The [src] starts to unpack \the [src]!</span>", \
|
||||
"<span class='notice'>You start to unpack \the [src]!</span>", \
|
||||
"You hear the shuffling of cloth.")
|
||||
if(do_after(H, 25))
|
||||
visible_message("<span class='notice'>\The [src] finishes unpacking \the [src]!</span>", \
|
||||
H.visible_message("<span class='notice'>\The [src] finishes unpacking \the [src]!</span>", \
|
||||
"<span class='notice'>You finish unpacking \the [src]!</span>", \
|
||||
"You hear the shuffling of cloth.")
|
||||
parachute = FALSE
|
||||
else
|
||||
visible_message("<span class='notice'>\The [src] decides not to unpack \the [src]!</span>", \
|
||||
H.visible_message("<span class='notice'>\The [src] decides not to unpack \the [src]!</span>", \
|
||||
"<span class='notice'>You decide not to unpack \the [src]!</span>")
|
||||
return
|
||||
@@ -116,4 +116,9 @@
|
||||
icon_state = "taurvest"
|
||||
icon_base = "taurvest"
|
||||
max_storage_space = INVENTORY_STANDARD_SPACE
|
||||
slowdown = 0
|
||||
slowdown = 0
|
||||
|
||||
/obj/item/weapon/storage/backpack/dufflebag/fluff //Black dufflebag without syndie buffs.
|
||||
name = "plain black dufflebag"
|
||||
desc = "A large dufflebag for holding extra tactical supplies."
|
||||
icon_state = "duffle_syndie"
|
||||
@@ -902,6 +902,32 @@ something, make sure it's not in one of the other lists.*/
|
||||
prob(1);/obj/item/weapon/beartrap,
|
||||
prob(2);/obj/item/weapon/handcuffs,)
|
||||
|
||||
/obj/random/sfr
|
||||
name = "random SFR headset"
|
||||
desc = "This is a headset spawn."
|
||||
icon = 'icons/misc/mark.dmi'
|
||||
icon_state = "rup"
|
||||
|
||||
/obj/random/sfr/item_to_spawn()
|
||||
return pick(prob(25);/obj/item/device/radio/headset/heads/captain/sfr,
|
||||
prob(25);/obj/item/device/radio/headset/headset_cargo/alt,
|
||||
prob(25);/obj/item/device/radio/headset/headset_com/alt,
|
||||
prob(25);/obj/item/device/radio/headset)
|
||||
|
||||
/obj/random/rigsuit
|
||||
name = "Random rigsuit"
|
||||
desc = "This is a random rigsuit."
|
||||
icon = 'icons/obj/rig_modules.dmi'
|
||||
icon_state = "generic"
|
||||
|
||||
/obj/random/rigsuit/item_to_spawn()
|
||||
return pick(prob(4);/obj/item/weapon/rig/light/hacker,
|
||||
prob(5);/obj/item/weapon/rig/industrial,
|
||||
prob(5);/obj/item/weapon/rig/eva,
|
||||
prob(4);/obj/item/weapon/rig/light/stealth,
|
||||
prob(3);/obj/item/weapon/rig/hazard,
|
||||
prob(1);/obj/item/weapon/rig/merc/empty)
|
||||
|
||||
var/list/random_junk_
|
||||
var/list/random_useful_
|
||||
/proc/get_random_useful_type()
|
||||
@@ -999,6 +1025,11 @@ var/list/multi_point_spawns
|
||||
id = "Captain's spare id"
|
||||
item_path = /obj/item/weapon/card/id/gold/captain/spare
|
||||
|
||||
/obj/random_multi/single_item/sfr_headset
|
||||
name = "Multi Point - headset"
|
||||
id = "SFR headset"
|
||||
item_path = /obj/random/sfr
|
||||
|
||||
//Multiple Object Spawn
|
||||
|
||||
/obj/random/multiple
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/structure/closet/secure_closet/guncabinet
|
||||
name = "gun cabinet"
|
||||
req_access = list(access_armory)
|
||||
req_one_access = list(access_armory)
|
||||
icon = 'icons/obj/guncabinet.dmi'
|
||||
icon_state = "base"
|
||||
icon_off ="base"
|
||||
|
||||
@@ -53,7 +53,8 @@
|
||||
/mob/living/simple_animal/hostile/bear;0.5,
|
||||
/mob/living/simple_animal/hostile/bear/brown;0.5,
|
||||
/mob/living/simple_animal/hostile/carp,
|
||||
/mob/living/simple_animal/hostile/mimic)
|
||||
/mob/living/simple_animal/hostile/mimic,
|
||||
/mob/living/simple_animal/otie;0.5)
|
||||
..()
|
||||
|
||||
|
||||
@@ -78,16 +79,28 @@
|
||||
desc = "The VARMAcorp bioengineering division flagship product on trained optimal snowflake guard dogs."
|
||||
icon = 'icons/obj/storage_vr.dmi'
|
||||
icon_state = "sotiecrate"
|
||||
held_type = /mob/living/simple_animal/otie/friendly/security
|
||||
held_type = /mob/living/simple_animal/otie/security
|
||||
|
||||
/obj/structure/largecrate/animal/guardmutant
|
||||
name = "VARMAcorp autoNOMous security solution for hostile environments."
|
||||
desc = "The VARMAcorp bioengineering division flagship product on trained optimal snowflake guard dogs. This one can survive hostile atmosphere."
|
||||
icon = 'icons/obj/storage_vr.dmi'
|
||||
icon_state = "sotiecrate"
|
||||
held_type = /mob/living/simple_animal/otie/security/phoron
|
||||
|
||||
/obj/structure/largecrate/animal/otie
|
||||
name = "VARMAcorp adoptable reject (Dangerous!)"
|
||||
desc = "A warning on the side says the creature inside was returned to the supplier after injuring or devouring several unlucky members of the previous adoption family. It was given a second chance with the next customer. Godspeed and good luck with your new pet!"
|
||||
icon = 'icons/obj/storage_vr.dmi'
|
||||
icon_state = "otiecrate2"
|
||||
held_type = /mob/living/simple_animal/otie/friendly/cotie
|
||||
held_type = /mob/living/simple_animal/otie/cotie
|
||||
var/taped = 1
|
||||
|
||||
/obj/structure/largecrate/animal/otie/phoron
|
||||
name = "VARMAcorp adaptive beta subject (Experimental)"
|
||||
desc = "VARMAcorp experimental hostile environment adaptive breeding development kit. WARNING, DO NOT RELEASE IN WILD!"
|
||||
held_type = /mob/living/simple_animal/otie/cotie/phoron
|
||||
|
||||
/obj/structure/largecrate/animal/otie/attack_hand(mob/living/carbon/human/M as mob)//I just couldn't decide between the icons lmao
|
||||
if(taped == 1)
|
||||
playsound(src, 'sound/items/poster_ripped.ogg', 50, 1)
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
/obj/structure/dogbed
|
||||
name = "dog bed"
|
||||
desc = "A bed made especially for dogs, or other similarly sized pets."
|
||||
icon = 'icons/obj/furniture.dmi'
|
||||
icon_state = "dogbed"
|
||||
can_buckle = 1
|
||||
buckle_dir = SOUTH
|
||||
buckle_lying = 1
|
||||
@@ -73,6 +73,7 @@
|
||||
return
|
||||
|
||||
is_stump = TRUE
|
||||
density = FALSE
|
||||
icon_state = "[base_state]_stump"
|
||||
overlays.Cut() // For the Sif tree and other future glowy trees.
|
||||
set_light(0)
|
||||
|
||||
@@ -6,9 +6,65 @@
|
||||
w_class = ITEMSIZE_HUGE
|
||||
var/state = 0
|
||||
var/health = 200
|
||||
var/max_health = 200
|
||||
var/displaced_health = 50
|
||||
var/current_damage = 0
|
||||
var/cover = 50 //how much cover the girder provides against projectiles.
|
||||
var/default_material = DEFAULT_WALL_MATERIAL
|
||||
var/material/girder_material
|
||||
var/material/reinf_material
|
||||
var/reinforcing = 0
|
||||
var/applies_material_colour = 1
|
||||
|
||||
/obj/structure/girder/New(var/newloc, var/material_key)
|
||||
..(newloc)
|
||||
if(!material_key)
|
||||
material_key = default_material
|
||||
set_material(material_key)
|
||||
update_icon()
|
||||
|
||||
/obj/structure/girder/Destroy()
|
||||
if(girder_material.products_need_process())
|
||||
processing_objects -= src
|
||||
. = ..()
|
||||
|
||||
/obj/structure/girder/process()
|
||||
if(!radiate())
|
||||
processing_objects -= src
|
||||
return
|
||||
|
||||
/obj/structure/girder/proc/radiate()
|
||||
var/total_radiation = girder_material.radioactivity + (reinf_material ? reinf_material.radioactivity / 2 : 0)
|
||||
if(!total_radiation)
|
||||
return
|
||||
|
||||
radiation_repository.radiate(src, total_radiation)
|
||||
return total_radiation
|
||||
|
||||
|
||||
/obj/structure/girder/proc/set_material(var/new_material)
|
||||
girder_material = get_material_by_name(new_material)
|
||||
if(!girder_material)
|
||||
qdel(src)
|
||||
name = "[girder_material.display_name] [initial(name)]"
|
||||
max_health = round(girder_material.integrity) //Should be 150 with default integrity (steel). Weaker than ye-olden Girders now.
|
||||
health = max_health
|
||||
displaced_health = round(max_health/4)
|
||||
if(applies_material_colour)
|
||||
color = girder_material.icon_colour
|
||||
if(girder_material.products_need_process()) //Am I radioactive or some other? Process me!
|
||||
processing_objects |= src
|
||||
else if(src in processing_objects) //If I happened to be radioactive or s.o. previously, and am not now, stop processing.
|
||||
processing_objects -= src
|
||||
|
||||
/obj/structure/girder/get_material()
|
||||
return girder_material
|
||||
|
||||
/obj/structure/girder/update_icon()
|
||||
if(anchored)
|
||||
icon_state = "girder"
|
||||
else
|
||||
icon_state = "displaced"
|
||||
|
||||
/obj/structure/girder/displaced
|
||||
icon_state = "displaced"
|
||||
@@ -16,6 +72,17 @@
|
||||
health = 50
|
||||
cover = 25
|
||||
|
||||
/obj/structure/girder/displaced/New(var/newloc, var/material_key)
|
||||
..(newloc, material_key)
|
||||
displace()
|
||||
|
||||
/obj/structure/girder/proc/displace()
|
||||
name = "displaced [girder_material.display_name] [initial(name)]"
|
||||
icon_state = "displaced"
|
||||
anchored = 0
|
||||
health = (displaced_health - round(current_damage / 4))
|
||||
cover = 25
|
||||
|
||||
/obj/structure/girder/attack_generic(var/mob/user, var/damage, var/attack_message = "smashes apart", var/wallbreaker)
|
||||
if(!damage || !wallbreaker)
|
||||
return 0
|
||||
@@ -36,6 +103,25 @@
|
||||
if(!istype(Proj, /obj/item/projectile/beam))
|
||||
damage *= 0.4 //non beams do reduced damage
|
||||
|
||||
else if(girder_material && girder_material.reflectivity >= 0.5) // Reflect lasers.
|
||||
var/new_damage = damage * girder_material.reflectivity
|
||||
var/outgoing_damage = damage - new_damage
|
||||
damage = round(new_damage)
|
||||
Proj.damage = outgoing_damage
|
||||
|
||||
visible_message("<span class='danger'>\The [src] reflects \the [Proj]!</span>")
|
||||
|
||||
// Find a turf near or on the original location to bounce to
|
||||
var/new_x = Proj.starting.x + pick(0, 0, 0, -1, 1, -2, 2)
|
||||
var/new_y = Proj.starting.y + pick(0, 0, 0, -1, 1, -2, 2)
|
||||
//var/turf/curloc = get_turf(src)
|
||||
var/turf/curloc = get_step(src, get_dir(src, Proj.starting))
|
||||
|
||||
Proj.penetrating += 1 // Needed for the beam to get out of the girder.
|
||||
|
||||
// redirect the projectile
|
||||
Proj.redirect(new_x, new_y, curloc, null)
|
||||
|
||||
health -= damage
|
||||
..()
|
||||
if(health <= 0)
|
||||
@@ -47,9 +133,10 @@
|
||||
dismantle()
|
||||
|
||||
/obj/structure/girder/proc/reset_girder()
|
||||
name = "[girder_material.display_name] [initial(name)]"
|
||||
anchored = 1
|
||||
cover = initial(cover)
|
||||
health = min(health,initial(health))
|
||||
health = min(max_health - current_damage,max_health)
|
||||
state = 0
|
||||
icon_state = initial(icon_state)
|
||||
reinforcing = 0
|
||||
@@ -60,62 +147,59 @@
|
||||
if(istype(W, /obj/item/weapon/wrench) && state == 0)
|
||||
if(anchored && !reinf_material)
|
||||
playsound(src, W.usesound, 100, 1)
|
||||
user << "<span class='notice'>Now disassembling the girder...</span>"
|
||||
if(do_after(user,40 * W.toolspeed))
|
||||
to_chat(user, "<span class='notice'>Now disassembling the girder...</span>")
|
||||
if(do_after(user,(35 + round(max_health/50)) * W.toolspeed))
|
||||
if(!src) return
|
||||
user << "<span class='notice'>You dissasembled the girder!</span>"
|
||||
to_chat(user, "<span class='notice'>You dissasembled the girder!</span>")
|
||||
dismantle()
|
||||
else if(!anchored)
|
||||
playsound(src, W.usesound, 100, 1)
|
||||
user << "<span class='notice'>Now securing the girder...</span>"
|
||||
to_chat(user, "<span class='notice'>Now securing the girder...</span>")
|
||||
if(do_after(user, 40 * W.toolspeed, src))
|
||||
user << "<span class='notice'>You secured the girder!</span>"
|
||||
to_chat(user, "<span class='notice'>You secured the girder!</span>")
|
||||
reset_girder()
|
||||
|
||||
else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter))
|
||||
user << "<span class='notice'>Now slicing apart the girder...</span>"
|
||||
to_chat(user, "<span class='notice'>Now slicing apart the girder...</span>")
|
||||
if(do_after(user,30 * W.toolspeed))
|
||||
if(!src) return
|
||||
user << "<span class='notice'>You slice apart the girder!</span>"
|
||||
to_chat(user, "<span class='notice'>You slice apart the girder!</span>")
|
||||
dismantle()
|
||||
|
||||
else if(istype(W, /obj/item/weapon/pickaxe/diamonddrill))
|
||||
user << "<span class='notice'>You drill through the girder!</span>"
|
||||
to_chat(user, "<span class='notice'>You drill through the girder!</span>")
|
||||
dismantle()
|
||||
|
||||
else if(istype(W, /obj/item/weapon/screwdriver))
|
||||
if(state == 2)
|
||||
playsound(src, W.usesound, 100, 1)
|
||||
user << "<span class='notice'>Now unsecuring support struts...</span>"
|
||||
to_chat(user, "<span class='notice'>Now unsecuring support struts...</span>")
|
||||
if(do_after(user,40 * W.toolspeed))
|
||||
if(!src) return
|
||||
user << "<span class='notice'>You unsecured the support struts!</span>"
|
||||
to_chat(user, "<span class='notice'>You unsecured the support struts!</span>")
|
||||
state = 1
|
||||
else if(anchored && !reinf_material)
|
||||
playsound(src, W.usesound, 100, 1)
|
||||
reinforcing = !reinforcing
|
||||
user << "<span class='notice'>\The [src] can now be [reinforcing? "reinforced" : "constructed"]!</span>"
|
||||
to_chat(user, "<span class='notice'>\The [src] can now be [reinforcing? "reinforced" : "constructed"]!</span>")
|
||||
|
||||
else if(istype(W, /obj/item/weapon/wirecutters) && state == 1)
|
||||
playsound(src, W.usesound, 100, 1)
|
||||
user << "<span class='notice'>Now removing support struts...</span>"
|
||||
to_chat(user, "<span class='notice'>Now removing support struts...</span>")
|
||||
if(do_after(user,40 * W.toolspeed))
|
||||
if(!src) return
|
||||
user << "<span class='notice'>You removed the support struts!</span>"
|
||||
to_chat(user, "<span class='notice'>You removed the support struts!</span>")
|
||||
reinf_material.place_dismantled_product(get_turf(src))
|
||||
reinf_material = null
|
||||
reset_girder()
|
||||
|
||||
else if(istype(W, /obj/item/weapon/crowbar) && state == 0 && anchored)
|
||||
playsound(src, W.usesound, 100, 1)
|
||||
user << "<span class='notice'>Now dislodging the girder...</span>"
|
||||
to_chat(user, "<span class='notice'>Now dislodging the girder...</span>")
|
||||
if(do_after(user, 40 * W.toolspeed))
|
||||
if(!src) return
|
||||
user << "<span class='notice'>You dislodged the girder!</span>"
|
||||
icon_state = "displaced"
|
||||
anchored = 0
|
||||
health = 50
|
||||
cover = 25
|
||||
to_chat(user, "<span class='notice'>You dislodged the girder!</span>")
|
||||
displace()
|
||||
|
||||
else if(istype(W, /obj/item/stack/material))
|
||||
if(reinforcing && !reinf_material)
|
||||
@@ -130,14 +214,16 @@
|
||||
|
||||
/obj/structure/girder/proc/take_damage(var/damage)
|
||||
health -= damage
|
||||
|
||||
if(health <= 0)
|
||||
dismantle()
|
||||
else
|
||||
current_damage = current_damage + damage //Rather than calculate this every time we need to use it, just calculate it here and save it.
|
||||
|
||||
|
||||
/obj/structure/girder/proc/construct_wall(obj/item/stack/material/S, mob/user)
|
||||
var/amount_to_use = reinf_material ? 1 : 2
|
||||
if(S.get_amount() < amount_to_use)
|
||||
user << "<span class='notice'>There isn't enough material here to construct a wall.</span>"
|
||||
to_chat(user, "<span class='notice'>There isn't enough material here to construct a wall.</span>")
|
||||
return 0
|
||||
|
||||
var/material/M = name_to_material[S.default_type]
|
||||
@@ -148,24 +234,24 @@
|
||||
add_hiddenprint(usr)
|
||||
|
||||
if(M.integrity < 50)
|
||||
user << "<span class='notice'>This material is too soft for use in wall construction.</span>"
|
||||
to_chat(user, "<span class='notice'>This material is too soft for use in wall construction.</span>")
|
||||
return 0
|
||||
|
||||
user << "<span class='notice'>You begin adding the plating...</span>"
|
||||
to_chat(user, "<span class='notice'>You begin adding the plating...</span>")
|
||||
|
||||
if(!do_after(user,40) || !S.use(amount_to_use))
|
||||
return 1 //once we've gotten this far don't call parent attackby()
|
||||
|
||||
if(anchored)
|
||||
user << "<span class='notice'>You added the plating!</span>"
|
||||
to_chat(user, "<span class='notice'>You added the plating!</span>")
|
||||
else
|
||||
user << "<span class='notice'>You create a false wall! Push on it to open or close the passage.</span>"
|
||||
to_chat(user, "<span class='notice'>You create a false wall! Push on it to open or close the passage.</span>")
|
||||
wall_fake = 1
|
||||
|
||||
var/turf/Tsrc = get_turf(src)
|
||||
Tsrc.ChangeTurf(/turf/simulated/wall)
|
||||
var/turf/simulated/wall/T = get_turf(src)
|
||||
T.set_material(M, reinf_material)
|
||||
T.set_material(M, reinf_material, girder_material)
|
||||
if(wall_fake)
|
||||
T.can_open = 1
|
||||
T.add_hiddenprint(usr)
|
||||
@@ -174,22 +260,22 @@
|
||||
|
||||
/obj/structure/girder/proc/reinforce_with_material(obj/item/stack/material/S, mob/user) //if the verb is removed this can be renamed.
|
||||
if(reinf_material)
|
||||
user << "<span class='notice'>\The [src] is already reinforced.</span>"
|
||||
to_chat(user, "<span class='notice'>\The [src] is already reinforced.</span>")
|
||||
return 0
|
||||
|
||||
if(S.get_amount() < 1)
|
||||
user << "<span class='notice'>There isn't enough material here to reinforce the girder.</span>"
|
||||
to_chat(user, "<span class='notice'>There isn't enough material here to reinforce the girder.</span>")
|
||||
return 0
|
||||
|
||||
var/material/M = name_to_material[S.default_type]
|
||||
if(!istype(M) || M.integrity < 50)
|
||||
user << "You cannot reinforce \the [src] with that; it is too soft."
|
||||
to_chat(user, "You cannot reinforce \the [src] with that; it is too soft.")
|
||||
return 0
|
||||
|
||||
user << "<span class='notice'>Now reinforcing...</span>"
|
||||
to_chat(user, "<span class='notice'>Now reinforcing...</span>")
|
||||
if (!do_after(user,40) || !S.use(1))
|
||||
return 1 //don't call parent attackby() past this point
|
||||
user << "<span class='notice'>You added reinforcement!</span>"
|
||||
to_chat(user, "<span class='notice'>You added reinforcement!</span>")
|
||||
|
||||
reinf_material = M
|
||||
reinforce_girder()
|
||||
@@ -197,13 +283,13 @@
|
||||
|
||||
/obj/structure/girder/proc/reinforce_girder()
|
||||
cover = reinf_material.hardness
|
||||
health = 500
|
||||
health = health + round(reinf_material.integrity/2)
|
||||
state = 2
|
||||
icon_state = "reinforced"
|
||||
reinforcing = 0
|
||||
|
||||
/obj/structure/girder/proc/dismantle()
|
||||
new /obj/item/stack/material/steel(get_turf(src))
|
||||
girder_material.place_dismantled_product(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/girder/attack_hand(mob/user as mob)
|
||||
@@ -235,6 +321,8 @@
|
||||
icon_state= "cultgirder"
|
||||
health = 250
|
||||
cover = 70
|
||||
girder_material = DEFAULT_WALL_MATERIAL
|
||||
applies_material_colour = 0
|
||||
|
||||
/obj/structure/girder/cult/dismantle()
|
||||
new /obj/effect/decal/remains/human(get_turf(src))
|
||||
@@ -243,18 +331,18 @@
|
||||
/obj/structure/girder/cult/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/weapon/wrench))
|
||||
playsound(src, W.usesound, 100, 1)
|
||||
user << "<span class='notice'>Now disassembling the girder...</span>"
|
||||
to_chat(user, "<span class='notice'>Now disassembling the girder...</span>")
|
||||
if(do_after(user,40 * W.toolspeed))
|
||||
user << "<span class='notice'>You dissasembled the girder!</span>"
|
||||
to_chat(user, "<span class='notice'>You dissasembled the girder!</span>")
|
||||
dismantle()
|
||||
|
||||
else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter))
|
||||
user << "<span class='notice'>Now slicing apart the girder...</span>"
|
||||
to_chat(user, "<span class='notice'>Now slicing apart the girder...</span>")
|
||||
if(do_after(user,30 * W.toolspeed))
|
||||
user << "<span class='notice'>You slice apart the girder!</span>"
|
||||
to_chat(user, "<span class='notice'>You slice apart the girder!</span>")
|
||||
dismantle()
|
||||
|
||||
else if(istype(W, /obj/item/weapon/pickaxe/diamonddrill))
|
||||
user << "<span class='notice'>You drill through the girder!</span>"
|
||||
to_chat(user, "<span class='notice'>You drill through the girder!</span>")
|
||||
new /obj/effect/decal/remains/human(get_turf(src))
|
||||
dismantle()
|
||||
|
||||
@@ -156,6 +156,9 @@
|
||||
|
||||
/obj/structure/sign/warning/docking_area
|
||||
name = "\improper KEEP CLEAR: DOCKING AREA"
|
||||
|
||||
/obj/structure/sign/warning/evac
|
||||
name = "\improper KEEP CLEAR: EVAC DOCKING AREA"
|
||||
icon_state = "evac"
|
||||
|
||||
/obj/structure/sign/warning/engineering_access
|
||||
@@ -777,3 +780,13 @@
|
||||
/obj/structure/sign/atmos/air
|
||||
name = "\improper AIR"
|
||||
icon_state = "atmos_air"
|
||||
|
||||
/obj/structure/sign/poi/engineleft
|
||||
name = "I.C.V."
|
||||
desc = "The charred name of a cargo ship of some description."
|
||||
icon_state = "poi_engine1"
|
||||
|
||||
/obj/structure/sign/poi/engineright
|
||||
name = "I.C.V."
|
||||
desc = "The charred name of a cargo ship of some description."
|
||||
icon_state = "poi_engine2"
|
||||
@@ -190,6 +190,7 @@
|
||||
prob(2);/obj/item/weapon/reagent_containers/glass/rag,
|
||||
prob(2);/obj/item/weapon/storage/box/sinpockets,
|
||||
prob(2);/obj/item/weapon/storage/secure/briefcase,
|
||||
prob(2);/obj/item/clothing/under/fluff/latexmaid,
|
||||
prob(1);/obj/item/clothing/glasses/sunglasses,
|
||||
prob(1);/obj/item/clothing/glasses/welding,
|
||||
prob(1);/obj/item/clothing/gloves/yellow,
|
||||
|
||||
@@ -5,8 +5,8 @@ var/list/floor_decals = list()
|
||||
|
||||
/obj/effect/floor_decal
|
||||
name = "floor decal"
|
||||
icon = 'icons/turf/flooring/decals_vr.dmi'
|
||||
layer = TURF_LAYER + 0.01
|
||||
icon = 'icons/turf/flooring/decals_vr.dmi' // VOREStation Edit
|
||||
layer = DECALS_LAYER
|
||||
var/supplied_dir
|
||||
|
||||
/obj/effect/floor_decal/New(var/newloc, var/newdir, var/newcolour)
|
||||
|
||||
@@ -62,16 +62,6 @@
|
||||
/turf/simulated/proc/initialize()
|
||||
return
|
||||
|
||||
/turf/simulated/proc/check_destroy_override()
|
||||
if(destroy_floor_override) //Don't bother doing the additional checks if we don't have to.
|
||||
var/area/my_area = get_area(src)
|
||||
// my_area = my_area.master
|
||||
if(is_type_in_list(my_area, destroy_floor_override_ignore_areas))
|
||||
return 0
|
||||
if(z in destroy_floor_override_z_levels)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/turf/simulated/proc/AddTracks(var/typepath,var/bloodDNA,var/comingdir,var/goingdir,var/bloodcolor="#A10808")
|
||||
var/obj/effect/decal/cleanable/blood/tracks/tracks = locate(typepath) in src
|
||||
if(!tracks)
|
||||
|
||||
@@ -48,10 +48,10 @@
|
||||
make_plating(defer_icon_update = 1)
|
||||
flooring = newflooring
|
||||
footstep_sounds = newflooring.footstep_sounds
|
||||
// VOREStation Edit - Remember decals from before we were pried up
|
||||
if(islist(old_decals))
|
||||
decals = old_decals
|
||||
old_decals = null
|
||||
// VOREStation Edit - We are plating switching to flooring, swap out old_decals for decals
|
||||
var/tmp/list/overfloor_decals = old_decals
|
||||
old_decals = decals
|
||||
decals = overfloor_decals
|
||||
// VOREStation Edit End
|
||||
update_icon(1)
|
||||
levelupdate()
|
||||
@@ -61,12 +61,12 @@
|
||||
/turf/simulated/floor/proc/make_plating(var/place_product, var/defer_icon_update)
|
||||
|
||||
overlays.Cut()
|
||||
if(islist(decals))
|
||||
// VOREStation Edit - Don't forget decals when pried up
|
||||
if(flooring)
|
||||
old_decals = decals
|
||||
// VOREStation Edit End
|
||||
decals = null
|
||||
// VOREStation Edit - We are flooring switching to plating, swap out old_decals for decals.
|
||||
if(flooring)
|
||||
var/tmp/list/underfloor_decals = old_decals
|
||||
old_decals = decals
|
||||
decals = underfloor_decals
|
||||
// VOREStation Edit End
|
||||
|
||||
name = base_name
|
||||
desc = base_desc
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
var/list/flooring_cache = list()
|
||||
|
||||
var/image/no_ceiling_image = null
|
||||
|
||||
/hook/startup/proc/setup_no_ceiling_image()
|
||||
cache_no_ceiling_image()
|
||||
return TRUE
|
||||
|
||||
/proc/cache_no_ceiling_image()
|
||||
no_ceiling_image = image(icon = 'icons/turf/open_space.dmi', icon_state = "no_ceiling", layer = OVERTURF_LAYER)
|
||||
no_ceiling_image.plane = PLANE_MESONS
|
||||
|
||||
/turf/simulated/floor/update_icon(var/update_neighbors)
|
||||
|
||||
if(lava)
|
||||
@@ -84,6 +94,11 @@ var/list/flooring_cache = list()
|
||||
continue
|
||||
F.update_icon()
|
||||
|
||||
// Show 'ceilingless' overlay.
|
||||
var/turf/above = GetAbove(src)
|
||||
if(above && isopenspace(above) && !istype(src, /turf/simulated/floor/outdoors)) // This won't apply to outdoor turfs since its assumed they don't have a ceiling anyways.
|
||||
overlays |= no_ceiling_image
|
||||
|
||||
/turf/simulated/floor/proc/get_flooring_overlay(var/cache_key, var/icon_base, var/icon_dir = 0)
|
||||
if(!flooring_cache[cache_key])
|
||||
var/image/I = image(icon = flooring.icon, icon_state = icon_base, dir = icon_dir)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
var/turf/turf_type
|
||||
var/turf/simulated/shuttle/my_turf
|
||||
var/image/turf_image
|
||||
var/list/decals
|
||||
|
||||
New(var/location = null, var/turf/simulated/shuttle/turf)
|
||||
my_turf = turf
|
||||
@@ -24,6 +25,7 @@
|
||||
var/old_dest_icon = T.icon
|
||||
var/list/old_dest_overlays = T.overlays.Copy()
|
||||
var/list/old_dest_underlays = T.underlays.Copy()
|
||||
var/list/old_dest_decals = T.decals ? T.decals.Copy() : null
|
||||
|
||||
//Set the destination to be like us
|
||||
T.Destroy()
|
||||
@@ -33,13 +35,17 @@
|
||||
new_dest.icon = my_turf.icon
|
||||
new_dest.overlays = my_turf.overlays
|
||||
new_dest.underlays = my_turf.underlays
|
||||
//Shuttle specific stuff
|
||||
new_dest.decals = my_turf.decals
|
||||
//Shuttle specific stuff
|
||||
new_dest.interior_corner = my_turf.interior_corner
|
||||
new_dest.takes_underlays = my_turf.takes_underlays
|
||||
new_dest.under_turf = my_turf.under_turf
|
||||
new_dest.join_flags = my_turf.join_flags
|
||||
new_dest.join_group = my_turf.join_group
|
||||
|
||||
if(new_dest.decals)
|
||||
new_dest.apply_decals()
|
||||
|
||||
//Tell the new turf about what was there before
|
||||
new_dest.landed_holder = new(turf = new_dest)
|
||||
new_dest.landed_holder.turf_type = old_dest_type
|
||||
@@ -48,6 +54,7 @@
|
||||
new_dest.landed_holder.icon_state = old_dest_icon_state
|
||||
new_dest.landed_holder.overlays = old_dest_overlays
|
||||
new_dest.landed_holder.underlays = old_dest_underlays
|
||||
new_dest.landed_holder.decals = old_dest_decals
|
||||
|
||||
//Update underlays if necessary (interior corners won't have changed).
|
||||
if(new_dest.takes_underlays && !new_dest.interior_corner)
|
||||
@@ -65,6 +72,9 @@
|
||||
new_source.icon = icon
|
||||
new_source.overlays = overlays
|
||||
new_source.underlays = underlays
|
||||
new_source.decals = decals
|
||||
if(new_source.decals)
|
||||
new_source.apply_decals()
|
||||
else
|
||||
new_source = my_turf.ChangeTurf(get_base_turf_by_area(my_turf),,1)
|
||||
|
||||
@@ -93,6 +103,8 @@
|
||||
return 0
|
||||
|
||||
var/turf/under //May be a path or a turf
|
||||
var/mutable_appearance/us = new(src) //We'll use this for changes later
|
||||
us.underlays.Cut()
|
||||
|
||||
//Mapper wanted something specific
|
||||
if(under_turf)
|
||||
@@ -100,8 +112,10 @@
|
||||
|
||||
//Well if this isn't our first rodeo, we know EXACTLY what we landed on, and it looks like this.
|
||||
if(landed_holder && !interior_corner)
|
||||
underlays.Cut()
|
||||
underlays += image(landed_holder,layer=FLOAT_LAYER)
|
||||
var/mutable_appearance/landed_on = new(landed_holder)
|
||||
landed_on.layer = FLOAT_LAYER //Not turf
|
||||
us.underlays = list(landed_on)
|
||||
appearance = us
|
||||
return
|
||||
|
||||
if(!under)
|
||||
@@ -122,20 +136,26 @@
|
||||
else
|
||||
under = get_base_turf_by_area(src)
|
||||
|
||||
var/use_icon = ispath(under) ? initial(under.icon) : under.icon
|
||||
var/use_icon_state
|
||||
|
||||
if(istype(under,/turf/simulated/shuttle))
|
||||
interior_corner = 1 //Prevents us from 'landing on grass' and having interior corners update.
|
||||
|
||||
if(ispath(under,/turf/space))
|
||||
use_icon_state = "[rand(1,25)]" //Space turfs should be random.
|
||||
else
|
||||
use_icon_state = ispath(under) ? initial(under.icon_state) : under.icon_state
|
||||
var/mutable_appearance/under_ma
|
||||
|
||||
var/image/under_image = new(use_icon,icon_state = use_icon_state)
|
||||
underlays.Cut()
|
||||
underlays |= under_image
|
||||
if(ispath(under)) //It's just a mapper-specified path
|
||||
under_ma = new()
|
||||
under_ma.icon = initial(under.icon)
|
||||
under_ma.icon_state = initial(under.icon_state)
|
||||
under_ma.color = initial(under.color)
|
||||
|
||||
else //It's a real turf
|
||||
under_ma = new(under)
|
||||
|
||||
if(under_ma)
|
||||
if(ispath(under,/turf/space)) //Scramble space turfs
|
||||
under_ma.icon_state = "[rand(1,25)]"
|
||||
us.underlays = list(under_ma)
|
||||
|
||||
appearance = us
|
||||
|
||||
return under
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/turf/simulated/mineral/cave
|
||||
oxygen = MOLES_O2STANDARD
|
||||
nitrogen = MOLES_N2STANDARD
|
||||
temperature = T20C
|
||||
|
||||
/turf/simulated/mineral/ignore_mapgen/cave
|
||||
oxygen = MOLES_O2STANDARD
|
||||
nitrogen = MOLES_N2STANDARD
|
||||
temperature = T20C
|
||||
|
||||
/turf/simulated/mineral/floor/cave
|
||||
oxygen = MOLES_O2STANDARD
|
||||
nitrogen = MOLES_N2STANDARD
|
||||
temperature = T20C
|
||||
|
||||
/turf/simulated/mineral/floor/ignore_mapgen/cave
|
||||
oxygen = MOLES_O2STANDARD
|
||||
nitrogen = MOLES_N2STANDARD
|
||||
temperature = T20C
|
||||
@@ -31,9 +31,13 @@
|
||||
update_icon()
|
||||
|
||||
|
||||
/turf/simulated/wall/proc/set_material(var/material/newmaterial, var/material/newrmaterial)
|
||||
/turf/simulated/wall/proc/set_material(var/material/newmaterial, var/material/newrmaterial, var/material/newgmaterial)
|
||||
material = newmaterial
|
||||
reinf_material = newrmaterial
|
||||
if(!newgmaterial)
|
||||
girder_material = DEFAULT_WALL_MATERIAL
|
||||
else
|
||||
girder_material = newgmaterial
|
||||
update_material()
|
||||
|
||||
/turf/simulated/wall/update_icon()
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
var/global/damage_overlays[16]
|
||||
var/active
|
||||
var/can_open = 0
|
||||
var/material/girder_material
|
||||
var/material/material
|
||||
var/material/reinf_material
|
||||
var/last_state
|
||||
@@ -26,12 +27,15 @@
|
||||
for(var/obj/O in src)
|
||||
O.hide(1)
|
||||
|
||||
/turf/simulated/wall/New(var/newloc, var/materialtype, var/rmaterialtype)
|
||||
/turf/simulated/wall/New(var/newloc, var/materialtype, var/rmaterialtype, var/girdertype)
|
||||
..(newloc)
|
||||
icon_state = "blank"
|
||||
if(!materialtype)
|
||||
materialtype = DEFAULT_WALL_MATERIAL
|
||||
material = get_material_by_name(materialtype)
|
||||
if(!girdertype)
|
||||
girdertype = DEFAULT_WALL_MATERIAL
|
||||
girder_material = get_material_by_name(girdertype)
|
||||
if(!isnull(rmaterialtype))
|
||||
reinf_material = get_material_by_name(rmaterialtype)
|
||||
update_material()
|
||||
@@ -120,18 +124,18 @@
|
||||
. = ..(user)
|
||||
|
||||
if(!damage)
|
||||
user << "<span class='notice'>It looks fully intact.</span>"
|
||||
to_chat(user, "<span class='notice'>It looks fully intact.</span>")
|
||||
else
|
||||
var/dam = damage / material.integrity
|
||||
if(dam <= 0.3)
|
||||
user << "<span class='warning'>It looks slightly damaged.</span>"
|
||||
to_chat(user, "<span class='warning'>It looks slightly damaged.</span>")
|
||||
else if(dam <= 0.6)
|
||||
user << "<span class='warning'>It looks moderately damaged.</span>"
|
||||
to_chat(user, "<span class='warning'>It looks moderately damaged.</span>")
|
||||
else
|
||||
user << "<span class='danger'>It looks heavily damaged.</span>"
|
||||
to_chat(user, "<span class='danger'>It looks heavily damaged.</span>")
|
||||
|
||||
if(locate(/obj/effect/overlay/wallrot) in src)
|
||||
user << "<span class='warning'>There is fungus growing on [src].</span>"
|
||||
to_chat(user, "<span class='warning'>There is fungus growing on [src].</span>")
|
||||
|
||||
//Damage
|
||||
|
||||
@@ -186,9 +190,9 @@
|
||||
playsound(src, 'sound/items/Welder.ogg', 100, 1)
|
||||
if(!no_product)
|
||||
if(reinf_material)
|
||||
reinf_material.place_dismantled_girder(src, reinf_material)
|
||||
reinf_material.place_dismantled_girder(src, reinf_material, girder_material)
|
||||
else
|
||||
material.place_dismantled_girder(src)
|
||||
material.place_dismantled_girder(src, null, girder_material)
|
||||
if(!devastated)
|
||||
material.place_dismantled_product(src)
|
||||
if (!reinf_material)
|
||||
@@ -204,6 +208,7 @@
|
||||
clear_plants()
|
||||
material = get_material_by_name("placeholder")
|
||||
reinf_material = null
|
||||
girder_material = null
|
||||
update_connections(1)
|
||||
|
||||
ChangeTurf(/turf/simulated/floor/plating)
|
||||
@@ -211,10 +216,9 @@
|
||||
/turf/simulated/wall/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
if(check_destroy_override())
|
||||
src.ChangeTurf(destroy_floor_override_path)
|
||||
else
|
||||
src.ChangeTurf(get_base_turf_by_area(src)) //VOREStation Edit - Use area base turf
|
||||
if(girder_material.explosion_resistance >= 25 && prob(girder_material.explosion_resistance))
|
||||
new /obj/structure/girder/displaced(src, girder_material.name)
|
||||
src.ChangeTurf(get_base_turf_by_area(src))
|
||||
if(2.0)
|
||||
if(prob(75))
|
||||
take_damage(rand(150, 250))
|
||||
@@ -250,12 +254,15 @@
|
||||
O.density = 1
|
||||
O.layer = 5
|
||||
|
||||
src.ChangeTurf(/turf/simulated/floor/plating)
|
||||
if(girder_material.integrity >= 150 && !girder_material.is_brittle()) //Strong girders will remain in place when a wall is melted.
|
||||
dismantle_wall(1,1)
|
||||
else
|
||||
src.ChangeTurf(/turf/simulated/floor/plating)
|
||||
|
||||
var/turf/simulated/floor/F = src
|
||||
F.burn_tile()
|
||||
F.icon_state = "wall_thermite"
|
||||
user << "<span class='warning'>The thermite starts melting through the wall.</span>"
|
||||
F.icon_state = "dmg[rand(1,4)]"
|
||||
to_chat(user, "<span class='warning'>The thermite starts melting through the wall.</span>")
|
||||
|
||||
spawn(100)
|
||||
if(O)
|
||||
@@ -264,7 +271,7 @@
|
||||
return
|
||||
|
||||
/turf/simulated/wall/proc/radiate()
|
||||
var/total_radiation = material.radioactivity + (reinf_material ? reinf_material.radioactivity / 2 : 0)
|
||||
var/total_radiation = material.radioactivity + (reinf_material ? reinf_material.radioactivity / 2 : 0) + (girder_material ? girder_material.radioactivity / 2 : 0)
|
||||
if(!total_radiation)
|
||||
return
|
||||
|
||||
@@ -274,7 +281,7 @@
|
||||
/turf/simulated/wall/proc/burn(temperature)
|
||||
if(material.combustion_effect(src, temperature, 0.7))
|
||||
spawn(2)
|
||||
new /obj/structure/girder(src)
|
||||
new /obj/structure/girder(src, girder_material.name)
|
||||
src.ChangeTurf(/turf/simulated/floor)
|
||||
for(var/turf/simulated/wall/W in range(3,src))
|
||||
W.burn((temperature/4))
|
||||
|
||||
@@ -91,7 +91,7 @@ turf/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
return
|
||||
if(istype(O, /obj/screen))
|
||||
return
|
||||
if(user.restrained() || user.stat || user.stunned || user.paralysis)
|
||||
if(user.restrained() || user.stat || user.stunned || user.paralysis || (!user.lying && !istype(user, /mob/living/silicon/robot)))
|
||||
return
|
||||
if((!(istype(O, /atom/movable)) || O.anchored || !Adjacent(user) || !Adjacent(O) || !user.Adjacent(O)))
|
||||
return
|
||||
|
||||
@@ -12,9 +12,14 @@
|
||||
// Called after turf replaces old one
|
||||
/turf/proc/post_change()
|
||||
levelupdate()
|
||||
var/turf/simulated/open/T = GetAbove(src)
|
||||
if(istype(T))
|
||||
T.update_icon()
|
||||
|
||||
var/turf/simulated/open/above = GetAbove(src)
|
||||
if(istype(above))
|
||||
above.update_icon()
|
||||
|
||||
var/turf/simulated/below = GetBelow(src)
|
||||
if(istype(below))
|
||||
below.update_icon() // To add or remove the 'ceiling-less' overlay.
|
||||
|
||||
//Creates a new turf
|
||||
/turf/proc/ChangeTurf(var/turf/N, var/tell_universe=1, var/force_lighting_update = 0)
|
||||
|
||||
@@ -22,14 +22,26 @@
|
||||
/turf/simulated/floor/beach
|
||||
name = "Beach"
|
||||
icon = 'icons/misc/beach.dmi'
|
||||
footstep_sounds = list("human" = list(
|
||||
'sound/effects/footstep/carpet1.ogg',
|
||||
'sound/effects/footstep/carpet2.ogg',
|
||||
'sound/effects/footstep/carpet3.ogg',
|
||||
'sound/effects/footstep/carpet4.ogg',
|
||||
'sound/effects/footstep/carpet5.ogg'))
|
||||
|
||||
/turf/simulated/floor/beach/sand
|
||||
name = "Sand"
|
||||
icon_state = "sand"
|
||||
|
||||
/turf/simulated/floor/beach/sand/desert
|
||||
icon = 'icons/turf/desert.dmi'
|
||||
icon_state = "desert"
|
||||
|
||||
/turf/simulated/floor/beach/sand/desert/initialize()
|
||||
..()
|
||||
if(prob(5))
|
||||
icon_state = "desert[rand(0,4)]"
|
||||
|
||||
/turf/simulated/floor/beach/coastline
|
||||
name = "Coastline"
|
||||
icon = 'icons/misc/beach2.dmi'
|
||||
|
||||
@@ -55,6 +55,10 @@ var/list/planetary_walls = list()
|
||||
nitrogen = 114.50978 * 0.819
|
||||
temperature = 243.15 // Roughly -30C / -22F
|
||||
|
||||
//High Alt Sif
|
||||
/turf/unsimulated/wall/planetary/sif/alt
|
||||
temperature = 225.15
|
||||
|
||||
// Fairly close to Mars in terms of temperature and pressure.
|
||||
/turf/unsimulated/wall/planetary/magni
|
||||
carbon_dioxide = 0.90998361
|
||||
|
||||
@@ -38,17 +38,6 @@ var/changelog_hash = ""
|
||||
var/game_year = (text2num(time2text(world.realtime, "YYYY")) + 544)
|
||||
var/round_progressing = 1
|
||||
|
||||
//On some maps, it does not make sense for space turf to appear when something blows up (e.g. on an asteroid colony, or planetside)
|
||||
//The turf listed here is what is created after ex_act() and other tile-destroying procs are called on a turf that
|
||||
//is not already in a blacklisted area.
|
||||
//Set to 1 to enable it.
|
||||
var/destroy_floor_override = 1
|
||||
//Below is the path of turf used in place of space tiles.
|
||||
var/destroy_floor_override_path = /turf/simulated/mineral/floor
|
||||
//A list of z-levels to apply the override to. This is so z-levels like tcomms work as they did before.
|
||||
var/list/destroy_floor_override_z_levels = list(1,4,5)
|
||||
//Some areas you may want to not turn into the override path you made above, like space or the solars.
|
||||
var/list/destroy_floor_override_ignore_areas = list(/area/space,/area/solar,/area/shuttle)
|
||||
var/master_mode = "extended" // "extended"
|
||||
var/secret_force_mode = "secret" // if this is anything but "secret", the secret rotation will forceably choose this mode.
|
||||
|
||||
|
||||
@@ -103,7 +103,6 @@ var/list/admin_verbs_admin = list(
|
||||
/datum/admins/proc/paralyze_mob,
|
||||
/client/proc/fixatmos,
|
||||
/datum/admins/proc/quick_nif, //VOREStation Add,
|
||||
/datum/admins/proc/assistant_ratio, //VOREStation Add,
|
||||
/datum/admins/proc/sendFax
|
||||
)
|
||||
|
||||
@@ -510,9 +509,11 @@ var/list/admin_verbs_event_manager = list(
|
||||
|
||||
if(choice == "Show 'em!" && mob.plane_holder)
|
||||
mob.plane_holder.set_vis(VIS_GHOSTS,TRUE)
|
||||
usr.see_invisible = SEE_INVISIBLE_CULT
|
||||
to_chat(src,"<span class='notice'>Ghosts are now visible (while in this mob).</span>")
|
||||
else if(mob.plane_holder)
|
||||
mob.plane_holder.set_vis(VIS_GHOSTS,FALSE)
|
||||
usr.see_invisible = initial(mob.see_invisible)
|
||||
to_chat(src,"<span class='notice'>Ghosts are now hidden (while in this mob).</span>")
|
||||
|
||||
/client/proc/invisimin()
|
||||
@@ -786,11 +787,11 @@ var/list/admin_verbs_event_manager = list(
|
||||
set category = "Debug"
|
||||
set name = "Kill Air"
|
||||
set desc = "Toggle Air Processing"
|
||||
if(air_processing_killed)
|
||||
air_processing_killed = 0
|
||||
if(!SSair.can_fire)
|
||||
SSair.can_fire = TRUE
|
||||
usr << "<b>Enabled air processing.</b>"
|
||||
else
|
||||
air_processing_killed = 1
|
||||
SSair.can_fire = FALSE
|
||||
usr << "<b>Disabled air processing.</b>"
|
||||
feedback_add_details("admin_verb","KA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
log_admin("[key_name(usr)] used 'kill air'.")
|
||||
@@ -1051,6 +1052,8 @@ var/list/admin_verbs_event_manager = list(
|
||||
set name = "Man Up"
|
||||
set desc = "Tells mob to man up and deal with it."
|
||||
|
||||
if(alert("Are you sure you want to tell them to man up?","Confirmation","Deal with it","No")=="No") return
|
||||
|
||||
T << "<span class='notice'><b><font size=3>Man up and deal with it.</font></b></span>"
|
||||
T << "<span class='notice'>Move on.</span>"
|
||||
|
||||
@@ -1062,6 +1065,8 @@ var/list/admin_verbs_event_manager = list(
|
||||
set name = "Man Up Global"
|
||||
set desc = "Tells everyone to man up and deal with it."
|
||||
|
||||
if(alert("Are you sure you want to tell the whole server up?","Confirmation","Deal with it","No")=="No") return
|
||||
|
||||
for (var/mob/T as mob in mob_list)
|
||||
T << "<br><center><span class='notice'><b><font size=4>Man up.<br> Deal with it.</font></b><br>Move on.</span></center><br>"
|
||||
T << 'sound/voice/ManUp1.ogg'
|
||||
|
||||
@@ -378,10 +378,15 @@
|
||||
qdel(adminmob)
|
||||
feedback_add_details("admin_verb","ADC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/take_picture(var/atom/A in world)
|
||||
set name = "Save PNG"
|
||||
set category = "Debug"
|
||||
set desc = "Opens a dialog to save a PNG of any object in the game."
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
|
||||
|
||||
downloadImage(A)
|
||||
|
||||
/client/proc/cmd_admin_areatest()
|
||||
set category = "Mapping"
|
||||
|
||||
@@ -30,18 +30,3 @@
|
||||
|
||||
log_and_message_admins("[key_name(src)] Quick NIF'd [H.real_name].")
|
||||
feedback_add_details("admin_verb","QNIF") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/datum/admins/proc/assistant_ratio()
|
||||
set category = "Admin"
|
||||
set name = "Toggle Asst. Ratio"
|
||||
set desc = "Toggles the assistant ratio enforcement on/off."
|
||||
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
if(isnull(config.assistants_ratio))
|
||||
to_chat(usr,"<span class='warning'>Assistant ratio enforcement isn't even turned on...</span>")
|
||||
return
|
||||
|
||||
config.assistants_ratio *= -1
|
||||
to_chat(usr,"<span class='notice'>Assistant ratio enforcement now [config.assistants_ratio > 0 ? "<b>en</b>abled" : "<b>dis</b>abled"].</span>")
|
||||
|
||||
@@ -45,10 +45,7 @@
|
||||
|
||||
usr << "\[4/5\] - All turfs reset to roundstart values."
|
||||
|
||||
qdel(air_master)
|
||||
air_master = new
|
||||
air_master.Setup()
|
||||
spawn air_master.Start()
|
||||
SSair.RebootZAS()
|
||||
|
||||
usr << "\[5/5\] - ZAS Rebooted"
|
||||
world << "<span class = 'danger'>Atmosphere restart completed in <b>[(world.timeofday - current_time)/10]</b> seconds.</span>"
|
||||
@@ -41,7 +41,12 @@
|
||||
if(!map)
|
||||
return
|
||||
template = map_templates[map]
|
||||
|
||||
|
||||
if(template.width > world.maxx || template.height > world.maxy)
|
||||
if(alert(usr,"This template is larger than the existing z-levels. It will EXPAND ALL Z-LEVELS to match the size of the template. This may cause chaos. Are you sure you want to do this?","DANGER!!!","Cancel","Yes") == "Cancel")
|
||||
to_chat(usr,"Template placement aborted.")
|
||||
return
|
||||
|
||||
if(alert(usr,"Confirm map load.", "Template Confirm","No","Yes") == "Yes")
|
||||
if(template.load_new_z())
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has placed a map template ([template.name]) on Z level [world.maxz].</span>")
|
||||
|
||||
@@ -162,7 +162,8 @@ var/list/debug_verbs = list (
|
||||
,/datum/admins/proc/setup_supermatter
|
||||
,/client/proc/atmos_toggle_debug
|
||||
,/client/proc/spawn_tanktransferbomb
|
||||
,/client/proc/debug_process_scheduler
|
||||
,/client/proc/debug_process_scheduler // VOREStation Edit - Nice
|
||||
,/client/proc/take_picture
|
||||
)
|
||||
|
||||
|
||||
@@ -274,14 +275,7 @@ var/list/debug_verbs = list (
|
||||
set name = "Reboot ZAS"
|
||||
|
||||
if(alert("This will destroy and remake all zone geometry on the whole map.","Reboot ZAS","Reboot ZAS","Nevermind") == "Reboot ZAS")
|
||||
var/datum/controller/air_system/old_air = air_master
|
||||
for(var/zone/zone in old_air.zones)
|
||||
zone.c_invalidate()
|
||||
qdel(old_air)
|
||||
air_master = new
|
||||
air_master.Setup()
|
||||
spawn air_master.Start()
|
||||
|
||||
SSair.RebootZAS()
|
||||
|
||||
/client/proc/count_objects_on_z_level()
|
||||
set category = "Mapping"
|
||||
|
||||
@@ -392,8 +392,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
var/samejob = alert(src,"Found [picked_client.prefs.real_name] in data core. They were [record_found.fields["real_rank"]] this round. Assign same job? They will not be re-added to the manifest/records, either way.","Previously spawned","Yes","Assistant","No")
|
||||
if(samejob == "Yes")
|
||||
charjob = record_found.fields["real_rank"]
|
||||
else if(samejob == "Assistant")
|
||||
charjob = "Assistant"
|
||||
else if(samejob == USELESS_JOB) //VOREStation Edit - Visitor not Assistant
|
||||
charjob = USELESS_JOB //VOREStation Edit - Visitor not Assistant
|
||||
else
|
||||
records = alert(src,"No data core entry detected. Would you like add them to the manifest, and sec/med/HR records?","Records","Yes","No","Cancel")
|
||||
if(records == "Cancel")
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user