Merge remote-tracking branch 'upstream/master' into pol-baycomps

This commit is contained in:
Aronai Sieyes
2020-03-31 10:47:47 -04:00
664 changed files with 25682 additions and 5900 deletions
+2
View File
@@ -1,5 +1,7 @@
#ignore misc BYOND files
Thumbs.db
vchat.db
vchat.db*
*.log
*.int
*.rsc
+31 -27
View File
@@ -1,16 +1,12 @@
#pretending we're C because otherwise ruby will initialize, even with "language: dm".
language: c
sudo: false
env:
global:
- BASENAME="polaris" # $BASENAME.dmb, $BASENAME.dme, etc.
- BYOND_MAJOR="513"
- BYOND_MINOR="1502"
- BYOND_MINOR="1513"
- 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:
@@ -22,30 +18,38 @@ addons:
- libc6-i386
- libgcc1:i386
- libstdc++6:i386
- libssl-dev:i386
before_script:
- chmod +x ./install-byond.sh
- ./install-byond.sh
before_install:
- chmod -R +x ./tools/travis
install:
- pip install --user PyYaml -q
- pip install --user beautifulsoup4 -q
- ./tools/travis/install_byond.sh
before_script:
- shopt -s globstar
script:
- shopt -s globstar
- (! grep 'step_[xy]' maps/**/*.dmm)
- (! grep -Pn '( |\t|;|{)tag( ?)=' maps/**/*.dmm)
- (! find nano/templates/ -type f -exec md5sum {} + | sort | uniq -D -w 32 | grep nano)
- (! grep -En "<\s*span\s+class\s*=\s*('[^'>]+|[^'>]+')\s*>" **/*.dm)
- awk -f tools/indentation.awk **/*.dm
- md5sum -c - <<< "88490b460c26947f5ec1ab1bb9fa9f17 *html/changelogs/example.yml"
- (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 ../..
# Run our test
- cp config/example/* config/
- echo "#define ${TEST_DEFINE} 1" > ${TEST_FILE}
- DreamMaker polaris.dme
- if [ $RUN -eq 1 ]; then DreamDaemon polaris.dmb -invisible -trusted -core 2>&1 | tee log.txt; fi
- if [ $RUN -eq 1 ]; then grep "All Unit Tests Passed" log.txt; fi
- ./tools/travis/compile_and_run.sh
# Build-specific settings
jobs:
include:
- stage: "File Tests" #This is the odd man out, with specific installs and stuff.
name: "Validate Files"
install: #Need python for some of the tag matching stuff
- pip install --user PyYaml -q
- pip install --user beautifulsoup4 -q
script: ./tools/travis/validate_files.sh
addons:
apt:
packages: ~ # Don't need any packages for this
- stage: "Unit Tests"
env: TEST_DEFINE="UNIT_TEST" TEST_FILE="code/_unit_tests.dm" RUN="1"
name: "Compile normally (unit tests)"
- stage: "Isolation Tests"
env: TEST_DEFINE="MAP_TEST" TEST_FILE="code/_map_tests.dm" RUN="0"
name: "Compile POIs (no run)"
- env: TEST_DEFINE="AWAY_MISSION_TEST" TEST_FILE="code/_away_mission_tests.dm" RUN="0"
name: "Compile away missions (no run)"
@@ -1,7 +1,7 @@
/obj/machinery/atmospherics/binary
dir = SOUTH
initialize_directions = SOUTH|NORTH
use_power = 1
use_power = USE_POWER_IDLE
var/datum/gas_mixture/air1
var/datum/gas_mixture/air2
@@ -20,7 +20,7 @@
level = 1
use_power = 0
use_power = USE_POWER_OFF
idle_power_usage = 150 //internal circuitry, friction losses and stuff
power_rating = 7500 //7500 W ~ 10 HP
@@ -214,10 +214,10 @@
if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command"))
return 0
if(signal.data["power"])
use_power = text2num(signal.data["power"])
update_use_power(text2num(signal.data["power"]))
if(signal.data["power_toggle"])
use_power = !use_power
update_use_power(!use_power)
if(signal.data["direction"])
pump_direction = text2num(signal.data["direction"])
@@ -12,7 +12,7 @@
name = "pressure regulator"
desc = "A one-way air valve that can be used to regulate input or output pressure, and flow rate. Does not require power."
use_power = 0
use_power = USE_POWER_OFF
var/unlocked = 0 //If 0, then the valve is locked closed, otherwise it is open(-able, it's a one-way valve so it closes if gas would flow backwards).
var/target_pressure = ONE_ATMOSPHERE
@@ -26,7 +26,7 @@ Thus, the two variables affect pump operation are set in New():
//var/max_volume_transfer = 10000
use_power = 0
use_power = USE_POWER_OFF
idle_power_usage = 150 //internal circuitry, friction losses and stuff
power_rating = 7500 //7500 W ~ 10 HP
@@ -47,7 +47,7 @@ Thus, the two variables affect pump operation are set in New():
/obj/machinery/atmospherics/binary/pump/on
icon_state = "map_on"
use_power = 1
use_power = USE_POWER_IDLE
/obj/machinery/atmospherics/binary/pump/update_icon()
@@ -160,12 +160,12 @@ Thus, the two variables affect pump operation are set in New():
if(signal.data["power"])
if(text2num(signal.data["power"]))
use_power = 1
update_use_power(USE_POWER_IDLE)
else
use_power = 0
update_use_power(USE_POWER_OFF)
if("power_toggle" in signal.data)
use_power = !use_power
update_use_power(!use_power)
if(signal.data["set_output_pressure"])
target_pressure = between(
@@ -199,7 +199,7 @@ Thus, the two variables affect pump operation are set in New():
if(..()) return 1
if(href_list["power"])
use_power = !use_power
update_use_power(!use_power)
switch(href_list["set_press"])
if ("min")
@@ -11,7 +11,7 @@
power_rating = 15000 //15000 W ~ 20 HP
/obj/machinery/atmospherics/binary/pump/high_power/on
use_power = 1
use_power = USE_POWER_IDLE
icon_state = "map_on"
/obj/machinery/atmospherics/binary/pump/high_power/update_icon()
@@ -11,7 +11,7 @@
var/datum/omni_port/input
var/datum/omni_port/output
use_power = 1
use_power = USE_POWER_IDLE
idle_power_usage = 150 //internal circuitry, friction losses and stuff
power_rating = 7500 //7500 W ~ 10 HP
@@ -161,13 +161,13 @@
switch(href_list["command"])
if("power")
if(!configuring)
use_power = !use_power
update_use_power(!use_power)
else
use_power = 0
update_use_power(USE_POWER_OFF)
if("configure")
configuring = !configuring
if(configuring)
use_power = 0
update_use_power(USE_POWER_OFF)
//only allows config changes when in configuring mode ~otherwise you'll get weird pressure stuff going on
if(configuring && !use_power)
@@ -6,7 +6,7 @@
icon_state = "map_mixer"
pipe_state = "omni_mixer"
use_power = 1
use_power = USE_POWER_IDLE
idle_power_usage = 150 //internal circuitry, friction losses and stuff
power_rating = 3700 //3700 W ~ 5 HP
@@ -178,13 +178,13 @@
switch(href_list["command"])
if("power")
if(!configuring)
use_power = !use_power
update_use_power(!use_power)
else
use_power = 0
update_use_power(USE_POWER_OFF)
if("configure")
configuring = !configuring
if(configuring)
use_power = 0
update_use_power(USE_POWER_OFF)
//only allows config changes when in configuring mode ~otherwise you'll get weird pressure stuff going on
if(configuring && !use_power)
@@ -5,7 +5,7 @@
name = "omni device"
icon = 'icons/atmos/omni_devices.dmi'
icon_state = "base"
use_power = 1
use_power = USE_POWER_IDLE
initialize_directions = 0
construction_type = /obj/item/pipe/quaternary
level = 1
@@ -67,7 +67,7 @@
last_flow_rate = 0
if(error_check())
use_power = 0
update_use_power(USE_POWER_OFF)
if((stat & (NOPOWER|BROKEN)) || !use_power)
return 0
@@ -18,7 +18,7 @@
var/datum/pipe_network/network
var/on = 0
use_power = 0
use_power = USE_POWER_OFF
level = 1
/obj/machinery/atmospherics/portables_connector/init_dir()
@@ -9,7 +9,7 @@
name = "Gas filter"
desc = "Filters one type of gas from an input, and pushes it out the side."
use_power = 1
use_power = USE_POWER_IDLE
idle_power_usage = 150 //internal circuitry, friction losses and stuff
power_rating = 7500 //This also doubles as a measure of how powerful the filter is, in Watts. 7500 W ~ 10 HP
@@ -73,7 +73,7 @@
icon_state += use_power ? "on" : "off"
else
icon_state += "off"
use_power = 0
update_use_power(USE_POWER_OFF)
/obj/machinery/atmospherics/trinary/atmos_filter/process()
..()
@@ -8,7 +8,7 @@
name = "Gas mixer"
use_power = 1
use_power = USE_POWER_IDLE
idle_power_usage = 150 //internal circuitry, friction losses and stuff
power_rating = 3700 //This also doubles as a measure of how powerful the mixer is, in Watts. 3700 W ~ 5 HP
@@ -35,7 +35,7 @@
icon_state += use_power ? "on" : "off"
else
icon_state += "off"
use_power = 0
update_use_power(USE_POWER_OFF)
/obj/machinery/atmospherics/trinary/mixer/New()
..()
@@ -114,7 +114,7 @@
/obj/machinery/atmospherics/trinary/mixer/Topic(href,href_list)
if(..()) return 1
if(href_list["power"])
use_power = !use_power
update_use_power(!use_power)
if(href_list["set_press"])
var/max_flow_rate = min(air1.volume, air2.volume)
var/new_flow_rate = input(usr,"Enter new flow rate limit (0-[max_flow_rate]L/s)","Flow Rate Control",src.set_flow_rate) as num
@@ -1,7 +1,7 @@
/obj/machinery/atmospherics/trinary
dir = SOUTH
initialize_directions = SOUTH|NORTH|WEST
use_power = 0
use_power = USE_POWER_OFF
pipe_flags = PIPING_DEFAULT_LAYER_ONLY|PIPING_ONE_PER_TURF
var/mirrored = FALSE
@@ -8,7 +8,7 @@
icon_state = "freezer_0"
density = 1
anchored = 1
use_power = 0
use_power = USE_POWER_OFF
idle_power_usage = 5 // 5 Watts for thermostat related circuitry
circuit = /obj/item/weapon/circuitboard/unary_atmos/cooler
@@ -99,7 +99,7 @@
if(..())
return 1
if(href_list["toggleStatus"])
use_power = !use_power
update_use_power(!use_power)
update_icon()
if(href_list["temp"])
var/amount = text2num(href_list["temp"])
@@ -8,7 +8,7 @@
icon_state = "heater_0"
density = 1
anchored = 1
use_power = 0
use_power = USE_POWER_OFF
idle_power_usage = 5 //5 Watts for thermostat related circuitry
circuit = /obj/item/weapon/circuitboard/unary_atmos/heater
@@ -119,7 +119,7 @@
if(..())
return 1
if(href_list["toggleStatus"])
use_power = !use_power
update_use_power(!use_power)
update_icon()
if(href_list["temp"])
var/amount = text2num(href_list["temp"])
@@ -10,7 +10,7 @@
name = "air injector"
desc = "Passively injects air into its surroundings. Has a valve attached to it that can control flow rate."
use_power = 0
use_power = USE_POWER_OFF
idle_power_usage = 150 //internal circuitry, friction losses and stuff
power_rating = 15000 //15000 W ~ 20 HP
@@ -132,10 +132,10 @@
return 0
if(signal.data["power"])
use_power = text2num(signal.data["power"])
update_use_power(text2num(signal.data["power"]))
if(signal.data["power_toggle"])
use_power = !use_power
update_use_power(!use_power)
if(signal.data["inject"])
spawn inject()
@@ -160,7 +160,7 @@
/obj/machinery/atmospherics/unary/outlet_injector/attack_hand(mob/user as mob)
to_chat(user, "<span class='notice'>You toggle \the [src].</span>")
injecting = !injecting
use_power = injecting
update_use_power(injecting ? USE_POWER_IDLE : USE_POWER_OFF)
update_icon()
/obj/machinery/atmospherics/unary/outlet_injector/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
@@ -14,7 +14,7 @@
name = "Air Vent"
desc = "Has a valve and pump attached to it"
use_power = 0
use_power = USE_POWER_OFF
idle_power_usage = 150 //internal circuitry, friction losses and stuff
power_rating = 7500 //7500 W ~ 10 HP
@@ -50,18 +50,18 @@
var/datum/looping_sound/air_pump/soundloop
/obj/machinery/atmospherics/unary/vent_pump/on
use_power = 1
use_power = USE_POWER_IDLE
icon_state = "map_vent_out"
/obj/machinery/atmospherics/unary/vent_pump/siphon
pump_direction = 0
/obj/machinery/atmospherics/unary/vent_pump/siphon/on
use_power = 1
use_power = USE_POWER_IDLE
icon_state = "map_vent_in"
/obj/machinery/atmospherics/unary/vent_pump/siphon/on/atmos
use_power = 1
use_power = USE_POWER_IDLE
icon_state = "map_vent_in"
external_pressure_bound = 0
external_pressure_bound_default = 0
@@ -173,7 +173,7 @@
return 1
if (!node)
use_power = 0
update_use_power(USE_POWER_OFF)
if(!can_pump())
return 0
@@ -295,10 +295,10 @@
pump_direction = 1
if(signal.data["power"] != null)
use_power = text2num(signal.data["power"])
update_use_power(text2num(signal.data["power"]))
if(signal.data["power_toggle"] != null)
use_power = !use_power
update_use_power(!use_power)
if(signal.data["checks"] != null)
if (signal.data["checks"] == "default")
@@ -5,7 +5,7 @@
name = "Air Scrubber"
desc = "Has a valve and pump attached to it"
use_power = 0
use_power = USE_POWER_OFF
idle_power_usage = 150 //internal circuitry, friction losses and stuff
power_rating = 7500 //7500 W ~ 10 HP
@@ -29,7 +29,7 @@
var/radio_filter_in
/obj/machinery/atmospherics/unary/vent_scrubber/on
use_power = 1
use_power = USE_POWER_IDLE
icon_state = "map_scrubber_on"
/obj/machinery/atmospherics/unary/vent_scrubber/New()
@@ -135,7 +135,7 @@
return 1
if (!node)
use_power = 0
update_use_power(USE_POWER_OFF)
//broadcast_status()
if(!use_power || (stat & (NOPOWER|BROKEN)))
return 0
@@ -180,21 +180,21 @@
return 0
if(signal.data["power"] != null)
use_power = text2num(signal.data["power"])
update_use_power(text2num(signal.data["power"]))
if(signal.data["power_toggle"] != null)
use_power = !use_power
update_use_power(!use_power)
if(signal.data["panic_siphon"]) //must be before if("scrubbing" thing
panic = text2num(signal.data["panic_siphon"])
if(panic)
use_power = 1
update_use_power(USE_POWER_IDLE)
scrubbing = 0
else
scrubbing = 1
if(signal.data["toggle_panic_siphon"] != null)
panic = !panic
if(panic)
use_power = 1
update_use_power(USE_POWER_IDLE)
scrubbing = 0
else
scrubbing = 1
+1 -1
View File
@@ -9,7 +9,7 @@
var/leaking = FALSE // Do not set directly, use set_leaking(TRUE/FALSE)
layer = PIPES_LAYER
use_power = 0
use_power = USE_POWER_OFF
pipe_flags = 0 // Does not have PIPING_DEFAULT_LAYER_ONLY flag.
+3
View File
@@ -11,6 +11,9 @@
//#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!
// Comment/Uncomment this to turn off/on shuttle code debugging logs
#define DEBUG_SHUTTLES
// 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
+3
View File
@@ -18,6 +18,9 @@
#define LAZYOR(L, I) if(!L) { L = list(); } L |= I;
// Adds I to L, initalizing L if necessary, if I is not already in L
#define LAZYDISTINCTADD(L, I) if(!L) { L = list(); } L |= I;
#define LAZYFIND(L, V) L ? L.Find(V) : 0
// Reads I from L safely - Works with both associative and traditional lists.
+6 -1
View File
@@ -42,6 +42,8 @@ What is the naming convention for planes or layers?
#define SPACE_PLANE -82 // Reserved for use in space/parallax
#define PARALLAX_PLANE -80 // Reserved for use in space/parallax
#define SKYBOX_PLANE -79 // Skybox parallax
#define DUST_PLANE -78 // For dust overlay on space turfs. Should be above skybox for parallax effect.
// OPENSPACE_PLANE reserves all planes between OPENSPACE_PLANE_START and OPENSPACE_PLANE_END inclusive
#define OPENSPACE_PLANE -75 // /turf/simulated/open will use OPENSPACE_PLANE + z (Valid z's being 2 thru 17)
@@ -50,7 +52,7 @@ What is the naming convention for planes or layers?
#define OVER_OPENSPACE_PLANE -57
// Turf Planes
#define SPACE_PLANE -43 // Space turfs themselves
#define SPACE_PLANE -82 // Space turfs themselves
#define PLATING_PLANE -44 // Plating
#define DISPOSAL_LAYER 2.1 // Under objects, even when planeswapped
#define PIPES_LAYER 2.2 // Under objects, even when planeswapped
@@ -86,6 +88,9 @@ What is the naming convention for planes or layers?
#define BELOW_MOB_LAYER 3.9 // Should be converted to plane swaps
#define ABOVE_MOB_LAYER 4.1 // Should be converted to plane swaps
// Invisible things plane
#define CLOAKED_PLANE -15
// Top plane (in the sense that it's the highest in 'the world' and not a UI element)
#define ABOVE_PLANE -10
+1
View File
@@ -29,6 +29,7 @@
#define MINIMUM_AIR_TO_SUSPEND (MOLES_CELLSTANDARD * MINIMUM_AIR_RATIO_TO_SUSPEND) // Minimum amount of air that has to move before a group processing can be suspended
#define MINIMUM_MOLES_DELTA_TO_MOVE (MOLES_CELLSTANDARD * MINIMUM_AIR_RATIO_TO_SUSPEND) // Either this must be active
#define MINIMUM_TEMPERATURE_TO_MOVE (T20C + 100) // or this (or both, obviously)
#define MINIMUM_PRESSURE_DIFFERENCE_TO_SUSPEND (MINIMUM_AIR_TO_SUSPEND*R_IDEAL_GAS_EQUATION*T20C)/CELL_VOLUME // Minimum pressure difference between zones to suspend
#define MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND 0.012 // Minimum temperature difference before group processing is suspended.
#define MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND 4
+1
View File
@@ -38,6 +38,7 @@
#define CONNECT_TYPE_SUPPLY 2
#define CONNECT_TYPE_SCRUBBER 4
#define CONNECT_TYPE_HE 8
#define CONNECT_TYPE_FUEL 16 // TODO - Implement this! Its piping so better ask Leshana
// We are based on the three named layers of supply, regular, and scrubber.
#define PIPING_LAYER_SUPPLY 1
+1
View File
@@ -6,6 +6,7 @@
//---------------
#define isatom(D) istype(D, /atom)
#define isclient(D) istype(D, /client)
//---------------
//#define isobj(D) istype(D, /obj) //Built in
+5
View File
@@ -11,6 +11,11 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called
#define DOOR_CRUSH_DAMAGE 20
#define ALIEN_SELECT_AFK_BUFFER 1 // How many minutes that a person can be AFK before not being allowed to be an alien.
// Constants for machine's use_power
#define USE_POWER_OFF 0 // No continuous power use
#define USE_POWER_IDLE 1 // Machine is using power at its idle power level
#define USE_POWER_ACTIVE 2 // Machine is using power at its active power level
// Channel numbers for power.
#define EQUIP 1
#define LIGHT 2
+3 -1
View File
@@ -80,7 +80,7 @@
#define COLOR_DARK_GRAY "#404040"
#define CLIENT_FROM_VAR(I) (ismob(I) ? I:client : (isclient(I) ? I : null))
// Shuttles.
@@ -106,6 +106,7 @@
#define FORCE_LAUNCH 2
#define WAIT_ARRIVE 3
#define WAIT_FINISH 4
#define DO_AUTOPILOT 5
// Setting this much higher than 1024 could allow spammers to DOS the server easily.
#define MAX_MESSAGE_LEN 1024
@@ -269,6 +270,7 @@
#define WORLD_ICON_SIZE 32 //Needed for the R-UST port
#define PIXEL_MULTIPLIER WORLD_ICON_SIZE/32 //Needed for the R-UST port
#define MAX_CLIENT_VIEW 34 // Maximum effective value of client.view (According to DM references)
// Maploader bounds indices
#define MAP_MINX 1
+3 -1
View File
@@ -396,7 +396,9 @@
#define VIS_BUILDMODE 22
#define VIS_COUNT 22 //Must be highest number from above.
#define VIS_CLOAKED 23
#define VIS_COUNT 23 //Must be highest number from above.
//Some mob icon layering defines
#define BODY_LAYER -100
+1
View File
@@ -26,6 +26,7 @@
#define QDEL_IN(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE)
#define QDEL_IN_CLIENT_TIME(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE | TIMER_CLIENT_TIME)
#define QDEL_NULL(item) qdel(item); item = null
#define QDEL_NULL_LIST QDEL_LIST_NULL
#define QDEL_LIST_NULL(x) if(x) { for(var/y in x) { qdel(y) } ; x = null }
#define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); }
#define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/______qdel_list_wrapper, L), time, TIMER_STOPPABLE)
+27
View File
@@ -0,0 +1,27 @@
// Shuttle flags
#define SHUTTLE_FLAGS_NONE 0
#define SHUTTLE_FLAGS_PROCESS 1 // Should be processed by shuttle subsystem
#define SHUTTLE_FLAGS_SUPPLY 2 // This is the supply shuttle. Why is this a tag?
#define SHUTTLE_FLAGS_ZERO_G 4 // Shuttle has no internal gravity generation
#define SHUTTLE_FLAGS_ALL (~SHUTTLE_FLAGS_NONE)
// shuttle_landmark flags
#define SLANDMARK_FLAG_AUTOSET 1 // If set, will set base area and turf type to same as where it was spawned at
#define SLANDMARK_FLAG_ZERO_G 2 // Zero-G shuttles moved here will lose gravity unless the area has ambient gravity.
// Overmap landable shuttles (/obj/effect/overmap/visitable/ship/landable on a /datum/shuttle/autodock/overmap)
#define SHIP_STATUS_LANDED 1 // Ship is at any other shuttle landmark.
#define SHIP_STATUS_TRANSIT 2 // Ship is at it's shuttle datum's transition shuttle landmark.
#define SHIP_STATUS_OVERMAP 3 // Ship is at its "overmap" shuttle landmark (allowed to move on overmap now)
// Ferry shuttle location constants
#define FERRY_LOCATION_STATION 0
#define FERRY_LOCATION_OFFSITE 1
#define FERRY_GOING_TO_STATION 0
#define FERRY_GOING_TO_OFFSITE 1
#ifndef DEBUG_SHUTTLES
#define log_shuttle(M)
#else
#define log_shuttle(M) log_debug("[M]")
#endif
+11 -4
View File
@@ -52,10 +52,11 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
// Subsystem init_order, from highest priority to lowest priority
// Subsystems shutdown in the reverse of the order they initialize in
// The numbers just define the ordering, they are meaningless otherwise.
#define INIT_ORDER_SQLITE 19
#define INIT_ORDER_CHEMISTRY 18
#define INIT_ORDER_MAPPING 17
#define INIT_ORDER_DECALS 16
#define INIT_ORDER_SQLITE 40
#define INIT_ORDER_CHEMISTRY 35
#define INIT_ORDER_SKYBOX 30
#define INIT_ORDER_MAPPING 25
#define INIT_ORDER_DECALS 20
#define INIT_ORDER_ATOMS 15
#define INIT_ORDER_MACHINES 10
#define INIT_ORDER_SHUTTLES 3
@@ -63,22 +64,27 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define INIT_ORDER_DEFAULT 0
#define INIT_ORDER_LIGHTING 0
#define INIT_ORDER_AIR -1
#define INIT_ORDER_ASSETS -3
#define INIT_ORDER_PLANETS -4
#define INIT_ORDER_HOLOMAPS -5
#define INIT_ORDER_OVERLAY -6
#define INIT_ORDER_ALARM -7
#define INIT_ORDER_XENOARCH -20
#define INIT_ORDER_CIRCUIT -21
#define INIT_ORDER_AI -22
#define INIT_ORDER_JOB -23
#define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init.
// Subsystem fire priority, from lowest to highest priority
// If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child)
#define FIRE_PRIORITY_SHUTTLES 5
#define FIRE_PRIORITY_SUPPLY 5
#define FIRE_PRIORITY_ORBIT 8
#define FIRE_PRIORITY_VOTE 9
#define FIRE_PRIORITY_AI 10
#define FIRE_PRIORITY_GARBAGE 15
#define FIRE_PRIORITY_ALARM 20
#define FIRE_PRIORITY_CHARSETUP 25
#define FIRE_PRIORITY_AIRFLOW 30
#define FIRE_PRIORITY_AIR 35
@@ -88,6 +94,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
#define FIRE_PRIORITY_PLANETS 75
#define FIRE_PRIORITY_MACHINES 100
#define FIRE_PRIORITY_PROJECTILES 150
#define FIRE_PRIORITY_CHAT 400
#define FIRE_PRIORITY_OVERLAYS 500
// Macro defining the actual code applying our overlays lists to the BYOND overlays list. (I guess a macro for speed)
+5 -1
View File
@@ -37,7 +37,11 @@
#define ARCHAEO_ALIEN_BOAT 37
#define ARCHAEO_IMPERION_CIRCUIT 38
#define ARCHAEO_TELECUBE 39
#define MAX_ARCHAEO 39
#define ARCHAEO_BATTERY 40
#define ARCHAEO_SYRINGE 41
#define ARCHAEO_RING 42
#define ARCHAEO_CLUB 43
#define MAX_ARCHAEO 43
#define DIGSITE_GARDEN 1
#define DIGSITE_ANIMAL 2
+2
View File
@@ -1,6 +1,8 @@
//Languages/species/whitelist.
GLOBAL_LIST_INIT(all_species, list())
GLOBAL_LIST_INIT(all_languages, list())
GLOBAL_LIST_INIT(language_name_conflicts, list())
GLOBAL_LIST_INIT(language_keys, list()) // Table of say codes for all languages
GLOBAL_LIST_INIT(language_key_conflicts, list())
GLOBAL_LIST_INIT(whitelisted_species, list(SPECIES_HUMAN)) // Species that require a whitelist check.
GLOBAL_LIST_INIT(playable_species, list(SPECIES_HUMAN)) // A list of ALL playable species, whitelisted, latejoin or otherwise.
+22 -1
View File
@@ -53,7 +53,7 @@
// atoms/items/objects can be pretty and whatnot
var/atom/A = item
if(output_icons && isicon(A.icon) && !ismob(A)) // mobs tend to have unusable icons
item_str += "\icon[A]&nbsp;"
item_str += "[bicon(A)]&nbsp;"
switch(determiners)
if(DET_NONE) item_str += A.name
if(DET_DEFINITE) item_str += "\the [A]"
@@ -206,6 +206,20 @@ proc/listclearnulls(list/list)
result = first - second
return result
/*
Two lists may be different (A!=B) even if they have the same elements.
This actually tests if they have the same entries and values.
*/
/proc/same_entries(var/list/first, var/list/second)
if(!islist(first) || !islist(second))
return 0
if(length(first) != length(second))
return 0
for(var/entry in first)
if(!(entry in second) || (first[entry] != second[entry]))
return 0
return 1
/*
* Returns list containing entries that are in either list but not both.
* If skipref = 1, repeated elements are treated as one.
@@ -308,6 +322,13 @@ proc/listclearnulls(list/list)
else
L[key] = temp[key]
// Return a list of the values in an assoc list (including null)
/proc/list_values(var/list/L)
var/list/V = list()
V.len = L.len // Preallocate!
for(var/i in 1 to L.len)
V[i] = L[L[i]] // We avoid += in case the value is itself a list
return V
//Mergesort: divides up the list into halves to begin the sort
/proc/sortKey(var/list/client/L, var/order = 1)
+16 -3
View File
@@ -153,17 +153,30 @@ var/global/list/string_slot_flags = list(
var/datum/job/J = new T
joblist[J.title] = J
//Languages and species.
//Languages
paths = typesof(/datum/language)-/datum/language
for(var/T in paths)
var/datum/language/L = new T
GLOB.all_languages[L.name] = L
if (isnull(GLOB.all_languages[L.name]))
GLOB.all_languages[L.name] = L
else
log_debug("Language name conflict! [T] is named [L.name], but that is taken by [GLOB.all_languages[L.name].type]")
if(isnull(GLOB.language_name_conflicts[L.name]))
GLOB.language_name_conflicts[L.name] = list(GLOB.all_languages[L.name])
GLOB.language_name_conflicts[L.name] += L
for (var/language_name in GLOB.all_languages)
var/datum/language/L = GLOB.all_languages[language_name]
if(!(L.flags & NONGLOBAL))
GLOB.language_keys[lowertext(L.key)] = L
if(isnull(GLOB.language_keys[L.key]))
GLOB.language_keys[L.key] = L
else
log_debug("Language key conflict! [L] has key [L.key], but that is taken by [(GLOB.language_keys[L.key])]")
if(isnull(GLOB.language_key_conflicts[L.key]))
GLOB.language_key_conflicts[L.key] = list(GLOB.language_keys[L.key])
GLOB.language_key_conflicts[L.key] += L
//Species
var/rkey = 0
paths = typesof(/datum/species)
for(var/T in paths)
+1 -1
View File
@@ -167,7 +167,7 @@ mob
Output_Icon()
set name = "2. Output Icon"
to_chat(src, "Icon is: \icon[getFlatIcon(src)]")
to_chat(src, "Icon is: [bicon(getFlatIcon(src))]")
Label_Icon()
set name = "3. Label Icon"
+6 -2
View File
@@ -301,11 +301,15 @@ proc/TextPreview(var/string,var/len=40)
//For generating neat chat tag-images
//The icon var could be local in the proc, but it's a waste of resources
// to always create it and then throw it out.
/var/icon/text_tag_icons = new('./icons/chattags.dmi')
/var/icon/text_tag_icons = 'icons/chattags.dmi'
/var/list/text_tag_cache = list()
/proc/create_text_tag(var/tagname, var/tagdesc = tagname, var/client/C = null)
if(!(C && C.is_preference_enabled(/datum/client_preference/chat_tags)))
return tagdesc
return "<IMG src='\ref[text_tag_icons.icon]' class='text_tag' iconstate='[tagname]'" + (tagdesc ? " alt='[tagdesc]'" : "") + ">"
if(!text_tag_cache[tagname])
var/icon/tag = icon(text_tag_icons, tagname)
text_tag_cache[tagname] = bicon(tag, TRUE, "text_tag")
return text_tag_cache[tagname]
/proc/contains_az09(var/input)
for(var/i=1, i<=length(input), i++)
+117 -1
View File
@@ -38,4 +38,120 @@
var/pressure = environment ? environment.return_pressure() : 0
if(pressure < SOUND_MINIMUM_PRESSURE)
return TRUE
return FALSE
return FALSE
/*
Turf manipulation
*/
//Returns an assoc list that describes how turfs would be changed if the
//turfs in turfs_src were translated by shifting the src_origin to the dst_origin
/proc/get_turf_translation(turf/src_origin, turf/dst_origin, list/turfs_src)
var/list/turf_map = list()
for(var/turf/source in turfs_src)
var/x_pos = (source.x - src_origin.x)
var/y_pos = (source.y - src_origin.y)
var/z_pos = (source.z - src_origin.z)
var/turf/target = locate(dst_origin.x + x_pos, dst_origin.y + y_pos, dst_origin.z + z_pos)
if(!target)
error("Null turf in translation @ ([dst_origin.x + x_pos], [dst_origin.y + y_pos], [dst_origin.z + z_pos])")
turf_map[source] = target //if target is null, preserve that information in the turf map
return turf_map
/proc/translate_turfs(var/list/translation, var/area/base_area = null, var/turf/base_turf)
for(var/turf/source in translation)
var/turf/target = translation[source]
if(target)
if(base_area) ChangeArea(target, get_area(source))
var/leave_turf = base_turf ? base_turf : get_base_turf_by_area(base_area ? base_area : source)
translate_turf(source, target, leave_turf)
if(base_area) ChangeArea(source, base_area)
//change the old turfs (Currently done by translate_turf for us)
//for(var/turf/source in translation)
// source.ChangeTurf(base_turf ? base_turf : get_base_turf_by_area(source), 1, 1)
// Parmaters for stupid historical reasons are:
// T - Origin
// B - Destination
/proc/translate_turf(var/turf/T, var/turf/B, var/turftoleave = null)
//You can stay, though.
if(istype(T,/turf/space))
error("Tried to translate a space turf: src=[log_info_line(T)] dst=[log_info_line(B)]")
return FALSE // TODO - Is this really okay to do nothing?
var/turf/X //New Destination Turf
//Are we doing shuttlework? Just to save another type check later.
var/shuttlework = 0
//Shuttle turfs handle their own fancy moving.
if(istype(T,/turf/simulated/shuttle))
shuttlework = 1
var/turf/simulated/shuttle/SS = T
if(!SS.landed_holder) SS.landed_holder = new(turf = SS)
X = SS.landed_holder.land_on(B)
//Generic non-shuttle turf move.
else
var/old_dir1 = T.dir
var/old_icon_state1 = T.icon_state
var/old_icon1 = T.icon
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)
X.icon_state = old_icon_state1
X.icon = old_icon1
X.copy_overlays(T, TRUE)
X.underlays = old_underlays
X.decals = old_decals
//Move the air from source to dest
var/turf/simulated/ST = T
if(istype(ST) && ST.zone)
var/turf/simulated/SX = X
if(!SX.air)
SX.make_air()
SX.air.copy_from(ST.zone.air)
ST.zone.remove(ST)
var/z_level_change = FALSE
if(T.z != X.z)
z_level_change = TRUE
//Move the objects. Not forceMove because the object isn't "moving" really, it's supposed to be on the "same" turf.
for(var/obj/O in T)
if(O.simulated)
O.loc = X
O.update_light()
if(z_level_change) // The objects still need to know if their z-level changed.
O.onTransitZ(T.z, X.z)
//Move the mobs unless it's an AI eye or other eye type.
for(var/mob/M in T)
if(isEye(M)) continue // If we need to check for more mobs, I'll add a variable
M.loc = X
if(z_level_change) // Same goes for mobs.
M.onTransitZ(T.z, X.z)
if(istype(M, /mob/living))
var/mob/living/LM = M
LM.check_shadow() // Need to check their Z-shadow, which is normally done in forceMove().
if(shuttlework)
var/turf/simulated/shuttle/SS = T
SS.landed_holder.leave_turf(turftoleave)
else if(turftoleave)
T.ChangeTurf(turftoleave)
else
T.ChangeTurf(get_base_turf_by_area(T))
return TRUE
+10 -1
View File
@@ -2,9 +2,16 @@
#define get_turf(A) get_step(A,0)
#define get_x(A) (get_step(A, 0)?.x || 0)
#define get_y(A) (get_step(A, 0)?.y || 0)
#define get_z(A) (get_step(A, 0)?.z || 0)
#define RANDOM_BLOOD_TYPE pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+")
#define to_chat(target, message) target << message
// #define to_chat(target, message) target << message Not anymore!
#define to_chat to_chat_filename=__FILE__;to_chat_line=__LINE__;to_chat_src=src;__to_chat
#define to_world(message) to_chat(world, message)
#define to_world_log(message) world.log << message
// TODO - Baystation has this log to crazy places. For now lets just world.log, but maybe look into it later.
@@ -26,6 +33,8 @@
#define qdel_null(x) if(x) { qdel(x) ; x = null }
#define sequential_id(key) uniqueness_repository.Generate(/datum/uniqueness_generator/id_sequential, key)
#define random_id(key,min_id,max_id) uniqueness_repository.Generate(/datum/uniqueness_generator/id_random, key, min_id, max_id)
#define ARGS_DEBUG log_debug("[__FILE__] - [__LINE__]") ; for(var/arg in args) { log_debug("\t[log_info_line(arg)]") }
+4 -4
View File
@@ -276,12 +276,12 @@
tankcheck = list(C.r_hand, C.l_hand, C.back)
// Rigs are a fucking pain since they keep an air tank in nullspace.
if(istype(C.back,/obj/item/weapon/rig))
var/obj/item/weapon/rig/rig = C.back
if(rig.air_supply && !rig.offline)
var/obj/item/weapon/rig/Rig = C.get_rig()
if(Rig)
if(Rig.air_supply && !Rig.offline)
from = "in"
nicename |= "hardsuit"
tankcheck |= rig.air_supply
tankcheck |= Rig.air_supply
for(var/i=1, i<tankcheck.len+1, ++i)
if(istype(tankcheck[i], /obj/item/weapon/tank))
+67
View File
@@ -0,0 +1,67 @@
#define SKYBOX_PADDING 4 // How much larger we want the skybox image to be than client's screen (in turfs)
#define SKYBOX_PIXELS 736 // Size of skybox image in pixels
#define SKYBOX_TURFS (SKYBOX_PIXELS/WORLD_ICON_SIZE)
// Skybox screen object.
/obj/skybox
name = "skybox"
mouse_opacity = 0
anchored = TRUE
simulated = FALSE
screen_loc = "CENTER,CENTER"
plane = SKYBOX_PLANE
blend_mode = BLEND_MULTIPLY // You actually need to do it this way or you see it in occlusion.
// Adjust transform property to scale for client's view var. We assume the skybox is 736x736 px
/obj/skybox/proc/scale_to_view(var/view)
var/matrix/M = matrix()
// Translate to center the icon over us!
M.Translate(-(SKYBOX_PIXELS - WORLD_ICON_SIZE) / 2)
// Scale appropriately based on view size. (7 results in scale of 1)
view = text2num(view) || 7 // Sanitize
M.Scale(((min(MAX_CLIENT_VIEW, view) + SKYBOX_PADDING) * 2 + 1) / SKYBOX_TURFS)
src.transform = M
/client
var/obj/skybox/skybox
/client/proc/update_skybox(rebuild)
if(!skybox)
skybox = new()
skybox.scale_to_view(src.view)
screen += skybox
rebuild = 1
var/turf/T = get_turf(eye)
if(T)
if(rebuild)
skybox.cut_overlays()
skybox.add_overlay(SSskybox.get_skybox(T.z))
screen |= skybox
skybox.screen_loc = "CENTER:[(world.maxx>>1) - T.x],CENTER:[(world.maxy>>1) - T.y]"
/mob/Login()
. = ..()
client.update_skybox(TRUE)
/mob/Move()
var/old_z = get_z(src)
. = ..()
if(. && client)
client.update_skybox(old_z != get_z(src))
/mob/forceMove()
var/old_z = get_z(src)
. = ..()
if(. && client)
client.update_skybox(old_z != get_z(src))
/mob/set_viewsize()
. = ..()
if (. && client)
client.update_skybox()
client.skybox?.scale_to_view(client.view)
#undef SKYBOX_BORDER
#undef SKYBOX_PIXELS
#undef SKYBOX_TURFS
-42
View File
@@ -1,42 +0,0 @@
// We manually initialize the alarm handlers instead of looping over all existing types
// to make it possible to write: camera.triggerAlarm() rather than alarm_manager.managers[datum/alarm_handler/camera].triggerAlarm() or a variant thereof.
/var/global/datum/alarm_handler/atmosphere/atmosphere_alarm = new()
/var/global/datum/alarm_handler/camera/camera_alarm = new()
/var/global/datum/alarm_handler/fire/fire_alarm = new()
/var/global/datum/alarm_handler/motion/motion_alarm = new()
/var/global/datum/alarm_handler/power/power_alarm = new()
// Alarm Manager, the manager for alarms.
var/datum/controller/process/alarm/alarm_manager
/datum/controller/process/alarm
var/list/datum/alarm/all_handlers = list()
/datum/controller/process/alarm/setup()
name = "alarm"
schedule_interval = 20 // every 2 seconds
all_handlers = list(atmosphere_alarm, camera_alarm, fire_alarm, motion_alarm, power_alarm)
alarm_manager = src
/datum/controller/process/alarm/doWork()
for(last_object in all_handlers)
var/datum/alarm_handler/AH = last_object
AH.process()
SCHECK
/datum/controller/process/alarm/proc/active_alarms()
var/list/all_alarms = new
for(var/datum/alarm_handler/AH in all_handlers)
var/list/alarms = AH.alarms
all_alarms += alarms
return all_alarms
/datum/controller/process/alarm/proc/number_of_active_alarms()
var/list/alarms = active_alarms()
return alarms.len
/datum/controller/process/alarm/statProcess()
..()
stat(null, "[number_of_active_alarms()] alarm\s")
+6 -1
View File
@@ -264,6 +264,10 @@ var/list/gamemode_cache = list()
var/sqlite_feedback_cooldown = 0 // How long one must wait, in days, to submit another feedback form. Used to help prevent spam, especially with privacy active. 0 = No limit.
var/sqlite_feedback_min_age = 0 // Used to block new people from giving feedback. This metric is very bad but it can help slow down spammers.
// disables the annoying "You have already logged in this round, disconnect or be banned" popup for multikeying, because it annoys the shit out of me when testing.
var/disable_cid_warn_popup = FALSE
/datum/configuration/New()
var/list/L = typesof(/datum/game_mode) - /datum/game_mode
for (var/T in L)
@@ -873,7 +877,8 @@ var/list/gamemode_cache = list()
if("sqlite_feedback_cooldown")
config.sqlite_feedback_cooldown = text2num(value)
if("disable_cid_warn_popup")
config.disable_cid_warn_popup = TRUE
else
log_misc("Unknown setting in configuration: '[name]'")
@@ -5,7 +5,7 @@
var/global/datum/emergency_shuttle_controller/emergency_shuttle
/datum/emergency_shuttle_controller
var/datum/shuttle/ferry/emergency/shuttle
var/datum/shuttle/autodock/ferry/emergency/shuttle // Set in shuttle_emergency.dm TODO - is it really?
var/list/escape_pods
var/launch_time //the time at which the shuttle will be launched
@@ -36,8 +36,8 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
if (!shuttle.location) //leaving from the station
//launch the pods!
for (var/EP in escape_pods)
var/datum/shuttle/ferry/escape_pod/pod
if(istype(escape_pods[EP], /datum/shuttle/ferry/escape_pod))
var/datum/shuttle/autodock/ferry/escape_pod/pod
if(istype(escape_pods[EP], /datum/shuttle/autodock/ferry/escape_pod))
pod = escape_pods[EP]
else
continue
@@ -63,8 +63,8 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
//arm the escape pods
if (evac)
for (var/EP in escape_pods)
var/datum/shuttle/ferry/escape_pod/pod
if(istype(escape_pods[EP], /datum/shuttle/ferry/escape_pod))
var/datum/shuttle/autodock/ferry/escape_pod/pod
if(istype(escape_pods[EP], /datum/shuttle/autodock/ferry/escape_pod))
pod = escape_pods[EP]
else
continue
@@ -215,11 +215,11 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
//returns 1 if the shuttle is currently in transit (or just leaving) to the station
/datum/emergency_shuttle_controller/proc/going_to_station()
return (!shuttle.direction && shuttle.moving_status != SHUTTLE_IDLE)
return shuttle && (!shuttle.direction && shuttle.moving_status != SHUTTLE_IDLE)
//returns 1 if the shuttle is currently in transit (or just leaving) to centcom
/datum/emergency_shuttle_controller/proc/going_to_centcom()
return (shuttle.direction && shuttle.moving_status != SHUTTLE_IDLE)
return shuttle && (shuttle.direction && shuttle.moving_status != SHUTTLE_IDLE)
/datum/emergency_shuttle_controller/proc/get_status_panel_eta()
+1 -1
View File
@@ -196,7 +196,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
#else
world.sleep_offline = 1
#endif
world.fps = config.fps
world.change_fps(config.fps)
var/initialized_tod = REALTIMEOFDAY
sleep(1)
initializations_finished_with_no_players_logged_in = initialized_tod < REALTIMEOFDAY - 10
+45
View File
@@ -0,0 +1,45 @@
// We manually initialize the alarm handlers instead of looping over all existing types
// to make it possible to write: camera_alarm.triggerAlarm() rather than SSalarm.managers[datum/alarm_handler/camera].triggerAlarm() or a variant thereof.
/var/global/datum/alarm_handler/atmosphere/atmosphere_alarm = new()
/var/global/datum/alarm_handler/camera/camera_alarm = new()
/var/global/datum/alarm_handler/fire/fire_alarm = new()
/var/global/datum/alarm_handler/motion/motion_alarm = new()
/var/global/datum/alarm_handler/power/power_alarm = new()
SUBSYSTEM_DEF(alarm)
name = "Alarm"
wait = 2 SECONDS
priority = FIRE_PRIORITY_ALARM
init_order = INIT_ORDER_ALARM
var/list/datum/alarm/all_handlers
var/tmp/list/currentrun = null
var/static/list/active_alarm_cache = list()
/datum/controller/subsystem/alarm/Initialize()
all_handlers = list(atmosphere_alarm, camera_alarm, fire_alarm, motion_alarm, power_alarm)
. = ..()
/datum/controller/subsystem/alarm/fire(resumed = FALSE)
if(!resumed)
src.currentrun = all_handlers.Copy()
active_alarm_cache.Cut()
var/list/currentrun = src.currentrun // Cache for sanic speed
while (currentrun.len)
var/datum/alarm_handler/AH = currentrun[currentrun.len]
currentrun.len--
AH.process()
active_alarm_cache += AH.alarms
if (MC_TICK_CHECK)
return
/datum/controller/subsystem/alarm/proc/active_alarms()
return active_alarm_cache.Copy()
/datum/controller/subsystem/alarm/proc/number_of_active_alarms()
return active_alarm_cache.len
/datum/controller/subsystem/alarm/stat_entry()
..("[number_of_active_alarms()] alarm\s")
+17
View File
@@ -0,0 +1,17 @@
SUBSYSTEM_DEF(assets)
name = "Assets"
init_order = INIT_ORDER_ASSETS
flags = SS_NO_FIRE
var/list/cache = list()
var/list/preload = list()
/datum/controller/subsystem/assets/Initialize(timeofday)
for(var/type in typesof(/datum/asset) - list(/datum/asset, /datum/asset/simple))
var/datum/asset/A = new type()
A.register()
preload = cache.Copy() //don't preload assets generated during the round
for(var/client/C in GLOB.clients)
addtimer(CALLBACK(GLOBAL_PROC, .proc/getFilesSlow, C, preload, FALSE), 10)
return ..()
+87
View File
@@ -0,0 +1,87 @@
SUBSYSTEM_DEF(chat)
name = "Chat"
flags = SS_TICKER
wait = 1 // SS_TICKER means this runs every tick
priority = FIRE_PRIORITY_CHAT
init_order = INIT_ORDER_CHAT
var/list/msg_queue = list()
/datum/controller/subsystem/chat/Initialize(timeofday)
init_vchat()
..()
/datum/controller/subsystem/chat/fire()
var/list/msg_queue = src.msg_queue // Local variable for sanic speed.
for(var/i in msg_queue)
var/client/C = i
var/list/messages = msg_queue[C]
msg_queue -= C
if (C)
C << output(jsEncode(messages), "htmloutput:putmessage")
if(MC_TICK_CHECK)
return
/datum/controller/subsystem/chat/stat_entry()
..("C:[msg_queue.len]")
/datum/controller/subsystem/chat/proc/queue(target, time, message, handle_whitespace = TRUE)
if(!target || !message)
return
if(!istext(message))
stack_trace("to_chat called with invalid input type")
return
// Currently to_chat(world, ...) gets sent individually to each client. Consider.
if(target == world)
target = GLOB.clients
//Some macros remain in the string even after parsing and fuck up the eventual output
var/original_message = message
message = replacetext(message, "\n", "<br>")
message = replacetext(message, "\improper", "")
message = replacetext(message, "\proper", "")
if(isnull(time))
time = world.time
var/list/messageStruct = list("time" = time, "message" = message);
if(islist(target))
for(var/I in target)
var/client/C = CLIENT_FROM_VAR(I) //Grab us a client if possible
if(!C)
return
if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
//Send it to the old style output window.
DIRECT_OUTPUT(C, original_message)
continue
// // Client still loading, put their messages in a queue - Actually don't, logged already in database.
// if(!C.chatOutput.loaded && C.chatOutput.message_queue && islist(C.chatOutput.message_queue))
// C.chatOutput.message_queue[++C.chatOutput.message_queue.len] = messageStruct
// continue
LAZYINITLIST(msg_queue[C])
msg_queue[C][++msg_queue[C].len] = messageStruct
else
var/client/C = CLIENT_FROM_VAR(target) //Grab us a client if possible
if(!C)
return
if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
DIRECT_OUTPUT(C, original_message)
return
// // Client still loading, put their messages in a queue - Actually don't, logged already in database.
// if(!C.chatOutput.loaded && C.chatOutput.message_queue && islist(C.chatOutput.message_queue))
// C.chatOutput.message_queue[++C.chatOutput.message_queue.len] = messageStruct
// return
LAZYINITLIST(msg_queue[C])
msg_queue[C][++msg_queue[C].len] = messageStruct
+8 -3
View File
@@ -15,8 +15,7 @@ SUBSYSTEM_DEF(inactivity)
while(client_list.len)
var/client/C = client_list[client_list.len]
client_list.len--
if(!C.holder && C.is_afk(config.kick_inactive MINUTES) && !isobserver(C.mob))
if(C.is_afk(config.kick_inactive MINUTES) && can_kick(C))
to_chat(C, "<span class='warning'>You have been inactive for more than [config.kick_inactive] minute\s and have been disconnected.</span>")
var/information
@@ -34,6 +33,9 @@ SUBSYSTEM_DEF(inactivity)
if(job)
information = " while [job]."
else if(isobserver(C.mob))
information = " while a ghost."
else if(issilicon(C.mob))
information = " while a silicon."
if(isAI(C.mob))
@@ -55,4 +57,7 @@ SUBSYSTEM_DEF(inactivity)
return
/datum/controller/subsystem/inactivity/stat_entry()
..("Kicked: [number_kicked]")
..("Kicked: [number_kicked]")
/datum/controller/subsystem/inactivity/proc/can_kick(var/client/C)
return TRUE
+1 -32
View File
@@ -1,41 +1,17 @@
SUBSYSTEM_DEF(nanoui)
name = "NanoUI"
wait = 5
flags = SS_NO_INIT
// a list of current open /nanoui UIs, grouped by src_object and ui_key
var/list/open_uis = list()
// a list of current open /nanoui UIs, not grouped, for use in processing
var/list/processing_uis = list()
// a list of asset filenames which are to be sent to the client on user logon
var/list/asset_files = list()
/datum/controller/subsystem/nanoui/Initialize()
var/list/nano_asset_dirs = list(\
"nano/css/",\
"nano/images/",\
"nano/images/status_icons/",\
"nano/images/modular_computers/",\
"nano/js/",\
"nano/templates/"\
)
var/list/filenames = null
for (var/path in nano_asset_dirs)
filenames = flist(path)
for(var/filename in filenames)
if(copytext(filename, length(filename)) != "/") // filenames which end in "/" are actually directories, which we want to ignore
if(fexists(path + filename))
asset_files.Add(fcopy_rsc(path + filename)) // add this file to asset_files for sending to clients when they connect
.=..()
for(var/i in GLOB.clients)
send_resources(i)
/datum/controller/subsystem/nanoui/Recover()
if(SSnanoui.open_uis)
open_uis |= SSnanoui.open_uis
if(SSnanoui.processing_uis)
processing_uis |= SSnanoui.processing_uis
if(SSnanoui.asset_files)
asset_files |= SSnanoui.asset_files
/datum/controller/subsystem/nanoui/stat_entry()
return ..("[processing_uis.len] UIs")
@@ -44,10 +20,3 @@ SUBSYSTEM_DEF(nanoui)
for(var/thing in processing_uis)
var/datum/nanoui/UI = thing
UI.process()
//Sends asset files to a client, called on client/New()
/datum/controller/subsystem/nanoui/proc/send_resources(client)
if(!subsystem_initialized)
return
for(var/file in asset_files)
client << browse_rsc(file) // send the file to the client
+148 -53
View File
@@ -1,6 +1,8 @@
//
// SSshuttles subsystem - Handles initialization and processing of shuttles.
//
// Also handles initialization and processing of overmap sectors.
//
// This global variable exists for legacy support so we don't have to rename every shuttle_controller to SSshuttles yet.
var/global/datum/controller/subsystem/shuttles/shuttle_controller
@@ -13,71 +15,164 @@ SUBSYSTEM_DEF(shuttles)
flags = SS_KEEP_TIMING|SS_NO_TICK_CHECK
runlevels = RUNLEVEL_GAME|RUNLEVEL_POSTGAME
var/list/shuttles = list() // Maps shuttle tags to shuttle datums, so that they can be looked up.
var/list/process_shuttles = list() // Simple list of shuttles, for processing
var/list/current_run = list() // Shuttles remaining to process this fire() tick
var/list/docks_init_callbacks // List of callbacks to run when we finish setting up shuttle docks.
var/docks_initialized = FALSE
var/overmap_halted = FALSE // Whether ships can move on the overmap; used for adminbus.
var/list/ships = list() // List of all ships.
var/list/shuttles = list() // Maps shuttle tags to shuttle datums, so that they can be looked up.
var/list/process_shuttles = list() // Simple list of shuttles, for processing
var/list/registered_shuttle_landmarks = list() // Maps shuttle landmark tags to instances
var/last_landmark_registration_time // world.time of most recent addition to registered_shuttle_landmarks
var/list/shuttle_logs = list() // (Not Implemented) Keeps records of shuttle movement, format is list(datum/shuttle = datum/shuttle_log)
var/list/shuttle_areas = list() // All the areas of all shuttles.
var/list/docking_registry = list() // Docking controller tag -> docking controller program, mostly for init purposes.
var/list/landmarks_awaiting_sector = list() // Stores automatic landmarks that are waiting for a sector to finish loading.
var/list/landmarks_still_needed = list() // Stores landmark_tags that need to be assigned to the sector (landmark_tag = sector) when registered.
var/list/shuttles_to_initialize // A queue for shuttles to initialize at the appropriate time.
var/list/sectors_to_initialize // Used to find all sector objects at the appropriate time.
var/block_init_queue = TRUE // Block initialization of new shuttles/sectors
var/tmp/list/current_run // Shuttles remaining to process this fire() tick
/datum/controller/subsystem/shuttles/PreInit()
global.shuttle_controller = src // TODO - Remove this! Change everything to point at SSshuttles intead
/datum/controller/subsystem/shuttles/Initialize(timeofday)
global.shuttle_controller = src
setup_shuttle_docks()
for(var/I in docks_init_callbacks)
var/datum/callback/cb = I
cb.InvokeAsync()
LAZYCLEARLIST(docks_init_callbacks)
docks_init_callbacks = null
last_landmark_registration_time = world.time
// Find all declared shuttle datums and initailize them. (Okay, queue them for initialization a few lines further down)
for(var/shuttle_type in subtypesof(/datum/shuttle)) // This accounts for most shuttles, though away maps can queue up more.
var/datum/shuttle/shuttle = shuttle_type
if(initial(shuttle.category) == shuttle_type)
continue // Its an "abstract class" datum, not for a real shuttle.
if(!initial(shuttle.defer_initialisation)) // Skip if it asks not to be initialized at startup.
LAZYDISTINCTADD(shuttles_to_initialize, shuttle_type)
block_init_queue = FALSE
process_init_queues()
return ..()
/datum/controller/subsystem/shuttles/fire(resumed = 0)
do_process_shuttles(resumed)
/datum/controller/subsystem/shuttles/stat_entry()
var/msg = list()
msg += "AS:[shuttles.len]|"
msg += "PS:[process_shuttles.len]|"
..(jointext(msg, null))
/datum/controller/subsystem/shuttles/proc/do_process_shuttles(resumed = 0)
if (!resumed)
src.current_run = process_shuttles.Copy()
var/list/current_run = src.current_run // Cache for sanic speed
while(current_run.len)
var/datum/shuttle/S = current_run[current_run.len]
current_run.len--
if(istype(S) && !QDELETED(S))
if(istype(S, /datum/shuttle/ferry)) // Ferry shuttles get special treatment
var/datum/shuttle/ferry/F = S
if(F.process_state || F.always_process)
F.process()
else
S.process()
else
var/list/working_shuttles = src.current_run // Cache for sanic speed
while(working_shuttles.len)
var/datum/shuttle/S = working_shuttles[working_shuttles.len]
working_shuttles.len--
if(!istype(S) || QDELETED(S))
error("Bad entry in SSshuttles.process_shuttles - [log_info_line(S)] ")
process_shuttles -= S
continue
// NOTE - In old system, /datum/shuttle/ferry was processed only if (F.process_state || F.always_process)
if(S.process_state && (S.process(wait, times_fired, src) == PROCESS_KILL))
process_shuttles -= S
if(MC_TICK_CHECK)
return
// This should be called after all the machines and radio frequencies have been properly initialized
/datum/controller/subsystem/shuttles/proc/setup_shuttle_docks()
// Find all declared shuttle datums and initailize them.
for(var/shuttle_type in subtypesof(/datum/shuttle))
var/datum/shuttle/shuttle = shuttle_type
if(initial(shuttle.category) == shuttle_type)
continue
/datum/controller/subsystem/shuttles/proc/process_init_queues()
if(block_init_queue)
return
initialize_shuttles()
initialize_sectors()
// Initializes all shuttles in shuttles_to_initialize
/datum/controller/subsystem/shuttles/proc/initialize_shuttles()
var/list/shuttles_made = list()
for(var/shuttle_type in shuttles_to_initialize)
var/shuttle = initialize_shuttle(shuttle_type)
if(shuttle)
shuttles_made += shuttle
hook_up_motherships(shuttles_made)
shuttles_to_initialize = null
/datum/controller/subsystem/shuttles/proc/initialize_sectors()
for(var/sector in sectors_to_initialize)
initialize_sector(sector)
sectors_to_initialize = null
/datum/controller/subsystem/shuttles/proc/register_landmark(shuttle_landmark_tag, obj/effect/shuttle_landmark/shuttle_landmark)
if (registered_shuttle_landmarks[shuttle_landmark_tag])
CRASH("Attempted to register shuttle landmark with tag [shuttle_landmark_tag], but it is already registered!")
if (istype(shuttle_landmark))
registered_shuttle_landmarks[shuttle_landmark_tag] = shuttle_landmark
last_landmark_registration_time = world.time
var/obj/effect/overmap/visitable/O = landmarks_still_needed[shuttle_landmark_tag]
if(O) //These need to be added to sectors, which we handle.
try_add_landmark_tag(shuttle_landmark_tag, O)
landmarks_still_needed -= shuttle_landmark_tag
else if(istype(shuttle_landmark, /obj/effect/shuttle_landmark/automatic)) //These find their sector automatically
O = map_sectors["[shuttle_landmark.z]"]
O ? O.add_landmark(shuttle_landmark, shuttle_landmark.shuttle_restricted) : (landmarks_awaiting_sector += shuttle_landmark)
/datum/controller/subsystem/shuttles/proc/get_landmark(var/shuttle_landmark_tag)
return registered_shuttle_landmarks[shuttle_landmark_tag]
//Checks if the given sector's landmarks have initialized; if so, registers them with the sector, if not, marks them for assignment after they come in.
//Also adds automatic landmarks that were waiting on their sector to spawn.
/datum/controller/subsystem/shuttles/proc/initialize_sector(obj/effect/overmap/visitable/given_sector)
given_sector.populate_sector_objects() // This is a late init operation that sets up the sector's map_z and does non-overmap-related init tasks.
for(var/landmark_tag in given_sector.initial_generic_waypoints)
if(!try_add_landmark_tag(landmark_tag, given_sector))
landmarks_still_needed[landmark_tag] = given_sector // Landmark isn't registered yet, queue it to be added once it is.
for(var/shuttle_name in given_sector.initial_restricted_waypoints)
for(var/landmark_tag in given_sector.initial_restricted_waypoints[shuttle_name])
if(!try_add_landmark_tag(landmark_tag, given_sector))
landmarks_still_needed[landmark_tag] = given_sector // Landmark isn't registered yet, queue it to be added once it is.
var/landmarks_to_check = landmarks_awaiting_sector.Copy()
for(var/thing in landmarks_to_check)
var/obj/effect/shuttle_landmark/automatic/landmark = thing
if(landmark.z in given_sector.map_z)
given_sector.add_landmark(landmark, landmark.shuttle_restricted)
landmarks_awaiting_sector -= landmark
// Attempts to add a landmark instance with a sector (returns false if landmark isn't registered yet)
/datum/controller/subsystem/shuttles/proc/try_add_landmark_tag(landmark_tag, obj/effect/overmap/visitable/given_sector)
var/obj/effect/shuttle_landmark/landmark = get_landmark(landmark_tag)
if(!landmark)
return
if(landmark.landmark_tag in given_sector.initial_generic_waypoints)
given_sector.add_landmark(landmark)
. = 1
for(var/shuttle_name in given_sector.initial_restricted_waypoints)
if(landmark.landmark_tag in given_sector.initial_restricted_waypoints[shuttle_name])
given_sector.add_landmark(landmark, shuttle_name)
. = 1
/datum/controller/subsystem/shuttles/proc/initialize_shuttle(var/shuttle_type)
var/datum/shuttle/shuttle = shuttle_type
if(initial(shuttle.category) != shuttle_type) // Skip if its an "abstract class" datum
shuttle = new shuttle()
shuttle.init_docking_controllers()
shuttle.dock() //makes all shuttles docked to something at round start go into the docked state
CHECK_TICK
shuttle_areas |= shuttle.shuttle_area
log_debug("Initialized shuttle [shuttle] ([shuttle.type])")
return shuttle
// Historical note: No need to call shuttle.init_docking_controllers(), controllers register themselves
// and shuttles fetch refs in New(). Shuttles also dock() themselves in new if they want.
for(var/obj/machinery/embedded_controller/C in machines)
if(istype(C.program, /datum/computer/file/embedded_program/docking))
C.program.tag = null //clear the tags, 'cause we don't need 'em anymore
docks_initialized = TRUE
// TODO - Leshana to hook up more of this when overmap is ported.
/datum/controller/subsystem/shuttles/proc/hook_up_motherships(shuttles_list)
for(var/datum/shuttle/S in shuttles_list)
if(S.mothershuttle && !S.motherdock)
var/datum/shuttle/mothership = shuttles[S.mothershuttle]
if(mothership)
S.motherdock = S.current_location.landmark_tag
mothership.shuttle_area |= S.shuttle_area
else
error("Shuttle [S] was unable to find mothership [mothership]!")
// Register a callback that will be invoked once the shuttles have been initialized
/datum/controller/subsystem/shuttles/proc/OnDocksInitialized(datum/callback/cb)
if(!docks_initialized)
LAZYADD(docks_init_callbacks, cb)
else
cb.InvokeAsync()
// Admin command to halt/resume overmap
/datum/controller/subsystem/shuttles/proc/toggle_overmap(new_setting)
if(overmap_halted == new_setting)
return
overmap_halted = !overmap_halted
for(var/ship in ships)
var/obj/effect/overmap/visitable/ship/ship_effect = ship
overmap_halted ? ship_effect.halt() : ship_effect.unhalt()
/datum/controller/subsystem/shuttles/stat_entry()
..("Shuttles:[process_shuttles.len]/[shuttles.len], Ships:[ships.len], L:[registered_shuttle_landmarks.len][overmap_halted ? ", HALT" : ""]")
+82
View File
@@ -0,0 +1,82 @@
//Exists to handle a few global variables that change enough to justify this. Technically a parallax, but it exhibits a skybox effect.
SUBSYSTEM_DEF(skybox)
name = "Space skybox"
init_order = INIT_ORDER_SKYBOX
flags = SS_NO_FIRE
var/list/skybox_cache = list()
/datum/controller/subsystem/skybox/Initialize()
. = ..()
/datum/controller/subsystem/skybox/Recover()
skybox_cache = SSskybox.skybox_cache
/datum/controller/subsystem/skybox/proc/get_skybox(z)
if(!skybox_cache["[z]"])
skybox_cache["[z]"] = generate_skybox(z)
if(global.using_map.use_overmap)
var/obj/effect/overmap/visitable/O = map_sectors["[z]"]
if(istype(O))
for(var/zlevel in O.map_z)
skybox_cache["[zlevel]"] = skybox_cache["[z]"]
return skybox_cache["[z]"]
/datum/controller/subsystem/skybox/proc/generate_skybox(z)
var/datum/skybox_settings/settings = global.using_map.get_skybox_datum(z)
var/image/res = image(settings.icon)
res.appearance_flags = KEEP_TOGETHER
var/image/base = image(settings.icon, settings.icon_state)
base.color = settings.color
if(settings.use_stars)
var/image/stars = image(settings.icon, settings.star_state)
stars.appearance_flags = RESET_COLOR
base.overlays += stars
res.overlays += base
if(global.using_map.use_overmap && settings.use_overmap_details)
var/obj/effect/overmap/visitable/O = map_sectors["[z]"]
if(istype(O))
var/image/overmap = image(settings.icon)
overmap.overlays += O.generate_skybox()
for(var/obj/effect/overmap/visitable/other in O.loc)
if(other != O)
overmap.overlays += other.get_skybox_representation()
overmap.appearance_flags = RESET_COLOR
res.overlays += overmap
// TODO - Allow events to apply custom overlays to skybox! (Awesome!)
//for(var/datum/event/E in SSevent.active_events)
// if(E.has_skybox_image && E.isRunning && (z in E.affecting_z))
// res.overlays += E.get_skybox_image()
return res
/datum/controller/subsystem/skybox/proc/rebuild_skyboxes(var/list/zlevels)
for(var/z in zlevels)
skybox_cache["[z]"] = generate_skybox(z)
for(var/client/C)
C.update_skybox(1)
// Settings datum that maps can override to play with their skyboxes
/datum/skybox_settings
var/icon = 'icons/skybox/skybox.dmi' //Path to our background. Lets us use anything we damn well please. Skyboxes need to be 736x736
var/icon_state = "dyable"
var/color
var/random_color = FALSE
var/use_stars = TRUE
var/star_icon = 'icons/skybox/skybox.dmi'
var/star_state = "stars"
var/use_overmap_details = TRUE //Do we try to draw overmap visitables in our sector on the map?
/datum/skybox_settings/New()
..()
if(random_color)
color = rgb(rand(0,255), rand(0,255), rand(0,255))
@@ -1,36 +1,15 @@
//Config stuff
#define SUPPLY_DOCKZ 2 //Z-level of the Dock.
#define SUPPLY_STATIONZ 1 //Z-level of the Station.
#define SUPPLY_STATION_AREATYPE "/area/supply/station" //Type of the supply shuttle area for station
#define SUPPLY_DOCK_AREATYPE "/area/supply/dock" //Type of the supply shuttle area for dock
//Supply packs are in /code/datums/supplypacks
//Computers are in /code/game/machinery/computer/supply.dm
SUBSYSTEM_DEF(supply)
name = "Supply"
wait = 20 SECONDS
priority = FIRE_PRIORITY_SUPPLY
//Initializes at default time
flags = SS_NO_TICK_CHECK
/datum/supply_order
var/ordernum // Unfabricatable index
var/index // Fabricatable index
var/datum/supply_pack/object = null
var/cost // Cost of the supply pack (Fabricatable) (Changes not reflected when purchasing supply packs, this is cosmetic only)
var/name // Name of the supply pack datum (Fabricatable)
var/ordered_by = null // Who requested the order
var/comment = null // What reason was given for the order
var/approved_by = null // Who approved the order
var/ordered_at // Date and time the order was requested at
var/approved_at // Date and time the order was approved at
var/status // [Requested, Accepted, Denied, Shipped]
/datum/exported_crate
var/name
var/value
var/list/contents
var/datum/controller/supply/supply_controller = new()
/datum/controller/supply
//supply points
var/points = 50
var/points_per_process = 1.5
var/points_per_process = 1.0 // Processes every 20 seconds, so this is 3 per minute
var/points_per_slip = 2
var/points_per_money = 0.02 // 1 point for $50
//control
@@ -43,16 +22,16 @@ var/datum/controller/supply/supply_controller = new()
var/list/adm_export_history = list() // Complete history of all crates sent back on the shuttle, for admin use
//shuttle movement
var/movetime = 1200
var/datum/shuttle/ferry/supply/shuttle
var/datum/shuttle/autodock/ferry/supply/shuttle
var/list/material_points_conversion = list( // Any materials not named in this list are worth 0 points
"phoron" = 5,
"platinum" = 5
)
/datum/controller/supply/New()
/datum/controller/subsystem/supply/Initialize()
ordernum = rand(1,9000)
// build master supply list
for(var/typepath in subtypesof(/datum/supply_pack))
var/datum/supply_pack/P = new typepath()
if(P.name)
@@ -60,20 +39,18 @@ var/datum/controller/supply/supply_controller = new()
else
qdel(P)
/datum/controller/process/supply/setup()
name = "supply controller"
schedule_interval = 300 // every 30 seconds
// TODO - Auto-build material_points_conversion from material datums
. = ..()
/datum/controller/process/supply/doWork()
supply_controller.process()
// Supply shuttle ticker - handles supply point regeneration
// This is called by the process scheduler every thirty seconds
/datum/controller/supply/process()
// Supply shuttle ticker - handles supply point regeneration. Just add points over time.
/datum/controller/subsystem/supply/fire()
points += points_per_process
/datum/controller/subsystem/supply/stat_entry()
..("Points: [points]")
//To stop things being sent to CentCom which should not be sent to centcomm. Recursively checks for these types.
/datum/controller/supply/proc/forbidden_atoms_check(atom/A)
/datum/controller/subsystem/supply/proc/forbidden_atoms_check(atom/A)
if(isliving(A))
return 1
if(istype(A,/obj/item/weapon/disk/nuclear))
@@ -88,88 +65,102 @@ var/datum/controller/supply/supply_controller = new()
return 1
//Selling
/datum/controller/supply/proc/sell()
var/area/area_shuttle = shuttle.get_location_area()
if(!area_shuttle)
return
/datum/controller/subsystem/supply/proc/sell()
// Loop over each area in the supply shuttle
for(var/area/subarea in shuttle.shuttle_area)
callHook("sell_shuttle", list(subarea));
for(var/atom/movable/MA in subarea)
if(MA.anchored)
continue
callHook("sell_shuttle", list(area_shuttle));
var/datum/exported_crate/EC = new /datum/exported_crate()
EC.name = "\proper[MA.name]"
EC.value = 0
EC.contents = list()
var/base_value = 0
for(var/atom/movable/MA in area_shuttle)
if(MA.anchored)
continue
// Must be in a crate!
if(istype(MA,/obj/structure/closet/crate))
var/obj/structure/closet/crate/CR = MA
callHook("sell_crate", list(CR, subarea))
var/datum/exported_crate/EC = new /datum/exported_crate()
EC.name = "\proper[MA.name]"
EC.value = 0
EC.contents = list()
var/base_value = 0
points += CR.points_per_crate
if(CR.points_per_crate)
base_value = CR.points_per_crate
var/find_slip = 1
// Must be in a crate!
if(istype(MA,/obj/structure/closet/crate))
var/obj/structure/closet/crate/CR = MA
callHook("sell_crate", list(CR, area_shuttle))
for(var/atom/A in CR)
EC.contents[++EC.contents.len] = list(
"object" = "\proper[A.name]",
"value" = 0,
"quantity" = 1
)
points += CR.points_per_crate
if(CR.points_per_crate)
base_value = CR.points_per_crate
var/find_slip = 1
// Sell manifests
if(find_slip && istype(A,/obj/item/weapon/paper/manifest))
var/obj/item/weapon/paper/manifest/slip = A
if(!slip.is_copy && slip.stamped && slip.stamped.len) //yes, the clown stamp will work. clown is the highest authority on the station, it makes sense
points += points_per_slip
EC.contents[EC.contents.len]["value"] = points_per_slip
find_slip = 0
continue
for(var/atom/A in CR)
EC.contents[++EC.contents.len] = list(
"object" = "\proper[A.name]",
"value" = 0,
"quantity" = 1
// Sell phoron and platinum
if(istype(A, /obj/item/stack))
var/obj/item/stack/P = A
if(material_points_conversion[P.get_material_name()])
EC.contents[EC.contents.len]["value"] = P.get_amount() * material_points_conversion[P.get_material_name()]
EC.contents[EC.contents.len]["quantity"] = P.get_amount()
EC.value += EC.contents[EC.contents.len]["value"]
//Sell spacebucks
if(istype(A, /obj/item/weapon/spacecash))
var/obj/item/weapon/spacecash/cashmoney = A
EC.contents[EC.contents.len]["value"] = cashmoney.worth * points_per_money
EC.contents[EC.contents.len]["quantity"] = cashmoney.worth
EC.value += EC.contents[EC.contents.len]["value"]
// Make a log of it, but it wasn't shipped properly, and so isn't worth anything
else
EC.contents = list(
"error" = "Error: Product was improperly packaged. Payment rendered null under terms of agreement."
)
// Sell manifests
if(find_slip && istype(A,/obj/item/weapon/paper/manifest))
var/obj/item/weapon/paper/manifest/slip = A
if(!slip.is_copy && slip.stamped && slip.stamped.len) //yes, the clown stamp will work. clown is the highest authority on the station, it makes sense
points += points_per_slip
EC.contents[EC.contents.len]["value"] = points_per_slip
find_slip = 0
exported_crates += EC
points += EC.value
EC.value += base_value
// Duplicate the receipt for the admin-side log
var/datum/exported_crate/adm = new()
adm.name = EC.name
adm.value = EC.value
adm.contents = deepCopyList(EC.contents)
adm_export_history += adm
qdel(MA)
/datum/controller/subsystem/supply/proc/get_clear_turfs()
var/list/clear_turfs = list()
for(var/area/subarea in shuttle.shuttle_area)
for(var/turf/T in subarea)
if(T.density)
continue
var/occupied = 0
for(var/atom/A in T.contents)
if(!A.simulated)
continue
occupied = 1
break
if(!occupied)
clear_turfs += T
// Sell phoron and platinum
if(istype(A, /obj/item/stack))
var/obj/item/stack/P = A
if(material_points_conversion[P.get_material_name()])
EC.contents[EC.contents.len]["value"] = P.get_amount() * material_points_conversion[P.get_material_name()]
EC.contents[EC.contents.len]["quantity"] = P.get_amount()
EC.value += EC.contents[EC.contents.len]["value"]
//Sell spacebucks
if(istype(A, /obj/item/weapon/spacecash))
var/obj/item/weapon/spacecash/cashmoney = A
EC.contents[EC.contents.len]["value"] = cashmoney.worth * points_per_money
EC.contents[EC.contents.len]["quantity"] = cashmoney.worth
EC.value += EC.contents[EC.contents.len]["value"]
// Make a log of it, but it wasn't shipped properly, and so isn't worth anything
else
EC.contents = list(
"error" = "Error: Product was improperly packaged. Payment rendered null under terms of agreement."
)
exported_crates += EC
points += EC.value
EC.value += base_value
// Duplicate the receipt for the admin-side log
var/datum/exported_crate/adm = new()
adm.name = EC.name
adm.value = EC.value
adm.contents = deepCopyList(EC.contents)
adm_export_history += adm
qdel(MA)
return clear_turfs
//Buying
/datum/controller/supply/proc/buy()
/datum/controller/subsystem/supply/proc/buy()
var/list/shoppinglist = list()
for(var/datum/supply_order/SO in order_history)
if(SO.status == SUP_ORDER_APPROVED)
@@ -177,26 +168,9 @@ var/datum/controller/supply/supply_controller = new()
if(!shoppinglist.len)
return
var/orderedamount = shoppinglist.len
var/area/area_shuttle = shuttle.get_location_area()
if(!area_shuttle)
return
var/list/clear_turfs = list()
for(var/turf/T in area_shuttle)
if(T.density)
continue
var/contcount
for(var/atom/A in T.contents)
if(!A.simulated)
continue
contcount++
if(contcount)
continue
clear_turfs += T
var/list/clear_turfs = get_clear_turfs()
for(var/datum/supply_order/SO in shoppinglist)
if(!clear_turfs.len)
@@ -265,9 +239,9 @@ var/datum/controller/supply/supply_controller = new()
return
// Will attempt to purchase the specified order, returning TRUE on success, FALSE on failure
/datum/controller/supply/proc/approve_order(var/datum/supply_order/O, var/mob/user)
/datum/controller/subsystem/supply/proc/approve_order(var/datum/supply_order/O, var/mob/user)
// Not enough points to purchase the crate
if(supply_controller.points <= O.object.cost)
if(points <= O.object.cost)
return FALSE
// Based on the current model, there shouldn't be any entries in order_history, requestlist, or shoppinglist, that aren't matched in adm_order_history
@@ -294,11 +268,11 @@ var/datum/controller/supply/supply_controller = new()
adm_order.approved_at = stationdate2text() + " - " + stationtime2text()
// Deduct cost
supply_controller.points -= O.object.cost
points -= O.object.cost
return TRUE
// Will deny the specified order. Only useful if the order is currently requested, but available at any status
/datum/controller/supply/proc/deny_order(var/datum/supply_order/O, var/mob/user)
/datum/controller/subsystem/supply/proc/deny_order(var/datum/supply_order/O, var/mob/user)
// Based on the current model, there shouldn't be any entries in order_history, requestlist, or shoppinglist, that aren't matched in adm_order_history
var/datum/supply_order/adm_order
for(var/datum/supply_order/temp in adm_order_history)
@@ -324,22 +298,22 @@ var/datum/controller/supply/supply_controller = new()
return
// Will deny all requested orders
/datum/controller/supply/proc/deny_all_pending(var/mob/user)
/datum/controller/subsystem/supply/proc/deny_all_pending(var/mob/user)
for(var/datum/supply_order/O in order_history)
if(O.status == SUP_ORDER_REQUESTED)
deny_order(O, user)
// Will delete the specified order from the user-side list
/datum/controller/supply/proc/delete_order(var/datum/supply_order/O, var/mob/user)
/datum/controller/subsystem/supply/proc/delete_order(var/datum/supply_order/O, var/mob/user)
// Making sure they know what they're doing
if(alert(user, "Are you sure you want to delete this record? If it has been approved, cargo points will NOT be refunded!", "Delete Record","No","Yes") == "Yes")
if(alert(user, "Are you really sure? There is no way to recover the order once deleted.", "Delete Record", "No", "Yes") == "Yes")
log_admin("[key_name(user)] has deleted supply order \ref[O] [O] from the user-side order history.")
supply_controller.order_history -= O
order_history -= O
return
// Will generate a new, requested order, for the given supply pack type
/datum/controller/supply/proc/create_order(var/datum/supply_pack/S, var/mob/user, var/reason)
/datum/controller/subsystem/supply/proc/create_order(var/datum/supply_pack/S, var/mob/user, var/reason)
var/datum/supply_order/new_order = new()
var/datum/supply_order/adm_order = new() // Admin-recorded order must be a separate copy in memory, or user-made edits will corrupt it
@@ -374,16 +348,16 @@ var/datum/controller/supply/supply_controller = new()
adm_order_history += adm_order
// Will delete the specified export receipt from the user-side list
/datum/controller/supply/proc/delete_export(var/datum/exported_crate/E, var/mob/user)
/datum/controller/subsystem/supply/proc/delete_export(var/datum/exported_crate/E, var/mob/user)
// Making sure they know what they're doing
if(alert(user, "Are you sure you want to delete this record?", "Delete Record","No","Yes") == "Yes")
if(alert(user, "Are you really sure? There is no way to recover the receipt once deleted.", "Delete Record", "No", "Yes") == "Yes")
log_admin("[key_name(user)] has deleted export receipt \ref[E] [E] from the user-side export history.")
supply_controller.exported_crates -= E
exported_crates -= E
return
// Will add an item entry to the specified export receipt on the user-side list
/datum/controller/supply/proc/add_export_item(var/datum/exported_crate/E, var/mob/user)
/datum/controller/subsystem/supply/proc/add_export_item(var/datum/exported_crate/E, var/mob/user)
var/new_name = input(user, "Name", "Please enter the name of the item.") as null|text
if(!new_name)
return
@@ -401,3 +375,21 @@ var/datum/controller/supply/supply_controller = new()
"quantity" = new_quantity,
"value" = new_value
)
/datum/exported_crate
var/name
var/value
var/list/contents
/datum/supply_order
var/ordernum // Unfabricatable index
var/index // Fabricatable index
var/datum/supply_pack/object = null
var/cost // Cost of the supply pack (Fabricatable) (Changes not reflected when purchasing supply packs, this is cosmetic only)
var/name // Name of the supply pack datum (Fabricatable)
var/ordered_by = null // Who requested the order
var/comment = null // What reason was given for the order
var/approved_by = null // Who approved the order
var/ordered_at // Date and time the order was requested at
var/approved_at // Date and time the order was approved at
var/status // [Requested, Accepted, Denied, Shipped]
-2
View File
@@ -94,14 +94,12 @@
options["LEGACY: air_master"] = air_master
options["LEGACY: job_master"] = job_master
options["LEGACY: radio_controller"] = radio_controller
options["LEGACY: supply_controller"] = supply_controller
options["LEGACY: emergency_shuttle"] = emergency_shuttle
options["LEGACY: paiController"] = paiController
options["LEGACY: cameranet"] = cameranet
options["LEGACY: transfer_controller"] = transfer_controller
options["LEGACY: gas_data"] = gas_data
options["LEGACY: plant_controller"] = plant_controller
options["LEGACY: alarm_manager"] = alarm_manager
var/pick = input(mob, "Choose a controller to debug/view variables of.", "VV controller:") as null|anything in options
if(!pick)
+8
View File
@@ -5,6 +5,7 @@
var/finished = FALSE
var/role_name = "a thing"
var/question = "Would you like to play as a thing?"
var/query_sound = 'sound/effects/ghost2.ogg' // A sound file to play to the ghost, to help people who are alt-tabbed know something might interest them.
var/be_special_flag = 0
var/list/check_bans = list()
var/wait_time = 60 SECONDS // How long to wait until returning the list of candidates.
@@ -42,6 +43,9 @@
spawn(0)
if(!C)
return
window_flash(C)
if(query_sound)
SEND_SOUND(C, sound(query_sound))
var/response = alert(C, question, "[role_name] request", "Yes", "No", "Never for this round")
if(response == "Yes")
response = alert(C, "Are you sure you want to play as a [role_name]?", "[role_name] request", "Yes", "No") // Protection from a misclick.
@@ -62,12 +66,14 @@
/datum/ghost_query/promethean
role_name = "Promethean"
question = "Someone is requesting a soul for a promethean. Would you like to play as one?"
query_sound = 'sound/effects/slime_squish.ogg'
be_special_flag = BE_ALIEN
cutoff_number = 1
/datum/ghost_query/posi_brain
role_name = "Positronic Intelligence"
question = "Someone has activated a Positronic Brain. Would you like to play as one?"
query_sound = 'sound/machines/boobeebeep.ogg'
be_special_flag = BE_AI
check_bans = list("AI", "Cyborg")
cutoff_number = 1
@@ -75,6 +81,7 @@
/datum/ghost_query/drone_brain
role_name = "Drone Intelligence"
question = "Someone has activated a Drone AI Chipset. Would you like to play as one?"
query_sound = 'sound/machines/boobeebeep.ogg'
be_special_flag = BE_AI
check_bans = list("AI", "Cyborg")
cutoff_number = 1
@@ -90,6 +97,7 @@
/datum/ghost_query/xeno
role_name = "Alien"
question = "An Alien has just been created on the facility. Would you like to play as them?"
query_sound = 'sound/voice/hiss5.ogg'
be_special_flag = BE_ALIEN
/datum/ghost_query/blob
+3
View File
@@ -9,6 +9,9 @@
/atom/proc/recursive_dir_set(var/atom/a, var/old_dir, var/new_dir)
set_dir(new_dir)
/datum/proc/qdel_self()
qdel(src)
/proc/register_all_movement(var/event_source, var/listener)
GLOB.moved_event.register(event_source, listener, /atom/movable/proc/recursive_move)
GLOB.dir_set_event.register(event_source, listener, /atom/proc/recursive_dir_set)
+22
View File
@@ -0,0 +1,22 @@
// Observer Pattern Implementation: Shuttle Added
// Registration type: /datum/shuttle (register for the global event only)
//
// Raised when: After a shuttle is initialized.
//
// Arguments that the called proc should expect:
// /datum/shuttle/shuttle: the new shuttle
GLOBAL_DATUM_INIT(shuttle_added, /decl/observ/shuttle_added, new)
/decl/observ/shuttle_added
name = "Shuttle Added"
expected_type = /datum/shuttle
/*****************************
* Shuttle Added Handling *
*****************************/
/datum/controller/subsystem/shuttles/initialize_shuttle()
. = ..()
if(.)
GLOB.shuttle_added.raise_event(.)
+38
View File
@@ -0,0 +1,38 @@
// Observer Pattern Implementation: Shuttle Moved
// Registration type: /datum/shuttle/autodock
//
// Raised when: A shuttle has moved to a new landmark.
//
// Arguments that the called proc should expect:
// /datum/shuttle/shuttle: the shuttle moving
// /obj/effect/shuttle_landmark/old_location: the old location's shuttle landmark
// /obj/effect/shuttle_landmark/new_location: the new location's shuttle landmark
// Observer Pattern Implementation: Shuttle Pre Move
// Registration type: /datum/shuttle/autodock
//
// Raised when: A shuttle is about to move to a new landmark.
//
// Arguments that the called proc should expect:
// /datum/shuttle/shuttle: the shuttle moving
// /obj/effect/shuttle_landmark/old_location: the old location's shuttle landmark
// /obj/effect/shuttle_landmark/new_location: the new location's shuttle landmark
GLOBAL_DATUM_INIT(shuttle_moved_event, /decl/observ/shuttle_moved, new)
/decl/observ/shuttle_moved
name = "Shuttle Moved"
expected_type = /datum/shuttle
GLOBAL_DATUM_INIT(shuttle_pre_move_event, /decl/observ/shuttle_pre_move, new)
/decl/observ/shuttle_pre_move
name = "Shuttle Pre Move"
expected_type = /datum/shuttle
/*****************
* Shuttle Moved/Pre Move Handling *
*****************/
// Located in modules/shuttle/shuttle.dm
// Proc: /datum/shuttle/proc/attempt_move()
+24
View File
@@ -0,0 +1,24 @@
// Observer Pattern Implementation: Stat Set
// Registration type: /mob/living
//
// Raised when: A /mob/living changes stat, using the set_stat() proc
//
// Arguments that the called proc should expect:
// /mob/living/stat_mob: The mob whose stat changed
// /old_stat: Status before the change.
// /new_stat: Status after the change.
GLOBAL_DATUM_INIT(stat_set_event, /decl/observ/stat_set, new)
/decl/observ/stat_set
name = "Stat Set"
expected_type = /mob/living
/****************
* Stat Handling *
****************/
/mob/living/set_stat(var/new_stat)
var/old_stat = stat
. = ..()
if(stat != old_stat)
GLOB.stat_set_event.raise_event(src, old_stat, new_stat)
+2 -2
View File
@@ -339,14 +339,14 @@
/datum/supply_pack/med/distillery
name = "Chemical distiller crate"
contains = list(/obj/machinery/portable_atmospherics/powered/reagent_distillery = 1)
cost = 175
cost = 50
containertype = /obj/structure/largecrate
containername = "Chemical distiller crate"
/datum/supply_pack/med/advdistillery
name = "Industrial Chemical distiller crate"
contains = list(/obj/machinery/portable_atmospherics/powered/reagent_distillery/industrial = 1)
cost = 250
cost = 150
containertype = /obj/structure/largecrate
containername = "Industrial Chemical distiller crate"
+9
View File
@@ -116,6 +116,15 @@
containername = "Robolimb blueprints (Bishop)"
access = access_robotics
/datum/supply_pack/robotics/robolimbs/cenilimicybernetics
name = "Cenilimi Cybernetics robolimb blueprints"
contains = list(/obj/item/weapon/disk/limb/cenilimicybernetics)
cost = 45
containertype = /obj/structure/closet/crate/secure/science
containername = "Robolimb blueprints (Cenilimi Cybernetics)"
access = access_robotics
/datum/supply_pack/robotics/mecha_ripley
name = "Circuit Crate (\"Ripley\" APLU)"
contains = list(
+2 -2
View File
@@ -13,7 +13,7 @@
/datum/uplink_item/abstract/announcements/fake_centcom
name = "Command Update Announcement"
desc = "Causes a falsified Command Update. Triggers immediately after supplying additional data."
item_cost = 40
item_cost = 20
/datum/uplink_item/abstract/announcements/fake_centcom/extra_args(var/mob/user)
var/title = sanitize(input("Enter your announcement title.", "Announcement Title") as null|text)
@@ -41,7 +41,7 @@
/datum/uplink_item/abstract/announcements/fake_crew_arrival
name = "Crew Arrival Announcement/Records"
desc = "Creates a fake crew arrival announcement as well as fake crew records, using your current appearance (including held items!) and worn id card. Trigger with care!"
item_cost = 30
item_cost = 15
/datum/uplink_item/abstract/announcements/fake_crew_arrival/get_goods(var/obj/item/device/uplink/U, var/loc, var/mob/user, var/list/args)
if(!user)
+15
View File
@@ -13,3 +13,18 @@
name = "Heavy Armor Vest"
item_cost = 40
path = /obj/item/clothing/suit/storage/vest/heavy/merc
/datum/uplink_item/item/armor/gorlexsuit
name = "Mercenary Voidsuit"
item_cost = 40
path = /obj/item/weapon/storage/box/syndie_kit/voidsuit
/datum/uplink_item/item/armor/gorlexsuit_fire
name = "Mercenary Voidsuit (Fire)"
item_cost = 40
path = /obj/item/weapon/storage/box/syndie_kit/voidsuit/fire
/datum/uplink_item/item/armor/combat
name = "Combat Platecarrier Set"
item_cost = 60
path = /obj/item/clothing/suit/armor/pcarrier/merc
+1 -1
View File
@@ -91,4 +91,4 @@
var/obj/structure/largecrate/C = /obj/structure/largecrate
icon = image(initial(C.icon), initial(C.icon_state))
return "\icon[icon]"
return "[bicon(icon)]"
+10 -10
View File
@@ -25,51 +25,51 @@
path = /obj/item/weapon/storage/box/syndie_kit/imp_uplink
/datum/uplink_item/item/implants/imp_shades
name = "Integrated Thermal-Shades Implant (Organic)"
name = "Integrated Thermal-Shades Implant"
item_cost = 80
path = /obj/item/weapon/storage/box/syndie_kit/imp_aug
/datum/uplink_item/item/implants/imp_taser
name = "Integrated Taser Implant (Organic)"
name = "Integrated Taser Implant"
item_cost = 30
path = /obj/item/weapon/storage/box/syndie_kit/imp_aug/taser
/datum/uplink_item/item/implants/imp_laser
name = "Integrated Laser Implant (Organic)"
name = "Integrated Laser Implant"
item_cost = 50
path = /obj/item/weapon/storage/box/syndie_kit/imp_aug/laser
/datum/uplink_item/item/implants/imp_dart
name = "Integrated Dart Implant (Organic)"
name = "Integrated Dart Implant"
item_cost = 60
path = /obj/item/weapon/storage/box/syndie_kit/imp_aug/dart
/datum/uplink_item/item/implants/imp_toolkit
name = "Integrated Toolkit Implant (Organic)"
name = "Integrated Toolkit Implant"
item_cost = 80
path = /obj/item/weapon/storage/box/syndie_kit/imp_aug/toolkit
/datum/uplink_item/item/implants/imp_medkit
name = "Integrated Medkit Implant (Organic)"
name = "Integrated Medkit Implant"
item_cost = 60
path = /obj/item/weapon/storage/box/syndie_kit/imp_aug/medkit
/datum/uplink_item/item/implants/imp_analyzer
name = "Integrated Research Scanner Implant (Organic)"
name = "Integrated Research Scanner Implant"
item_cost = 20
path = /obj/item/weapon/storage/box/syndie_kit/imp_aug/analyzer
/datum/uplink_item/item/implants/imp_sword
name = "Integrated Sword Implant (Organic)"
name = "Integrated Sword Implant"
item_cost = 40
path = /obj/item/weapon/storage/box/syndie_kit/imp_aug/sword
/datum/uplink_item/item/implants/imp_sprinter
name = "Integrated Sprinter Implant (Organic)"
name = "Integrated Sprinter Implant"
item_cost = 40
path = /obj/item/weapon/storage/box/syndie_kit/imp_aug/sprinter
/datum/uplink_item/item/implants/imp_sprinter
name = "Integrated Surge Implant (Organic)"
name = "Integrated Surge Implant"
item_cost = 40
path = /obj/item/weapon/storage/box/syndie_kit/imp_aug/surge
+12
View File
@@ -24,11 +24,23 @@
item_cost = 10
path = /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/clotting
/datum/uplink_item/item/medical/clotting_case
name = "Clotting Medicine case"
item_cost = 20
desc = "A case of three myelamine injectors. Can rapidly remove and stow up to six injectors."
path = /obj/item/weapon/storage/quickdraw/syringe_case/clotting
/datum/uplink_item/item/medical/bonemeds
name = "Bone Repair injector"
item_cost = 10
path = /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/bonemed
/datum/uplink_item/item/medical/bonemeds_case
name = "Bone Repair case"
item_cost = 20
desc = "A case of three osteodaxon injectors. Can rapidly remove and stow up to six injectors."
path = /obj/item/weapon/storage/quickdraw/syringe_case/bonemed
/datum/uplink_item/item/medical/ambrosiadeusseeds
name = "Box of 7x ambrosia deus seed packets"
item_cost = 10
+48
View File
@@ -0,0 +1,48 @@
/datum/uplink_item/crated/resources
name = "Resource Crate"
desc = "A crate routed from an in-system trading post, containing various valuable materials."
item_cost = 60
category = /datum/uplink_category/services
paths = list(\
/obj/fiftyspawner/uranium,\
/obj/fiftyspawner/phoron,\
/obj/fiftyspawner/gold,\
/obj/fiftyspawner/silver,\
/obj/fiftyspawner/osmium,\
/obj/fiftyspawner/plasteel\
)
/datum/uplink_item/crated/seeds
name = "Exotic Plantlife Crate"
desc = "A crate routed from an in-system trading post, containing various exotic plants."
item_cost = 20
category = /datum/uplink_category/services
paths = list(\
/obj/item/seeds/random,\
/obj/item/seeds/random,\
/obj/item/seeds/random,\
/obj/item/seeds/random,\
/obj/item/seeds/random,\
/obj/item/seeds/random,\
/obj/item/seeds/random,\
/obj/item/seeds/random\
)
/datum/uplink_item/crated/spare_organs
name = "Spare Organ Crate"
desc = "A crate stolen from a medical relief ship, containing various bioprinted organs."
item_cost = 20
category = /datum/uplink_category/services
crate_path = /obj/structure/closet/crate/freezer
paths = list(\
/obj/item/organ/internal/eyes/replicant,\
/obj/item/organ/internal/heart/replicant,\
/obj/item/organ/internal/kidneys/replicant,\
/obj/item/organ/internal/liver/replicant,\
/obj/item/organ/internal/lungs/replicant,\
/obj/item/organ/internal/voicebox/replicant\
)
+13 -1
View File
@@ -37,4 +37,16 @@
/datum/uplink_item/item/stealth_items/makeover
name = "Makeover Kit"
item_cost = 5
path = /obj/item/weapon/makeover
path = /obj/item/weapon/makeover
/datum/uplink_item/item/stealth_items/thievesgloves
name = "Thieve's Gloves"
desc = "A pair of sterile gloves that allow the wearer to inspect the backpacks of other players, and swap pocket items."
item_cost = 30
path = /obj/item/clothing/gloves/sterile/thieves
/datum/uplink_item/item/stealth_items/deadringer
name = "Stealth Watch"
desc = "A strange watch which can be used to create a fake corpse if you are injured when it is active, as it projects a cloaking field around your person."
item_cost = 50
path = /obj/item/weapon/deadringer
+48
View File
@@ -33,3 +33,51 @@
name = "Random Toxin - Beaker"
item_cost = 10
path = /obj/item/weapon/storage/box/syndie_kit/toxin
/datum/uplink_item/item/stealthy_weapons/penblade
name = "Energy Penblade, Black"
desc = "A concealed energy dagger with the functional casing of a pen. Makes an impressive throwing weapon."
item_cost = 20
path = /obj/item/weapon/pen/blade
/datum/uplink_item/item/stealthy_weapons/penblade_red
name = "Energy Penblade, Red"
desc = "A concealed energy dagger with the functional casing of a pen. Makes an impressive throwing weapon."
item_cost = 20
path = /obj/item/weapon/pen/blade/red
/datum/uplink_item/item/stealthy_weapons/penblade_blue
name = "Energy Penblade, Blue"
desc = "A concealed energy dagger with the functional casing of a pen. Makes an impressive throwing weapon."
item_cost = 20
path = /obj/item/weapon/pen/blade/blue
/datum/uplink_item/item/stealthy_weapons/penblade_fancy
name = "Energy Penblade, Fountain"
desc = "A concealed energy dagger with the functional casing of a pen. Makes an impressive throwing weapon."
item_cost = 20
path = /obj/item/weapon/pen/blade/fountain
/datum/uplink_item/item/stealthy_weapons/angrybuzzer
name = "Morphium Shock Ring"
desc = "An enigmatic ring used to create powerful electric shocks when punching. Can be used as a brute-force method of defibrillation."
item_cost = 40
path = /obj/item/clothing/gloves/ring/buzzer
/datum/uplink_item/item/stealthy_weapons/huntingtrap
name = "Camonetted Beartraps"
desc = "A box of unique beartraps which will partially cloak when deployed, allowing for more effective hunting."
item_cost = 30
path = /obj/item/weapon/storage/box/syndie_kit/deadliest_game
/datum/uplink_item/item/stealthy_weapons/virus
name = "Virus Cultures"
desc = "A box of three unique virus cultures. As dangerous to you as anyone else if handled improperly."
item_cost = 40
path = /obj/item/weapon/storage/box/syndie_kit/viral
/datum/uplink_item/item/stealthy_weapons/syringe_case
name = "Quickdraw Syringe Case"
desc = "A small box capable of holding six syringes for rapid deployment. Fits in your pocket."
item_cost = 20
path = /obj/item/weapon/storage/quickdraw/syringe_case
+11
View File
@@ -91,6 +91,12 @@
item_cost = 30
path = /obj/item/weapon/card/emag
/datum/uplink_item/item/tools/graviton
name = "Graviton Goggles"
desc = "An obvious, if useful pair of advanced imaging goggles that allow you to see objects and turfs through walls."
item_cost = 15
path = /obj/item/clothing/glasses/graviton
/datum/uplink_item/item/tools/thermal
name = "Thermal Imaging Glasses"
item_cost = 30
@@ -111,6 +117,11 @@
item_cost = 60
path = /obj/item/weapon/storage/box/syndie_kit/demolitions_heavy
/datum/uplink_item/item/tools/integratedcircuitprinter
name = "Integrated Circuit Printer (Upgraded)"
item_cost = 10
path = /obj/item/device/integrated_circuit_printer/upgraded
/*
/datum/uplink_item/item/tools/packagebomb/huge
name = "Package Bomb (Huge)
+1 -1
View File
@@ -52,4 +52,4 @@ datum/uplink_category/ammunition
name = "Telecrystals"
/datum/uplink_category/backup
name = "Backup"
name = "Backup"
+32 -2
View File
@@ -146,7 +146,7 @@ datum/uplink_item/dd_SortValue()
/datum/uplink_item/item/log_icon()
var/obj/I = path
return "\icon[I]"
return "[bicon(I)]"
/********************************
* *
@@ -160,7 +160,37 @@ datum/uplink_item/dd_SortValue()
if(!default_abstract_uplink_icon)
default_abstract_uplink_icon = image('icons/obj/pda.dmi', "pda-syn")
return "\icon[default_abstract_uplink_icon]"
return "[bicon(default_abstract_uplink_icon)]"
/*
* Crated goods.
*/
/datum/uplink_item/crated
var/crate_path = /obj/structure/largecrate
var/list/paths = list() // List of paths to be spawned into the crate.
/datum/uplink_item/crated/get_goods(var/obj/item/device/uplink/U, var/loc)
var/obj/L = new crate_path(get_turf(loc))
L.adjust_scale(rand(9, 12) / 10, rand(9, 12) / 10) // Some variation in the crate / locker size.
for(var/path in paths)
var/obj/O = new path(L)
O.forceMove(L)
return L
/datum/uplink_item/crated/description()
if(!desc)
// Fallback description
var/obj/temp = crate_path
desc = initial(temp.desc)
return ..()
/datum/uplink_item/crated/log_icon()
var/obj/I = crate_path
return "\icon[I]"
/****************
* Support procs *
+15 -3
View File
@@ -61,7 +61,7 @@
/datum/uplink_item/item/visible_weapons/riggedlaser
name = "Exosuit Rigged Laser"
item_cost = 60
item_cost = 30
path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/riggedlaser
/datum/uplink_item/item/visible_weapons/revolver
@@ -146,7 +146,7 @@
/datum/uplink_item/item/visible_weapons/egun
name = "Energy Gun"
item_cost = 60
item_cost = 30
path = /obj/item/weapon/gun/energy/gun
/datum/uplink_item/item/visible_weapons/lasercannon
@@ -171,5 +171,17 @@
/datum/uplink_item/item/visible_weapons/xray
name = "Xray Gun"
item_cost = 85
item_cost = 60
path = /obj/item/weapon/gun/energy/xray
/datum/uplink_item/item/visible_weapons/flamethrower
name = "Heavy Flamethrower"
desc = "A large flamethrower that runs on pressurized, gaseous phoron and electric charge."
item_cost = 60
path = /obj/item/weapon/storage/secure/briefcase/flamer
/datum/uplink_item/item/visible_weapons/concussion_grenades
name = "Concussion Grenades (8)"
desc = "A box of eight concussion grenades."
item_cost = 30
path = /obj/item/weapon/storage/box/syndie_kit/concussion_grenade
+1 -1
View File
@@ -60,7 +60,7 @@ var/const/CAMERA_WIRE_NOTHING2 = 32
C.light_disabled = !C.light_disabled
if(CAMERA_WIRE_ALARM)
C.visible_message("\icon[C] *beep*", "\icon[C] *beep*")
C.visible_message("[bicon(C)] *beep*", "[bicon(C)] *beep*")
return
/datum/wires/camera/proc/CanDeconstruct()
+5 -5
View File
@@ -34,16 +34,16 @@ var/const/WIRE_NEXT = 1024
var/obj/machinery/media/jukebox/A = holder
switch(index)
if(WIRE_POWER)
holder.visible_message("<span class='notice'>\icon[holder] The power light flickers.</span>")
holder.visible_message("<span class='notice'>[bicon(holder)] The power light flickers.</span>")
A.shock(usr, 90)
if(WIRE_HACK)
holder.visible_message("<span class='notice'>\icon[holder] The parental guidance light flickers.</span>")
holder.visible_message("<span class='notice'>[bicon(holder)] The parental guidance light flickers.</span>")
if(WIRE_REVERSE)
holder.visible_message("<span class='notice'>\icon[holder] The data light blinks ominously.</span>")
holder.visible_message("<span class='notice'>[bicon(holder)] The data light blinks ominously.</span>")
if(WIRE_SPEEDUP)
holder.visible_message("<span class='notice'>\icon[holder] The speakers squeaks.</span>")
holder.visible_message("<span class='notice'>[bicon(holder)] The speakers squeaks.</span>")
if(WIRE_SPEEDDOWN)
holder.visible_message("<span class='notice'>\icon[holder] The speakers rumble.</span>")
holder.visible_message("<span class='notice'>[bicon(holder)] The speakers rumble.</span>")
if(WIRE_START)
A.StartPlaying()
if(WIRE_STOP)
+10 -10
View File
@@ -23,15 +23,15 @@
switch(index)
if(WIRE_DETONATE)
C.visible_message("\icon[C] *BEEE-*", "\icon[C] *BEEE-*")
C.visible_message("[bicon(C)] *BEEE-*", "[bicon(C)] *BEEE-*")
C.explode()
if(WIRE_TIMED_DET)
C.visible_message("\icon[C] *BEEE-*", "\icon[C] *BEEE-*")
C.visible_message("[bicon(C)] *BEEE-*", "[bicon(C)] *BEEE-*")
C.explode()
if(WIRE_DISARM)
C.visible_message("\icon[C] *click!*", "\icon[C] *click!*")
C.visible_message("[bicon(C)] *click!*", "[bicon(C)] *click!*")
new C.mineitemtype(get_turf(C))
spawn(0)
qdel(C)
@@ -45,7 +45,7 @@
return
if(WIRE_BADDISARM)
C.visible_message("\icon[C] *BEEPBEEPBEEP*", "\icon[C] *BEEPBEEPBEEP*")
C.visible_message("[bicon(C)] *BEEPBEEPBEEP*", "[bicon(C)] *BEEPBEEPBEEP*")
spawn(20)
C.explode()
return
@@ -56,24 +56,24 @@
return
switch(index)
if(WIRE_DETONATE)
C.visible_message("\icon[C] *beep*", "\icon[C] *beep*")
C.visible_message("[bicon(C)] *beep*", "[bicon(C)] *beep*")
if(WIRE_TIMED_DET)
C.visible_message("\icon[C] *BEEPBEEPBEEP*", "\icon[C] *BEEPBEEPBEEP*")
C.visible_message("[bicon(C)] *BEEPBEEPBEEP*", "[bicon(C)] *BEEPBEEPBEEP*")
spawn(20)
C.explode()
if(WIRE_DISARM)
C.visible_message("\icon[C] *ping*", "\icon[C] *ping*")
C.visible_message("[bicon(C)] *ping*", "[bicon(C)] *ping*")
if(WIRE_DUMMY_1)
C.visible_message("\icon[C] *ping*", "\icon[C] *ping*")
C.visible_message("[bicon(C)] *ping*", "[bicon(C)] *ping*")
if(WIRE_DUMMY_2)
C.visible_message("\icon[C] *beep*", "\icon[C] *beep*")
C.visible_message("[bicon(C)] *beep*", "[bicon(C)] *beep*")
if(WIRE_BADDISARM)
C.visible_message("\icon[C] *ping*", "\icon[C] *ping*")
C.visible_message("[bicon(C)] *ping*", "[bicon(C)] *ping*")
return
/datum/wires/mines/CanUse(var/mob/living/L)
+1 -1
View File
@@ -28,7 +28,7 @@ var/const/PARTICLE_LIMIT_POWER_WIRE = 8 // Determines how strong the PA can be.
C.interface_control = !C.interface_control
if(PARTICLE_LIMIT_POWER_WIRE)
C.visible_message("\icon[C]<b>[C]</b> makes a large whirring noise.")
C.visible_message("[bicon(C)]<b>[C]</b> makes a large whirring noise.")
/datum/wires/particle_acc/control_box/UpdateCut(var/index, var/mended)
var/obj/machinery/particle_accelerator/control_box/C = holder
+1 -1
View File
@@ -124,7 +124,7 @@ var/global/list/PDA_Manifest = list()
if(depthead && car.len != 1)
car.Swap(1,car.len)
if(SSjob.is_job_in_department(real_rank, DEPARTMENT_CARGO))
if(SSjob.is_job_in_department(real_rank, DEPARTMENT_CIVILIAN))
civ[++civ.len] = list("name" = name, "rank" = rank, "active" = isactive)
department = 1
if(depthead && civ.len != 1)
-136
View File
@@ -66,7 +66,6 @@
attack_verb = list("HONKED")
var/spam_flag = 0
/obj/item/weapon/c_tube
name = "cardboard tube"
desc = "A tube... of cardboard."
@@ -77,141 +76,6 @@
throw_speed = 4
throw_range = 5
/obj/item/weapon/cane
name = "cane"
desc = "A cane used by a true gentleman."
icon = 'icons/obj/weapons.dmi'
icon_state = "cane"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi',
)
force = 5.0
throwforce = 7.0
w_class = ITEMSIZE_NORMAL
matter = list(DEFAULT_WALL_MATERIAL = 50)
attack_verb = list("bludgeoned", "whacked", "disciplined", "thrashed")
/obj/item/weapon/cane/concealed
var/concealed_blade
/obj/item/weapon/cane/concealed/New()
..()
var/obj/item/weapon/material/butterfly/switchblade/temp_blade = new(src)
concealed_blade = temp_blade
temp_blade.attack_self()
/obj/item/weapon/cane/concealed/attack_self(var/mob/user)
var/datum/gender/T = gender_datums[user.get_visible_gender()]
if(concealed_blade)
user.visible_message("<span class='warning'>[user] has unsheathed \a [concealed_blade] from [T.his] [src]!</span>", "You unsheathe \the [concealed_blade] from \the [src].")
// Calling drop/put in hands to properly call item drop/pickup procs
playsound(user.loc, 'sound/weapons/holster/sheathout.ogg', 50, 1)
user.drop_from_inventory(src)
user.put_in_hands(concealed_blade)
user.put_in_hands(src)
user.update_inv_l_hand(0)
user.update_inv_r_hand()
concealed_blade = null
else
..()
/obj/item/weapon/cane/concealed/attackby(var/obj/item/weapon/material/butterfly/W, var/mob/user)
if(!src.concealed_blade && istype(W))
var/datum/gender/T = gender_datums[user.get_visible_gender()]
user.visible_message("<span class='warning'>[user] has sheathed \a [W] into [T.his] [src]!</span>", "You sheathe \the [W] into \the [src].")
playsound(user.loc, 'sound/weapons/holster/sheathin.ogg', 50, 1)
user.drop_from_inventory(W)
W.loc = src
src.concealed_blade = W
update_icon()
else
..()
/obj/item/weapon/cane/concealed/update_icon()
if(concealed_blade)
name = initial(name)
icon_state = initial(icon_state)
item_state = initial(icon_state)
else
name = "cane shaft"
icon_state = "nullrod"
item_state = "foldcane"
/obj/item/weapon/cane/whitecane
name = "white cane"
desc = "A white cane. They are commonly used by the blind or visually impaired as a mobility tool or as a courtesy to others."
icon = 'icons/obj/weapons.dmi'
icon_state = "whitecane"
/obj/item/weapon/cane/whitecane/attack(mob/M as mob, mob/user as mob)
if(user.a_intent == I_HELP)
user.visible_message("<span class='notice'>\The [user] has lightly tapped [M] on the ankle with their white cane!</span>")
return
else
..()
/obj/item/weapon/cane/crutch
name ="crutch"
desc = "A long stick with a crosspiece at the top, used to help with walking."
icon_state = "crutch"
item_state = "crutch"
//Code for Telescopic White Cane writen by Gozulio
/obj/item/weapon/melee/collapsable_whitecane
name = "telescopic white cane"
desc = "A telescoping white cane. They are commonly used by the blind or visually impaired as a mobility tool or as a courtesy to others."
icon = 'icons/obj/weapons.dmi'
icon_state = "whitecane1in"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi',
)
slot_flags = SLOT_BELT
w_class = ITEMSIZE_SMALL
force = 3
var/on = 0
/obj/item/weapon/melee/collapsable_whitecane/attack_self(mob/user as mob)
on = !on
if(on)
user.visible_message("<span class='notice'>\The [user] extends the white cane.</span>",\
"<span class='warning'>You extend the white cane.</span>",\
"You hear an ominous click.")
icon_state = "whitecane1out"
item_state_slots = list(slot_r_hand_str = "whitecane", slot_l_hand_str = "whitecane")
w_class = ITEMSIZE_NORMAL
force = 5
attack_verb = list("smacked", "struck", "cracked", "beaten")
else
user.visible_message("<span class='notice'>\The [user] collapses the white cane.</span>",\
"<span class='notice'>You collapse the white cane.</span>",\
"You hear a click.")
icon_state = "whitecane1in"
item_state_slots = list(slot_r_hand_str = null, slot_l_hand_str = null)
w_class = ITEMSIZE_SMALL
force = 3
attack_verb = list("hit", "poked")
if(istype(user,/mob/living/carbon/human))
var/mob/living/carbon/human/H = user
H.update_inv_l_hand()
H.update_inv_r_hand()
playsound(src.loc, 'sound/weapons/empty.ogg', 50, 1)
add_fingerprint(user)
return
/obj/item/weapon/melee/collapsable_whitecane/attack(mob/M as mob, mob/user as mob)
if(user.a_intent == I_HELP)
user.visible_message("<span class='notice'>\The [user] has lightly tapped [M] on the ankle with their white cane!</span>")
return
else
..()
/obj/item/weapon/disk
name = "disk"
icon = 'icons/obj/items.dmi'
+11 -11
View File
@@ -49,20 +49,20 @@
datum/announcement/proc/Message(message as text, message_title as text)
for(var/mob/M in player_list)
if(!istype(M,/mob/new_player) && !isdeaf(M))
M << "<h2 class='alert'>[title]</h2>"
M << "<span class='alert'>[message]</span>"
to_chat(M, "<h2 class='alert'>[title]</h2>")
to_chat(M, "<span class='alert'>[message]</span>")
if (announcer)
M << "<span class='alert'> -[html_encode(announcer)]</span>"
to_chat(M, "<span class='alert'> -[html_encode(announcer)]</span>")
datum/announcement/minor/Message(message as text, message_title as text)
world << "<b>[message]</b>"
to_world("<b>[message]</b>")
datum/announcement/priority/Message(message as text, message_title as text)
world << "<h1 class='alert'>[message_title]</h1>"
world << "<span class='alert'>[message]</span>"
to_world("<h1 class='alert'>[message_title]</h1>")
to_world("<span class='alert'>[message]</span>")
if(announcer)
world << "<span class='alert'> -[html_encode(announcer)]</span>"
world << "<br>"
to_world("<span class='alert'> -[html_encode(announcer)]</span>")
to_world("<br>")
datum/announcement/priority/command/Message(message as text, message_title as text)
var/command
@@ -74,11 +74,11 @@ datum/announcement/priority/command/Message(message as text, message_title as te
command += "<br>"
for(var/mob/M in player_list)
if(!istype(M,/mob/new_player) && !isdeaf(M))
M << command
to_chat(M, command)
datum/announcement/priority/security/Message(message as text, message_title as text)
world << "<font size=4 color='red'>[message_title]</font>"
world << "<font color='red'>[message]</font>"
to_world("<font size=4 color='red'>[message_title]</font>")
to_world("<font color='red'>[message]</font>")
datum/announcement/proc/NewsCast(message as text, message_title as text)
if(!newscast)
+1
View File
@@ -7,6 +7,7 @@
// Strings.
var/welcome_text = "Cry havoc and let slip the dogs of war!"
var/antag_sound = 'sound/effects/antag_notice/general_baddie_alert.ogg' // The sound file to play when someone gets this role. Only they can hear it.
var/leader_welcome_text // Text shown to the leader, if any.
var/victory_text // World output at roundend for victory.
var/loss_text // As above for loss.
@@ -95,6 +95,10 @@
return code
/datum/antagonist/proc/greet(var/datum/mind/player)
// Makes it harder to miss if you're alt-tabbed or not paying attention.
if(antag_sound)
SEND_SOUND(player.current, sound(antag_sound))
window_flash(player.current.client)
// Basic intro text.
to_chat(player.current, "<span class='danger'><font size=3>You are a [role_text]!</font></span>")
@@ -6,6 +6,7 @@ var/datum/antagonist/deathsquad/mercenary/commandos
role_text = "Syndicate Commando"
role_text_plural = "Commandos"
welcome_text = "You are in the employ of a criminal syndicate hostile to corporate interests."
antag_sound = 'sound/effects/antag_notice/deathsquid_alert.ogg'
id_type = /obj/item/weapon/card/id/centcom/ERT
hard_cap = 4
@@ -6,6 +6,7 @@ var/datum/antagonist/deathsquad/deathsquad
role_text = "Death Commando"
role_text_plural = "Death Commandos"
welcome_text = "You work in the service of corporate Asset Protection, answering directly to the Board of Directors."
antag_sound = 'sound/effects/antag_notice/deathsquid_alert.ogg'
landmark_id = "Commando"
flags = ANTAG_OVERRIDE_JOB | ANTAG_OVERRIDE_MOB | ANTAG_HAS_NUKE | ANTAG_HAS_LEADER
default_access = list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage)
+1
View File
@@ -7,6 +7,7 @@ var/datum/antagonist/ert/ert
role_text = "Emergency Responder"
role_text_plural = "Emergency Responders"
welcome_text = "As member of the Emergency Response Team, you answer only to your leader and company officials."
antag_sound = 'sound/effects/antag_notice/general_goodie_alert.ogg'
antag_text = "You are an <b>anti</b> antagonist! Within the rules, \
try to save the station and its inhabitants from the ongoing crisis. \
Try to make sure other players have <i>fun</i>! If you are confused or at a loss, always adminhelp, \
@@ -10,7 +10,8 @@ var/datum/antagonist/technomancer/technomancers
welcome_text = "You will need to purchase <b>functions</b> and perhaps some <b>equipment</b> from the various machines around your \
base. Choose your technological arsenal carefully. Remember that without the <b>core</b> on your back, your functions are \
powerless, and therefore you will be as well.<br>\
In your pockets you will find a one-time use teleport device. Use it to leave the base and go to the colony, when you are ready."
In your pockets you will find a one-time use teleport device. Use it to leave the base and go to the station, when you are ready."
antag_sound = 'sound/effects/antag_notice/technomancer_alert.ogg'
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_SET_APPEARANCE | ANTAG_VOTABLE
antaghud_indicator = "hudwizard"
+1
View File
@@ -6,6 +6,7 @@ var/datum/antagonist/trader/traders
role_text = "Trader"
role_text_plural = "Traders"
welcome_text = "As a crewmember of the Beruang, you answer to your captain and international laws of space."
antag_sound = 'sound/effects/antag_notice/general_goodie_alert.ogg'
antag_text = "You are an <b>non-antagonist</b> visitor! Within the rules, \
try to provide interesting interaction for the crew. \
Try to make sure other players have <i>fun</i>! If you are confused or at a loss, always adminhelp, \
@@ -8,6 +8,7 @@
restricted_jobs = list("AI", "Cyborg")
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Colony Director")
welcome_text = "Use say \"#g message\" to communicate with your fellow changelings. Remember: you get all of their absorbed DNA if you absorb them."
antag_sound = 'sound/effects/antag_notice/ling_alert.ogg'
flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE
antaghud_indicator = "hudchangeling"
+1
View File
@@ -18,6 +18,7 @@ var/datum/antagonist/cultist/cult
feedback_tag = "cult_objective"
antag_indicator = "cult"
welcome_text = "You have a talisman in your possession; one that will help you start the cult on this station. Use it well and remember - there are others."
antag_sound = 'sound/effects/antag_notice/cult_alert.ogg'
victory_text = "The cult wins! It has succeeded in serving its dark masters!"
loss_text = "The staff managed to stop the cult!"
victory_feedback_tag = "win - cult win"
+1
View File
@@ -9,6 +9,7 @@ var/datum/antagonist/loyalists/loyalists
feedback_tag = "loyalist_objective"
antag_indicator = "loyal_head"
welcome_text = "You belong to the Company, body and soul. Preserve its interests against the conspirators amongst the crew."
antag_sound = 'sound/effects/antag_notice/general_goodie_alert.ogg'
victory_text = "The heads of staff remained at their posts! The loyalists win!"
loss_text = "The heads of staff did not stop the revolution!"
victory_feedback_tag = "win - rev heads killed"
+1
View File
@@ -8,6 +8,7 @@ var/datum/antagonist/renegade/renegades
bantype = "renegade"
restricted_jobs = list("AI", "Cyborg")
welcome_text = "Something's going to go wrong today, you can just feel it. You're paranoid, you've got a gun, and you're going to survive."
antag_sound = 'sound/effects/antag_notice/general_goodie_alert.ogg'
antag_text = "You are a <b>minor</b> antagonist! Within the rules, \
try to protect yourself and what's important to you. You aren't here to cause trouble, \
you're just more willing (and equipped) to go to extremes to stop it than others are. \
+1
View File
@@ -8,6 +8,7 @@ var/datum/antagonist/rogue_ai/malf
mob_path = /mob/living/silicon/ai
landmark_id = "AI"
welcome_text = "You are malfunctioning! You do not have to follow any laws."
antag_sound = 'sound/effects/antag_notice/malf_alert.ogg'
victory_text = "The AI has taken control of all of the station's systems."
loss_text = "The AI has been shut down!"
flags = ANTAG_VOTABLE | ANTAG_OVERRIDE_MOB | ANTAG_OVERRIDE_JOB | ANTAG_CHOOSE_NAME
+1
View File
@@ -3,6 +3,7 @@ var/datum/antagonist/traitor/traitors
// Inherits most of its vars from the base datum.
/datum/antagonist/traitor
id = MODE_TRAITOR
antag_sound = 'sound/effects/antag_notice/traitor_alert.ogg'
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Colony Director")
flags = ANTAG_SUSPICIOUS | ANTAG_RANDSPAWN | ANTAG_VOTABLE
can_speak_aooc = FALSE // If they want to plot and plan as this sort of traitor, they'll need to do it ICly.
+3 -159
View File
@@ -62,8 +62,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
////////////
//SHUTTLES//
////////////
//shuttle areas must contain at least two areas in a subgroup if you want to move a shuttle from one
//place to another. Look at escape shuttle for example.
//Shuttles only need starting area, movement is handled by landmarks
//All shuttles should now be under shuttle since we have smooth-wall code.
/area/shuttle
@@ -76,160 +75,55 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "\improper Arrival Shuttle"
ambience = AMBIENCE_ARRIVALS
/area/shuttle/arrival/pre_game
/area/shuttle/supply
name = "\improper Supply Shuttle"
icon_state = "shuttle2"
/area/shuttle/arrival/station
icon_state = "shuttle"
dynamic_lighting = 0
ambience = AMBIENCE_ARRIVALS
/area/shuttle/escape
name = "\improper Emergency Shuttle"
music = "music/escape.ogg"
/area/shuttle/escape/station
name = "\improper Emergency Shuttle Station"
icon_state = "shuttle2"
dynamic_lighting = 0
/area/shuttle/escape/centcom
name = "\improper Emergency Shuttle CentCom"
icon_state = "shuttle"
/area/shuttle/escape/transit // the area to pass through for 3 minute transit
name = "\improper Emergency Shuttle Transit"
icon_state = "shuttle"
/area/shuttle/escape_pod1
name = "\improper Escape Pod One"
music = "music/escape.ogg"
/area/shuttle/escape_pod1/station
icon_state = "shuttle2"
/area/shuttle/escape_pod1/centcom
icon_state = "shuttle"
/area/shuttle/escape_pod1/transit
icon_state = "shuttle"
/area/shuttle/escape_pod2
name = "\improper Escape Pod Two"
music = "music/escape.ogg"
/area/shuttle/escape_pod2/station
icon_state = "shuttle2"
/area/shuttle/escape_pod2/centcom
icon_state = "shuttle"
/area/shuttle/escape_pod2/transit
icon_state = "shuttle"
/area/shuttle/escape_pod3
name = "\improper Escape Pod Three"
music = "music/escape.ogg"
/area/shuttle/escape_pod3/station
icon_state = "shuttle2"
/area/shuttle/escape_pod3/centcom
icon_state = "shuttle"
/area/shuttle/escape_pod3/transit
icon_state = "shuttle"
/area/shuttle/escape_pod4
name = "\improper Escape Pod Four"
music = "music/escape.ogg"
/area/shuttle/escape_pod4/station
icon_state = "shuttle2"
/area/shuttle/escape_pod4/centcom
icon_state = "shuttle"
/area/shuttle/escape_pod4/transit
icon_state = "shuttle"
/area/shuttle/escape_pod5
name = "\improper Escape Pod Five"
music = "music/escape.ogg"
/area/shuttle/escape_pod5/station
icon_state = "shuttle2"
/area/shuttle/escape_pod5/centcom
icon_state = "shuttle"
/area/shuttle/escape_pod5/transit
icon_state = "shuttle"
/area/shuttle/escape_pod6
name = "\improper Escape Pod Six"
music = "music/escape.ogg"
/area/shuttle/escape_pod6/station
icon_state = "shuttle2"
/area/shuttle/escape_pod6/centcom
icon_state = "shuttle"
/area/shuttle/escape_pod6/transit
icon_state = "shuttle"
/area/shuttle/large_escape_pod1
name = "\improper Large Escape Pod One"
music = "music/escape.ogg"
/area/shuttle/large_escape_pod1/station
icon_state = "shuttle2"
/area/shuttle/large_escape_pod1/centcom
icon_state = "shuttle"
/area/shuttle/large_escape_pod1/transit
icon_state = "shuttle"
/area/shuttle/large_escape_pod2
name = "\improper Large Escape Pod Two"
music = "music/escape.ogg"
/area/shuttle/large_escape_pod2/station
icon_state = "shuttle2"
/area/shuttle/large_escape_pod2/centcom
icon_state = "shuttle"
/area/shuttle/large_escape_pod2/transit
icon_state = "shuttle"
/area/shuttle/cryo
name = "\improper Cryogenic Storage"
/area/shuttle/cryo/station
icon_state = "shuttle2"
base_turf = /turf/simulated/mineral/floor/ignore_mapgen
/area/shuttle/cryo/centcom
icon_state = "shuttle"
/area/shuttle/cryo/transit
icon_state = "shuttle"
/area/shuttle/mining
name = "\improper Mining Elevator"
music = "music/escape.ogg"
dynamic_lighting = 0
base_turf = /turf/simulated/mineral/floor/ignore_mapgen
/area/shuttle/mining/station
icon_state = "shuttle2"
/area/shuttle/mining/outpost
icon_state = "shuttle"
/area/shuttle/transport1/centcom
icon_state = "shuttle"
name = "\improper Transport Shuttle CentCom"
@@ -286,54 +180,15 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
icon_state = "red"
dynamic_lighting = 0
/area/shuttle/trade/centcom
name = "\improper Trade Shuttle CentCom"
icon_state = "shuttlered"
/area/shuttle/trade/station
name = "\improper Trade Shuttle"
icon_state = "shuttlered"
/area/shuttle/thunderdome
name = "honk"
/area/shuttle/thunderdome/grnshuttle
name = "\improper Thunderdome GRN Shuttle"
icon_state = "green"
/area/shuttle/thunderdome/grnshuttle/dome
name = "\improper GRN Shuttle"
icon_state = "shuttlegrn"
/area/shuttle/thunderdome/grnshuttle/station
name = "\improper GRN Station"
icon_state = "shuttlegrn2"
/area/shuttle/thunderdome/redshuttle
name = "\improper Thunderdome RED Shuttle"
icon_state = "red"
/area/shuttle/thunderdome/redshuttle/dome
name = "\improper RED Shuttle"
icon_state = "shuttlered"
/area/shuttle/thunderdome/redshuttle/station
name = "\improper RED Station"
icon_state = "shuttlered2"
// === Trying to remove these areas:
/area/shuttle/research
name = "\improper Research Elevator"
music = "music/escape.ogg"
dynamic_lighting = 0
base_turf = /turf/simulated/mineral/floor/ignore_mapgen
/area/shuttle/research/station
icon_state = "shuttle2"
/area/shuttle/research/outpost
icon_state = "shuttle"
/area/airtunnel1/ // referenced in airtunnel.dm:759
/area/dummy/ // Referenced in engine.dm:261
@@ -2039,17 +1894,6 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "\improper Cargo Mining Dock"
icon_state = "mining"
/area/supply/station
name = "Supply Shuttle"
icon_state = "shuttle3"
requires_power = 0
base_turf = /turf/space
/area/supply/dock
name = "Supply Shuttle"
icon_state = "shuttle3"
requires_power = 0
base_turf = /turf/space
// SCIENCE
+25
View File
@@ -71,6 +71,31 @@
power_change() // all machines set to current power level, also updates lighting icon
return INITIALIZE_HINT_LATELOAD
// Changes the area of T to A. Do not do this manually.
// Area is expected to be a non-null instance.
/proc/ChangeArea(var/turf/T, var/area/A)
if(!istype(A))
CRASH("Area change attempt failed: invalid area supplied.")
var/area/old_area = get_area(T)
if(old_area == A)
return
// NOTE: BayStation calles area.Exited/Entered for the TURF T. So far we don't do that.s
// NOTE: There probably won't be any atoms in these turfs, but just in case we should call these procs.
A.contents.Add(T)
if(old_area)
// Handle dynamic lighting update if
if(T.dynamic_lighting && old_area.dynamic_lighting != A.dynamic_lighting)
if(A.dynamic_lighting)
T.lighting_build_overlay()
else
T.lighting_clear_overlay()
for(var/atom/movable/AM in T)
old_area.Exited(AM, A)
for(var/atom/movable/AM in T)
A.Entered(AM, old_area)
for(var/obj/machinery/M in T)
M.power_change()
/area/proc/get_contents()
return contents
+164
View File
@@ -0,0 +1,164 @@
//
// Shuttles formerly required at least two areas in a subgroup if you want to move a shuttle from one
// place to another. Since shuttles now used landmarks instead these areas are deprecated!
// They are left here for the moment in order to make existing maps loadable, but should be phased out.
//
/area/shuttle/arrival/pre_game
icon_state = "shuttle2"
/area/shuttle/arrival/station
icon_state = "shuttle"
dynamic_lighting = 0
ambience = AMBIENCE_ARRIVALS
/area/shuttle/escape/station
name = "\improper Emergency Shuttle Station"
icon_state = "shuttle2"
dynamic_lighting = 0
/area/shuttle/escape/centcom
name = "\improper Emergency Shuttle CentCom"
icon_state = "shuttle"
/area/shuttle/escape/transit // the area to pass through for 3 minute transit
name = "\improper Emergency Shuttle Transit"
icon_state = "shuttle"
/area/shuttle/escape_pod1/station
icon_state = "shuttle2"
/area/shuttle/escape_pod1/centcom
icon_state = "shuttle"
/area/shuttle/escape_pod1/transit
icon_state = "shuttle"
/area/shuttle/escape_pod2/station
icon_state = "shuttle2"
/area/shuttle/escape_pod2/centcom
icon_state = "shuttle"
/area/shuttle/escape_pod2/transit
icon_state = "shuttle"
/area/shuttle/escape_pod3/station
icon_state = "shuttle2"
/area/shuttle/escape_pod3/centcom
icon_state = "shuttle"
/area/shuttle/escape_pod3/transit
icon_state = "shuttle"
/area/shuttle/escape_pod4/station
icon_state = "shuttle2"
/area/shuttle/escape_pod4/centcom
icon_state = "shuttle"
/area/shuttle/escape_pod4/transit
icon_state = "shuttle"
/area/shuttle/escape_pod5/station
icon_state = "shuttle2"
/area/shuttle/escape_pod5/centcom
icon_state = "shuttle"
/area/shuttle/escape_pod5/transit
icon_state = "shuttle"
/area/shuttle/escape_pod6/station
icon_state = "shuttle2"
/area/shuttle/escape_pod6/centcom
icon_state = "shuttle"
/area/shuttle/escape_pod6/transit
icon_state = "shuttle"
/area/shuttle/large_escape_pod1/station
icon_state = "shuttle2"
/area/shuttle/large_escape_pod1/centcom
icon_state = "shuttle"
/area/shuttle/large_escape_pod1/transit
icon_state = "shuttle"
/area/shuttle/large_escape_pod2/station
icon_state = "shuttle2"
/area/shuttle/large_escape_pod2/centcom
icon_state = "shuttle"
/area/shuttle/large_escape_pod2/transit
icon_state = "shuttle"
/area/shuttle/cryo/station
icon_state = "shuttle2"
base_turf = /turf/simulated/mineral/floor/ignore_mapgen
/area/shuttle/cryo/centcom
icon_state = "shuttle"
/area/shuttle/cryo/transit
icon_state = "shuttle"
/area/shuttle/mining/station
icon_state = "shuttle2"
/area/shuttle/mining/outpost
icon_state = "shuttle"
/area/shuttle/trade/centcom
name = "\improper Trade Shuttle CentCom"
icon_state = "shuttlered"
/area/shuttle/trade/station
name = "\improper Trade Shuttle"
icon_state = "shuttlered"
/area/shuttle/thunderdome/grnshuttle
name = "\improper Thunderdome GRN Shuttle"
icon_state = "green"
/area/shuttle/thunderdome/grnshuttle/dome
name = "\improper GRN Shuttle"
icon_state = "shuttlegrn"
/area/shuttle/thunderdome/grnshuttle/station
name = "\improper GRN Station"
icon_state = "shuttlegrn2"
/area/shuttle/thunderdome/redshuttle
name = "\improper Thunderdome RED Shuttle"
icon_state = "red"
/area/shuttle/thunderdome/redshuttle/dome
name = "\improper RED Shuttle"
icon_state = "shuttlered"
/area/shuttle/thunderdome/redshuttle/station
name = "\improper RED Station"
icon_state = "shuttlered2"
/area/shuttle/research/station
icon_state = "shuttle2"
/area/shuttle/research/outpost
icon_state = "shuttle"
/area/supply/station
name = "Supply Shuttle"
icon_state = "shuttle3"
requires_power = 0
base_turf = /turf/space
/area/supply/dock
name = "Supply Shuttle"
icon_state = "shuttle3"
requires_power = 0
base_turf = /turf/space
+1 -1
View File
@@ -183,7 +183,7 @@
else
f_name += "oil-stained [name][infix]."
to_chat(user, "\icon[src] That's [f_name] [suffix]")
to_chat(user, "[bicon(src)] That's [f_name] [suffix]")
to_chat(user,desc)
return distance == -1 || (get_dist(src, user) <= distance)
+95 -2
View File
@@ -23,6 +23,9 @@
var/old_y = 0
var/does_spin = TRUE // Does the atom spin when thrown (of course it does :P)
var/movement_type = NONE
var/cloaked = FALSE //If we're cloaked or not
var/image/cloaked_selfimage //The image we use for our client to let them see where we are
/atom/movable/Destroy()
. = ..()
@@ -44,7 +47,7 @@
pulledby = null
/atom/movable/vv_edit_var(var_name, var_value)
if(GLOB.VVpixelmovement[var_name]) //Pixel movement is not yet implemented, changing this will break everything irreversibly.
if(var_name in GLOB.VVpixelmovement) //Pixel movement is not yet implemented, changing this will break everything irreversibly.
return FALSE
return ..()
@@ -446,7 +449,7 @@
if(z in using_map.sealed_levels)
return
if(config.use_overmap)
if(using_map.use_overmap)
overmap_spacetravel(get_turf(src), src)
return
@@ -509,3 +512,93 @@
// Called when touching a lava tile.
/atom/movable/proc/lava_act()
fire_act(null, 10000, 1000)
// Procs to cloak/uncloak
/atom/movable/proc/cloak()
if(cloaked)
return FALSE
cloaked = TRUE
. = TRUE // We did work
var/static/animation_time = 1 SECOND
cloaked_selfimage = get_cloaked_selfimage()
//Wheeee
cloak_animation(animation_time)
//Needs to be last so people can actually see the effect before we become invisible
plane = CLOAKED_PLANE
/atom/movable/proc/uncloak()
if(!cloaked)
return FALSE
cloaked = FALSE
. = TRUE // We did work
var/static/animation_time = 1 SECOND
QDEL_NULL(cloaked_selfimage)
//Needs to be first so people can actually see the effect, so become uninvisible first
plane = initial(plane)
//Oooooo
uncloak_animation(animation_time)
// Animations for cloaking/uncloaking
/atom/movable/proc/cloak_animation(var/length = 1 SECOND)
//Save these
var/initial_alpha = alpha
//Animate alpha fade
animate(src, alpha = 0, time = length)
//Animate a cloaking effect
var/our_filter = filters.len+1 //Filters don't appear to have a type that can be stored in a var and accessed. This is how the DM reference does it.
filters += filter(type="wave", x = 0, y = 16, size = 0, offset = 0, flags = WAVE_SIDEWAYS)
animate(filters[our_filter], offset = 1, size = 8, time = length, flags = ANIMATION_PARALLEL)
//Wait for animations to finish
sleep(length+5)
//Remove those
filters -= filters[our_filter]
//Back to original alpha
alpha = initial_alpha
/atom/movable/proc/uncloak_animation(var/length = 1 SECOND)
//Save these
var/initial_alpha = alpha
//Put us back to normal, but no alpha
alpha = 0
//Animate alpha fade up
animate(src, alpha = initial_alpha, time = length)
//Animate a cloaking effect
var/our_filter = filters.len+1 //Filters don't appear to have a type that can be stored in a var and accessed. This is how the DM reference does it.
filters += filter(type="wave", x=0, y = 16, size = 8, offset = 1, flags = WAVE_SIDEWAYS)
animate(filters[our_filter], offset = 0, size = 0, time = length, flags = ANIMATION_PARALLEL)
//Wait for animations to finish
sleep(length+5)
//Remove those
filters -= filters[our_filter]
// So cloaked things can see themselves, if necessary
/atom/movable/proc/get_cloaked_selfimage()
var/icon/selficon = icon(icon, icon_state)
selficon.MapColors(0,0,0, 0,0,0, 0,0,0, 1,1,1) //White
var/image/selfimage = image(selficon)
selfimage.color = "#0000FF"
selfimage.alpha = 100
selfimage.layer = initial(layer)
selfimage.plane = initial(plane)
selfimage.loc = src
return selfimage
+2 -2
View File
@@ -46,7 +46,7 @@
icon_state = "scanner_0"
density = 1
anchored = 1.0
use_power = 1
use_power = USE_POWER_IDLE
idle_power_usage = 50
active_power_usage = 300
interact_offline = 1
@@ -260,7 +260,7 @@
var/obj/item/weapon/disk/data/disk = null
var/selected_menu_key = null
anchored = 1
use_power = 1
use_power = USE_POWER_IDLE
idle_power_usage = 10
active_power_usage = 400
var/waiting_for_user_input=0 // Fix for #274 (Mash create block injector without answering dialog to make unlimited injectors) - N3X

Some files were not shown because too many files have changed in this diff Show More