Merge branch 'release' of https://github.com/VOREStation/VOREStation into izac-voreupdate

This commit is contained in:
izac112
2020-05-11 18:20:43 +02:00
295 changed files with 6398 additions and 3317 deletions

View File

@@ -48,6 +48,9 @@ Pipelines + Other Objects -> Pipe network
pipe_color = null pipe_color = null
init_dir() init_dir()
/obj/machinery/atmospherics/examine_icon()
return icon(icon=initial(icon),icon_state=initial(icon_state))
// This is used to set up what directions pipes will connect to. Should be called inside New() and whenever a dir changes. // This is used to set up what directions pipes will connect to. Should be called inside New() and whenever a dir changes.
/obj/machinery/atmospherics/proc/init_dir() /obj/machinery/atmospherics/proc/init_dir()
return return

View File

@@ -21,15 +21,9 @@
var/set_temperature = T20C // Thermostat var/set_temperature = T20C // Thermostat
var/cooling = 0 var/cooling = 0
/obj/machinery/atmospherics/unary/freezer/New() /obj/machinery/atmospherics/unary/freezer/Initialize()
..() . = ..()
component_parts = list() default_apply_parts()
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/stack/cable_coil(src, 2)
RefreshParts()
/obj/machinery/atmospherics/unary/freezer/atmos_init() /obj/machinery/atmospherics/unary/freezer/atmos_init()
if(node) if(node)

View File

@@ -21,15 +21,9 @@
var/set_temperature = T20C //thermostat var/set_temperature = T20C //thermostat
var/heating = 0 //mainly for icon updates var/heating = 0 //mainly for icon updates
/obj/machinery/atmospherics/unary/heater/New() /obj/machinery/atmospherics/unary/heater/Initialize()
..() . = ..()
component_parts = list() default_apply_parts()
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
component_parts += new /obj/item/stack/cable_coil(src, 5)
RefreshParts()
/obj/machinery/atmospherics/unary/heater/atmos_init() /obj/machinery/atmospherics/unary/heater/atmos_init()
if(node) if(node)

View File

@@ -378,3 +378,8 @@ var/global/list/##LIST_NAME = list();\
// Used by radios to indicate that they have sent a message via something other than subspace // Used by radios to indicate that they have sent a message via something other than subspace
#define RADIO_CONNECTION_FAIL 0 #define RADIO_CONNECTION_FAIL 0
#define RADIO_CONNECTION_NON_SUBSPACE 1 #define RADIO_CONNECTION_NON_SUBSPACE 1
#define JOB_CARBON 0x1
#define JOB_SILICON_ROBOT 0x2
#define JOB_SILICON_AI 0x4
#define JOB_SILICON 0x6 // 2|4, probably don't set jobs to this, but good for checking

View File

@@ -1,6 +1,15 @@
// Modes for examine text output
#define EXAMINE_MODE_DEFAULT 0 #define EXAMINE_MODE_DEFAULT 0
#define EXAMINE_MODE_INCLUDE_USAGE 1 #define EXAMINE_MODE_INCLUDE_USAGE 1
#define EXAMINE_MODE_SWITCH_TO_PANEL 2 #define EXAMINE_MODE_SWITCH_TO_PANEL 2
// Should be one higher than the above // Should be one higher than the above
#define EXAMINE_MODE_MAX 3 #define EXAMINE_MODE_MAX 3
// Modes for parsing multilingual speech
#define MULTILINGUAL_DEFAULT 0
#define MULTILINGUAL_SPACE 1
#define MULTILINGUAL_DOUBLE_DELIMITER 2
#define MULTILINGUAL_OFF 3
#define MULTILINGUAL_MODE_MAX 4

View File

@@ -54,7 +54,7 @@
#define LANGUAGE_AKHANI "Akhani" #define LANGUAGE_AKHANI "Akhani"
#define LANGUAGE_ALAI "Alai" #define LANGUAGE_ALAI "Alai"
#define LANGUAGE_ZADDAT "Vedahq" #define LANGUAGE_ZADDAT "Vedahq"
#define LANGUAGE_PROMETHEAN "Promethean" #define LANGUAGE_PROMETHEAN "Promethean Biolinguistics"
#define LANGUAGE_BLOB "Blob" #define LANGUAGE_BLOB "Blob"
#define LANGUAGE_GIBBERISH "Babel" #define LANGUAGE_GIBBERISH "Babel"

View File

@@ -0,0 +1,12 @@
#define TGS_EXTERNAL_CONFIGURATION
#define TGS_V3_API
#define TGS_DEFINE_AND_SET_GLOBAL(Name, Value) GLOBAL_VAR_INIT(##Name, ##Value); GLOBAL_PROTECT(##Name)
#define TGS_READ_GLOBAL(Name) GLOB.##Name
#define TGS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value
#define TGS_WORLD_ANNOUNCE(message) to_chat(world, "<span class='boldannounce'>[html_encode(##message)]</span>")
#define TGS_INFO_LOG(message) log_to_dd("TGS Info: [##message]")
#define TGS_WARNING_LOG(message) log_to_dd("TGS Warn: [##message]")
#define TGS_ERROR_LOG(message) log_to_dd("TGS Error: [##message]")
#define TGS_NOTIFY_ADMINS(event) message_admins(##event)
#define TGS_CLIENT_COUNT GLOB.clients.len
#define TGS_PROTECT_DATUM(Path) GENERAL_PROTECT_DATUM(##Path)

273
code/__defines/tgs.dm Normal file
View File

