# 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:
Kelshark
2018-02-02 19:25:51 -05:00
382 changed files with 13820 additions and 17519 deletions
+1
View File
@@ -6,6 +6,7 @@ Thumbs.db
*.dmb
*.lk
*.backup
*.pyc
data/
cfg/
+12 -12
View File
@@ -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
+8 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+7 -1
View File
@@ -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"
-8
View File
@@ -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
+6
View File
@@ -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
+4
View File
@@ -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
+5 -2
View File
@@ -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
+1 -1
View File
@@ -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"
+3
View File
@@ -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
View File
@@ -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.
+6 -6
View File
@@ -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
+1
View File
@@ -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
+10
View File
@@ -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
+5
View File
@@ -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.
+4
View File
@@ -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()
+16
View File
@@ -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
-7
View File
@@ -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
+8
View File
@@ -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)
+6
View File
@@ -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
+8
View File
@@ -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")
+12 -6
View File
@@ -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
-3
View File
@@ -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
-1
View File
@@ -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
+271
View File
@@ -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
+163
View File
@@ -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
+1 -1
View File
@@ -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)
+31 -1
View File
@@ -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.
+81
View File
@@ -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
View File
@@ -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()
+6 -2
View File
@@ -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
+20
View File
@@ -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
+2 -1
View File
@@ -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"
+7
View File
@@ -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
+9
View File
@@ -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,
+12
View File
@@ -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),
-1
View File
@@ -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"
+6
View File
@@ -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
+28 -5
View File
@@ -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
+1 -1
View File
@@ -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
+35 -8
View File
@@ -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
+5 -5
View File
@@ -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")
+4 -3
View File
@@ -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)
+8 -1
View File
@@ -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)
+81
View File
@@ -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
-194
View File
@@ -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)
+5 -5
View File
@@ -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
+3 -7
View File
@@ -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
)
+1 -1
View File
@@ -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
+6 -1
View File
@@ -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
+5 -2
View File
@@ -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
+18 -12
View File
@@ -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()
+10 -4
View File
@@ -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 -2
View File
@@ -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
+3 -1
View File
@@ -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
+1 -5
View File
@@ -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))
+19 -1
View File
@@ -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
+17 -6
View File
@@ -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."
+54
View File
@@ -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 ..()
+1 -4
View File
@@ -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"
+31
View File
@@ -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)
+8
View File
@@ -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)
+127 -39
View File
@@ -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()
+13
View File
@@ -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,
+2 -2
View File
@@ -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)
-10
View File
@@ -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)
+10 -10
View File
@@ -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
+15
View File
@@ -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)
+33 -13
View File
@@ -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
+5 -1
View File
@@ -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()
+24 -17
View File
@@ -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))
+1 -1
View File
@@ -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
+8 -3
View File
@@ -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)
+12
View File
@@ -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'
+4
View File
@@ -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
-11
View File
@@ -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.
+9 -4
View File
@@ -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'
+7 -2
View File
@@ -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"
-15
View File
@@ -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>")
+1 -4
View File
@@ -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>")
+3 -9
View File
@@ -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"
+2 -2
View File
@@ -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