@@ -0,0 +1,273 @@
//tgstation-server DMAPI
#define TGS_DMAPI_VERSION "5.0.0"
//All functions and datums outside this document are subject to change with any version and should not be relied on
//CONFIGURATION
//create this define if you want to do configuration outside of this file
#ifndef TGS_EXTERNAL_CONFIGURATION
//Comment this out once you've filled in the below
#error TGS API unconfigured
//Uncomment this if you wish to allow the game to interact with TGS 3
//This will raise the minimum required security level of your game to TGS_SECURITY_TRUSTED due to it utilizing call()()
//#define TGS_V3_API
//Required interfaces (fill in with your codebase equivalent):
//create a global variable named `Name` and set it to `Value`
#define TGS_DEFINE_AND_SET_GLOBAL(Name, Value)
//Read the value in the global variable `Name`
#define TGS_READ_GLOBAL(Name)
//Set the value in the global variable `Name` to `Value`
#define TGS_WRITE_GLOBAL(Name, Value)
//Disallow ANYONE from reflecting a given `path`, security measure to prevent in-game use of DD -> TGS capabilities
#define TGS_PROTECT_DATUM(Path)
//Display an announcement `message` from the server to all players
#define TGS_WORLD_ANNOUNCE(message)
//Notify current in-game administrators of a string `event`
#define TGS_NOTIFY_ADMINS(event)
//Write an info `message` to a server log
#define TGS_INFO_LOG(message)
//Write an warning `message` to a server log
#define TGS_WARNING_LOG(message)
//Write an error `message` to a server log
#define TGS_ERROR_LOG(message)
//Get the number of connected /clients
#define TGS_CLIENT_COUNT
#endif
//EVENT CODES
#define TGS_EVENT_REBOOT_MODE_CHANGE -1 //Before a reboot mode change, extras parameters are the current and new reboot mode enums
#define TGS_EVENT_PORT_SWAP -2 //Before a port change is about to happen, extra parameters is new port
#define TGS_EVENT_INSTANCE_RENAMED -3 //Before the instance is renamed, extra prameter is the new name
//See the descriptions for the parameters of these codes here: https://github.com/tgstation/tgstation-server/blob/master/src/Tgstation.Server.Host/Components/EventType.cs
#define TGS_EVENT_REPO_RESET_ORIGIN 0
#define TGS_EVENT_REPO_CHECKOUT 1
#define TGS_EVENT_REPO_FETCH 2
#define TGS_EVENT_REPO_MERGE_PULL_REQUEST 3
#define TGS_EVENT_REPO_PRE_SYNCHRONIZE 4
#define TGS_EVENT_BYOND_INSTALL_START 5
#define TGS_EVENT_BYOND_INSTALL_FAIL 6
#define TGS_EVENT_BYOND_ACTIVE_VERSION_CHANGE 7
#define TGS_EVENT_COMPILE_START 8
#define TGS_EVENT_COMPILE_CANCELLED 9
#define TGS_EVENT_COMPILE_FAILURE 10
#define TGS_EVENT_COMPILE_COMPLETE 11 // Note, this event fires before the new .dmb is loaded into the watchdog. Consider using the TGS_EVENT_DEPLOYMENT_COMPLETE instead
#define TGS_EVENT_INSTANCE_AUTO_UPDATE_START 12
#define TGS_EVENT_DEPLOYMENT_COMPLETE 13
//OTHER ENUMS
#define TGS_REBOOT_MODE_NORMAL 0
#define TGS_REBOOT_MODE_SHUTDOWN 1
#define TGS_REBOOT_MODE_RESTART 2
#define TGS_SECURITY_TRUSTED 0
#define TGS_SECURITY_SAFE 1
#define TGS_SECURITY_ULTRASAFE 2
//REQUIRED HOOKS
//Call this somewhere in /world/New() that is always run
//IMPORTANT: This function may sleep! Other TGS functions will not succeed until it completes
//event_handler: optional user defined event handler. The default behaviour is to broadcast the event in english to all connected admin channels
//minimum_required_security_level: The minimum required security level to run the game in which the DMAPI is integrated
/world/proc/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE)
return
//Call this when your initializations are complete and your game is ready to play before any player interactions happen
//This may use world.sleep_offline to make this happen so ensure no changes are made to it while this call is running
//Most importantly, before this point, note that any static files or directories may be in use by another server. Your code should account for this
//This function should not be called before ..() in /world/New()
/world/proc/TgsInitializationComplete()
return
//Put this at the start of /world/Topic()
#define TGS_TOPIC var/tgs_topic_return = TgsTopic(args[1]); if(tgs_topic_return) return tgs_topic_return
//Call this at the beginning of world/Reboot(reason)
/world/proc/TgsReboot()
return
//DATUM DEFINITIONS
//unless otherwise specified all datums defined here should be considered read-only, warranty void if written
//represents git revision information about the current world build
/datum/tgs_revision_information
var/commit //full sha of compiled commit
var/origin_commit //full sha of last known remote commit. This may be null if the TGS repository is not currently tracking a remote branch
//represents a version of tgstation-server
/datum/tgs_version
var/suite //The suite/major version, can be >=3
//this group of variables can be null to represent a wild card
var/minor //The minor version
var/patch //The patch version
var/deprecated_patch //The legacy version
var/raw_parameter //The unparsed parameter
var/deprefixed_parameter //The version only bit of raw_parameter
//if the tgs_version is a wildcard version
/datum/tgs_version/proc/Wildcard()
return
//if the tgs_version equals some other_version
/datum/tgs_version/proc/Equals(datum/tgs_version/other_version)
return
//represents a merge of a GitHub pull request
/datum/tgs_revision_information/test_merge
var/number //pull request number
var/title //pull request title
var/body //pull request body
var/author //pull request github author
var/url //link to pull request html
var/pull_request_commit //commit of the pull request when it was merged
var/time_merged //timestamp of when the merge commit for the pull request was created
var/comment //optional comment left by the one who initiated the test merge
//represents a connected chat channel
/datum/tgs_chat_channel
var/id //internal channel representation
var/friendly_name //user friendly channel name
var/connection_name //the name of the configured chat connection
var/is_admin_channel //if the server operator has marked this channel for game admins only
var/is_private_channel //if this is a private chat channel
var/custom_tag //user defined string associated with channel
//represents a chat user
/datum/tgs_chat_user
var/id //Internal user representation, requires channel to be unique
var/friendly_name //The user's public name
var/mention //The text to use to ping this user in a message
var/datum/tgs_chat_channel/channel //The /datum/tgs_chat_channel this user was from
//user definable callback for handling events
//extra parameters may be specified depending on the event
/datum/tgs_event_handler/proc/HandleEvent(event_code, ...)
set waitfor = FALSE
return
//user definable chat command
/datum/tgs_chat_command
var/name = "" //the string to trigger this command on a chat bot. e.g. TGS3_BOT: do_this_command
var/help_text = "" //help text for this command
var/admin_only = FALSE //set to TRUE if this command should only be usable by registered chat admins
//override to implement command
//sender: The tgs_chat_user who send to command
//params: The trimmed string following the command name
//The return value will be stringified and sent to the appropriate chat
/datum/tgs_chat_command/proc/Run(datum/tgs_chat_user/sender, params)
CRASH("[type] has no implementation for Run()")
//FUNCTIONS
//Returns the respective supported /datum/tgs_version of the API
/world/proc/TgsMaximumAPIVersion()
return
/world/proc/TgsMinimumAPIVersion()
return
//Returns TRUE if the world was launched under the server tools and the API matches, FALSE otherwise
//No function below this succeeds if it returns FALSE or if TgsNew() has yet to be called
/world/proc/TgsAvailable()
return
//Gets the current /datum/tgs_version of the server tools running the server
/world/proc/TgsVersion()
return
//Gets the current /datum/tgs_version of the DMAPI being used
/world/proc/TgsApiVersion()
return
//Gets the name of the TGS instance running the game
/world/proc/TgsInstanceName()
return
//Get the current `/datum/tgs_revision_information`
/world/proc/TgsRevision()
return
//Get the current BYOND security level
/world/proc/TgsSecurityLevel()
return
//Gets a list of active `/datum/tgs_revision_information/test_merge`s
/world/proc/TgsTestMerges()
return
//Forces a hard reboot of BYOND by ending the process
//unlike del(world) clients will try to reconnect
//If the service has not requested a shutdown, the next server will take over
/world/proc/TgsEndProcess()
return
//Gets a list of connected tgs_chat_channel
/world/proc/TgsChatChannelInfo()
return
//Sends a message to connected game chats
//message: The message to send
//channels: optional channels to limit the broadcast to
/world/proc/TgsChatBroadcast(message, list/channels)
return
//Send a message to non-admin connected chats
//message: The message to send
//admin_only: If TRUE, message will instead be sent to only admin connected chats
/world/proc/TgsTargetedChatBroadcast(message, admin_only)
return
//Send a private message to a specific user
//message: The message to send
//user: The /datum/tgs_chat_user to send to
/world/proc/TgsChatPrivateMessage(message, datum/tgs_chat_user/user)
return
/*
The MIT License
Copyright (c) 2017 Jordan Brown
Permission is hereby granted, free of charge,
to any person obtaining a copy of this software and
associated documentation files (the "Software"), to
deal in the Software without restriction, including
without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom
the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

View File

@@ -107,7 +107,7 @@ AngleToHue(hue)
Converts an angle to a hue in the valid range. Converts an angle to a hue in the valid range.
RotateHue(hsv, angle) RotateHue(hsv, angle)
Takes an HSV or HSVA value and rotates the hue forward through red, green, and blue by an angle from 0 to 360. Takes an HSV or HSVA value and rotates the hue forward through red, green, and blue by an angle from 0 to 360.
(Rotating red by 60<EFBFBD> produces yellow.) The result is another HSV or HSVA color with the same saturation and value (Rotating red by 60deg produces yellow.) The result is another HSV or HSVA color with the same saturation and value
as the original, but a different hue. as the original, but a different hue.
GrayScale(rgb) GrayScale(rgb)
Takes an RGB or RGBA color and converts it to grayscale. Returns an RGB or RGBA string. Takes an RGB or RGBA color and converts it to grayscale. Returns an RGB or RGBA string.
@@ -679,7 +679,7 @@ proc/ColorTone(rgb, tone)
var/curstate = A.icon_state || defstate var/curstate = A.icon_state || defstate
if(!((noIcon = (!curicon)))) if(!((noIcon = (!curicon))))
var/curstates = icon_states(curicon) var/curstates = cached_icon_states(curicon)
if(!(curstate in curstates)) if(!(curstate in curstates))
if("" in curstates) if("" in curstates)
curstate = "" curstate = ""
@@ -689,19 +689,16 @@ proc/ColorTone(rgb, tone)
var/curdir var/curdir
var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have
//These should use the parent's direction (most likely) // Use the requested dir or the atom's current dir
if(!A.dir || A.dir == SOUTH) curdir = defdir || A.dir
curdir = defdir
else
curdir = A.dir
//Try to remove/optimize this section ASAP, CPU hog. //Try to remove/optimize this section ASAP, CPU hog. //Slightly mitigated by implementing caching using cached_icon_states
//Determines if there's directionals. //Determines if there's directionals.
if(!noIcon && curdir != SOUTH) if(!noIcon && curdir != SOUTH)
var/exist = FALSE var/exist = FALSE
var/static/list/checkdirs = list(NORTH, EAST, WEST) var/static/list/checkdirs = list(NORTH, EAST, WEST)
for(var/i in checkdirs) //Not using GLOB for a reason. for(var/i in checkdirs) //Not using GLOB for a reason.
if(length(icon_states(icon(curicon, curstate, i)))) if(length(cached_icon_states(icon(curicon, curstate, i))))
exist = TRUE exist = TRUE
break break
if(!exist) if(!exist)
@@ -739,8 +736,8 @@ proc/ColorTone(rgb, tone)
continue continue
var/current_layer = current.layer var/current_layer = current.layer
if(current_layer < 0) if(current_layer < 0)
if(current_layer <= -1000) //if(current_layer <= -1000)
return flat //return flat
current_layer = process_set + A.layer + current_layer / 1000 current_layer = process_set + A.layer + current_layer / 1000
for(var/p in 1 to layers.len) for(var/p in 1 to layers.len)
@@ -768,7 +765,7 @@ proc/ColorTone(rgb, tone)
curblend = BLEND_OVERLAY curblend = BLEND_OVERLAY
add = icon(I.icon, I.icon_state, base_icon_dir) add = icon(I.icon, I.icon_state, base_icon_dir)
else // 'I' is an appearance object. else // 'I' is an appearance object.
add = getFlatIcon(image(I), curdir, curicon, curstate, curblend, FALSE, no_anim) add = getFlatIcon(image(I), I.dir||curdir, curicon, curstate, curblend, FALSE, no_anim)
if(!add) if(!add)
continue continue
// Find the new dimensions of the flat icon to fit the added overlay // Find the new dimensions of the flat icon to fit the added overlay
@@ -899,6 +896,37 @@ proc/ColorTone(rgb, tone)
composite.Blend(icon(I.icon, I.icon_state, I.dir, 1), ICON_OVERLAY) composite.Blend(icon(I.icon, I.icon_state, I.dir, 1), ICON_OVERLAY)
return composite return composite
GLOBAL_LIST_EMPTY(icon_state_lists)
/proc/cached_icon_states(var/icon/I)
if(!I)
return list()
var/key = I
var/returnlist = GLOB.icon_state_lists[key]
if(!returnlist)
returnlist = icon_states(I)
if(isfile(I)) // It's something that will stick around
GLOB.icon_state_lists[key] = returnlist
return returnlist
/proc/expire_states_cache(var/key)
if(GLOB.icon_state_lists[key])
GLOB.icon_state_lists -= key
return TRUE
return FALSE
GLOBAL_LIST_EMPTY(cached_examine_icons)
/proc/set_cached_examine_icon(var/atom/A, var/icon/I, var/expiry = 12000)
GLOB.cached_examine_icons[weakref(A)] = I
if(expiry)
addtimer(CALLBACK(GLOBAL_PROC, .proc/uncache_examine_icon, weakref(A)), expiry, TIMER_UNIQUE)
/proc/get_cached_examine_icon(var/atom/A)
var/weakref/WR = weakref(A)
return GLOB.cached_examine_icons[WR]
/proc/uncache_examine_icon(var/weakref/WR)
GLOB.cached_examine_icons -= WR
proc/adjust_brightness(var/color, var/value) proc/adjust_brightness(var/color, var/value)
if (!color) return "#FFFFFF" if (!color) return "#FFFFFF"
if (!value) return color if (!value) return color

View File

@@ -94,7 +94,7 @@ proc/age2agedescription(age)
else return "unknown" else return "unknown"
/proc/RoundHealth(health) /proc/RoundHealth(health)
var/list/icon_states = icon_states(ingame_hud_med) var/list/icon_states = cached_icon_states(ingame_hud_med)
for(var/icon_state in icon_states) for(var/icon_state in icon_states)
if(health >= text2num(icon_state)) if(health >= text2num(icon_state))
return icon_state return icon_state

View File

@@ -18,6 +18,7 @@
#define DS2TICKS(DS) ((DS)/world.tick_lag) // Convert deciseconds to ticks #define DS2TICKS(DS) ((DS)/world.tick_lag) // Convert deciseconds to ticks
#define TICKS2DS(T) ((T) TICKS) // Convert ticks to deciseconds #define TICKS2DS(T) ((T) TICKS) // Convert ticks to deciseconds
#define DS2NEARESTTICK(DS) TICKS2DS(-round(-(DS2TICKS(DS))))
/proc/get_game_time() /proc/get_game_time()
var/global/time_offset = 0 var/global/time_offset = 0
@@ -35,25 +36,25 @@
return wtime + (time_offset + wusage) * world.tick_lag return wtime + (time_offset + wusage) * world.tick_lag
var/roundstart_hour GLOBAL_VAR_INIT(roundstart_hour, pick(2,7,12,17))
var/station_date = "" var/station_date = ""
var/next_station_date_change = 1 DAY var/next_station_date_change = 1 DAY
#define duration2stationtime(time) time2text(station_time_in_ticks + time, "hh:mm") #define duration2stationtime(time) time2text(station_time_in_ds + time, "hh:mm")
#define worldtime2stationtime(time) time2text(roundstart_hour HOURS + time, "hh:mm") #define worldtime2stationtime(time) time2text(GLOB.roundstart_hour HOURS + time, "hh:mm")
#define round_duration_in_ticks (round_start_time ? world.time - round_start_time : 0) #define round_duration_in_ds (GLOB.round_start_time ? world.time - GLOB.round_start_time : 0)
#define station_time_in_ticks (roundstart_hour HOURS + round_duration_in_ticks) #define station_time_in_ds (GLOB.roundstart_hour HOURS + round_duration_in_ds)
/proc/stationtime2text() /proc/stationtime2text()
return time2text(station_time_in_ticks, "hh:mm") return time2text(station_time_in_ds + GLOB.timezoneOffset, "hh:mm")
/proc/stationdate2text() /proc/stationdate2text()
var/update_time = FALSE var/update_time = FALSE
if(station_time_in_ticks > next_station_date_change) if(station_time_in_ds > next_station_date_change)
next_station_date_change += 1 DAY next_station_date_change += 1 DAY
update_time = TRUE update_time = TRUE
if(!station_date || update_time) if(!station_date || update_time)
var/extra_days = round(station_time_in_ticks / (1 DAY)) DAYS var/extra_days = round(station_time_in_ds / (1 DAY)) DAYS
var/timeofday = world.timeofday + extra_days var/timeofday = world.timeofday + extra_days
station_date = num2text((text2num(time2text(timeofday, "YYYY"))+300)) + "-" + time2text(timeofday, "MM-DD") //VOREStation Edit station_date = num2text((text2num(time2text(timeofday, "YYYY"))+300)) + "-" + time2text(timeofday, "MM-DD") //VOREStation Edit
return station_date return station_date
@@ -64,6 +65,13 @@ var/next_station_date_change = 1 DAY
var/time_portion = time2text(world.timeofday, "hh:mm:ss") var/time_portion = time2text(world.timeofday, "hh:mm:ss")
return "[date_portion]T[time_portion]" return "[date_portion]T[time_portion]"
/proc/get_timezone_offset()
var/midnight_gmt_here = text2num(time2text(0,"hh")) * 36000
if(midnight_gmt_here > 12 HOURS)
return 24 HOURS - midnight_gmt_here
else
return midnight_gmt_here
/proc/gameTimestamp(format = "hh:mm:ss", wtime=null) /proc/gameTimestamp(format = "hh:mm:ss", wtime=null)
if(!wtime) if(!wtime)
wtime = world.time wtime = world.time
@@ -83,19 +91,19 @@ proc/isDay(var/month, var/day)
var/next_duration_update = 0 var/next_duration_update = 0
var/last_round_duration = 0 var/last_round_duration = 0
var/round_start_time = 0 GLOBAL_VAR_INIT(round_start_time, 0)
/hook/roundstart/proc/start_timer() /hook/roundstart/proc/start_timer()
round_start_time = world.time GLOB.round_start_time = world.time
return 1 return 1
/proc/roundduration2text() /proc/roundduration2text()
if(!round_start_time) if(!GLOB.round_start_time)
return "00:00" return "00:00"
if(last_round_duration && world.time < next_duration_update) if(last_round_duration && world.time < next_duration_update)
return last_round_duration return last_round_duration
var/mills = round_duration_in_ticks // 1/10 of a second, not real milliseconds but whatever var/mills = round_duration_in_ds // 1/10 of a second, not real milliseconds but whatever
//var/secs = ((mills % 36000) % 600) / 10 //Not really needed, but I'll leave it here for refrence.. or something //var/secs = ((mills % 36000) % 600) / 10 //Not really needed, but I'll leave it here for refrence.. or something
var/mins = round((mills % 36000) / 600) var/mins = round((mills % 36000) / 600)
var/hours = round(mills / 36000) var/hours = round(mills / 36000)
@@ -107,10 +115,6 @@ var/round_start_time = 0
next_duration_update = world.time + 1 MINUTES next_duration_update = world.time + 1 MINUTES
return last_round_duration return last_round_duration
/hook/startup/proc/set_roundstart_hour()
roundstart_hour = pick(2,7,12,17)
return 1
/var/midnight_rollovers = 0 /var/midnight_rollovers = 0
/var/rollovercheck_last_timeofday = 0 /var/rollovercheck_last_timeofday = 0
/proc/update_midnight_rollover() /proc/update_midnight_rollover()

View File

@@ -31,6 +31,14 @@
if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked
build_click(src, client.buildmode, params, A) build_click(src, client.buildmode, params, A)
return return
if(multicam_on)
var/turf/T = get_turf(A)
if(T)
for(var/obj/screen/movable/pic_in_pic/ai/P in T.vis_locs)
if(P.ai == src)
P.Click(params)
break
if(stat) if(stat)
return return

View File

@@ -257,6 +257,9 @@
if(Adjacent(user)) if(Adjacent(user))
user.start_pulling(src) user.start_pulling(src)
/turf/CtrlClick(var/mob/user)
user.stop_pulling()
/* /*
Alt click Alt click
Unused except for AI Unused except for AI

View File

@@ -75,6 +75,8 @@
#define ui_ai_pda_log "SOUTH:6,WEST+11:16" #define ui_ai_pda_log "SOUTH:6,WEST+11:16"
#define ui_ai_take_picture "SOUTH:6,WEST+12:16" #define ui_ai_take_picture "SOUTH:6,WEST+12:16"
#define ui_ai_view_images "SOUTH:6,WEST+13:16" #define ui_ai_view_images "SOUTH:6,WEST+13:16"
#define ui_ai_multicam "SOUTH+1:6,WEST+12:16"
#define ui_ai_add_multicam "SOUTH+1:6,WEST+13:16"
//Gun buttons //Gun buttons
#define ui_gun1 "EAST-2:26,SOUTH+2:7" #define ui_gun1 "EAST-2:26,SOUTH+2:7"

View File

@@ -1,3 +1,25 @@
/obj/screen/ai/multicam
name = "Multicamera Mode"
icon = 'icons/mob/screen_ai.dmi'
icon_state = "multicam"
/obj/screen/ai/multicam/Click()
if(..())
return
var/mob/living/silicon/ai/AI = usr
AI.toggle_multicam()
/obj/screen/ai/add_multicam
name = "New Camera"
icon = 'icons/mob/screen_ai.dmi'
icon_state = "new_cam"
/obj/screen/ai/add_multicam/Click()
if(..())
return
var/mob/living/silicon/ai/AI = usr
AI.drop_new_multicam()
/datum/hud/proc/ai_hud() /datum/hud/proc/ai_hud()
adding = list() adding = list()
other = list() other = list()
@@ -130,6 +152,16 @@
using.layer = SCREEN_LAYER using.layer = SCREEN_LAYER
adding += using adding += using
//Multicamera mode
using = new /obj/screen/ai/multicam()
using.screen_loc = ui_ai_multicam
adding += using
//Add multicamera camera
using = new /obj/screen/ai/add_multicam()
using.screen_loc = ui_ai_add_multicam
adding += using
mymob.client.screen = list() mymob.client.screen = list()
mymob.client.screen += adding + other mymob.client.screen += adding + other
mymob.client.screen += mymob.client.void mymob.client.screen += mymob.client.void

View File

@@ -28,6 +28,7 @@
inv_box.icon = ui_style inv_box.icon = ui_style
inv_box.color = ui_color inv_box.color = ui_color
inv_box.alpha = ui_alpha inv_box.alpha = ui_alpha
inv_box.hud = src
var/list/slot_data = hud_data.gear[gear_slot] var/list/slot_data = hud_data.gear[gear_slot]
inv_box.name = gear_slot inv_box.name = gear_slot
@@ -192,6 +193,7 @@
using.screen_loc = ui_swaphand1 using.screen_loc = ui_swaphand1
using.color = ui_color using.color = ui_color
using.alpha = ui_alpha using.alpha = ui_alpha
using.hud = src
src.adding += using src.adding += using
using = new /obj/screen/inventory() using = new /obj/screen/inventory()
@@ -201,6 +203,7 @@
using.screen_loc = ui_swaphand2 using.screen_loc = ui_swaphand2
using.color = ui_color using.color = ui_color
using.alpha = ui_alpha using.alpha = ui_alpha
using.hud = src
src.adding += using src.adding += using
if(hud_data.has_resist) if(hud_data.has_resist)

View File

@@ -11,6 +11,8 @@
/obj/screen/movable /obj/screen/movable
var/snap2grid = FALSE var/snap2grid = FALSE
var/moved = FALSE var/moved = FALSE
var/x_off = -16
var/y_off = -16
//Snap Screen Object //Snap Screen Object
//Tied to the grid, snaps to the nearest turf //Tied to the grid, snaps to the nearest turf
@@ -40,8 +42,8 @@
screen_loc = "[screen_loc_X[1]],[screen_loc_Y[1]]" screen_loc = "[screen_loc_X[1]],[screen_loc_Y[1]]"
else //Normalise Pixel Values (So the object drops at the center of the mouse, not 16 pixels off) else //Normalise Pixel Values (So the object drops at the center of the mouse, not 16 pixels off)
var/pix_X = text2num(screen_loc_X[2]) - 16 var/pix_X = text2num(screen_loc_X[2]) + x_off
var/pix_Y = text2num(screen_loc_Y[2]) - 16 var/pix_Y = text2num(screen_loc_Y[2]) + y_off
screen_loc = "[screen_loc_X[1]]:[pix_X],[screen_loc_Y[1]]:[pix_Y]" screen_loc = "[screen_loc_X[1]]:[pix_X],[screen_loc_Y[1]]:[pix_Y]"
/obj/screen/movable/proc/encode_screen_X(X) /obj/screen/movable/proc/encode_screen_X(X)

View File

@@ -0,0 +1,175 @@
/obj/screen/movable/pic_in_pic
name = "Picture-in-picture"
screen_loc = "CENTER"
plane = PLANE_WORLD
icon = null
var/atom/center
var/width = 0
var/height = 0
var/list/shown_to = list()
var/list/viewing_turfs = list()
var/obj/screen/component_button/button_x
var/obj/screen/component_button/button_expand
var/obj/screen/component_button/button_shrink
var/list/background_mas = list()
var/const/max_dimensions = 10
/obj/screen/movable/pic_in_pic/Initialize()
. = ..()
make_backgrounds()
/obj/screen/movable/pic_in_pic/Destroy()
for(var/C in shown_to)
unshow_to(C)
QDEL_NULL(button_x)
QDEL_NULL(button_shrink)
QDEL_NULL(button_expand)
return ..()
/obj/screen/movable/pic_in_pic/component_click(obj/screen/component_button/component, params)
if(component == button_x)
qdel(src)
else if(component == button_expand)
set_view_size(width+1, height+1)
else if(component == button_shrink)
set_view_size(width-1, height-1)
/obj/screen/movable/pic_in_pic/proc/make_backgrounds()
var/mutable_appearance/base = new /mutable_appearance()
base.icon = 'icons/misc/pic_in_pic.dmi'
base.layer = DISPOSAL_LAYER
base.plane = PLATING_PLANE
base.appearance_flags = PIXEL_SCALE
for(var/direction in cardinal)
var/mutable_appearance/dir = new /mutable_appearance(base)
dir.dir = direction
dir.icon_state = "background_[direction]"
background_mas += dir
/obj/screen/movable/pic_in_pic/proc/add_buttons()
var/static/mutable_appearance/move_tab
if(!move_tab)
move_tab = new /mutable_appearance()
//all these properties are always the same, and since adding something to the overlay
//list makes a copy, there is no reason to make a new one each call
move_tab.icon = 'icons/misc/pic_in_pic.dmi'
move_tab.icon_state = "move"
move_tab.plane = PLANE_PLAYER_HUD
var/matrix/M = matrix()
M.Translate(0, (height + 0.25) * world.icon_size)
move_tab.transform = M
overlays += move_tab
if(!button_x)
button_x = new /obj/screen/component_button(null, src)
var/mutable_appearance/MA = new /mutable_appearance()
MA.name = "close"
MA.icon = 'icons/misc/pic_in_pic.dmi'
MA.icon_state = "x"
MA.plane = PLANE_PLAYER_HUD
button_x.appearance = MA
M = matrix()
M.Translate((max(4, width) - 0.75) * world.icon_size, (height + 0.25) * world.icon_size)
button_x.transform = M
vis_contents += button_x
if(!button_expand)
button_expand = new /obj/screen/component_button(null, src)
var/mutable_appearance/MA = new /mutable_appearance()
MA.name = "expand"
MA.icon = 'icons/misc/pic_in_pic.dmi'
MA.icon_state = "expand"
MA.plane = PLANE_PLAYER_HUD
button_expand.appearance = MA
M = matrix()
M.Translate(world.icon_size, (height + 0.25) * world.icon_size)
button_expand.transform = M
vis_contents += button_expand
if(!button_shrink)
button_shrink = new /obj/screen/component_button(null, src)
var/mutable_appearance/MA = new /mutable_appearance()
MA.name = "shrink"
MA.icon = 'icons/misc/pic_in_pic.dmi'
MA.icon_state = "shrink"
MA.plane = PLANE_PLAYER_HUD
button_shrink.appearance = MA
M = matrix()
M.Translate(2 * world.icon_size, (height + 0.25) * world.icon_size)
button_shrink.transform = M
vis_contents += button_shrink
/obj/screen/movable/pic_in_pic/proc/add_background()
if((width > 0) && (height > 0))
for(var/mutable_appearance/dir in background_mas)
var/matrix/M = matrix()
var/x_scale = 1
var/y_scale = 1
var/x_off = 0
var/y_off = 0
if(dir.dir & (NORTH|SOUTH))
x_scale = width
x_off = (width-1)/2 * world.icon_size
if(dir.dir & NORTH)
y_off = ((height-1) * world.icon_size) + 3
else
y_off = -3
if(dir.dir & (EAST|WEST))
y_scale = height
y_off = (height-1)/2 * world.icon_size
if(dir.dir & EAST)
x_off = ((width-1) * world.icon_size) + 3
else
x_off = -3
M.Scale(x_scale, y_scale)
M.Translate(x_off, y_off)
dir.transform = M
overlays += dir
/obj/screen/movable/pic_in_pic/proc/set_view_size(width, height, do_refresh = TRUE)
width = CLAMP(width, 0, max_dimensions)
height = CLAMP(height, 0, max_dimensions)
src.width = width
src.height = height
y_off = -height * world.icon_size - 16
overlays.Cut()
add_background()
add_buttons()
if(do_refresh)
refresh_view()
/obj/screen/movable/pic_in_pic/proc/set_view_center(atom/target, do_refresh = TRUE)
center = target
if(do_refresh)
refresh_view()
/obj/screen/movable/pic_in_pic/proc/refresh_view()
vis_contents -= viewing_turfs
if(!width || !height)
return
var/turf/T = get_turf(center)
if(!T)
return
var/turf/lowerleft = locate(max(1, T.x - round(width/2)), max(1, T.y - round(height/2)), T.z)
var/turf/upperright = locate(min(world.maxx, lowerleft.x + width - 1), min(world.maxy, lowerleft.y + height - 1), lowerleft.z)
viewing_turfs = block(lowerleft, upperright)
vis_contents += viewing_turfs
/obj/screen/movable/pic_in_pic/proc/show_to(client/C)
if(C)
shown_to[C] = 1
C.screen += src
/obj/screen/movable/pic_in_pic/proc/unshow_to(client/C)
if(C)
shown_to -= C
C.screen -= src

View File

@@ -19,6 +19,9 @@
/obj/screen/Destroy() /obj/screen/Destroy()
master = null master = null
return ..() return ..()
/obj/screen/proc/component_click(obj/screen/component_button/component, params)
return
/obj/screen/text /obj/screen/text
icon = null icon = null
@@ -31,7 +34,36 @@
/obj/screen/inventory /obj/screen/inventory
var/slot_id //The indentifier for the slot. It has nothing to do with ID cards. var/slot_id //The indentifier for the slot. It has nothing to do with ID cards.
var/list/object_overlays = list() // Required for inventory/screen overlays.
/obj/screen/inventory/MouseEntered()
..()
add_overlays()
/obj/screen/inventory/MouseExited()
..()
cut_overlay(object_overlays)
object_overlays.Cut()
/obj/screen/inventory/proc/add_overlays()
var/mob/user = hud.mymob
if(hud && user && slot_id)
var/obj/item/holding = user.get_active_hand()
if(!holding || user.get_equipped_item(slot_id))
return
var/image/item_overlay = image(holding)
item_overlay.alpha = 92
if(!holding.mob_can_equip(user, slot_id, disable_warning = TRUE))
item_overlay.color = "#ff0000"
else
item_overlay.color = "#00ff00"
object_overlays += item_overlay
add_overlay(object_overlays)
/obj/screen/close /obj/screen/close
name = "close" name = "close"
@@ -102,78 +134,116 @@
icon_state = "zone_sel" icon_state = "zone_sel"
screen_loc = ui_zonesel screen_loc = ui_zonesel
var/selecting = BP_TORSO var/selecting = BP_TORSO
var/static/list/hover_overlays_cache = list()
var/hovering_choice
var/mutable_appearance/selecting_appearance
/obj/screen/zone_sel/Click(location, control,params) /obj/screen/zone_sel/Click(location, control,params)
if(isobserver(usr))
return
var/list/PL = params2list(params) var/list/PL = params2list(params)
var/icon_x = text2num(PL["icon-x"]) var/icon_x = text2num(PL["icon-x"])
var/icon_y = text2num(PL["icon-y"]) var/icon_y = text2num(PL["icon-y"])
var/old_selecting = selecting //We're only going to update_icon() if there's been a change var/choice = get_zone_at(icon_x, icon_y)
if(!choice)
return 1
return set_selected_zone(choice, usr)
/obj/screen/zone_sel/MouseEntered(location, control, params)
MouseMove(location, control, params)
/obj/screen/zone_sel/MouseMove(location, control, params)
if(isobserver(usr))
return
var/list/PL = params2list(params)
var/icon_x = text2num(PL["icon-x"])
var/icon_y = text2num(PL["icon-y"])
var/choice = get_zone_at(icon_x, icon_y)
if(hovering_choice == choice)
return
vis_contents -= hover_overlays_cache[hovering_choice]
hovering_choice = choice
var/obj/effect/overlay/zone_sel/overlay_object = hover_overlays_cache[choice]
if(!overlay_object)
overlay_object = new
overlay_object.icon_state = "[choice]"
hover_overlays_cache[choice] = overlay_object
vis_contents += overlay_object
/obj/effect/overlay/zone_sel
icon = 'icons/mob/zone_sel.dmi'
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
alpha = 128
anchored = TRUE
layer = LAYER_HUD_ABOVE
plane = PLANE_PLAYER_HUD_ABOVE
/obj/screen/zone_sel/MouseExited(location, control, params)
if(!isobserver(usr) && hovering_choice)
vis_contents -= hover_overlays_cache[hovering_choice]
hovering_choice = null
/obj/screen/zone_sel/proc/get_zone_at(icon_x, icon_y)
switch(icon_y) switch(icon_y)
if(1 to 3) //Feet if(1 to 3) //Feet
switch(icon_x) switch(icon_x)
if(10 to 15) if(10 to 15)
selecting = BP_R_FOOT return BP_R_FOOT
if(17 to 22) if(17 to 22)
selecting = BP_L_FOOT return BP_L_FOOT
else
return 1
if(4 to 9) //Legs if(4 to 9) //Legs
switch(icon_x) switch(icon_x)
if(10 to 15) if(10 to 15)
selecting = BP_R_LEG return BP_R_LEG
if(17 to 22) if(17 to 22)
selecting = BP_L_LEG return BP_L_LEG
else
return 1
if(10 to 13) //Hands and groin if(10 to 13) //Hands and groin
switch(icon_x) switch(icon_x)
if(8 to 11) if(8 to 11)
selecting = BP_R_HAND return BP_R_HAND
if(12 to 20) if(12 to 20)
selecting = BP_GROIN return BP_GROIN
if(21 to 24) if(21 to 24)
selecting = BP_L_HAND return BP_L_HAND
else
return 1
if(14 to 22) //Chest and arms to shoulders if(14 to 22) //Chest and arms to shoulders
switch(icon_x) switch(icon_x)
if(8 to 11) if(8 to 11)
selecting = BP_R_ARM return BP_R_ARM
if(12 to 20) if(12 to 20)
selecting = BP_TORSO return BP_TORSO
if(21 to 24) if(21 to 24)
selecting = BP_L_ARM return BP_L_ARM
else
return 1
if(23 to 30) //Head, but we need to check for eye or mouth if(23 to 30) //Head, but we need to check for eye or mouth
if(icon_x in 12 to 20) if(icon_x in 12 to 20)
selecting = BP_HEAD
switch(icon_y) switch(icon_y)
if(23 to 24) if(23 to 24)
if(icon_x in 15 to 17) if(icon_x in 15 to 17)
selecting = O_MOUTH return O_MOUTH
if(26) //Eyeline, eyes are on 15 and 17 if(26) //Eyeline, eyes are on 15 and 17
if(icon_x in 14 to 18) if(icon_x in 14 to 18)
selecting = O_EYES return O_EYES
if(25 to 27) if(25 to 27)
if(icon_x in 15 to 17) if(icon_x in 15 to 17)
selecting = O_EYES return O_EYES
return BP_HEAD
if(old_selecting != selecting) /obj/screen/zone_sel/proc/set_selected_zone(choice, mob/user)
update_icon() if(isobserver(user))
return 1 return
if(choice != selecting)
/obj/screen/zone_sel/proc/set_selected_zone(bodypart) selecting = choice
var/old_selecting = selecting
selecting = bodypart
if(old_selecting != selecting)
update_icon() update_icon()
/obj/screen/zone_sel/update_icon() /obj/screen/zone_sel/update_icon()
overlays.Cut() cut_overlay(selecting_appearance)
overlays += image('icons/mob/zone_sel.dmi', "[selecting]") selecting_appearance = mutable_appearance('icons/mob/zone_sel.dmi', "[selecting]")
add_overlay(selecting_appearance)
/obj/screen/Click(location, control, params) /obj/screen/Click(location, control, params)
if(!usr) return 1 if(!usr) return 1
@@ -535,3 +605,15 @@
var/mob/living/carbon/C = hud.mymob var/mob/living/carbon/C = hud.mymob
if(C.handcuffed) if(C.handcuffed)
overlays |= handcuff_overlay overlays |= handcuff_overlay
// PIP stuff
/obj/screen/component_button
var/obj/screen/parent
/obj/screen/component_button/Initialize(mapload, obj/screen/new_parent)
. = ..()
parent = new_parent
/obj/screen/component_button/Click(params)
if(parent)
parent.component_click(src, params)

View File

@@ -50,8 +50,8 @@
/obj/machinery/teleport/hub/attack_ghost(mob/user as mob) /obj/machinery/teleport/hub/attack_ghost(mob/user as mob)
var/atom/l = loc var/atom/l = loc
var/obj/machinery/computer/teleporter/com = locate(/obj/machinery/computer/teleporter, locate(l.x - 2, l.y, l.z)) var/obj/machinery/computer/teleporter/com = locate(/obj/machinery/computer/teleporter, locate(l.x - 2, l.y, l.z))
if(com.locked) if(com?.teleport_control.locked)
user.loc = get_turf(com.locked) user.loc = get_turf(com.teleport_control.locked)
/obj/effect/portal/attack_ghost(mob/user as mob) /obj/effect/portal/attack_ghost(mob/user as mob)
if(target) if(target)

View File

@@ -17,14 +17,14 @@ datum/controller/transfer_controller/Destroy()
datum/controller/transfer_controller/process() datum/controller/transfer_controller/process()
currenttick = currenttick + 1 currenttick = currenttick + 1
//VOREStation Edit START //VOREStation Edit START
if (round_duration_in_ticks >= shift_last_vote - 2 MINUTES) if (round_duration_in_ds >= shift_last_vote - 2 MINUTES)
shift_last_vote = 999999999999 //Setting to a stupidly high number since it'll be not used again. shift_last_vote = 99999999 //Setting to a stupidly high number since it'll be not used again.
to_world("Warning: This upcoming round-extend vote will be your ONLY extend vote. Wrap up your scenes in the next 4 fuckin hours if the round is extended.") //YAWN EDIT NIGGA VOREStation Edit to_world("<b>Warning: You have one hour left in the shift. Wrap up your scenes in the next 60 minutes before the transfer is called.</b>") //VOREStation Edit
if (round_duration_in_ticks >= shift_hard_end - 1 MINUTE) if (round_duration_in_ds >= shift_hard_end - 1 MINUTE)
init_shift_change(null, 1) init_shift_change(null, 1)
shift_hard_end = timerbuffer + config.vote_autotransfer_interval //If shuttle somehow gets recalled, let's force it to call again next time a vote would occur. shift_hard_end = timerbuffer + config.vote_autotransfer_interval //If shuttle somehow gets recalled, let's force it to call again next time a vote would occur.
timerbuffer = timerbuffer + config.vote_autotransfer_interval //Just to make sure a vote doesn't occur immediately afterwords. timerbuffer = timerbuffer + config.vote_autotransfer_interval //Just to make sure a vote doesn't occur immediately afterwords.
else if (round_duration_in_ticks >= timerbuffer - 1 MINUTE) else if (round_duration_in_ds >= timerbuffer - 1 MINUTE)
SSvote.autotransfer() SSvote.autotransfer()
//VOREStation Edit END //VOREStation Edit END
timerbuffer = timerbuffer + config.vote_autotransfer_interval timerbuffer = timerbuffer + config.vote_autotransfer_interval

View File

@@ -11,6 +11,7 @@
var/static/pto_cap = 100 //Hours var/static/pto_cap = 100 //Hours
var/static/require_flavor = FALSE var/static/require_flavor = FALSE
var/static/ipqualityscore_apikey //API key for ipqualityscore.com var/static/ipqualityscore_apikey //API key for ipqualityscore.com
var/static/use_playtime_restriction_for_jobs = FALSE
/hook/startup/proc/read_vs_config() /hook/startup/proc/read_vs_config()
var/list/Lines = file2list("config/config.txt") var/list/Lines = file2list("config/config.txt")
@@ -61,4 +62,6 @@
config.require_flavor = TRUE config.require_flavor = TRUE
if ("ipqualityscore_apikey") if ("ipqualityscore_apikey")
config.ipqualityscore_apikey = value config.ipqualityscore_apikey = value
if ("use_playtime_restriction_for_jobs")
config.use_playtime_restriction_for_jobs = TRUE
return 1 return 1

View File

@@ -156,12 +156,15 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
// Please don't stuff random bullshit here, // Please don't stuff random bullshit here,
// Make a subsystem, give it the SS_NO_FIRE flag, and do your work in it's Initialize() // Make a subsystem, give it the SS_NO_FIRE flag, and do your work in it's Initialize()
/datum/controller/master/Initialize(delay, init_sss) /datum/controller/master/Initialize(delay, init_sss, tgs_prime)
set waitfor = 0 set waitfor = 0
if(delay) if(delay)
sleep(delay) sleep(delay)
if(tgs_prime)
world.TgsInitializationComplete()
if(init_sss) if(init_sss)
init_subtypes(/datum/controller/subsystem, subsystems) init_subtypes(/datum/controller/subsystem, subsystems)

View File

@@ -109,7 +109,7 @@ SUBSYSTEM_DEF(game_master)
return FALSE return FALSE
// Last minute antagging is bad for humans to do, so the GM will respect the start and end of the round. // Last minute antagging is bad for humans to do, so the GM will respect the start and end of the round.
var/mills = round_duration_in_ticks var/mills = round_duration_in_ds
var/mins = round((mills % 36000) / 600) var/mins = round((mills % 36000) / 600)
var/hours = round(mills / 36000) var/hours = round(mills / 36000)

View File

@@ -20,7 +20,7 @@ SUBSYSTEM_DEF(nightshift)
return ..() return ..()
/datum/controller/subsystem/nightshift/fire(resumed = FALSE) /datum/controller/subsystem/nightshift/fire(resumed = FALSE)
if(round_duration_in_ticks < nightshift_first_check) if(round_duration_in_ds < nightshift_first_check)
return return
check_nightshift() check_nightshift()

View File

@@ -47,23 +47,33 @@ SUBSYSTEM_DEF(persist)
// Update client whatever // Update client whatever
var/client/C = M.client var/client/C = M.client
var/wait_in_hours = (wait / (1 HOUR)) * J.timeoff_factor var/wait_in_hours = wait / (1 HOUR)
var/pto_factored = wait_in_hours * J.timeoff_factor
LAZYINITLIST(C.department_hours) LAZYINITLIST(C.department_hours)
LAZYINITLIST(C.play_hours)
var/dept_hours = C.department_hours var/dept_hours = C.department_hours
if(isnum(C.department_hours[department_earning])) var/play_hours = C.play_hours
dept_hours[department_earning] += wait_in_hours if(isnum(dept_hours[department_earning]))
dept_hours[department_earning] += pto_factored
else else
dept_hours[department_earning] = wait_in_hours dept_hours[department_earning] = pto_factored
//Cap it // If they're earning PTO they must be in a useful job so are earning playtime in that department
if(J.timeoff_factor > 0)
if(isnum(play_hours[department_earning]))
play_hours[department_earning] += wait_in_hours
else
play_hours[department_earning] = wait_in_hours
// Cap it
dept_hours[department_earning] = min(config.pto_cap, dept_hours[department_earning]) dept_hours[department_earning] = min(config.pto_cap, dept_hours[department_earning])
// Okay we figured it out, lets update database! // Okay we figured it out, lets update database!
var/sql_ckey = sql_sanitize_text(C.ckey) var/sql_ckey = sql_sanitize_text(C.ckey)
var/sql_dpt = sql_sanitize_text(department_earning) var/sql_dpt = sql_sanitize_text(department_earning)
var/sql_bal = text2num("[C.department_hours[department_earning]]") var/sql_bal = text2num("[C.department_hours[department_earning]]")
var/DBQuery/query = dbcon.NewQuery("INSERT INTO vr_player_hours (ckey, department, hours) VALUES ('[sql_ckey]', '[sql_dpt]', [sql_bal]) ON DUPLICATE KEY UPDATE hours = VALUES(hours)") var/sql_total = text2num("[C.play_hours[department_earning]]")
var/DBQuery/query = dbcon.NewQuery("INSERT INTO vr_player_hours (ckey, department, hours, total_hours) VALUES ('[sql_ckey]', '[sql_dpt]', [sql_bal], [sql_total]) ON DUPLICATE KEY UPDATE hours = VALUES(hours), total_hours = VALUES(total_hours)")
query.Execute() query.Execute()
if (MC_TICK_CHECK) if (MC_TICK_CHECK)

View File

@@ -394,21 +394,26 @@ var/global/datum/controller/subsystem/ticker/ticker
/datum/controller/subsystem/ticker/proc/create_characters() /datum/controller/subsystem/ticker/proc/create_characters()
for(var/mob/new_player/player in player_list) for(var/mob/new_player/player in player_list)
if(player && player.ready && player.mind) if(player && player.ready && player.mind?.assigned_role)
if(player.mind.assigned_role=="AI") var/datum/job/J = SSjob.get_job(player.mind.assigned_role)
// Snowflakey AI treatment
if(J.mob_type & JOB_SILICON_AI)
player.close_spawn_windows() player.close_spawn_windows()
player.AIize() player.AIize(move = TRUE)
else if(!player.mind.assigned_role)
continue continue
else
//VOREStation Edit Start // Ask their new_player mob to spawn them
var/mob/living/carbon/human/new_char = player.create_character() if(!player.spawn_checks_vr(player.mind.assigned_role)) continue //VOREStation Add
if(new_char) var/mob/living/carbon/human/new_char = player.create_character()
qdel(player)
if(istype(new_char) && !(new_char.mind.assigned_role=="Cyborg")) // Created their playable character, delete their /mob/new_player
data_core.manifest_inject(new_char) if(new_char)
//VOREStation Edit End qdel(player)
// If they're a carbon, they can get manifested
if(J.mob_type & JOB_CARBON)
data_core.manifest_inject(new_char)
/datum/controller/subsystem/ticker/proc/collect_minds() /datum/controller/subsystem/ticker/proc/collect_minds()
for(var/mob/living/player in player_list) for(var/mob/living/player in player_list)

View File

@@ -4,10 +4,12 @@
var/lock = TRUE var/lock = TRUE
var/turf/lastloc var/turf/lastloc
var/lastprocess var/lastprocess
var/matrix/init_transform
/datum/orbit/New(_orbiter, _orbiting, _lock) /datum/orbit/New(var/atom/movable/_orbiter, var/atom/_orbiting, _lock)
orbiter = _orbiter orbiter = _orbiter
orbiting = _orbiting orbiting = _orbiting
init_transform = _orbiter.transform
SSorbit.processing += src SSorbit.processing += src
if (!orbiting.orbiters) if (!orbiting.orbiters)
orbiting.orbiters = list() orbiting.orbiters = list()
@@ -24,6 +26,7 @@
SSorbit.processing -= src SSorbit.processing -= src
if (orbiter) if (orbiter)
orbiter.orbiting = null orbiter.orbiting = null
orbiter.transform = init_transform
orbiter = null orbiter = null
if (orbiting) if (orbiting)
if (orbiting.orbiters) if (orbiting.orbiters)
@@ -84,7 +87,6 @@
new/datum/orbit(src, A, lockinorbit) new/datum/orbit(src, A, lockinorbit)
if (!orbiting) //something failed, and our orbit datum deleted itself if (!orbiting) //something failed, and our orbit datum deleted itself
return return
var/matrix/initial_transform = matrix(transform)
//Head first! //Head first!
if (pre_rotation) if (pre_rotation)
@@ -101,9 +103,6 @@
SpinAnimation(rotation_speed, -1, clockwise, rotation_segments) SpinAnimation(rotation_speed, -1, clockwise, rotation_segments)
//we stack the orbits up client side, so we can assign this back to normal server side without it breaking the orbit
transform = initial_transform
/atom/movable/proc/stop_orbit() /atom/movable/proc/stop_orbit()
SpinAnimation(0,0) SpinAnimation(0,0)
qdel(orbiting) qdel(orbiting)

View File

@@ -4,6 +4,7 @@
var/list/restricted_jobs = list() // Jobs that cannot be this antagonist (depending on config) var/list/restricted_jobs = list() // Jobs that cannot be this antagonist (depending on config)
var/list/protected_jobs = list() // As above. var/list/protected_jobs = list() // As above.
var/list/roundstart_restricted = list() //Jobs that can be this antag, but not at roundstart var/list/roundstart_restricted = list() //Jobs that can be this antag, but not at roundstart
var/avoid_silicons = FALSE // If we won't hand this antag role to silicons (AI, borg, etc)
// Strings. // Strings.
var/welcome_text = "Cry havoc and let slip the dogs of war!" var/welcome_text = "Cry havoc and let slip the dogs of war!"

View File

@@ -10,6 +10,10 @@
return FALSE return FALSE
if(config.protect_roles_from_antagonist && (player.assigned_role in protected_jobs)) if(config.protect_roles_from_antagonist && (player.assigned_role in protected_jobs))
return FALSE return FALSE
if(avoid_silicons)
var/datum/job/J = SSjob.get_job(player.assigned_role)
if(J.mob_type & JOB_SILICON)
return FALSE
return TRUE return TRUE
/datum/antagonist/proc/antags_are_dead() /datum/antagonist/proc/antags_are_dead()

View File

@@ -5,7 +5,7 @@
role_text_plural = "Changelings" role_text_plural = "Changelings"
bantype = "changeling" bantype = "changeling"
feedback_tag = "changeling_objective" feedback_tag = "changeling_objective"
restricted_jobs = list("AI", "Cyborg") avoid_silicons = TRUE
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Colony Director") 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." 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' antag_sound = 'sound/effects/antag_notice/ling_alert.ogg'

View File

@@ -11,7 +11,8 @@ var/datum/antagonist/cultist/cult
role_text = "Cultist" role_text = "Cultist"
role_text_plural = "Cultists" role_text_plural = "Cultists"
bantype = "cultist" bantype = "cultist"
restricted_jobs = list("Chaplain","AI", "Cyborg") restricted_jobs = list("Chaplain")
avoid_silicons = TRUE
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Colony Director") protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Head of Security", "Colony Director")
roundstart_restricted = list("Internal Affairs Agent", "Head of Security", "Colony Director") roundstart_restricted = list("Internal Affairs Agent", "Head of Security", "Colony Director")
role_type = BE_CULTIST role_type = BE_CULTIST

View File

@@ -29,7 +29,7 @@ var/datum/antagonist/loyalists/loyalists
faction_welcome = "Preserve NanoTrasen's interests against the traitorous recidivists amongst the crew. Protect the heads of staff with your life." faction_welcome = "Preserve NanoTrasen's interests against the traitorous recidivists amongst the crew. Protect the heads of staff with your life."
faction_indicator = "loyal" faction_indicator = "loyal"
faction_invisible = 1 faction_invisible = 1
restricted_jobs = list("AI", "Cyborg") avoid_silicons = TRUE
/datum/antagonist/loyalists/New() /datum/antagonist/loyalists/New()
..() ..()

View File

@@ -6,7 +6,7 @@ var/datum/antagonist/renegade/renegades
role_text = "Renegade" role_text = "Renegade"
role_text_plural = "Renegades" role_text_plural = "Renegades"
bantype = "renegade" bantype = "renegade"
restricted_jobs = list("AI", "Cyborg") avoid_silicons = TRUE
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." 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_sound = 'sound/effects/antag_notice/general_goodie_alert.ogg'
antag_text = "You are a <b>minor</b> antagonist! Within the rules, \ antag_text = "You are a <b>minor</b> antagonist! Within the rules, \

View File

@@ -29,7 +29,7 @@ var/datum/antagonist/revolutionary/revs
faction_indicator = "rev" faction_indicator = "rev"
faction_invisible = 1 faction_invisible = 1
restricted_jobs = list("AI", "Cyborg") avoid_silicons = TRUE
protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Colony Director", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer") protected_jobs = list("Security Officer", "Warden", "Detective", "Internal Affairs Agent", "Colony Director", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer")
roundstart_restricted = list("Internal Affairs Agent", "Colony Director", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer") roundstart_restricted = list("Internal Affairs Agent", "Colony Director", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer")

View File

@@ -6,7 +6,7 @@ var/datum/antagonist/stowaway/stowaways
role_text = "Stowaway" role_text = "Stowaway"
role_text_plural = "Stowaways" role_text_plural = "Stowaways"
bantype = "renegade" bantype = "renegade"
restricted_jobs = list("AI") avoid_silicons = TRUE // This was previously allowing cyborgs to be stowaways, but given that they would just connect to the AI, it didn't make much sense
welcome_text = "People are known to run from many things, or to many things, for many different reasons. You happen to be one of those people." welcome_text = "People are known to run from many things, or to many things, for many different reasons. You happen to be one of those people."
antag_text = "You are a <b>minor</b> antagonist! Within the server rules, do whatever it is \ antag_text = "You are a <b>minor</b> antagonist! Within the server rules, do whatever it is \
that you came to the station to do. Espionage, thievery, or just running from the law are all examples. \ that you came to the station to do. Espionage, thievery, or just running from the law are all examples. \

View File

@@ -6,7 +6,7 @@ var/datum/antagonist/thug/thugs
role_text = "Thug" role_text = "Thug"
role_text_plural = "Thugs" role_text_plural = "Thugs"
bantype = "renegade" bantype = "renegade"
restricted_jobs = list("AI", "Cyborg") avoid_silicons = TRUE
welcome_text = "Sometimes, people just need to get messed up. Luckily, that's what you're here to do." welcome_text = "Sometimes, people just need to get messed up. Luckily, that's what you're here to do."
antag_text = "You are a <b>minor</b> antagonist! Within the server rules, do whatever it is \ antag_text = "You are a <b>minor</b> antagonist! Within the server rules, do whatever it is \
that you came to the station to do, be it violence, theft, or just extreme self-defense. \ that you came to the station to do, be it violence, theft, or just extreme self-defense. \

View File

@@ -37,8 +37,8 @@
// During dynamic mapload (reader.dm) this assigns the var overrides from the .dmm file // During dynamic mapload (reader.dm) this assigns the var overrides from the .dmm file
// Native BYOND maploading sets those vars before invoking New(), by doing this FIRST we come as close to that behavior as we can. // Native BYOND maploading sets those vars before invoking New(), by doing this FIRST we come as close to that behavior as we can.
if(use_preloader && (src.type == _preloader.target_path))//in case the instanciated atom is creating other atoms in New() if(GLOB.use_preloader && (src.type == GLOB._preloader.target_path))//in case the instanciated atom is creating other atoms in New()
_preloader.load(src) GLOB._preloader.load(src)
// Pass our arguments to InitAtom so they can be passed to initialize(), but replace 1st with if-we're-during-mapload. // Pass our arguments to InitAtom so they can be passed to initialize(), but replace 1st with if-we're-during-mapload.
var/do_initialize = SSatoms.initialized var/do_initialize = SSatoms.initialized
@@ -184,14 +184,18 @@
var/list/output = list("[bicon(src)] That's [f_name] [suffix]", desc) var/list/output = list("[bicon(src)] That's [f_name] [suffix]", desc)
if(user.client?.examine_text_mode == EXAMINE_MODE_INCLUDE_USAGE) if(user.client?.prefs.examine_text_mode == EXAMINE_MODE_INCLUDE_USAGE)
output += description_info output += description_info
if(user.client?.examine_text_mode == EXAMINE_MODE_SWITCH_TO_PANEL) if(user.client?.prefs.examine_text_mode == EXAMINE_MODE_SWITCH_TO_PANEL)
user.client.statpanel = "Examine" // Switch to stat panel user.client.statpanel = "Examine" // Switch to stat panel
return output return output
// Don't make these call bicon or anything, these are what bicon uses. They need to return an icon.
/atom/proc/examine_icon()
return icon(icon=src.icon, icon_state=src.icon_state, dir=SOUTH, frame=1, moving=0)
// called by mobs when e.g. having the atom as their machine, pulledby, loc (AKA mob being inside the atom) or buckled var set. // called by mobs when e.g. having the atom as their machine, pulledby, loc (AKA mob being inside the atom) or buckled var set.
// see code/modules/mob/mob_movement.dm for more. // see code/modules/mob/mob_movement.dm for more.
/atom/proc/relaymove() /atom/proc/relaymove()

View File

@@ -56,16 +56,9 @@
var/obj/item/weapon/reagent_containers/glass/beaker = null var/obj/item/weapon/reagent_containers/glass/beaker = null
var/opened = 0 var/opened = 0
/obj/machinery/dna_scannernew/New() /obj/machinery/dna_scannernew/Initialize()
..() . = ..()
component_parts = list() default_apply_parts()
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
component_parts += new /obj/item/weapon/stock_parts/console_screen(src)
component_parts += new /obj/item/stack/cable_coil(src)
component_parts += new /obj/item/stack/cable_coil(src)
RefreshParts()
/obj/machinery/dna_scannernew/relaymove(mob/user as mob) /obj/machinery/dna_scannernew/relaymove(mob/user as mob)
if (user.stat) if (user.stat)

View File

@@ -34,7 +34,7 @@
if(emergency_shuttle.shuttle && (emergency_shuttle.shuttle.moving_status == SHUTTLE_WARMUP || emergency_shuttle.shuttle.moving_status == SHUTTLE_INTRANSIT)) if(emergency_shuttle.shuttle && (emergency_shuttle.shuttle.moving_status == SHUTTLE_WARMUP || emergency_shuttle.shuttle.moving_status == SHUTTLE_INTRANSIT))
return // Don't do anything if the shuttle's coming. return // Don't do anything if the shuttle's coming.
var/mills = round_duration_in_ticks var/mills = round_duration_in_ds
var/mins = round((mills % 36000) / 600) var/mins = round((mills % 36000) / 600)
var/hours = round(mills / 36000) var/hours = round(mills / 36000)

View File

@@ -1,12 +1,14 @@
/datum/job/captain /datum/job/captain
disallow_jobhop = TRUE disallow_jobhop = TRUE
pto_type = PTO_CIVILIAN pto_type = PTO_CIVILIAN
//dept_time_required = 60 //Pending something more complicated
/datum/job/hop /datum/job/hop
disallow_jobhop = TRUE disallow_jobhop = TRUE
pto_type = PTO_CIVILIAN pto_type = PTO_CIVILIAN
departments = list(DEPARTMENT_COMMAND, DEPARTMENT_CIVILIAN) departments = list(DEPARTMENT_COMMAND, DEPARTMENT_CIVILIAN)
departments_managed = list(DEPARTMENT_CIVILIAN, DEPARTMENT_CARGO, DEPARTMENT_PLANET) departments_managed = list(DEPARTMENT_CIVILIAN, DEPARTMENT_CARGO, DEPARTMENT_PLANET)
dept_time_required = 60
alt_titles = list("Crew Resources Officer" = /datum/alt_title/cro, alt_titles = list("Crew Resources Officer" = /datum/alt_title/cro,
"Deputy Director" = /datum/alt_title/deputy_director) "Deputy Director" = /datum/alt_title/deputy_director)

View File

@@ -12,6 +12,7 @@
/datum/job/qm /datum/job/qm
pto_type = PTO_CARGO pto_type = PTO_CARGO
dept_time_required = 20
/datum/job/cargo_tech /datum/job/cargo_tech
total_positions = 3 total_positions = 3

View File

@@ -1,6 +1,7 @@
/datum/job/chief_engineer /datum/job/chief_engineer
disallow_jobhop = TRUE disallow_jobhop = TRUE
pto_type = PTO_ENGINEERING pto_type = PTO_ENGINEERING
dept_time_required = 60
/datum/job/engineer /datum/job/engineer
pto_type = PTO_ENGINEERING pto_type = PTO_ENGINEERING

View File

@@ -44,6 +44,7 @@ var/const/SAR =(1<<14)
economic_modifier = 8 economic_modifier = 8
minimal_player_age = 7 minimal_player_age = 7
pto_type = PTO_EXPLORATION pto_type = PTO_EXPLORATION
dept_time_required = 20
access = list(access_eva, access_maint_tunnels, access_external_airlocks, access_pilot, access_explorer, access_gateway) access = list(access_eva, access_maint_tunnels, access_external_airlocks, access_pilot, access_explorer, access_gateway)
minimal_access = list(access_eva, access_maint_tunnels, access_external_airlocks, access_pilot, access_explorer, access_gateway) minimal_access = list(access_eva, access_maint_tunnels, access_external_airlocks, access_pilot, access_explorer, access_gateway)

View File

@@ -31,6 +31,7 @@
var/outfit_type // What outfit datum does this job use in its default title? var/outfit_type // What outfit datum does this job use in its default title?
var/offmap_spawn = FALSE // Do we require weird and special spawning and datacore handling? var/offmap_spawn = FALSE // Do we require weird and special spawning and datacore handling?
var/mob_type = JOB_CARBON // Bitflags representing mob type this job spawns
// Description of the job's role and minimum responsibilities. // Description of the job's role and minimum responsibilities.
var/job_description = "This Job doesn't have a description! Please report it!" var/job_description = "This Job doesn't have a description! Please report it!"

View File

@@ -14,6 +14,20 @@
//Disallow joining as this job midround from off-duty position via going on-duty //Disallow joining as this job midround from off-duty position via going on-duty
var/disallow_jobhop = FALSE var/disallow_jobhop = FALSE
//Time required in the department as other jobs before playing this one (in hours)
var/dept_time_required = 0
// Check client-specific availability rules. // Check client-specific availability rules.
/datum/job/proc/player_has_enough_pto(client/C) /datum/job/proc/player_has_enough_pto(client/C)
return timeoff_factor >= 0 || (C && LAZYACCESS(C.department_hours, pto_type) > 0) return timeoff_factor >= 0 || (C && LAZYACCESS(C.department_hours, pto_type) > 0)
/datum/job/proc/player_has_enough_playtime(client/C)
return (available_in_playhours(C) == 0)
/datum/job/proc/available_in_playhours(client/C)
if(C && config.use_playtime_restriction_for_jobs)
if(isnum(C.play_hours[pto_type])) // Has played that department before
return max(0, dept_time_required - C.play_hours[pto_type])
else // List doesn't have that entry, maybe never played, maybe invalid PTO type (you should fix that...)
return dept_time_required // Could be 0, too, which is fine! They can play that
return 0

View File

@@ -1,6 +1,7 @@
/datum/job/cmo /datum/job/cmo
disallow_jobhop = TRUE disallow_jobhop = TRUE
pto_type = PTO_MEDICAL pto_type = PTO_MEDICAL
dept_time_required = 60
/datum/job/doctor /datum/job/doctor
spawn_positions = 5 spawn_positions = 5

View File

@@ -1,6 +1,7 @@
/datum/job/rd /datum/job/rd
disallow_jobhop = TRUE disallow_jobhop = TRUE
pto_type = PTO_SCIENCE pto_type = PTO_SCIENCE
dept_time_required = 60
access = list(access_rd, access_heads, access_tox, access_genetics, access_morgue, access = list(access_rd, access_heads, access_tox, access_genetics, access_morgue,
access_tox_storage, access_teleporter, access_sec_doors, access_tox_storage, access_teleporter, access_sec_doors,

View File

@@ -1,6 +1,7 @@
/datum/job/hos /datum/job/hos
disallow_jobhop = TRUE disallow_jobhop = TRUE
pto_type = PTO_SECURITY pto_type = PTO_SECURITY
dept_time_required = 60
access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory, access = list(access_security, access_eva, access_sec_doors, access_brig, access_armory,
access_forensics_lockers, access_morgue, access_maint_tunnels, access_all_personal_lockers, access_forensics_lockers, access_morgue, access_maint_tunnels, access_all_personal_lockers,
@@ -13,6 +14,7 @@
/datum/job/warden /datum/job/warden
pto_type = PTO_SECURITY pto_type = PTO_SECURITY
dept_time_required = 20
/datum/job/detective /datum/job/detective
pto_type = PTO_SECURITY pto_type = PTO_SECURITY

View File

@@ -18,6 +18,7 @@
economic_modifier = 0 economic_modifier = 0
has_headset = FALSE has_headset = FALSE
assignable = FALSE assignable = FALSE
mob_type = JOB_SILICON_AI
outfit_type = /decl/hierarchy/outfit/job/silicon/ai outfit_type = /decl/hierarchy/outfit/job/silicon/ai
job_description = "The AI oversees the operation of the station and its crew, but has no real authority over them. \ job_description = "The AI oversees the operation of the station and its crew, but has no real authority over them. \
The AI is required to follow its Laws, and Lawbound Synthetics that are linked to it are expected to follow \ The AI is required to follow its Laws, and Lawbound Synthetics that are linked to it are expected to follow \
@@ -54,6 +55,7 @@
economic_modifier = 0 economic_modifier = 0
has_headset = FALSE has_headset = FALSE
assignable = FALSE assignable = FALSE
mob_type = JOB_SILICON_ROBOT
outfit_type = /decl/hierarchy/outfit/job/silicon/cyborg outfit_type = /decl/hierarchy/outfit/job/silicon/cyborg
job_description = "A Cyborg is a mobile station synthetic, piloted by a cybernetically preserved brain. It is considered a person, but is still required \ job_description = "A Cyborg is a mobile station synthetic, piloted by a cybernetically preserved brain. It is considered a person, but is still required \
to follow its Laws." to follow its Laws."

View File

@@ -60,8 +60,12 @@ var/global/datum/controller/occupations/job_master
return 0 return 0
if(!job.player_old_enough(player.client)) if(!job.player_old_enough(player.client))
return 0 return 0
if(!is_job_whitelisted(player, rank)) //VOREStation Code //VOREStation Add
if(!job.player_has_enough_playtime(player.client))
return 0 return 0
if(!is_job_whitelisted(player, rank))
return 0
//VOREStation Add End
var/position_limit = job.total_positions var/position_limit = job.total_positions
if(!latejoin) if(!latejoin)
@@ -97,6 +101,9 @@ var/global/datum/controller/occupations/job_master
Debug("FOC character not old enough, Player: [player]") Debug("FOC character not old enough, Player: [player]")
continue continue
//VOREStation Code Start //VOREStation Code Start
if(!job.player_has_enough_playtime(player.client))
Debug("FOC character not enough playtime, Player: [player]")
continue
if(!is_job_whitelisted(player, job.title)) if(!is_job_whitelisted(player, job.title))
Debug("FOC is_job_whitelisted failed, Player: [player]") Debug("FOC is_job_whitelisted failed, Player: [player]")
continue continue
@@ -133,6 +140,9 @@ var/global/datum/controller/occupations/job_master
continue continue
//VOREStation Code Start //VOREStation Code Start
if(!job.player_has_enough_playtime(player.client))
Debug("GRJ player not enough playtime, Player: [player]")
continue
if(!is_job_whitelisted(player, job.title)) if(!is_job_whitelisted(player, job.title))
Debug("GRJ player not whitelisted for this job, Player: [player], Job: [job.title]") Debug("GRJ player not whitelisted for this job, Player: [player], Job: [job.title]")
continue continue
@@ -283,6 +293,12 @@ var/global/datum/controller/occupations/job_master
Debug("DO player not old enough, Player: [player], Job:[job.title]") Debug("DO player not old enough, Player: [player], Job:[job.title]")
continue continue
//VOREStation Add
if(!job.player_has_enough_playtime(player.client))
Debug("DO player not enough playtime, Player: [player]")
continue
//VOREStation Add End
// If the player wants that job on this level, then try give it to him. // If the player wants that job on this level, then try give it to him.
if(player.client.prefs.GetJobDepartment(job, level) & job.flag) if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
@@ -373,54 +389,64 @@ var/global/datum/controller/occupations/job_master
//Equip custom gear loadout. //Equip custom gear loadout.
var/list/custom_equip_slots = list() //If more than one item takes the same slot, all after the first one spawn in storage. var/list/custom_equip_slots = list() //If more than one item takes the same slot, all after the first one spawn in storage.
var/list/custom_equip_leftovers = list() var/list/custom_equip_leftovers = list()
if(H.client.prefs.gear && H.client.prefs.gear.len && job.title != "Cyborg" && job.title != "AI") if(H.client.prefs.gear && H.client.prefs.gear.len && !(job.mob_type & JOB_SILICON))
for(var/thing in H.client.prefs.gear) for(var/thing in H.client.prefs.gear)
var/datum/gear/G = gear_datums[thing] var/datum/gear/G = gear_datums[thing]
if(G) if(!G) //Not a real gear datum (maybe removed, as this is loaded from their savefile)
var/permitted continue
if(G.allowed_roles)
for(var/job_name in G.allowed_roles) var/permitted
if(job.title == job_name) // Check if it is restricted to certain roles
permitted = 1 if(G.allowed_roles)
for(var/job_name in G.allowed_roles)
if(job.title == job_name)
permitted = 1
else
permitted = 1
// Check if they're whitelisted for this gear (in alien whitelist? seriously?)
if(G.whitelisted && !is_alien_whitelisted(H, GLOB.all_species[G.whitelisted]))
permitted = 0
// If they aren't, tell them
if(!permitted)
to_chat(H, "<span class='warning'>Your current species, job or whitelist status does not permit you to spawn with [thing]!</span>")
continue
// Implants get special treatment
if(G.slot == "implant")
var/obj/item/weapon/implant/I = G.spawn_item(H)
I.invisibility = 100
I.implant_loadout(H)
continue
// Try desperately (and sorta poorly) to equip the item
if(G.slot && !(G.slot in custom_equip_slots))
var/metadata = H.client.prefs.gear[G.display_name]
if(G.slot == slot_wear_mask || G.slot == slot_wear_suit || G.slot == slot_head)
custom_equip_leftovers += thing
else if(H.equip_to_slot_or_del(G.spawn_item(H, metadata), G.slot))
to_chat(H, "<span class='notice'>Equipping you with \the [thing]!</span>")
custom_equip_slots.Add(G.slot)
else else
permitted = 1 custom_equip_leftovers.Add(thing)
else
spawn_in_storage += thing
if(G.whitelisted && !is_alien_whitelisted(H, GLOB.all_species[G.whitelisted])) // Set up their account
//if(G.whitelisted && (G.whitelisted != H.species.name || !is_alien_whitelisted(H, G.whitelisted)))
permitted = 0
if(!permitted)
to_chat(H, "<span class='warning'>Your current species, job or whitelist status does not permit you to spawn with [thing]!</span>")
continue
if(G.slot == "implant")
var/obj/item/weapon/implant/I = G.spawn_item(H)
I.invisibility = 100
I.implant_loadout(H)
continue
if(G.slot && !(G.slot in custom_equip_slots))
// This is a miserable way to fix the loadout overwrite bug, but the alternative requires
// adding an arg to a bunch of different procs. Will look into it after this merge. ~ Z
var/metadata = H.client.prefs.gear[G.display_name]
if(G.slot == slot_wear_mask || G.slot == slot_wear_suit || G.slot == slot_head)
custom_equip_leftovers += thing
else if(H.equip_to_slot_or_del(G.spawn_item(H, metadata), G.slot))
to_chat(H, "<span class='notice'>Equipping you with \the [thing]!</span>")
custom_equip_slots.Add(G.slot)
else
custom_equip_leftovers.Add(thing)
else
spawn_in_storage += thing
//Equip job items.
job.setup_account(H) job.setup_account(H)
// Equip job items.
job.equip(H, H.mind ? H.mind.role_alt_title : "") job.equip(H, H.mind ? H.mind.role_alt_title : "")
// Stick their fingerprints on literally everything
job.apply_fingerprints(H) job.apply_fingerprints(H)
if(job.title != "Cyborg" && job.title != "AI")
// Only non-silicons get post-job-equip equipment
if(!(job.mob_type & JOB_SILICON))
H.equip_post_job() H.equip_post_job()
//If some custom items could not be equipped before, try again now. // If some custom items could not be equipped before, try again now.
for(var/thing in custom_equip_leftovers) for(var/thing in custom_equip_leftovers)
var/datum/gear/G = gear_datums[thing] var/datum/gear/G = gear_datums[thing]
if(G.slot in custom_equip_slots) if(G.slot in custom_equip_slots)
@@ -456,14 +482,16 @@ var/global/datum/controller/occupations/job_master
H.mind.assigned_role = rank H.mind.assigned_role = rank
alt_title = H.mind.role_alt_title alt_title = H.mind.role_alt_title
switch(rank) // If we're a silicon, we may be done at this point
if("Cyborg") if(job.mob_type & JOB_SILICON_ROBOT)
return H.Robotize() return H.Robotize()
if("AI") if(job.mob_type & JOB_SILICON_AI)
return H return H
if("Colony Director")
var/sound/announce_sound = (ticker.current_state <= GAME_STATE_SETTING_UP) ? null : sound('sound/misc/boatswain.ogg', volume=20) // TWEET PEEP
captain_announcement.Announce("All hands, [alt_title ? alt_title : "Colony Director"] [H.real_name] on deck!", new_sound = announce_sound, zlevel = H.z) if(rank == "Colony Director")
var/sound/announce_sound = (ticker.current_state <= GAME_STATE_SETTING_UP) ? null : sound('sound/misc/boatswain.ogg', volume=20)
captain_announcement.Announce("All hands, [alt_title ? alt_title : "Colony Director"] [H.real_name] on deck!", new_sound = announce_sound, zlevel = H.z)
//Deferred item spawning. //Deferred item spawning.
if(spawn_in_storage && spawn_in_storage.len) if(spawn_in_storage && spawn_in_storage.len)
@@ -573,7 +601,7 @@ var/global/datum/controller/occupations/job_master
if(!J) continue if(!J) continue
J.total_positions = text2num(value) J.total_positions = text2num(value)
J.spawn_positions = text2num(value) J.spawn_positions = text2num(value)
if(name == "AI" || name == "Cyborg")//I dont like this here but it will do for now if(J.mob_type & JOB_SILICON)
J.total_positions = 0 J.total_positions = 0
return 1 return 1
@@ -598,6 +626,11 @@ var/global/datum/controller/occupations/job_master
if(!job.player_old_enough(player.client)) if(!job.player_old_enough(player.client))
level6++ level6++
continue continue
//VOREStation Add
if(!job.player_has_enough_playtime(player.client))
level6++
continue
//VOREStation Add End
if(player.client.prefs.GetJobDepartment(job, 1) & job.flag) if(player.client.prefs.GetJobDepartment(job, 1) & job.flag)
level1++ level1++
else if(player.client.prefs.GetJobDepartment(job, 2) & job.flag) else if(player.client.prefs.GetJobDepartment(job, 2) & job.flag)

View File

@@ -180,21 +180,10 @@
idle_power_usage = 15 idle_power_usage = 15
active_power_usage = 200 //builtin health analyzer, dialysis machine, injectors. active_power_usage = 200 //builtin health analyzer, dialysis machine, injectors.
/obj/machinery/sleeper/New() /obj/machinery/sleeper/Initialize()
..() . = ..()
beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src) beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src)
component_parts = list() default_apply_parts()
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src)
component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src)
component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(src)
component_parts += new /obj/item/weapon/reagent_containers/syringe(src)
component_parts += new /obj/item/weapon/reagent_containers/syringe(src)
component_parts += new /obj/item/weapon/reagent_containers/syringe(src)
component_parts += new /obj/item/stack/material/glass/reinforced(src, 2)
RefreshParts()
/obj/machinery/sleeper/Destroy() /obj/machinery/sleeper/Destroy()
if(console) if(console)

View File

@@ -15,14 +15,9 @@
light_color = "#00FF00" light_color = "#00FF00"
var/obj/machinery/body_scanconsole/console var/obj/machinery/body_scanconsole/console
/obj/machinery/bodyscanner/New() /obj/machinery/bodyscanner/Initialize()
..() . = ..()
component_parts = list() default_apply_parts()
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
component_parts += new /obj/item/stack/material/glass/reinforced(src, 2)
RefreshParts()
/obj/machinery/bodyscanner/Destroy() /obj/machinery/bodyscanner/Destroy()
if(console) if(console)

View File

@@ -29,15 +29,10 @@
var/filtertext var/filtertext
/obj/machinery/autolathe/New() /obj/machinery/autolathe/Initialize()
..() . = ..()
wires = new(src) wires = new(src)
component_parts = list() default_apply_parts()
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/console_screen(src)
RefreshParts() RefreshParts()
/obj/machinery/autolathe/Destroy() /obj/machinery/autolathe/Destroy()

View File

@@ -15,17 +15,14 @@
var/build_eff = 1 var/build_eff = 1
var/eat_eff = 1 var/eat_eff = 1
/obj/machinery/biogenerator/New() /obj/machinery/biogenerator/Initialize()
..() . = ..()
var/datum/reagents/R = new/datum/reagents(1000) var/datum/reagents/R = new/datum/reagents(1000)
reagents = R reagents = R
R.my_atom = src R.my_atom = src
beaker = new /obj/item/weapon/reagent_containers/glass/bottle(src) beaker = new /obj/item/weapon/reagent_containers/glass/bottle(src)
component_parts = list() default_apply_parts()
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
RefreshParts()
/obj/machinery/biogenerator/on_reagent_change() //When the reagents change, change the icon as well. /obj/machinery/biogenerator/on_reagent_change() //When the reagents change, change the icon as well.
update_icon() update_icon()

View File

@@ -77,14 +77,10 @@
add_overlay("bioprinter_working") add_overlay("bioprinter_working")
//VOREStation Edit End //VOREStation Edit End
/obj/machinery/organ_printer/New() /obj/machinery/organ_printer/Initialize()
..() . = ..()
default_apply_parts()
component_parts = list()
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
RefreshParts()
/obj/machinery/organ_printer/examine(var/mob/user) /obj/machinery/organ_printer/examine(var/mob/user)
. = ..() . = ..()
var/biomass = get_biomass_volume() var/biomass = get_biomass_volume()
@@ -274,7 +270,7 @@
icon_state = "bioprinter" icon_state = "bioprinter"
circuit = /obj/item/weapon/circuitboard/bioprinter circuit = /obj/item/weapon/circuitboard/bioprinter
/obj/machinery/organ_printer/flesh/full/New() /obj/machinery/organ_printer/flesh/full/Initialize()
. = ..() . = ..()
container = new /obj/item/weapon/reagent_containers/glass/bottle/biomass(src) container = new /obj/item/weapon/reagent_containers/glass/bottle/biomass(src)

View File

@@ -29,6 +29,7 @@
var/short_range = 2 var/short_range = 2
var/light_disabled = 0 var/light_disabled = 0
var/in_use_lights = 0 // TO BE IMPLEMENTED - LIES.
var/alarm_on = 0 var/alarm_on = 0
var/busy = 0 var/busy = 0

View File

@@ -13,13 +13,9 @@
var/chargelevel = -1 var/chargelevel = -1
circuit = /obj/item/weapon/circuitboard/cell_charger circuit = /obj/item/weapon/circuitboard/cell_charger
/obj/machinery/cell_charger/New() /obj/machinery/cell_charger/Initialize()
component_parts = list() . = ..()
component_parts += new /obj/item/weapon/stock_parts/capacitor(src) default_apply_parts()
component_parts += new /obj/item/stack/cable_coil(src, 5)
RefreshParts()
..()
return
/obj/machinery/cell_charger/update_icon() /obj/machinery/cell_charger/update_icon()
icon_state = "ccharger[charging ? 1 : 0]" icon_state = "ccharger[charging ? 1 : 0]"

View File

@@ -46,17 +46,9 @@
var/list/containers = list() // Beakers for our liquid biomass var/list/containers = list() // Beakers for our liquid biomass
var/container_limit = 3 // How many beakers can the machine hold? var/container_limit = 3 // How many beakers can the machine hold?
/obj/machinery/clonepod/New() /obj/machinery/clonepod/Initialize()
..() . = ..()
component_parts = list() default_apply_parts()
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
component_parts += new /obj/item/weapon/stock_parts/console_screen(src)
component_parts += new /obj/item/stack/cable_coil(src, 2)
RefreshParts()
update_icon() update_icon()
/obj/machinery/clonepod/attack_ai(mob/user as mob) /obj/machinery/clonepod/attack_ai(mob/user as mob)

View File

@@ -2,7 +2,7 @@
name = "automated shutoff valve monitor" name = "automated shutoff valve monitor"
desc = "Console used to remotely monitor shutoff valves on the station." desc = "Console used to remotely monitor shutoff valves on the station."
icon_keyboard = "power_key" icon_keyboard = "power_key"
icon_screen = "power:0" icon_screen = "power_monitor"
light_color = "#a97faa" light_color = "#a97faa"
circuit = /obj/item/weapon/circuitboard/shutoff_monitor circuit = /obj/item/weapon/circuitboard/shutoff_monitor
var/datum/nano_module/shutoff_monitor/monitor var/datum/nano_module/shutoff_monitor/monitor

View File

@@ -154,6 +154,7 @@
&& !job.whitelist_only \ && !job.whitelist_only \
&& !jobban_isbanned(user,job.title) \ && !jobban_isbanned(user,job.title) \
&& job.player_old_enough(user.client) \ && job.player_old_enough(user.client) \
&& job.player_has_enough_playtime(user.client) \
&& job.pto_type == department \ && job.pto_type == department \
&& !job.disallow_jobhop \ && !job.disallow_jobhop \
&& job.timeoff_factor > 0 && job.timeoff_factor > 0

View File

@@ -64,7 +64,7 @@
if (usr.stat || usr.restrained() || (!ishuman(usr) && !istype(usr,/mob/living/silicon))) if (usr.stat || usr.restrained() || (!ishuman(usr) && !istype(usr,/mob/living/silicon)))
return return
if (href_list["close"]) if (href_list["close"])
usr << browse(null, "window=airlock") usr << browse(null, "window=airlock_electronics")
return return
if (href_list["login"]) if (href_list["login"])

View File

@@ -21,21 +21,9 @@
// Proc: New() // Proc: New()
// Parameters: None // Parameters: None
// Description: Adds components to the machine for deconstruction. // Description: Adds components to the machine for deconstruction.
/obj/machinery/exonet_node/map/New() /obj/machinery/exonet_node/map/Initialize()
..() . = ..()
default_apply_parts()
component_parts = list()
component_parts += new /obj/item/weapon/stock_parts/subspace/ansible(src)
component_parts += new /obj/item/weapon/stock_parts/subspace/sub_filter(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
component_parts += new /obj/item/weapon/stock_parts/subspace/crystal(src)
component_parts += new /obj/item/weapon/stock_parts/subspace/treatment(src)
component_parts += new /obj/item/weapon/stock_parts/subspace/treatment(src)
component_parts += new /obj/item/stack/cable_coil(src, 2)
RefreshParts()
desc = "This machine is one of many, many nodes inside [using_map.starsys_name]'s section of the Exonet, connecting the [using_map.station_short] to the rest of the system, at least \ desc = "This machine is one of many, many nodes inside [using_map.starsys_name]'s section of the Exonet, connecting the [using_map.station_short] to the rest of the system, at least \
electronically." electronically."
@@ -187,7 +175,7 @@
// Description: This writes to the logs list, so that people can see what people are doing on the Exonet ingame. Note that this is not an admin logging function. // Description: This writes to the logs list, so that people can see what people are doing on the Exonet ingame. Note that this is not an admin logging function.
// Communicators are already logged seperately. // Communicators are already logged seperately.
/obj/machinery/exonet_node/proc/write_log(var/origin_address, var/target_address, var/data_type, var/content) /obj/machinery/exonet_node/proc/write_log(var/origin_address, var/target_address, var/data_type, var/content)
//var/timestamp = time2text(station_time_in_ticks, "hh:mm:ss") //var/timestamp = time2text(station_time_in_ds, "hh:mm:ss")
var/timestamp = "[stationdate2text()] [stationtime2text()]" var/timestamp = "[stationdate2text()] [stationtime2text()]"
var/msg = "[timestamp] | FROM [origin_address] TO [target_address] | TYPE: [data_type] | CONTENT: [content]" var/msg = "[timestamp] | FROM [origin_address] TO [target_address] | TYPE: [data_type] | CONTENT: [content]"
logs.Add(msg) logs.Add(msg)

View File

@@ -54,8 +54,8 @@
new/datum/track("Russkiy rep Diskoteka", 'sound/music/russianrapdisco.ogg') new/datum/track("Russkiy rep Diskoteka", 'sound/music/russianrapdisco.ogg')
) )
/obj/machinery/media/jukebox/New() /obj/machinery/media/jukebox/Initialize()
..() . = ..()
default_apply_parts() default_apply_parts()
wires = new/datum/wires/jukebox(src) wires = new/datum/wires/jukebox(src)
update_icon() update_icon()
@@ -63,7 +63,7 @@
/obj/machinery/media/jukebox/Destroy() /obj/machinery/media/jukebox/Destroy()
qdel(wires) qdel(wires)
wires = null wires = null
..() return ..()
// On initialization, copy our tracks from the global list // On initialization, copy our tracks from the global list
/obj/machinery/media/jukebox/Initialize() /obj/machinery/media/jukebox/Initialize()

View File

@@ -121,13 +121,17 @@ Class Procs:
if(ispath(circuit)) if(ispath(circuit))
circuit = new circuit(src) circuit = new circuit(src)
/obj/machinery/Initialize() /obj/machinery/Initialize(var/mapload)
. = ..() . = ..()
global.machines += src global.machines += src
if(ispath(circuit))
circuit = new circuit(src)
if(!speed_process) if(!speed_process)
START_MACHINE_PROCESSING(src) START_MACHINE_PROCESSING(src)
else else
START_PROCESSING(SSfastprocess, src) START_PROCESSING(SSfastprocess, src)
if(!mapload)
power_change()
/obj/machinery/Destroy() /obj/machinery/Destroy()
if(!speed_process) if(!speed_process)
@@ -452,6 +456,7 @@ Class Procs:
return 1 return 1
/datum/proc/apply_visual(mob/M) /datum/proc/apply_visual(mob/M)
M.sight = 0 //Just reset their mesons and stuff so they can't use them, by default.
return return
/datum/proc/remove_visual(mob/M) /datum/proc/remove_visual(mob/M)

View File

@@ -17,16 +17,8 @@
var/drive_range = 50 //this is mostly irrelevant since current mass drivers throw into space, but you could make a lower-range mass driver for interstation transport or something I guess. var/drive_range = 50 //this is mostly irrelevant since current mass drivers throw into space, but you could make a lower-range mass driver for interstation transport or something I guess.
/obj/machinery/mass_driver/New() /obj/machinery/mass_driver/New()
..() . = ..()
component_parts = list() default_apply_parts()
component_parts += new /obj/item/weapon/stock_parts/motor(src)
component_parts += new /obj/item/weapon/stock_parts/motor(src)
component_parts += new /obj/item/weapon/stock_parts/gear(src)
component_parts += new /obj/item/weapon/stock_parts/gear(src)
component_parts += new /obj/item/weapon/stock_parts/spring(src)
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
component_parts += new /obj/item/stack/cable_coil(src, 5)
RefreshParts()
/obj/machinery/mass_driver/attackby(var/obj/item/I, mob/user) /obj/machinery/mass_driver/attackby(var/obj/item/I, mob/user)
if(default_deconstruction_screwdriver(user, I)) if(default_deconstruction_screwdriver(user, I))

View File

@@ -79,7 +79,7 @@
newMsg.body = msg newMsg.body = msg
newMsg.time_stamp = "[stationtime2text()]" newMsg.time_stamp = "[stationtime2text()]"
newMsg.is_admin_message = adminMessage newMsg.is_admin_message = adminMessage
newMsg.post_time = round_duration_in_ticks // Should be almost universally unique newMsg.post_time = round_duration_in_ds // Should be almost universally unique
if(message_type) if(message_type)
newMsg.message_type = message_type newMsg.message_type = message_type
if(photo) if(photo)

View File

@@ -23,17 +23,9 @@
"cargo" = new /obj/item/device/pda/multicaster/cargo(src), "cargo" = new /obj/item/device/pda/multicaster/cargo(src),
"civilian" = new /obj/item/device/pda/multicaster/civilian(src)) "civilian" = new /obj/item/device/pda/multicaster/civilian(src))
/obj/machinery/pda_multicaster/prebuilt/New() /obj/machinery/pda_multicaster/prebuilt/Initialize()
..() . = ..()
default_apply_parts()
component_parts = list()
component_parts += new /obj/item/weapon/circuitboard/telecomms/pda_multicaster(src)
component_parts += new /obj/item/weapon/stock_parts/subspace/ansible(src)
component_parts += new /obj/item/weapon/stock_parts/subspace/sub_filter(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/subspace/treatment(src)
component_parts += new /obj/item/stack/cable_coil(src, 2)
RefreshParts()
/obj/machinery/pda_multicaster/Destroy() /obj/machinery/pda_multicaster/Destroy()
for(var/atom/movable/AM in contents) for(var/atom/movable/AM in contents)

View File

@@ -17,13 +17,9 @@
var/portable = 1 var/portable = 1
circuit = /obj/item/weapon/circuitboard/recharger circuit = /obj/item/weapon/circuitboard/recharger
/obj/machinery/recharger/New() /obj/machinery/recharger/Initialize()
component_parts = list() . = ..()
component_parts += new /obj/item/weapon/stock_parts/capacitor(src) default_apply_parts()
component_parts += new /obj/item/stack/cable_coil(src, 5)
RefreshParts()
..()
return
/obj/machinery/recharger/examine(mob/user) /obj/machinery/recharger/examine(mob/user)
. = ..() . = ..()

View File

@@ -22,17 +22,9 @@
var/weld_power_use = 2300 // power used per point of brute damage repaired. 2.3 kW ~ about the same power usage of a handheld arc welder var/weld_power_use = 2300 // power used per point of brute damage repaired. 2.3 kW ~ about the same power usage of a handheld arc welder
var/wire_power_use = 500 // power used per point of burn damage repaired. var/wire_power_use = 500 // power used per point of burn damage repaired.
/obj/machinery/recharge_station/New() /obj/machinery/recharge_station/Initialize()
..() . = ..()
component_parts = list() default_apply_parts()
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
component_parts += new /obj/item/weapon/cell/high(src)
component_parts += new /obj/item/stack/cable_coil(src, 5)
RefreshParts()
update_icon() update_icon()
/obj/machinery/recharge_station/proc/has_cell_power() /obj/machinery/recharge_station/proc/has_cell_power()

View File

@@ -32,13 +32,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
/obj/machinery/telecomms/processor/Initialize() /obj/machinery/telecomms/processor/Initialize()
. = ..() . = ..()
component_parts = list() default_apply_parts()
component_parts += new /obj/item/weapon/stock_parts/subspace/sub_filter(src)
component_parts += new /obj/item/weapon/stock_parts/subspace/crystal(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/micro_laser/high(src)
component_parts += new /obj/item/stack/cable_coil(src, 1)
/obj/machinery/telecomms/broadcaster/proc/link_radio(var/obj/item/device/radio/R) /obj/machinery/telecomms/broadcaster/proc/link_radio(var/obj/item/device/radio/R)
if(!istype(R)) if(!istype(R))

View File

@@ -266,13 +266,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
/obj/machinery/telecomms/receiver/Initialize() /obj/machinery/telecomms/receiver/Initialize()
. = ..() . = ..()
component_parts = list() default_apply_parts()
component_parts += new /obj/item/weapon/stock_parts/subspace/ansible(src)
component_parts += new /obj/item/weapon/stock_parts/subspace/sub_filter(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
RefreshParts()
/obj/machinery/telecomms/receiver/proc/link_radio(var/obj/item/device/radio/R) /obj/machinery/telecomms/receiver/proc/link_radio(var/obj/item/device/radio/R)
if(!istype(R)) if(!istype(R))
@@ -355,13 +349,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
/obj/machinery/telecomms/hub/Initialize() /obj/machinery/telecomms/hub/Initialize()
. = ..() . = ..()
component_parts = list() default_apply_parts()
component_parts += new /obj/item/weapon/stock_parts/subspace/sub_filter(src)
component_parts += new /obj/item/weapon/stock_parts/subspace/sub_filter(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/stack/cable_coil(src, 2)
RefreshParts()
/obj/machinery/telecomms/hub/receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from) /obj/machinery/telecomms/hub/receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from)
if(is_freq_listening(signal)) if(is_freq_listening(signal))
@@ -401,13 +389,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
/obj/machinery/telecomms/relay/Initialize() /obj/machinery/telecomms/relay/Initialize()
. = ..() . = ..()
component_parts = list() default_apply_parts()
component_parts += new /obj/item/weapon/stock_parts/subspace/sub_filter(src)
component_parts += new /obj/item/weapon/stock_parts/subspace/sub_filter(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/stack/cable_coil(src, 2)
RefreshParts()
/obj/machinery/telecomms/relay/forceMove(var/newloc) /obj/machinery/telecomms/relay/forceMove(var/newloc)
. = ..(newloc) . = ..(newloc)
@@ -464,12 +446,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
/obj/machinery/telecomms/bus/Initialize() /obj/machinery/telecomms/bus/Initialize()
. = ..() . = ..()
component_parts = list() default_apply_parts()
component_parts += new /obj/item/weapon/stock_parts/subspace/sub_filter(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/stack/cable_coil(src, 1)
RefreshParts()
/obj/machinery/telecomms/bus/receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from) /obj/machinery/telecomms/bus/receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from)
@@ -525,17 +502,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
/obj/machinery/telecomms/processor/Initialize() /obj/machinery/telecomms/processor/Initialize()
. = ..() . = ..()
component_parts = list() default_apply_parts()
component_parts += new /obj/item/weapon/stock_parts/subspace/sub_filter(src)
component_parts += new /obj/item/weapon/stock_parts/subspace/treatment(src)
component_parts += new /obj/item/weapon/stock_parts/subspace/treatment(src)
component_parts += new /obj/item/weapon/stock_parts/subspace/amplifier(src)
component_parts += new /obj/item/weapon/stock_parts/subspace/analyzer(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/stack/cable_coil(src, 2)
RefreshParts()
/obj/machinery/telecomms/processor/receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from) /obj/machinery/telecomms/processor/receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from)
@@ -596,12 +563,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
/obj/machinery/telecomms/server/Initialize() /obj/machinery/telecomms/server/Initialize()
. = ..() . = ..()
component_parts = list() default_apply_parts()
component_parts += new /obj/item/weapon/stock_parts/subspace/sub_filter(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/stack/cable_coil(src, 1)
RefreshParts()
/obj/machinery/telecomms/server/receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from) /obj/machinery/telecomms/server/receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from)

View File

@@ -1,3 +1,6 @@
//////
////// Teleporter computer
//////
/obj/machinery/computer/teleporter /obj/machinery/computer/teleporter
name = "teleporter control console" name = "teleporter control console"
desc = "Used to control a linked teleportation Hub and Station." desc = "Used to control a linked teleportation Hub and Station."
@@ -5,23 +8,23 @@
icon_screen = "teleport" icon_screen = "teleport"
circuit = /obj/item/weapon/circuitboard/teleporter circuit = /obj/item/weapon/circuitboard/teleporter
dir = 4 dir = 4
var/obj/item/locked = null
var/id = null var/id = null
var/one_time_use = 0 //Used for one-time-use teleport cards (such as clown planet coordinates.) var/one_time_use = 0 //Used for one-time-use teleport cards (such as clown planet coordinates.)
//Setting this to 1 will set locked to null after a player enters the portal and will not allow hand-teles to open portals to that location. //Setting this to 1 will set locked to null after a player enters the portal and will not allow hand-teles to open portals to that location.
var/datum/nano_module/program/teleport_control/teleport_control
/obj/machinery/computer/teleporter/New() /obj/machinery/computer/teleporter/New()
id = "[rand(1000, 9999)]" id = "[rand(1000, 9999)]"
..() ..()
underlays.Cut() underlays.Cut()
underlays += image('icons/obj/stationobjs_vr.dmi', icon_state = "telecomp-wires") //VOREStation Edit: different direction for wires to account for dirs underlays += image('icons/obj/stationobjs_vr.dmi', icon_state = "telecomp-wires") //VOREStation Edit: different direction for wires to account for dirs
return teleport_control = new(src)
/obj/machinery/computer/teleporter/Initialize() /obj/machinery/computer/teleporter/Initialize()
. = ..() . = ..()
var/obj/machinery/teleport/station/station var/obj/machinery/teleport/station/station = null
var/obj/machinery/teleport/hub/hub var/obj/machinery/teleport/hub/hub = null
// Search surrounding turfs for the station, and then search the station's surrounding turfs for the hub. // Search surrounding turfs for the station, and then search the station's surrounding turfs for the hub.
for(var/direction in cardinal) for(var/direction in cardinal)
station = locate(/obj/machinery/teleport/station, get_step(src, direction)) station = locate(/obj/machinery/teleport/station, get_step(src, direction))
@@ -34,9 +37,15 @@
if(istype(station)) if(istype(station))
station.com = hub station.com = hub
teleport_control.hub = hub
if(istype(hub)) if(istype(hub))
hub.com = src hub.com = src
teleport_control.station = station
/obj/machinery/computer/teleporter/Destroy()
qdel_null(teleport_control)
return ..()
/obj/machinery/computer/teleporter/attackby(I as obj, mob/living/user as mob) /obj/machinery/computer/teleporter/attackby(I as obj, mob/living/user as mob)
if(istype(I, /obj/item/weapon/card/data/)) if(istype(I, /obj/item/weapon/card/data/))
@@ -74,7 +83,7 @@
else else
for(var/mob/O in hearers(src, null)) for(var/mob/O in hearers(src, null))
O.show_message("<span class='notice'>Locked In</span>", 2) O.show_message("<span class='notice'>Locked In</span>", 2)
locked = L teleport_control.locked = L
one_time_use = 1 one_time_use = 1
add_fingerprint(usr) add_fingerprint(usr)
@@ -86,57 +95,109 @@
/obj/machinery/teleport/station/attack_ai() /obj/machinery/teleport/station/attack_ai()
attack_hand() attack_hand()
/obj/machinery/computer/teleporter/attack_hand(user as mob) /obj/machinery/computer/teleporter/attack_ai(mob/user)
if(..()) return ui_interact(user)
/* Ghosts can't use this one because it's a direct selection */ /obj/machinery/computer/teleporter/attack_hand(mob/user)
if(istype(user, /mob/observer/dead)) return add_fingerprint(user)
if(stat & (BROKEN|NOPOWER))
return
ui_interact(user)
var/list/L = list() /obj/machinery/computer/teleporter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/list/areaindex = list() teleport_control.ui_interact(user, ui_key, ui, force_open)
for(var/obj/item/device/radio/beacon/R in all_beacons) /obj/machinery/computer/teleporter/interact(mob/user)
var/turf/T = get_turf(R) teleport_control.ui_interact(user)
if(!T)
continue
if(!(T.z in using_map.player_levels))
continue
var/tmpname = T.loc.name
if(areaindex[tmpname])
tmpname = "[tmpname] ([++areaindex[tmpname]])"
else
areaindex[tmpname] = 1
L[tmpname] = R
for (var/obj/item/weapon/implant/tracking/I in all_tracking_implants) //////
if(!I.implanted || !ismob(I.loc)) ////// Nano-module for teleporter
continue //////
else /datum/nano_module/program/teleport_control
var/mob/M = I.loc name = "Teleporter Control"
if(M.stat == 2) var/locked_name = "Not Locked"
if(M.timeofdeath + 6000 < world.time) var/obj/item/locked = null
continue var/obj/machinery/teleport/station/station = null
var/turf/T = get_turf(M) var/obj/machinery/teleport/hub/hub = null
if(T) continue
if(T.z == 2) continue /datum/nano_module/program/teleport_control/Topic(href, href_list)
var/tmpname = M.real_name if(..()) return 1
if(href_list["select_target"])
var/list/L = list()
var/list/areaindex = list()
for(var/obj/item/device/radio/beacon/R in all_beacons)
var/turf/T = get_turf(R)
if(!T)
continue
if(!(T.z in using_map.player_levels))
continue
var/tmpname = T.loc.name
if(areaindex[tmpname]) if(areaindex[tmpname])
tmpname = "[tmpname] ([++areaindex[tmpname]])" tmpname = "[tmpname] ([++areaindex[tmpname]])"
else else
areaindex[tmpname] = 1 areaindex[tmpname] = 1
L[tmpname] = I L[tmpname] = R
var/desc = input("Please select a location to lock in.", "Locking Computer") in L|null for (var/obj/item/weapon/implant/tracking/I in all_tracking_implants)
if(!desc) if(!I.implanted || !ismob(I.loc))
return continue
if(get_dist(src, usr) > 1 && !issilicon(usr)) else
return var/mob/M = I.loc
if(M.stat == 2)
if(M.timeofdeath + 6000 < world.time)
continue
var/turf/T = get_turf(M)
if(T) continue
if(T.z == 2) continue
var/tmpname = M.real_name
if(areaindex[tmpname])
tmpname = "[tmpname] ([++areaindex[tmpname]])"
else
areaindex[tmpname] = 1
L[tmpname] = I
locked = L[desc] var/desc = input("Please select a location to lock in.", "Locking Menu") in L|null
for(var/mob/O in hearers(src, null)) if(!desc)
O.show_message("<span class='notice'>Locked In</span>", 2) return 0
add_fingerprint(usr) if(get_dist(host, usr) > 1 && !issilicon(usr))
return return 0
locked = L[desc]
locked_name = desc
return 1
if(href_list["test_fire"])
station?.testfire()
return 1
if(href_list["toggle_on"])
if(!station)
return 0
if(station.engaged)
station.disengage()
else
station.engage()
return 1
/datum/nano_module/program/teleport_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
var/list/data = host.initial_data()
data["locked_name"] = locked_name ? locked_name : "No Target"
data["station_connected"] = station ? 1 : 0
data["hub_connected"] = hub ? 1 : 0
data["calibrated"] = hub ? hub.accurate : 0
data["teleporter_on"] = station ? station.engaged : 0
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
ui = new(user, src, ui_key, "teleport_control.tmpl", "Teleport Control Console", 400, 500, state = state)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/computer/teleporter/verb/set_id(t as text) /obj/machinery/computer/teleporter/verb/set_id(t as text)
set category = "Object" set category = "Object"
@@ -158,6 +219,9 @@
if(!T || istype(T, /area)) return null if(!T || istype(T, /area)) return null
return T return T
//////
////// Root of all the machinery
//////
/obj/machinery/teleport /obj/machinery/teleport
name = "teleport" name = "teleport"
icon = 'icons/obj/stationobjs.dmi' icon = 'icons/obj/stationobjs.dmi'
@@ -165,6 +229,9 @@
anchored = 1.0 anchored = 1.0
var/lockeddown = 0 var/lockeddown = 0
//////
////// The part you step into
//////
/obj/machinery/teleport/hub /obj/machinery/teleport/hub
name = "teleporter hub" name = "teleporter hub"
desc = "It's the hub of a teleporting machine." desc = "It's the hub of a teleporting machine."
@@ -178,22 +245,15 @@
circuit = /obj/item/weapon/circuitboard/teleporter_hub circuit = /obj/item/weapon/circuitboard/teleporter_hub
var/obj/machinery/computer/teleporter/com var/obj/machinery/computer/teleporter/com
/obj/machinery/teleport/hub/New() /obj/machinery/teleport/hub/Initialize()
..() . = ..()
underlays.Cut()
underlays += image('icons/obj/stationobjs.dmi', icon_state = "tele-wires") underlays += image('icons/obj/stationobjs.dmi', icon_state = "tele-wires")
default_apply_parts()
component_parts = list() /obj/machinery/teleport/hub/Destroy()
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src) com?.teleport_control.hub = null
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src) com = null
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src) return ..()
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
component_parts += new /obj/item/stack/cable_coil(src, 10)
RefreshParts()
/obj/machinery/teleport/hub/Bumped(M as mob|obj) /obj/machinery/teleport/hub/Bumped(M as mob|obj)
spawn() spawn()
@@ -205,7 +265,7 @@
/obj/machinery/teleport/hub/proc/teleport(atom/movable/M as mob|obj) /obj/machinery/teleport/hub/proc/teleport(atom/movable/M as mob|obj)
if(!com) if(!com)
return return
if(!com.locked) if(!com.teleport_control.locked)
for(var/mob/O in hearers(src, null)) for(var/mob/O in hearers(src, null))
O.show_message("<span class='warning'>Failure: Cannot authenticate locked on coordinates. Please reinstate coordinate matrix.</span>") O.show_message("<span class='warning'>Failure: Cannot authenticate locked on coordinates. Please reinstate coordinate matrix.</span>")
return return
@@ -221,11 +281,11 @@
if(prob(5) && !accurate) //oh dear a problem, put em in deep space if(prob(5) && !accurate) //oh dear a problem, put em in deep space
do_teleport(M, locate(rand((2*TRANSITIONEDGE), world.maxx - (2*TRANSITIONEDGE)), rand((2*TRANSITIONEDGE), world.maxy - (2*TRANSITIONEDGE)), 3), 2) do_teleport(M, locate(rand((2*TRANSITIONEDGE), world.maxx - (2*TRANSITIONEDGE)), rand((2*TRANSITIONEDGE), world.maxy - (2*TRANSITIONEDGE)), 3), 2)
else else
do_teleport(M, com.locked) //dead-on precision do_teleport(M, com.teleport_control.locked) //dead-on precision
if(com.one_time_use) //Make one-time-use cards only usable one time! if(com.one_time_use) //Make one-time-use cards only usable one time!
com.one_time_use = 0 com.one_time_use = 0
com.locked = null com.teleport_control.locked = null
else else
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src) s.set_up(5, 1, src)
@@ -235,92 +295,10 @@
for(var/mob/B in hearers(src, null)) for(var/mob/B in hearers(src, null))
B.show_message("<span class='notice'>Test fire completed.</span>") B.show_message("<span class='notice'>Test fire completed.</span>")
return return
/*
/proc/do_teleport(atom/movable/M as mob|obj, atom/destination, precision)
if(istype(M, /obj/effect))
qdel(M)
return
if(istype(M, /obj/item/weapon/disk/nuclear)) // Don't let nuke disks get teleported --NeoFite
for(var/mob/O in viewers(M, null))
O.show_message(text("<span class='danger'>The [] bounces off of the portal!</span>", M.name), 1)
return
if(istype(M, /mob/living))
var/mob/living/MM = M
if(MM.check_contents_for(/obj/item/weapon/disk/nuclear))
to_chat(MM, "<span class='warning'>Something you are carrying seems to be unable to pass through the portal. Better drop it if you want to go through.</span>")
return
var/disky = 0
for (var/atom/O in M.contents) //I'm pretty sure this accounts for the maximum amount of container in container stacking. --NeoFite
if(istype(O, /obj/item/weapon/storage) || istype(O, /obj/item/weapon/gift))
for (var/obj/OO in O.contents)
if(istype(OO, /obj/item/weapon/storage) || istype(OO, /obj/item/weapon/gift))
for (var/obj/OOO in OO.contents)
if(istype(OOO, /obj/item/weapon/disk/nuclear))
disky = 1
if(istype(OO, /obj/item/weapon/disk/nuclear))
disky = 1
if(istype(O, /obj/item/weapon/disk/nuclear))
disky = 1
if(istype(O, /mob/living))
var/mob/living/MM = O
if(MM.check_contents_for(/obj/item/weapon/disk/nuclear))
disky = 1
if(disky)
for(var/mob/P in viewers(M, null))
P.show_message(text("<span class='danger'>The [] bounces off of the portal!</span>", M.name), 1)
return
//Bags of Holding cause bluespace teleportation to go funky. --NeoFite
if(istype(M, /mob/living))
var/mob/living/MM = M
if(MM.check_contents_for(/obj/item/weapon/storage/backpack/holding))
to_chat(MM, "<span class='warning'>The Bluespace interface on your Bag of Holding interferes with the teleport!</span>")
precision = rand(1,100)
if(istype(M, /obj/item/weapon/storage/backpack/holding))
precision = rand(1,100)
for (var/atom/O in M.contents) //I'm pretty sure this accounts for the maximum amount of container in container stacking. --NeoFite
if(istype(O, /obj/item/weapon/storage) || istype(O, /obj/item/weapon/gift))
for (var/obj/OO in O.contents)
if(istype(OO, /obj/item/weapon/storage) || istype(OO, /obj/item/weapon/gift))
for (var/obj/OOO in OO.contents)
if(istype(OOO, /obj/item/weapon/storage/backpack/holding))
precision = rand(1,100)
if(istype(OO, /obj/item/weapon/storage/backpack/holding))
precision = rand(1,100)
if(istype(O, /obj/item/weapon/storage/backpack/holding))
precision = rand(1,100)
if(istype(O, /mob/living))
var/mob/living/MM = O
if(MM.check_contents_for(/obj/item/weapon/storage/backpack/holding))
precision = rand(1,100)
var/turf/destturf = get_turf(destination)
var/tx = destturf.x + rand(precision * -1, precision)
var/ty = destturf.y + rand(precision * -1, precision)
var/tmploc
if(ismob(destination.loc)) //If this is an implant.
tmploc = locate(tx, ty, destturf.z)
else
tmploc = locate(tx, ty, destination.z)
if(tx == destturf.x && ty == destturf.y && (istype(destination.loc, /obj/structure/closet) || istype(destination.loc, /obj/structure/closet/secure_closet)))
tmploc = destination.loc
if(tmploc==null)
return
M.loc = tmploc
sleep(2)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, M)
s.start()
return
*/
//////
////// The middle part
//////
/obj/machinery/teleport/station /obj/machinery/teleport/station
name = "station" name = "station"
desc = "It's the station thingy of a teleport thingy." //seriously, wtf. desc = "It's the station thingy of a teleport thingy." //seriously, wtf.
@@ -335,29 +313,15 @@
circuit = /obj/item/weapon/circuitboard/teleporter_station circuit = /obj/item/weapon/circuitboard/teleporter_station
var/obj/machinery/teleport/hub/com var/obj/machinery/teleport/hub/com
/obj/machinery/teleport/station/New() /obj/machinery/teleport/station/Initialize()
..() . = ..()
overlays.Cut() add_overlay("controller-wires")
overlays += image('icons/obj/stationobjs.dmi', icon_state = "controller-wires") default_apply_parts()
component_parts = list() /obj/machinery/teleport/station/Destroy()
component_parts += new /obj/item/weapon/stock_parts/console_screen(src) com?.com?.teleport_control.station = null
component_parts += new /obj/item/weapon/stock_parts/capacitor(src) com = null
component_parts += new /obj/item/weapon/stock_parts/capacitor(src) return ..()
component_parts += new /obj/item/stack/cable_coil(src, 10)
RefreshParts()
/obj/machinery/teleport/station/attackby(var/obj/item/weapon/W)
attack_hand()
/obj/machinery/teleport/station/attack_ai()
attack_hand()
/obj/machinery/teleport/station/attack_hand()
if(engaged)
disengage()
else
engage()
/obj/machinery/teleport/station/proc/engage() /obj/machinery/teleport/station/proc/engage()
if(stat & (BROKEN|NOPOWER)) if(stat & (BROKEN|NOPOWER))
@@ -389,27 +353,17 @@
engaged = 0 engaged = 0
return return
/obj/machinery/teleport/station/verb/testfire() /obj/machinery/teleport/station/proc/testfire()
set name = "Test Fire Teleporter" if(!com || active)
set category = "Object"
set src in oview(1)
if(stat & (BROKEN|NOPOWER) || !istype(usr,/mob/living))
return return
if(com && !active) active = TRUE
active = 1 visible_message("<span class='notice'>Test firing!</span>")
for(var/mob/O in hearers(src, null)) com.teleport()
O.show_message("<span class='notice'>Test firing!</span>", 2) use_power(5000)
com.teleport() flick(src, "controller-c") //VOREStation Add
use_power(5000)
flick(src, "controller-c") //VOREStation Add
spawn(30) VARSET_IN(src, active, FALSE, 3 SECONDS)
active=0
add_fingerprint(usr)
return
/obj/machinery/teleport/station/power_change() /obj/machinery/teleport/station/power_change()
..() ..()

View File

@@ -23,13 +23,9 @@
active_power_usage = 200 active_power_usage = 200
light_color = "#FF0000" light_color = "#FF0000"
/obj/machinery/vr_sleeper/New() /obj/machinery/vr_sleeper/Initialize()
..() . = ..()
component_parts = list() default_apply_parts()
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
component_parts += new /obj/item/stack/material/glass/reinforced(src, 2)
RefreshParts()
/obj/machinery/vr_sleeper/Initialize() /obj/machinery/vr_sleeper/Initialize()
. = ..() . = ..()

View File

@@ -29,14 +29,10 @@
/obj/item/clothing/head/helmet/space /obj/item/clothing/head/helmet/space
) )
/obj/machinery/washing_machine/New() /obj/machinery/washing_machine/Initialize()
..() . = ..()
component_parts = list() default_apply_parts()
component_parts += new /obj/item/weapon/stock_parts/motor(src)
component_parts += new /obj/item/weapon/stock_parts/gear(src)
component_parts += new /obj/item/weapon/stock_parts/gear(src)
RefreshParts()
/obj/machinery/washing_machine/verb/start() /obj/machinery/washing_machine/verb/start()
set name = "Start Washing" set name = "Start Washing"
set category = "Object" set category = "Object"

View File

@@ -12,15 +12,9 @@
var/charge = 45 var/charge = 45
var/repair = 0 var/repair = 0
/obj/machinery/mech_recharger/New() /obj/machinery/mech_recharger/Initialize()
..() . = ..()
component_parts = list() default_apply_parts()
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
component_parts += new /obj/item/weapon/stock_parts/capacitor(src)
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
RefreshParts()
/obj/machinery/mech_recharger/Crossed(var/obj/mecha/M) /obj/machinery/mech_recharger/Crossed(var/obj/mecha/M)
. = ..() . = ..()

View File

@@ -26,22 +26,11 @@
var/category = null var/category = null
var/sync_message = "" var/sync_message = ""
/obj/machinery/mecha_part_fabricator/New()
..()
component_parts = list()
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
component_parts += new /obj/item/weapon/stock_parts/console_screen(src)
RefreshParts()
files = new /datum/research(src) //Setup the research data holder.
return
/obj/machinery/mecha_part_fabricator/Initialize() /obj/machinery/mecha_part_fabricator/Initialize()
update_categories()
. = ..() . = ..()
default_apply_parts()
files = new /datum/research(src) //Setup the research data holder.
update_categories()
/obj/machinery/mecha_part_fabricator/process() /obj/machinery/mecha_part_fabricator/process()
..() ..()

View File

@@ -29,18 +29,11 @@
var/species = "Human" var/species = "Human"
var/sync_message = "" var/sync_message = ""
/obj/machinery/pros_fabricator/New() /obj/machinery/pros_fabricator/Initialize()
..() . = ..()
component_parts = list() default_apply_parts()
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
component_parts += new /obj/item/weapon/stock_parts/matter_bin(src)
component_parts += new /obj/item/weapon/stock_parts/manipulator(src)
component_parts += new /obj/item/weapon/stock_parts/micro_laser(src)
component_parts += new /obj/item/weapon/stock_parts/console_screen(src)
RefreshParts()
files = new /datum/research(src) //Setup the research data holder. files = new /datum/research(src) //Setup the research data holder.
return
/obj/machinery/pros_fabricator/Initialize() /obj/machinery/pros_fabricator/Initialize()
. = ..() . = ..()

View File

@@ -95,9 +95,9 @@
var/list/cargo = list() var/list/cargo = list()
var/cargo_capacity = 3 var/cargo_capacity = 3
var/static/image/radial_image_eject = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject"), var/static/image/radial_image_eject = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject")
var/static/image/radial_image_airtoggle = image(icon= 'icons/mob/radial.dmi', icon_state = "radial_airtank"), var/static/image/radial_image_airtoggle = image(icon= 'icons/mob/radial.dmi', icon_state = "radial_airtank")
var/static/image/radial_image_lighttoggle = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_light"), var/static/image/radial_image_lighttoggle = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_light")
var/static/image/radial_image_statpanel = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine2") var/static/image/radial_image_statpanel = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine2")

View File

@@ -49,6 +49,9 @@
if(triggered) if(triggered)
return return
if(istype(M, /obj/mecha))
explode(M)
if(istype(M, /mob/living/)) if(istype(M, /mob/living/))
if(!M.hovering) if(!M.hovering)
explode(M) explode(M)
@@ -79,7 +82,7 @@
triggered = 1 triggered = 1
s.set_up(3, 1, src) s.set_up(3, 1, src)
s.start() s.start()
if(M) if(istype(M))
M.radiation += 50 M.radiation += 50
randmutb(M) randmutb(M)
domutcheck(M,null) domutcheck(M,null)
@@ -96,7 +99,7 @@
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread() var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
s.set_up(3, 1, src) s.set_up(3, 1, src)
s.start() s.start()
if(M) if(istype(M))
M.Stun(30) M.Stun(30)
visible_message("\The [src.name] flashes violently before disintegrating!") visible_message("\The [src.name] flashes violently before disintegrating!")
spawn(0) spawn(0)
@@ -136,7 +139,10 @@
triggered = 1 triggered = 1
s.set_up(3, 1, src) s.set_up(3, 1, src)
s.start() s.start()
if(M) if(istype(M, /obj/mecha))
var/obj/mecha/E = M
M = E.occupant
if(istype(M))
qdel(M.client) qdel(M.client)
spawn(0) spawn(0)
qdel(s) qdel(s)
@@ -195,7 +201,7 @@
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread() var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
s.set_up(3, 1, src) s.set_up(3, 1, src)
s.start() s.start()
if(M) if(istype(M))
M.adjust_fire_stacks(5) M.adjust_fire_stacks(5)
M.fire_act() M.fire_act()
visible_message("\The [src.name] bursts into flames!") visible_message("\The [src.name] bursts into flames!")

View File

@@ -7,7 +7,7 @@
layer = ABOVE_TURF_LAYER layer = ABOVE_TURF_LAYER
anchored = 1 anchored = 1
w_class = ITEMSIZE_LARGE w_class = ITEMSIZE_LARGE
canhear_range = 2 canhear_range = 7 //VOREStation Edit
flags = NOBLOODY flags = NOBLOODY
var/circuit = /obj/item/weapon/circuitboard/intercom var/circuit = /obj/item/weapon/circuitboard/intercom
var/number = 0 var/number = 0
@@ -195,7 +195,19 @@
icon_state = "intercom_open" icon_state = "intercom_open"
else else
icon_state = initial(icon_state) icon_state = initial(icon_state)
//VOREStation Add Start
/obj/item/device/radio/intercom/AICtrlClick(var/mob/user)
ToggleBroadcast()
to_chat(user, "<span class='notice'>\The [src]'s microphone is now <b>[broadcasting ? "enabled" : "disabled"]</b>.</span>")
/obj/item/device/radio/intercom/AIAltClick(var/mob/user)
if(frequency == AI_FREQ)
set_frequency(initial(frequency))
to_chat(user, "<span class='notice'>\The [src]'s frequency is now set to <font color='green'><b>Default</b></font>.</span>")
else
set_frequency(AI_FREQ)
to_chat(user, "<span class='notice'>\The [src]'s frequency is now set to <font color='pink'><b>AI Private</b></font>.</span>")
//VOREStation Add End
/obj/item/device/radio/intercom/locked /obj/item/device/radio/intercom/locked
var/locked_frequency var/locked_frequency

View File

@@ -9,9 +9,9 @@
var/ammostate var/ammostate
var/list/effects = list() var/list/effects = list()
var/static/image/radial_image_airlock = image(icon = 'icons/mob/radial.dmi', icon_state = "airlock"), var/static/image/radial_image_airlock = image(icon = 'icons/mob/radial.dmi', icon_state = "airlock")
var/static/image/radial_image_decon = image(icon= 'icons/mob/radial.dmi', icon_state = "delete"), var/static/image/radial_image_decon = image(icon= 'icons/mob/radial.dmi', icon_state = "delete")
var/static/image/radial_image_grillewind = image(icon = 'icons/mob/radial.dmi', icon_state = "grillewindow"), var/static/image/radial_image_grillewind = image(icon = 'icons/mob/radial.dmi', icon_state = "grillewindow")
var/static/image/radial_image_floorwall = image(icon = 'icons/mob/radial.dmi', icon_state = "wallfloor") var/static/image/radial_image_floorwall = image(icon = 'icons/mob/radial.dmi', icon_state = "wallfloor")
// Ammo for the (non-electric) RCDs. // Ammo for the (non-electric) RCDs.

View File

@@ -1,90 +1,90 @@
//A storage item intended to be used by other items to provide storage functionality. //A storage item intended to be used by other items to provide storage functionality.
//Types that use this should consider overriding emp_act() and hear_talk(), unless they shield their contents somehow. //Types that use this should consider overriding emp_act() and hear_talk(), unless they shield their contents somehow.
/obj/item/weapon/storage/internal /obj/item/weapon/storage/internal
preserve_item = 1 preserve_item = 1
var/obj/item/master_item var/obj/item/master_item
/obj/item/weapon/storage/internal/New(obj/item/MI) /obj/item/weapon/storage/internal/New(obj/item/MI)
master_item = MI master_item = MI
loc = master_item loc = master_item
//name = master_item.name //VOREStation Removal //name = master_item.name //VOREStation Removal
verbs -= /obj/item/verb/verb_pickup //make sure this is never picked up. verbs -= /obj/item/verb/verb_pickup //make sure this is never picked up.
..() ..()
/obj/item/weapon/storage/internal/Destroy() /obj/item/weapon/storage/internal/Destroy()
master_item = null master_item = null
. = ..() . = ..()
/obj/item/weapon/storage/internal/attack_hand() /obj/item/weapon/storage/internal/attack_hand()
return //make sure this is never picked up return //make sure this is never picked up
/obj/item/weapon/storage/internal/mob_can_equip() /obj/item/weapon/storage/internal/mob_can_equip(M as mob, slot, disable_warning = 0)
return 0 //make sure this is never picked up return 0 //make sure this is never picked up
//Helper procs to cleanly implement internal storages - storage items that provide inventory slots for other items. //Helper procs to cleanly implement internal storages - storage items that provide inventory slots for other items.
//These procs are completely optional, it is up to the master item to decide when it's storage get's opened by calling open() //These procs are completely optional, it is up to the master item to decide when it's storage get's opened by calling open()
//However they are helpful for allowing the master item to pretend it is a storage item itself. //However they are helpful for allowing the master item to pretend it is a storage item itself.
//If you are using these you will probably want to override attackby() as well. //If you are using these you will probably want to override attackby() as well.
//See /obj/item/clothing/suit/storage for an example. //See /obj/item/clothing/suit/storage for an example.
//items that use internal storage have the option of calling this to emulate default storage MouseDrop behaviour. //items that use internal storage have the option of calling this to emulate default storage MouseDrop behaviour.
//returns 1 if the master item's parent's MouseDrop() should be called, 0 otherwise. It's strange, but no other way of //returns 1 if the master item's parent's MouseDrop() should be called, 0 otherwise. It's strange, but no other way of
//doing it without the ability to call another proc's parent, really. //doing it without the ability to call another proc's parent, really.
/obj/item/weapon/storage/internal/proc/handle_mousedrop(mob/user as mob, obj/over_object as obj) /obj/item/weapon/storage/internal/proc/handle_mousedrop(mob/user as mob, obj/over_object as obj)
if (ishuman(user) || issmall(user)) //so monkeys can take off their backpacks -- Urist if (ishuman(user) || issmall(user)) //so monkeys can take off their backpacks -- Urist
if (istype(user.loc,/obj/mecha)) // stops inventory actions in a mech if (istype(user.loc,/obj/mecha)) // stops inventory actions in a mech
return 0 return 0
if(over_object == user && Adjacent(user)) // this must come before the screen objects only block if(over_object == user && Adjacent(user)) // this must come before the screen objects only block
src.open(user) src.open(user)
return 0 return 0
if (!( istype(over_object, /obj/screen) )) if (!( istype(over_object, /obj/screen) ))
return 1 return 1
//makes sure master_item is equipped before putting it in hand, so that we can't drag it into our hand from miles away. //makes sure master_item is equipped before putting it in hand, so that we can't drag it into our hand from miles away.
//there's got to be a better way of doing this... //there's got to be a better way of doing this...
if (!(master_item.loc == user) || (master_item.loc && master_item.loc.loc == user)) if (!(master_item.loc == user) || (master_item.loc && master_item.loc.loc == user))
return 0 return 0
if (!( user.restrained() ) && !( user.stat )) if (!( user.restrained() ) && !( user.stat ))
switch(over_object.name) switch(over_object.name)
if("r_hand") if("r_hand")
user.unEquip(master_item) user.unEquip(master_item)
user.put_in_r_hand(master_item) user.put_in_r_hand(master_item)
if("l_hand") if("l_hand")
user.unEquip(master_item) user.unEquip(master_item)
user.put_in_l_hand(master_item) user.put_in_l_hand(master_item)
master_item.add_fingerprint(user) master_item.add_fingerprint(user)
return 0 return 0
return 0 return 0
//items that use internal storage have the option of calling this to emulate default storage attack_hand behaviour. //items that use internal storage have the option of calling this to emulate default storage attack_hand behaviour.
//returns 1 if the master item's parent's attack_hand() should be called, 0 otherwise. //returns 1 if the master item's parent's attack_hand() should be called, 0 otherwise.
//It's strange, but no other way of doing it without the ability to call another proc's parent, really. //It's strange, but no other way of doing it without the ability to call another proc's parent, really.
/obj/item/weapon/storage/internal/proc/handle_attack_hand(mob/user as mob) /obj/item/weapon/storage/internal/proc/handle_attack_hand(mob/user as mob)
if(ishuman(user)) if(ishuman(user))
var/mob/living/carbon/human/H = user var/mob/living/carbon/human/H = user
if(H.l_store == master_item && !H.get_active_hand()) //Prevents opening if it's in a pocket. if(H.l_store == master_item && !H.get_active_hand()) //Prevents opening if it's in a pocket.
H.put_in_hands(master_item) H.put_in_hands(master_item)
H.l_store = null H.l_store = null
return 0 return 0
if(H.r_store == master_item && !H.get_active_hand()) if(H.r_store == master_item && !H.get_active_hand())
H.put_in_hands(master_item) H.put_in_hands(master_item)
H.r_store = null H.r_store = null
return 0 return 0
src.add_fingerprint(user) src.add_fingerprint(user)
if (master_item.loc == user) if (master_item.loc == user)
src.open(user) src.open(user)
return 0 return 0
for(var/mob/M in range(1, master_item.loc)) for(var/mob/M in range(1, master_item.loc))
if (M.s_active == src) if (M.s_active == src)
src.close(M) src.close(M)
return 1 return 1
/obj/item/weapon/storage/internal/Adjacent(var/atom/neighbor) /obj/item/weapon/storage/internal/Adjacent(var/atom/neighbor)
return master_item.Adjacent(neighbor) return master_item.Adjacent(neighbor)

View File

@@ -63,7 +63,7 @@
overlays.Cut() overlays.Cut()
if(front_id) if(front_id)
var/tiny_state = "id-generic" var/tiny_state = "id-generic"
if("id-"+front_id.icon_state in icon_states(icon)) if("id-"+front_id.icon_state in cached_icon_states(icon))
tiny_state = "id-"+front_id.icon_state tiny_state = "id-"+front_id.icon_state
var/image/tiny_image = new/image(icon, icon_state = tiny_state) var/image/tiny_image = new/image(icon, icon_state = tiny_state)
tiny_image.appearance_flags = RESET_COLOR tiny_image.appearance_flags = RESET_COLOR

View File

@@ -147,11 +147,11 @@ Frequency:
if(com) if(com)
break break
break break
if (istype(com, /obj/machinery/computer/teleporter) && com.locked && !com.one_time_use) if (istype(com, /obj/machinery/computer/teleporter) && com.teleport_control.locked && !com.one_time_use)
if(R.icon_state == "tele1") if(R.icon_state == "tele1")
L["[com.id] (Active)"] = com.locked L["[com.id] (Active)"] = com.teleport_control.locked
else else
L["[com.id] (Inactive)"] = com.locked L["[com.id] (Inactive)"] = com.teleport_control.locked
var/list/turfs = list( ) var/list/turfs = list( )
for(var/turf/T in orange(10)) for(var/turf/T in orange(10))
if(T.x>world.maxx-8 || T.x<8) continue //putting them at the edge is dumb if(T.x>world.maxx-8 || T.x<8) continue //putting them at the edge is dumb

View File

@@ -6,7 +6,7 @@
var/cult = 0 var/cult = 0
/obj/structure/sign/double/barsign/proc/get_valid_states(initial=1) /obj/structure/sign/double/barsign/proc/get_valid_states(initial=1)
. = icon_states(icon) . = cached_icon_states(icon)
. -= "on" . -= "on"
. -= "narsiebistro" . -= "narsiebistro"
. -= "empty" . -= "empty"

View File

@@ -114,7 +114,7 @@ two tiles on initialization, and which way a cliff is facing may change during m
var/subtraction_icon_state = "[icon_state]-subtract" var/subtraction_icon_state = "[icon_state]-subtract"
var/cache_string = "[icon_state]_[T.icon]_[T.icon_state]" var/cache_string = "[icon_state]_[T.icon]_[T.icon_state]"
if(T && subtraction_icon_state in icon_states(icon)) if(T && subtraction_icon_state in cached_icon_states(icon))
cut_overlays() cut_overlays()
// If we've made the same icon before, just recycle it. // If we've made the same icon before, just recycle it.
if(cache_string in GLOB.cliff_icon_cache) if(cache_string in GLOB.cliff_icon_cache)

View File

@@ -47,6 +47,9 @@
else else
. += "<span class='notice'>There is a thick layer of silicate covering it.</span>" . += "<span class='notice'>There is a thick layer of silicate covering it.</span>"
/obj/structure/window/examine_icon()
return icon(icon=initial(icon),icon_state=initial(icon_state))
/obj/structure/window/take_damage(var/damage = 0, var/sound_effect = 1) /obj/structure/window/take_damage(var/damage = 0, var/sound_effect = 1)
var/initialhealth = health var/initialhealth = health

View File

@@ -26,9 +26,10 @@ var/list/flooring_types
var/name = "floor" var/name = "floor"
var/desc var/desc
var/icon var/icon
var/icon_base var/icon_base // initial base icon_state without edges or corners.
var/has_base_range var/has_base_range // This will pick between a range of 0 - x. Number icon_states accordingly.
// Note that this will append a 0 - x number automatically to icon_base, but NOT the dmi. Do icon_base = "grass", but name grass0 inside the dmi. etc etc.
var/has_damage_range var/has_damage_range
var/has_burn_range var/has_burn_range
var/damage_temperature var/damage_temperature
@@ -42,17 +43,69 @@ var/list/flooring_types
var/descriptor = "tiles" var/descriptor = "tiles"
var/flags var/flags
var/can_paint var/can_paint
var/list/footstep_sounds = list() // key=species name, value = list of soundss var/list/footstep_sounds = list() // key=species name, value = list of sounds,
// For instance, footstep_sounds = list("key" = list(sound.ogg))
/decl/flooring/grass /decl/flooring/grass
name = "grass" name = "grass"
desc = "Do they smoke grass out in space, Bowie? Or do they smoke AstroTurf?" desc = "Do they smoke grass out in space, Bowie? Or do they smoke AstroTurf?"
icon = 'icons/turf/flooring/grass.dmi' icon = 'icons/turf/flooring/grass.dmi'
icon_base = "grass" icon_base = "grass"
has_base_range = 3 has_base_range = 1
damage_temperature = T0C+80 damage_temperature = T0C+80
flags = TURF_HAS_EDGES | TURF_REMOVE_SHOVEL flags = TURF_HAS_EDGES | TURF_REMOVE_SHOVEL
build_type = /obj/item/stack/tile/grass build_type = /obj/item/stack/tile/grass
footstep_sounds = list("human" = list(
'sound/effects/footstep/grass1.ogg',
'sound/effects/footstep/grass2.ogg',
'sound/effects/footstep/grass3.ogg',
'sound/effects/footstep/grass4.ogg'))
/decl/flooring/grass/sif // Subtype for Sif's grass.
name = "growth"
desc = "A natural moss that has adapted to the sheer cold climate."
icon = 'icons/turf/outdoors.dmi'
icon_base = "grass_sif"
has_base_range = 1
/decl/flooring/water
name = "water"
desc = "Water is wet, gosh, who knew!"
icon = 'icons/turf/outdoors.dmi'
icon_base = "seashallow"
footstep_sounds = list("human" = list(
'sound/effects/footstep/water1.ogg',
'sound/effects/footstep/water2.ogg',
'sound/effects/footstep/water3.ogg',
'sound/effects/footstep/water4.ogg'))
/decl/flooring/sand
name = "sand"
desc = "I don't like sand. It's coarse and rough and irritating and it gets everywhere."
icon = 'icons/misc/beach.dmi'
icon_base = "sand"
footstep_sounds = list("human" = list(
'sound/effects/footstep/HeavySand1.ogg',
'sound/effects/footstep/HeavySand2.ogg',
'sound/effects/footstep/HeavySand3.ogg',
'sound/effects/footstep/HeavySand4.ogg'))
/decl/flooring/sand/desert // Subtype of sand, desert.
name = "desert"
desc = "I don't like sand. It's coarse and rough and irritating and it gets everywhere."
icon = 'icons/turf/desert.dmi'
icon_base = "desert"
/decl/flooring/mud
name = "mud"
desc = "STICKY AND WET!"
icon = 'icons/turf/outdoors.dmi'
icon_base = "mud_dark"
footstep_sounds = list("human" = list(
'sound/effects/footstep/mud1.ogg',
'sound/effects/footstep/mud2.ogg',
'sound/effects/footstep/mud3.ogg',
'sound/effects/footstep/mud4.ogg'))
/decl/flooring/asteroid /decl/flooring/asteroid
name = "coarse sand" name = "coarse sand"
@@ -61,6 +114,26 @@ var/list/flooring_types
icon_base = "asteroid" icon_base = "asteroid"
flags = TURF_HAS_EDGES | TURF_REMOVE_SHOVEL flags = TURF_HAS_EDGES | TURF_REMOVE_SHOVEL
build_type = null build_type = null
footstep_sounds = list("human" = list(
'sound/effects/footstep/asteroid1.ogg',
'sound/effects/footstep/asteroid2.ogg',
'sound/effects/footstep/asteroid3.ogg',
'sound/effects/footstep/asteroid4.ogg',
'sound/effects/footstep/asteroid5.ogg'))
/decl/flooring/dirt
name = "dirt"
desc = "Gritty and unpleasant, just like dirt."
icon = 'icons/turf/outdoors.dmi'
icon_base = "dirt-dark"
flags = TURF_HAS_EDGES | TURF_REMOVE_SHOVEL
build_type = null
footstep_sounds = list("human" = list(
'sound/effects/footstep/asteroid1.ogg',
'sound/effects/footstep/asteroid2.ogg',
'sound/effects/footstep/asteroid3.ogg',
'sound/effects/footstep/asteroid4.ogg',
'sound/effects/footstep/asteroid5.ogg'))
/decl/flooring/snow /decl/flooring/snow
name = "snow" name = "snow"
@@ -216,7 +289,7 @@ var/list/flooring_types
icon_base = "lino" icon_base = "lino"
can_paint = 1 can_paint = 1
build_type = /obj/item/stack/tile/linoleum build_type = /obj/item/stack/tile/linoleum
flags = TURF_REMOVE_SCREWDRIVER flags = TURF_REMOVE_SCREWDRIVER | TURF_CAN_BREAK | TURF_CAN_BURN
/decl/flooring/tiling/red /decl/flooring/tiling/red
name = "floor" name = "floor"
@@ -239,7 +312,6 @@ var/list/flooring_types
name = "floor" name = "floor"
icon_base = "asteroidfloor" icon_base = "asteroidfloor"
has_damage_range = null has_damage_range = null
flags = TURF_REMOVE_CROWBAR
build_type = /obj/item/stack/tile/floor/steel build_type = /obj/item/stack/tile/floor/steel
/decl/flooring/tiling/white /decl/flooring/tiling/white
@@ -252,7 +324,6 @@ var/list/flooring_types
name = "floor" name = "floor"
icon_base = "white" icon_base = "white"
has_damage_range = null has_damage_range = null
flags = TURF_REMOVE_CROWBAR
build_type = /obj/item/stack/tile/floor/yellow build_type = /obj/item/stack/tile/floor/yellow
/decl/flooring/tiling/dark /decl/flooring/tiling/dark
@@ -260,7 +331,6 @@ var/list/flooring_types
desc = "How ominous." desc = "How ominous."
icon_base = "dark" icon_base = "dark"
has_damage_range = null has_damage_range = null
flags = TURF_REMOVE_CROWBAR
build_type = /obj/item/stack/tile/floor/dark build_type = /obj/item/stack/tile/floor/dark
/decl/flooring/tiling/hydro /decl/flooring/tiling/hydro
@@ -308,20 +378,26 @@ var/list/flooring_types
desc = "Heavily reinforced with steel rods." desc = "Heavily reinforced with steel rods."
icon = 'icons/turf/flooring/tiles.dmi' icon = 'icons/turf/flooring/tiles.dmi'
icon_base = "reinforced" icon_base = "reinforced"
flags = TURF_REMOVE_WRENCH | TURF_ACID_IMMUNE flags = TURF_REMOVE_WRENCH | TURF_ACID_IMMUNE | TURF_CAN_BURN | TURF_CAN_BREAK
build_type = /obj/item/stack/rods build_type = /obj/item/stack/rods
build_cost = 2 build_cost = 2
build_time = 30 build_time = 30
apply_thermal_conductivity = 0.025 apply_thermal_conductivity = 0.025
apply_heat_capacity = 325000 apply_heat_capacity = 325000
can_paint = 1 can_paint = 1
footstep_sounds = list("human" = list(
'sound/effects/footstep/hull1.ogg',
'sound/effects/footstep/hull2.ogg',
'sound/effects/footstep/hull3.ogg',
'sound/effects/footstep/hull4.ogg',
'sound/effects/footstep/hull5.ogg'))
/decl/flooring/reinforced/circuit /decl/flooring/reinforced/circuit
name = "processing strata" name = "processing strata"
icon = 'icons/turf/flooring/circuit.dmi' icon = 'icons/turf/flooring/circuit.dmi'
icon_base = "bcircuit" icon_base = "bcircuit"
build_type = null build_type = null
flags = TURF_ACID_IMMUNE | TURF_CAN_BREAK | TURF_REMOVE_CROWBAR flags = TURF_ACID_IMMUNE | TURF_CAN_BREAK | TURF_CAN_BURN | TURF_REMOVE_CROWBAR
can_paint = 1 can_paint = 1
/decl/flooring/reinforced/circuit/green /decl/flooring/reinforced/circuit/green
@@ -337,3 +413,13 @@ var/list/flooring_types
has_damage_range = 6 has_damage_range = 6
flags = TURF_ACID_IMMUNE | TURF_CAN_BREAK flags = TURF_ACID_IMMUNE | TURF_CAN_BREAK
can_paint = null can_paint = null
/decl/flooring/lava // Defining this in case someone DOES step on lava and survive. Somehow.
name = "lava"
desc = "Lava. Y'know. Sets you on fire. AAAAAAAAAAA"
icon = 'icons/turf/outdoors.dmi'
icon_base = "lava"
footstep_sounds = list("human" = list(
'sound/effects/footstep/lava1.ogg',
'sound/effects/footstep/lava2.ogg',
'sound/effects/footstep/lava3.ogg'))

View File

@@ -387,8 +387,7 @@
name = "snow" name = "snow"
icon = 'icons/turf/snow_new.dmi' icon = 'icons/turf/snow_new.dmi'
icon_state = "snow" icon_state = "snow"
outdoors = TRUE initial_flooring = /decl/flooring/snow
movement_cost = 8
var/list/crossed_dirs = list() var/list/crossed_dirs = list()
footstep_sounds = list("human" = list( //YW edit: Should provide proper snow stepping! footstep_sounds = list("human" = list( //YW edit: Should provide proper snow stepping!
'sound/effects/footstep/snow1.ogg', 'sound/effects/footstep/snow1.ogg',

View File

@@ -1,4 +1,4 @@
var/list/flooring_cache = list() GLOBAL_LIST_EMPTY(flooring_cache)
var/image/no_ceiling_image = null var/image/no_ceiling_image = null
@@ -79,10 +79,11 @@ var/image/no_ceiling_image = null
icon = 'icons/turf/flooring/plating.dmi' icon = 'icons/turf/flooring/plating.dmi'
icon_state = "dmg[rand(1,4)]" icon_state = "dmg[rand(1,4)]"
else if(flooring) else if(flooring)
var/rand_key = rand(0,2)
if(!isnull(broken) && (flooring.flags & TURF_CAN_BREAK)) if(!isnull(broken) && (flooring.flags & TURF_CAN_BREAK))
add_overlay(get_flooring_overlay("[flooring.icon_base]-broken-[broken]","broken[broken]")) // VOREStation Edit - Eris overlays add_overlay(get_flooring_overlay("[flooring.icon_base]-broken-[rand_key]","broken[rand_key]"))
if(!isnull(burnt) && (flooring.flags & TURF_CAN_BURN)) if(!isnull(burnt) && (flooring.flags & TURF_CAN_BURN))
add_overlay(get_flooring_overlay("[flooring.icon_base]-burned-[burnt]","burned[burnt]")) // VOREStation Edit - Eris overlays add_overlay(get_flooring_overlay("[flooring.icon_base]-burned-[rand_key]","burned[rand_key]"))
if(update_neighbors) if(update_neighbors)
for(var/turf/simulated/floor/F in range(src, 1)) for(var/turf/simulated/floor/F in range(src, 1))
@@ -96,8 +97,8 @@ var/image/no_ceiling_image = null
add_overlay(no_ceiling_image) add_overlay(no_ceiling_image)
/turf/simulated/floor/proc/get_flooring_overlay(var/cache_key, var/icon_base, var/icon_dir = 0) /turf/simulated/floor/proc/get_flooring_overlay(var/cache_key, var/icon_base, var/icon_dir = 0)
if(!flooring_cache[cache_key]) if(!GLOB.flooring_cache[cache_key])
var/image/I = image(icon = flooring.icon, icon_state = icon_base, dir = icon_dir) var/image/I = image(icon = flooring.icon, icon_state = icon_base, dir = icon_dir)
I.layer = layer I.layer = layer
flooring_cache[cache_key] = I GLOB.flooring_cache[cache_key] = I
return flooring_cache[cache_key] return GLOB.flooring_cache[cache_key]

View File

@@ -13,6 +13,7 @@
movement_cost = 2 movement_cost = 2
can_build_into_floor = TRUE can_build_into_floor = TRUE
can_dirty = FALSE can_dirty = FALSE
initial_flooring = /decl/flooring/lava // Defining this in case someone DOES step on lava and survive. Somehow.
/turf/simulated/floor/lava/outdoors /turf/simulated/floor/lava/outdoors
outdoors = TRUE outdoors = TRUE

View File

@@ -1,6 +1,7 @@
/turf/simulated/floor/outdoors/dirt /turf/simulated/floor/outdoors/dirt
name = "dirt" name = "dirt"
desc = "Quite dirty!" desc = "Quite dirty!"
icon_state = "dirt-dark" icon_state = "dirt-dark"
edge_blending_priority = 2 edge_blending_priority = 2
turf_layers = list(/turf/simulated/floor/outdoors/rocks) turf_layers = list(/turf/simulated/floor/outdoors/rocks)
initial_flooring = /decl/flooring/asteroid

View File

@@ -4,21 +4,22 @@ var/list/grass_types = list(
/turf/simulated/floor/outdoors/grass /turf/simulated/floor/outdoors/grass
name = "grass" name = "grass"
icon_state = "grass" icon_state = "grass0"
edge_blending_priority = 4 edge_blending_priority = 4
initial_flooring = /decl/flooring/grass
turf_layers = list( turf_layers = list(
/turf/simulated/floor/outdoors/rocks, /turf/simulated/floor/outdoors/rocks,
/turf/simulated/floor/outdoors/dirt /turf/simulated/floor/outdoors/dirt
) )
var/grass_chance = 20 var/grass_chance = 20
/*
var/animal_chance = 1 var/animal_chance = 1
// Weighted spawn list. // Weighted spawn list.
var/list/animal_types = list( var/list/animal_types = list(
/mob/living/simple_mob/animal/passive/tindalos = 1 /mob/living/simple_mob/animal/passive/tindalos = 1
) )
*/
var/list/grass_types = list( var/list/grass_types = list(
/obj/structure/flora/ausbushes/sparsegrass, /obj/structure/flora/ausbushes/sparsegrass,
/obj/structure/flora/ausbushes/fullgrass /obj/structure/flora/ausbushes/fullgrass
@@ -34,12 +35,13 @@ var/list/grass_types = list(
/turf/simulated/floor/outdoors/grass/sif /turf/simulated/floor/outdoors/grass/sif
name = "growth" name = "growth"
icon_state = "grass_sif" icon_state = "grass_sif0"
initial_flooring = /decl/flooring/grass/sif
edge_blending_priority = 4 edge_blending_priority = 4
grass_chance = 5 grass_chance = 5
var/tree_chance = 2 var/tree_chance = 2
/*
animal_chance = 0 //VOREStation Edit animal_chance = 0.5
animal_types = list( animal_types = list(
/mob/living/simple_mob/animal/sif/diyaab = 10, /mob/living/simple_mob/animal/sif/diyaab = 10,
@@ -48,7 +50,7 @@ var/list/grass_types = list(
/mob/living/simple_mob/animal/sif/shantak/retaliate = 2, /mob/living/simple_mob/animal/sif/shantak/retaliate = 2,
/obj/random/mob/multiple/sifmobs = 1 /obj/random/mob/multiple/sifmobs = 1
) )
*/
grass_types = list( grass_types = list(
/obj/structure/flora/sif/eyes = 1, /obj/structure/flora/sif/eyes = 1,
/obj/structure/flora/sif/tendrils = 10 /obj/structure/flora/sif/tendrils = 10
@@ -63,30 +65,26 @@ var/list/grass_types = list(
. = ..() . = ..()
/turf/simulated/floor/outdoors/grass/Initialize() /turf/simulated/floor/outdoors/grass/Initialize()
if(prob(50))
icon_state = "[initial(icon_state)]2"
//edge_blending_priority++
if(grass_chance && prob(grass_chance) && !check_density()) if(grass_chance && prob(grass_chance) && !check_density())
var/grass_type = pickweight(grass_types) var/grass_type = pickweight(grass_types)
new grass_type(src) new grass_type(src)
/*
if(animal_chance && prob(animal_chance) && !check_density()) if(animal_chance && prob(animal_chance) && !check_density())
var/animal_type = pickweight(animal_types) var/animal_type = pickweight(animal_types)
new animal_type(src) new animal_type(src)
*/
. = ..() . = ..()
/turf/simulated/floor/outdoors/grass/forest /turf/simulated/floor/outdoors/grass/forest
name = "thick grass" name = "thick grass"
icon_state = "grass-dark" icon_state = "grass-dark0"
grass_chance = 80 grass_chance = 80
//tree_chance = 20 //tree_chance = 20
edge_blending_priority = 5 edge_blending_priority = 5
/turf/simulated/floor/outdoors/grass/sif/forest /turf/simulated/floor/outdoors/grass/sif/forest
name = "thick growth" name = "thick growth"
icon_state = "grass_sif_dark" icon_state = "grass_sif_dark0"
edge_blending_priority = 5 edge_blending_priority = 5
tree_chance = 10 tree_chance = 10
grass_chance = 0 grass_chance = 0

View File

@@ -81,6 +81,7 @@ var/list/turf_edge_cache = list()
name = "mud" name = "mud"
icon_state = "mud_dark" icon_state = "mud_dark"
edge_blending_priority = 3 edge_blending_priority = 3
initial_flooring = /decl/flooring/mud
/turf/simulated/floor/outdoors/rocks /turf/simulated/floor/outdoors/rocks
name = "rocks" name = "rocks"

View File

@@ -67,7 +67,7 @@
I.color = reinf_material.icon_colour I.color = reinf_material.icon_colour
add_overlay(I) add_overlay(I)
else else
if("[reinf_material.icon_reinf]0" in icon_states('icons/turf/wall_masks.dmi')) if("[reinf_material.icon_reinf]0" in cached_icon_states('icons/turf/wall_masks.dmi'))
// Directional icon // Directional icon
for(var/i = 1 to 4) for(var/i = 1 to 4)
I = image('icons/turf/wall_masks.dmi', "[reinf_material.icon_reinf][wall_connections[i]]", dir = 1<<(i-1)) I = image('icons/turf/wall_masks.dmi', "[reinf_material.icon_reinf][wall_connections[i]]", dir = 1<<(i-1))

View File

@@ -46,6 +46,9 @@
dismantle_wall(null,null,1) dismantle_wall(null,null,1)
..() ..()
/turf/simulated/wall/examine_icon()
return icon(icon=initial(icon), icon_state=initial(icon_state))
/turf/simulated/wall/process() /turf/simulated/wall/process()
// Calling parent will kill processing // Calling parent will kill processing
if(!radiate()) if(!radiate())

View File

@@ -20,6 +20,8 @@
/turf/simulated/floor/water/Initialize() /turf/simulated/floor/water/Initialize()
. = ..() . = ..()
var/decl/flooring/F = get_flooring_data(/decl/flooring/water)
footstep_sounds = F?.footstep_sounds
update_icon() update_icon()
handle_fish() handle_fish()

View File

@@ -15,6 +15,7 @@
name = "Water" name = "Water"
icon_state = "water" icon_state = "water"
initialized = FALSE initialized = FALSE
movement_cost = 4 // Water should slow you down, just like simulated turf.
/turf/unsimulated/beach/water/Initialize() /turf/unsimulated/beach/water/Initialize()
. = ..() . = ..()
@@ -23,20 +24,17 @@
/turf/simulated/floor/beach /turf/simulated/floor/beach
name = "Beach" name = "Beach"
icon = 'icons/misc/beach.dmi' icon = 'icons/misc/beach.dmi'
footstep_sounds = list("human" = list( initial_flooring = /decl/flooring/sand
'sound/effects/footstep/carpet1.ogg',
'sound/effects/footstep/carpet2.ogg',
'sound/effects/footstep/carpet3.ogg',
'sound/effects/footstep/carpet4.ogg',
'sound/effects/footstep/carpet5.ogg'))
/turf/simulated/floor/beach/sand /turf/simulated/floor/beach/sand
name = "Sand" name = "Sand"
icon_state = "sand" icon_state = "sand"
initial_flooring = /decl/flooring/sand
/turf/simulated/floor/beach/sand/desert /turf/simulated/floor/beach/sand/desert
icon = 'icons/turf/desert.dmi' icon = 'icons/turf/desert.dmi'
icon_state = "desert" icon_state = "desert"
initial_flooring = /decl/flooring/sand/desert
/turf/simulated/floor/beach/sand/desert/Initialize() /turf/simulated/floor/beach/sand/desert/Initialize()
. = ..() . = ..()
@@ -51,10 +49,24 @@
/turf/simulated/floor/beach/water /turf/simulated/floor/beach/water
name = "Water" name = "Water"
icon_state = "water" icon_state = "water"
movement_cost = 4 // Water should slow you down, just like the original simulated turf.
initial_flooring = /decl/flooring/water
/turf/simulated/floor/beach/water/ocean /turf/simulated/floor/beach/water/ocean
icon_state = "seadeep" icon_state = "seadeep"
movement_cost = 8 // Deep water should be difficult to wade through.
initial_flooring = /decl/flooring/water/beach/deep
/turf/simulated/floor/beach/water/Initialize() /turf/simulated/floor/beach/water/Initialize()
. = ..() . = ..()
add_overlay(image("icon"='icons/misc/beach.dmi',"icon_state"="water5","layer"=MOB_LAYER+0.1)) add_overlay(image("icon"='icons/misc/beach.dmi',"icon_state"="water5","layer"=MOB_LAYER+0.1))
/decl/flooring/water/beach/deep // We're custom-defining a 'deep' water turf for the beach.
name = "deep water"
desc = "Deep Ocean Water"
icon = 'icons/misc/beach.dmi'
icon_base = "seadeep"
footstep_sounds = list("human" = list(
'sound/effects/footstep/bubbles3.ogg', // No I don't get why it's named 3/4/5 either. Whatever.
'sound/effects/footstep/bubbles4.ogg',
'sound/effects/footstep/bubbles5.ogg'))

View File

@@ -15,6 +15,8 @@
if(byond_version < RECOMMENDED_VERSION) if(byond_version < RECOMMENDED_VERSION)
to_world_log("Your server's byond version does not meet the recommended requirements for this server. Please update BYOND") to_world_log("Your server's byond version does not meet the recommended requirements for this server. Please update BYOND")
TgsNew()
config.post_load() config.post_load()
if(config && config.server_name != null && config.server_suffix && world.port > 0) if(config && config.server_name != null && config.server_suffix && world.port > 0)
@@ -25,7 +27,7 @@
// if(config && config.log_runtime) // if(config && config.log_runtime)
// log = file("data/logs/runtime/[time2text(world.realtime,"YYYY-MM-DD-(hh-mm-ss)")]-runtime.log") // log = file("data/logs/runtime/[time2text(world.realtime,"YYYY-MM-DD-(hh-mm-ss)")]-runtime.log")
GLOB.timezoneOffset = text2num(time2text(0,"hh")) * 36000 GLOB.timezoneOffset = get_timezone_offset()
callHook("startup") callHook("startup")
init_vchat() init_vchat()
@@ -62,7 +64,7 @@
master_controller = new /datum/controller/game_controller() master_controller = new /datum/controller/game_controller()
Master.Initialize(10, FALSE) Master.Initialize(10, FALSE, TRUE)
spawn(1) spawn(1)
master_controller.setup() master_controller.setup()
@@ -82,6 +84,7 @@ var/world_topic_spam_protect_ip = "0.0.0.0"
var/world_topic_spam_protect_time = world.timeofday var/world_topic_spam_protect_time = world.timeofday
/world/Topic(T, addr, master, key) /world/Topic(T, addr, master, key)
TGS_TOPIC
log_topic("\"[T]\", from:[addr], master:[master], key:[key]") log_topic("\"[T]\", from:[addr], master:[master], key:[key]")
if (T == "ping") if (T == "ping")
@@ -409,6 +412,7 @@ var/world_topic_spam_protect_time = world.timeofday
if(config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite if(config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
C << link("byond://[config.server]") C << link("byond://[config.server]")
TgsReboot()
log_world("World rebooted at [time_stamp()]") log_world("World rebooted at [time_stamp()]")
..() ..()

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