mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2026-01-06 15:34:35 +00:00
Merge branch 'master' into ProteanNerf
This commit is contained in:
@@ -96,15 +96,6 @@
|
||||
"You hear a ratchet.")
|
||||
deconstruct()
|
||||
|
||||
/obj/machinery/atmospherics/omni/can_unwrench()
|
||||
var/int_pressure = 0
|
||||
for(var/datum/omni_port/P in ports)
|
||||
int_pressure += P.air.return_pressure()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if((int_pressure - env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/omni/attack_hand(user as mob)
|
||||
if(..())
|
||||
return
|
||||
|
||||
@@ -173,6 +173,5 @@ What is the naming convention for planes or layers?
|
||||
plane = initial(plane)
|
||||
layer = initial(layer)
|
||||
|
||||
|
||||
// Check if a mob can "logically" see an atom plane
|
||||
#define MOB_CAN_SEE_PLANE(M, P) (P <= PLANE_WORLD || (P in M.planes_visible))
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define DM_FLAG_STRIPPING 0x2
|
||||
#define DM_FLAG_LEAVEREMAINS 0x4
|
||||
#define DM_FLAG_THICKBELLY 0x8
|
||||
#define DM_FLAG_AFFECTWORN 0x10
|
||||
|
||||
//Item related modes
|
||||
#define IM_HOLD "Hold"
|
||||
|
||||
@@ -61,4 +61,8 @@
|
||||
#define INFECTION_LEVEL_ONE 100
|
||||
#define INFECTION_LEVEL_TWO 500
|
||||
#define INFECTION_LEVEL_THREE 1000
|
||||
#define INFECTION_LEVEL_MAX 1500
|
||||
#define INFECTION_LEVEL_MAX 1500
|
||||
|
||||
#define MODULAR_BODYPART_INVALID 0 // Cannot be detached or reattached.
|
||||
#define MODULAR_BODYPART_PROSTHETIC 1 // Can be detached or reattached freely.
|
||||
#define MODULAR_BODYPART_CYBERNETIC 2 // Can be detached or reattached to compatible parent organs.
|
||||
|
||||
@@ -157,6 +157,16 @@
|
||||
#define MAT_GRAPHITE "graphite"
|
||||
#define MAT_LEATHER "leather"
|
||||
#define MAT_CHITIN "chitin"
|
||||
#define MAT_CLOTH "cloth"
|
||||
#define MAT_SYNCLOTH "syncloth"
|
||||
#define MAT_COPPER "copper"
|
||||
#define MAT_QUARTZ "quartz"
|
||||
#define MAT_TIN "tin"
|
||||
#define MAT_VOPAL "void opal"
|
||||
#define MAT_ALUMINIUM "aluminium"
|
||||
#define MAT_BRONZE "bronze"
|
||||
#define MAT_PAINITE "painite"
|
||||
#define MAT_BOROSILICATE "borosilicate glass"
|
||||
|
||||
#define SHARD_SHARD "shard"
|
||||
#define SHARD_SHRAPNEL "shrapnel"
|
||||
|
||||
@@ -160,12 +160,6 @@
|
||||
#define FLASH_PROTECTION_MODERATE 1
|
||||
#define FLASH_PROTECTION_MAJOR 2
|
||||
|
||||
#define ANIMAL_SPAWN_DELAY round(config.respawn_delay / 6)
|
||||
#define DRONE_SPAWN_DELAY round(config.respawn_delay / 3)
|
||||
|
||||
#define ANIMAL_SPAWN_DELAY round(config.respawn_delay / 6)
|
||||
#define DRONE_SPAWN_DELAY round(config.respawn_delay / 3)
|
||||
|
||||
// Incapacitation flags, used by the mob/proc/incapacitated() proc
|
||||
#define INCAPACITATION_RESTRAINED 1
|
||||
#define INCAPACITATION_BUCKLED_PARTIALLY 2
|
||||
|
||||
@@ -24,6 +24,30 @@
|
||||
#define EMP_TOX_DMG 0x80 // EMPs inflict toxin damage
|
||||
#define EMP_OXY_DMG 0x100 // EMPs inflict oxy damage
|
||||
|
||||
// Species allergens
|
||||
#define MEAT 0x1 // Skrell won't like this.
|
||||
#define FISH 0x2 // Seperate for completion's sake. Still bad for skrell.
|
||||
#define FRUIT 0x4 // An apple a day only keeps the doctor away if they're allergic.
|
||||
#define VEGETABLE 0x8 // Taters 'n' carrots. Potato allergy is a thing, apparently.
|
||||
#define GRAINS 0x10 // Wheat, oats, etc.
|
||||
#define BEANS 0x20 // The musical fruit! Includes soy.
|
||||
#define SEEDS 0x40 // Hope you don't have a nut allergy.
|
||||
#define DAIRY 0x80 // Lactose intolerance, ho! Also bad for skrell.
|
||||
#define FUNGI 0x100 // Delicious shrooms.
|
||||
#define COFFEE 0x200 // Mostly here for tajara.
|
||||
#define GENERIC 0x400 // Catchall for stuff that doesn't fall into the groups above. You shouldn't be allergic to this type, ever.
|
||||
#define SUGARS 0x800 // For unathi-like reactions
|
||||
#define EGGS 0x1000 // For Skrell eggs allergy
|
||||
|
||||
// Allergen reactions
|
||||
#define AG_TOX_DMG 0x1 // the classic
|
||||
#define AG_OXY_DMG 0x2 // intense airway reactions
|
||||
#define AG_EMOTE 0x4 // general emote reactions based on affect type
|
||||
#define AG_PAIN 0x8 // short-lived hurt
|
||||
#define AG_WEAKEN 0x10 // too weak to move, oof
|
||||
#define AG_BLURRY 0x20 // blurred vision!
|
||||
#define AG_SLEEPY 0x40 // fatigue/exhaustion
|
||||
|
||||
// Species spawn flags
|
||||
#define SPECIES_IS_WHITELISTED 0x1 // Must be whitelisted to play.
|
||||
#define SPECIES_IS_RESTRICTED 0x2 // Is not a core/normally playable species. (castes, mutantraces)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#define LANGUAGE_ENOCHIAN "Enochian"
|
||||
#define LANGUAGE_VESPINAE "Vespinae"
|
||||
#define LANGUAGE_SPACER "Spacer"
|
||||
#define LANGUAGE_CLOWNISH "Coulrian"
|
||||
|
||||
#define LANGUAGE_CHIMPANZEE "Chimpanzee"
|
||||
#define LANGUAGE_NEAERA "Neaera"
|
||||
|
||||
@@ -52,6 +52,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
|
||||
// Subsystem init_order, from highest priority to lowest priority
|
||||
// Subsystems shutdown in the reverse of the order they initialize in
|
||||
// The numbers just define the ordering, they are meaningless otherwise.
|
||||
#define INIT_ORDER_DBCORE 41 //CHOMPEdit
|
||||
#define INIT_ORDER_SQLITE 40
|
||||
#define INIT_ORDER_CHEMISTRY 35
|
||||
#define INIT_ORDER_SKYBOX 30
|
||||
|
||||
@@ -1,254 +1,351 @@
|
||||
//tgstation-server DMAPI
|
||||
// tgstation-server DMAPI
|
||||
|
||||
#define TGS_DMAPI_VERSION "5.1.1"
|
||||
#define TGS_DMAPI_VERSION "6.0.3"
|
||||
|
||||
//All functions and datums outside this document are subject to change with any version and should not be relied on
|
||||
// All functions and datums outside this document are subject to change with any version and should not be relied on.
|
||||
|
||||
//CONFIGURATION
|
||||
// CONFIGURATION
|
||||
|
||||
//create this define if you want to do configuration outside of this file
|
||||
/// Create this define if you want to do TGS configuration outside of this file.
|
||||
#ifndef TGS_EXTERNAL_CONFIGURATION
|
||||
|
||||
//Comment this out once you've filled in the below
|
||||
// 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
|
||||
// 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):
|
||||
// Required interfaces (fill in with your codebase equivalent):
|
||||
|
||||
//create a global variable named `Name` and set it to `Value`
|
||||
/// 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`
|
||||
/// Read the value in the global variable `Name`.
|
||||
#define TGS_READ_GLOBAL(Name)
|
||||
|
||||
//Set the value in the global variable `Name` to `Value`
|
||||
/// 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
|
||||
/// 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
|
||||
/// Display an announcement `message` from the server to all players.
|
||||
#define TGS_WORLD_ANNOUNCE(message)
|
||||
|
||||
//Notify current in-game administrators of a string `event`
|
||||
/// Notify current in-game administrators of a string `event`.
|
||||
#define TGS_NOTIFY_ADMINS(event)
|
||||
|
||||
//Write an info `message` to a server log
|
||||
/// Write an info `message` to a server log.
|
||||
#define TGS_INFO_LOG(message)
|
||||
|
||||
//Write an warning `message` to a server log
|
||||
/// Write an warning `message` to a server log.
|
||||
#define TGS_WARNING_LOG(message)
|
||||
|
||||
//Write an error `message` to a server log
|
||||
/// Write an error `message` to a server log.
|
||||
#define TGS_ERROR_LOG(message)
|
||||
|
||||
//Get the number of connected /clients
|
||||
/// Get the number of connected /clients.
|
||||
#define TGS_CLIENT_COUNT
|
||||
|
||||
#endif
|
||||
|
||||
//EVENT CODES
|
||||
// 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 parameter is the new name
|
||||
#define TGS_EVENT_WATCHDOG_REATTACH -4 //After the watchdog reattaches to DD, extra parameter is the new /datum/tgs_version of the server
|
||||
/// Before a reboot mode change, extras parameters are the current and new reboot mode enums
|
||||
#define TGS_EVENT_REBOOT_MODE_CHANGE -1
|
||||
/// Before a port change is about to happen, extra parameters is new port
|
||||
#define TGS_EVENT_PORT_SWAP -2
|
||||
/// Before the instance is renamed, extra parameter is the new name
|
||||
#define TGS_EVENT_INSTANCE_RENAMED -3
|
||||
/// After the watchdog reattaches to DD, extra parameter is the new [/datum/tgs_version] of the server
|
||||
#define TGS_EVENT_WATCHDOG_REATTACH -4
|
||||
|
||||
//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
|
||||
/// When the repository is reset to its origin reference. Parameters: Reference name, Commit SHA
|
||||
#define TGS_EVENT_REPO_RESET_ORIGIN 0
|
||||
/// When the repository performs a checkout. Parameters: Checkout git object
|
||||
#define TGS_EVENT_REPO_CHECKOUT 1
|
||||
/// When the repository performs a fetch operation. No parameters
|
||||
#define TGS_EVENT_REPO_FETCH 2
|
||||
/// When the repository test merges. Parameters: PR Number, PR Sha, (Nullable) Comment made by TGS user
|
||||
#define TGS_EVENT_REPO_MERGE_PULL_REQUEST 3
|
||||
/// Before the repository makes a sychronize operation. Parameters: Absolute repostiory path
|
||||
#define TGS_EVENT_REPO_PRE_SYNCHRONIZE 4
|
||||
/// Before a BYOND install operation begins. Parameters: [/datum/tgs_version] of the installing BYOND
|
||||
#define TGS_EVENT_BYOND_INSTALL_START 5
|
||||
/// When a BYOND install operation fails. Parameters: Error message
|
||||
#define TGS_EVENT_BYOND_INSTALL_FAIL 6
|
||||
/// When the active BYOND version changes. Parameters: (Nullable) [/datum/tgs_version] of the current BYOND, [/datum/tgs_version] of the new BYOND
|
||||
#define TGS_EVENT_BYOND_ACTIVE_VERSION_CHANGE 7
|
||||
/// When the compiler starts running. Parameters: Game directory path, origin commit SHA
|
||||
#define TGS_EVENT_COMPILE_START 8
|
||||
/// When a compile is cancelled. No parameters
|
||||
#define TGS_EVENT_COMPILE_CANCELLED 9
|
||||
/// When a compile fails. Parameters: Game directory path, [TRUE]/[FALSE] based on if the cause for failure was DMAPI validation
|
||||
#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
|
||||
/// When a compile operation completes. Note, this event fires before the new .dmb is loaded into the watchdog. Consider using the [TGS_EVENT_DEPLOYMENT_COMPLETE] instead. Parameters: Game directory path
|
||||
#define TGS_EVENT_COMPILE_COMPLETE 11
|
||||
/// When an automatic update for the current instance begins. No parameters
|
||||
#define TGS_EVENT_INSTANCE_AUTO_UPDATE_START 12
|
||||
/// When the repository encounters a merge conflict: Parameters: Base SHA, target SHA, base reference, target reference
|
||||
#define TGS_EVENT_REPO_MERGE_CONFLICT 13
|
||||
/// When a deployment completes. No Parameters
|
||||
#define TGS_EVENT_DEPLOYMENT_COMPLETE 14
|
||||
/// Before the watchdog shuts down. Not sent for graceful shutdowns. No parameters.
|
||||
#define TGS_EVENT_WATCHDOG_SHUTDOWN 15
|
||||
/// Before the watchdog detaches for a TGS update/restart. No parameters.
|
||||
#define TGS_EVENT_WATCHDOG_DETACH 16
|
||||
// We don't actually implement these 4 events as the DMAPI can never receive them.
|
||||
// #define TGS_EVENT_WATCHDOG_LAUNCH 17
|
||||
// #define TGS_EVENT_WATCHDOG_CRASH 18
|
||||
// #define TGS_EVENT_WORLD_END_PROCESS 19
|
||||
// #define TGS_EVENT_WORLD_REBOOT 20
|
||||
/// Watchdog event when TgsInitializationComplete() is called. No parameters.
|
||||
#define TGS_EVENT_WORLD_PRIME 21
|
||||
|
||||
//OTHER ENUMS
|
||||
// OTHER ENUMS
|
||||
|
||||
/// The server will reboot normally.
|
||||
#define TGS_REBOOT_MODE_NORMAL 0
|
||||
/// The server will stop running on reboot.
|
||||
#define TGS_REBOOT_MODE_SHUTDOWN 1
|
||||
/// The watchdog will restart on reboot.
|
||||
#define TGS_REBOOT_MODE_RESTART 2
|
||||
|
||||
/// DreamDaemon Trusted security level.
|
||||
#define TGS_SECURITY_TRUSTED 0
|
||||
/// DreamDaemon Safe security level.
|
||||
#define TGS_SECURITY_SAFE 1
|
||||
/// DreamDaemon Ultrasafe security level.
|
||||
#define TGS_SECURITY_ULTRASAFE 2
|
||||
|
||||
//REQUIRED HOOKS
|
||||
|
||||
//Call this somewhere in /world/New() that is always run
|
||||
//IMPORTANT: This function may sleep!
|
||||
//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
|
||||
/**
|
||||
* Call this somewhere in [/world/proc/New] that is always run. This function may sleep!
|
||||
*
|
||||
* * event_handler - Optional user defined [/datum/tgs_event_handler].
|
||||
* * minimum_required_security_level: The minimum required security level to run the game in which the DMAPI is integrated. Can be one of [TGS_SECURITY_ULTRASAFE], [TGS_SECURITY_SAFE], or [TGS_SECURITY_TRUSTED].
|
||||
*/
|
||||
/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()
|
||||
/**
|
||||
* Call this when your initializations are complete and your game is ready to play before any player interactions happen.
|
||||
*
|
||||
* This may use [/world/var/sleep_offline] to make this happen so ensure no changes are made to it while this call is running.
|
||||
* Afterwards, consider explicitly setting it to what you want to avoid this BYOND bug: http://www.byond.com/forum/post/2575184
|
||||
* This function should not be called before ..() in [/world/proc/New].
|
||||
*/
|
||||
/world/proc/TgsInitializationComplete()
|
||||
return
|
||||
|
||||
//Put this at the start of /world/Topic()
|
||||
/// Put this at the start of [/world/proc/Topic].
|
||||
#define TGS_TOPIC var/tgs_topic_return = TgsTopic(args[1]); if(tgs_topic_return) return tgs_topic_return
|
||||
#define VGS_TOPIC var/vgs_topic_return = VgsTopic(args[1]); if(vgs_topic_return) return vgs_topic_return // VOREStation Edit - VGS
|
||||
|
||||
//Call this at the beginning of world/Reboot(reason)
|
||||
/**
|
||||
* Call this as late as possible in [world/proc/Reboot].
|
||||
*/
|
||||
/world/proc/TgsReboot()
|
||||
return
|
||||
|
||||
//DATUM DEFINITIONS
|
||||
//unless otherwise specified all datums defined here should be considered read-only, warranty void if written
|
||||
// DATUM DEFINITIONS
|
||||
// All datums defined here should be considered read-only
|
||||
|
||||
//represents git revision information about the current world build
|
||||
/// Represents git revision information.
|
||||
/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
|
||||
/// Full SHA of the commit.
|
||||
var/commit
|
||||
/// ISO 8601 timestamp of when the commit was created
|
||||
var/timestamp
|
||||
/// Full sha of last known remote commit. This may be null if the TGS repository is not currently tracking a remote branch.
|
||||
var/origin_commit
|
||||
|
||||
//represents a version of tgstation-server
|
||||
/// Represents a version.
|
||||
/datum/tgs_version
|
||||
var/suite //The suite/major version, can be >=3
|
||||
/// The suite/major version number
|
||||
var/suite
|
||||
|
||||
//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
|
||||
// This group of variables can be null to represent a wild card
|
||||
/// The minor version number. null for wildcards
|
||||
var/minor
|
||||
/// The patch version number. null for wildcards
|
||||
var/patch
|
||||
|
||||
var/raw_parameter //The unparsed parameter
|
||||
var/deprefixed_parameter //The version only bit of raw_parameter
|
||||
/// Legacy version number. Generally null
|
||||
var/deprecated_patch
|
||||
|
||||
//if the tgs_version is a wildcard version
|
||||
/// Unparsed string value
|
||||
var/raw_parameter
|
||||
/// String value minus prefix
|
||||
var/deprefixed_parameter
|
||||
|
||||
/**
|
||||
* Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] contains wildcards.
|
||||
*/
|
||||
/datum/tgs_version/proc/Wildcard()
|
||||
return
|
||||
|
||||
//if the tgs_version equals some other_version
|
||||
/**
|
||||
* Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] equals some other version.
|
||||
*
|
||||
* other_version - The [/datum/tgs_version] to compare against.
|
||||
*/
|
||||
/datum/tgs_version/proc/Equals(datum/tgs_version/other_version)
|
||||
return
|
||||
|
||||
//represents a merge of a GitHub pull request
|
||||
/// 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
|
||||
/// The test merge number.
|
||||
var/number
|
||||
/// The test merge source's title when it was merged.
|
||||
var/title
|
||||
/// The test merge source's body when it was merged.
|
||||
var/body
|
||||
/// The Username of the test merge source's author.
|
||||
var/author
|
||||
/// An http URL to the test merge source.
|
||||
var/url
|
||||
/// The SHA of the test merge when that was merged.
|
||||
var/head_commit
|
||||
/// Optional comment left by the TGS user who initiated the merge.
|
||||
var/comment
|
||||
|
||||
//represents a connected chat channel
|
||||
/// 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
|
||||
/// TGS internal channel ID.
|
||||
var/id
|
||||
/// User friendly name of the channel.
|
||||
var/friendly_name
|
||||
/// Name of the chat connection. This is the IRC server address or the Discord guild.
|
||||
var/connection_name
|
||||
/// [TRUE]/[FALSE] based on if the server operator has marked this channel for game admins only.
|
||||
var/is_admin_channel
|
||||
/// [TRUE]/[FALSE] if the channel is a private message channel for a [/datum/tgs_chat_user].
|
||||
var/is_private_channel
|
||||
/// Tag string associated with the channel in TGS
|
||||
var/custom_tag
|
||||
|
||||
//represents a chat user
|
||||
// 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
|
||||
/// TGS internal user ID.
|
||||
var/id
|
||||
// The user's display name.
|
||||
var/friendly_name
|
||||
// The string to use to ping this user in a message.
|
||||
var/mention
|
||||
/// The [/datum/tgs_chat_channel] the user was from
|
||||
var/datum/tgs_chat_channel/channel
|
||||
|
||||
//user definable callback for handling events
|
||||
//extra parameters may be specified depending on the event
|
||||
/**
|
||||
* User definable callback for handling TGS events.
|
||||
*
|
||||
* event_code - One of the TGS_EVENT_ defines. Extra parameters will be documented in each
|
||||
*/
|
||||
/datum/tgs_event_handler/proc/HandleEvent(event_code, ...)
|
||||
set waitfor = FALSE
|
||||
return
|
||||
|
||||
//user definable chat command
|
||||
/// 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
|
||||
/// The string to trigger this command on a chat bot. e.g `@bot name ...` or `!tgs name ...`
|
||||
var/name = ""
|
||||
/// The help text displayed for this command
|
||||
var/help_text = ""
|
||||
/// If this command should be available to game administrators only
|
||||
var/admin_only = FALSE
|
||||
|
||||
//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
|
||||
/**
|
||||
* Process command activation. Should return a string to respond to the issuer with.
|
||||
*
|
||||
* sender - The [/datum/tgs_chat_user] who issued the command.
|
||||
* params - The trimmed string following the command `/datum/tgs_chat_command/var/name].
|
||||
*/
|
||||
/datum/tgs_chat_command/proc/Run(datum/tgs_chat_user/sender, params)
|
||||
CRASH("[type] has no implementation for Run()")
|
||||
|
||||
//FUNCTIONS
|
||||
// API FUNCTIONS
|
||||
|
||||
//Returns the respective supported /datum/tgs_version of the API
|
||||
/world/proc/TgsMaximumAPIVersion()
|
||||
/// Returns the maximum supported [/datum/tgs_version] of the DMAPI.
|
||||
/world/proc/TgsMaximumApiVersion()
|
||||
return
|
||||
|
||||
/world/proc/TgsMinimumAPIVersion()
|
||||
/// Returns the minimum supported [/datum/tgs_version] of the DMAPI.
|
||||
/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
|
||||
/**
|
||||
* Returns [TRUE] if DreamDaemon was launched under TGS, the API matches, and was properly initialized. [FALSE] will be returned otherwise.
|
||||
*/
|
||||
/world/proc/TgsAvailable()
|
||||
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
|
||||
// No function below this succeeds if it TgsAvailable() returns FALSE or if TgsNew() has yet to be called.
|
||||
|
||||
/**
|
||||
* Forces a hard reboot of DreamDaemon by ending the process.
|
||||
*
|
||||
* Unlike del(world) clients will try to reconnect.
|
||||
* If TGS has not requested a [TGS_REBOOT_MODE_SHUTDOWN] DreamDaemon will be launched again
|
||||
*/
|
||||
/world/proc/TgsEndProcess()
|
||||
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)
|
||||
/**
|
||||
* Send a message to connected chats.
|
||||
*
|
||||
* message - The string to send.
|
||||
* admin_only: If [TRUE], message will be sent to admin connected chats. Vice-versa applies.
|
||||
*/
|
||||
/world/proc/TgsTargetedChatBroadcast(message, admin_only = FALSE)
|
||||
return
|
||||
|
||||
//Send a private message to a specific user
|
||||
//message: The message to send
|
||||
//user: The /datum/tgs_chat_user to send to
|
||||
/**
|
||||
* Send a private message to a specific user.
|
||||
*
|
||||
* message - The string to send.
|
||||
* user: The [/datum/tgs_chat_user] to PM.
|
||||
*/
|
||||
/world/proc/TgsChatPrivateMessage(message, datum/tgs_chat_user/user)
|
||||
return
|
||||
|
||||
//The following functions will sleep if a call to TgsNew() is sleeping
|
||||
// The following functions will sleep if a call to TgsNew() is sleeping
|
||||
|
||||
//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)
|
||||
/**
|
||||
* Send a message to connected chats that are flagged as game-related in TGS.
|
||||
*
|
||||
* message - The string to send.
|
||||
* channels - Optional list of [/datum/tgs_chat_channel]s to restrict the message to.
|
||||
*/
|
||||
/world/proc/TgsChatBroadcast(message, list/channels = null)
|
||||
return
|
||||
|
||||
//Gets the current /datum/tgs_version of the server tools running the server
|
||||
/// Returns the current [/datum/tgs_version] of TGS if it is running the server, null otherwise.
|
||||
/world/proc/TgsVersion()
|
||||
return
|
||||
|
||||
//Gets the current /datum/tgs_version of the DMAPI being used
|
||||
/// Returns the current [/datum/tgs_version] of the DMAPI being used if it was activated, null otherwise.
|
||||
/world/proc/TgsApiVersion()
|
||||
return
|
||||
|
||||
//Gets the name of the TGS instance running the game
|
||||
/// Returns the name of the TGS instance running the game if TGS is present, null otherwise.
|
||||
/world/proc/TgsInstanceName()
|
||||
return
|
||||
|
||||
//Get the current `/datum/tgs_revision_information`
|
||||
/// Return the current [/datum/tgs_revision_information] of the running server if TGS is present, null otherwise.
|
||||
/world/proc/TgsRevision()
|
||||
return
|
||||
|
||||
//Get the current BYOND security level
|
||||
/// Returns the current BYOND security level as a TGS_SECURITY_ define if TGS is present, null otherwise.
|
||||
/world/proc/TgsSecurityLevel()
|
||||
return
|
||||
|
||||
//Gets a list of active `/datum/tgs_revision_information/test_merge`s
|
||||
/// Returns a list of active [/datum/tgs_revision_information/test_merge]s if TGS is present, null otherwise.
|
||||
/world/proc/TgsTestMerges()
|
||||
return
|
||||
|
||||
//Gets a list of connected tgs_chat_channel
|
||||
/// Returns a list of connected [/datum/tgs_chat_channel]s if TGS is present, null otherwise.
|
||||
/world/proc/TgsChatChannelInfo()
|
||||
return
|
||||
|
||||
|
||||
@@ -5,4 +5,7 @@ GLOBAL_LIST_EMPTY(meteor_list)
|
||||
GLOBAL_LIST_EMPTY(wire_color_directory) // This is an associative list with the `holder_type` as the key, and a list of colors as the value.
|
||||
|
||||
// Reference list for disposal sort junctions. Filled up by sorting junction's New()
|
||||
GLOBAL_LIST_EMPTY(tagger_locations)
|
||||
GLOBAL_LIST_EMPTY(tagger_locations)
|
||||
|
||||
GLOBAL_LIST_INIT(char_directory_tags, list("Pred", "Prey", "Switch", "Non-Vore", "Unset"))
|
||||
GLOBAL_LIST_INIT(char_directory_erptags, list("Top", "Bottom", "Switch", "No ERP", "Unset"))
|
||||
@@ -6,4 +6,3 @@ GLOBAL_LIST_EMPTY(directory) //all ckeys with associated client
|
||||
GLOBAL_LIST_EMPTY(clients)
|
||||
GLOBAL_LIST_EMPTY(players_by_zlevel)
|
||||
GLOBAL_LIST_EMPTY(round_text_log)
|
||||
GLOBAL_LIST_EMPTY(ghost_mob_list) //CHOMPedit List of all ghosts, including clientless. Excludes /mob/new_player
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
var/datum/gear_tweak/color/gear_tweak_free_color_choice = new()
|
||||
var/datum/gear_tweak/color/gear_tweak_free_color_choice = new()
|
||||
var/datum/gear_tweak/implant_location/gear_tweak_implant_location = new()
|
||||
@@ -43,6 +43,11 @@ var/global/list/facial_hair_styles_male_list = list()
|
||||
var/global/list/facial_hair_styles_female_list = list()
|
||||
var/global/list/skin_styles_female_list = list() //unused
|
||||
var/global/list/body_marking_styles_list = list() //stores /datum/sprite_accessory/marking indexed by name
|
||||
var/global/list/ear_styles_list = list() // Stores /datum/sprite_accessory/ears indexed by type
|
||||
var/global/list/tail_styles_list = list() // Stores /datum/sprite_accessory/tail indexed by type
|
||||
var/global/list/wing_styles_list = list() // Stores /datum/sprite_accessory/wing indexed by type
|
||||
|
||||
GLOBAL_LIST_INIT(custom_species_bases, new) // Species that can be used for a Custom Species icon base
|
||||
//Underwear
|
||||
var/datum/category_collection/underwear/global_underwear = new()
|
||||
|
||||
@@ -94,13 +99,13 @@ var/global/list/string_slot_flags = list(
|
||||
"holster" = SLOT_HOLSTER
|
||||
)
|
||||
|
||||
/proc/get_mannequin(var/ckey)
|
||||
if(!mannequins_)
|
||||
mannequins_ = new()
|
||||
. = mannequins_[ckey]
|
||||
if(!.)
|
||||
. = new/mob/living/carbon/human/dummy/mannequin()
|
||||
mannequins_[ckey] = .
|
||||
GLOBAL_LIST_EMPTY(mannequins)
|
||||
/proc/get_mannequin(var/ckey = "NULL")
|
||||
var/mob/living/carbon/human/dummy/mannequin/M = GLOB.mannequins[ckey]
|
||||
if(!istype(M))
|
||||
GLOB.mannequins[ckey] = new /mob/living/carbon/human/dummy/mannequin(null)
|
||||
M = GLOB.mannequins[ckey]
|
||||
return M
|
||||
|
||||
//////////////////////////
|
||||
/////Initial Building/////
|
||||
@@ -214,6 +219,23 @@ var/global/list/string_slot_flags = list(
|
||||
var/decl/closet_appearance/app = new T()
|
||||
GLOB.closet_appearances[T] = app
|
||||
|
||||
paths = typesof(/datum/sprite_accessory/ears) - /datum/sprite_accessory/ears
|
||||
for(var/path in paths)
|
||||
var/obj/item/clothing/head/instance = new path()
|
||||
ear_styles_list[path] = instance
|
||||
|
||||
// Custom Tails
|
||||
paths = typesof(/datum/sprite_accessory/tail) - /datum/sprite_accessory/tail - /datum/sprite_accessory/tail/taur
|
||||
for(var/path in paths)
|
||||
var/datum/sprite_accessory/tail/instance = new path()
|
||||
tail_styles_list[path] = instance
|
||||
|
||||
// Custom Wings
|
||||
paths = typesof(/datum/sprite_accessory/wing) - /datum/sprite_accessory/wing
|
||||
for(var/path in paths)
|
||||
var/datum/sprite_accessory/wing/instance = new path()
|
||||
wing_styles_list[path] = instance
|
||||
|
||||
// VOREStation Add - Vore Modes!
|
||||
paths = typesof(/datum/digest_mode)
|
||||
for(var/T in paths)
|
||||
@@ -221,6 +243,41 @@ var/global/list/string_slot_flags = list(
|
||||
GLOB.digest_modes[DM.id] = DM
|
||||
// VOREStation Add End
|
||||
|
||||
/*
|
||||
// Custom species traits
|
||||
paths = typesof(/datum/trait) - /datum/trait
|
||||
for(var/path in paths)
|
||||
var/datum/trait/instance = new path()
|
||||
if(!instance.name)
|
||||
continue //A prototype or something
|
||||
var/cost = instance.cost
|
||||
traits_costs[path] = cost
|
||||
all_traits[path] = instance
|
||||
switch(cost)
|
||||
if(-INFINITY to -0.1)
|
||||
negative_traits[path] = instance
|
||||
if(0)
|
||||
neutral_traits[path] = instance
|
||||
if(0.1 to INFINITY)
|
||||
positive_traits[path] = instance
|
||||
*/
|
||||
|
||||
// Custom species icon bases
|
||||
var/list/blacklisted_icons = list(SPECIES_CUSTOM,SPECIES_PROMETHEAN) //VOREStation Edit
|
||||
var/list/whitelisted_icons = list(SPECIES_FENNEC,SPECIES_XENOHYBRID) //VOREStation Edit
|
||||
for(var/species_name in GLOB.playable_species)
|
||||
if(species_name in blacklisted_icons)
|
||||
continue
|
||||
var/datum/species/S = GLOB.all_species[species_name]
|
||||
if(S.spawn_flags & SPECIES_IS_WHITELISTED)
|
||||
continue
|
||||
GLOB.custom_species_bases += species_name
|
||||
for(var/species_name in whitelisted_icons)
|
||||
GLOB.custom_species_bases += species_name
|
||||
|
||||
return 1 // Hooks must return 1
|
||||
|
||||
|
||||
return 1
|
||||
|
||||
/* // Uncomment to debug chemical reaction list.
|
||||
|
||||
@@ -13,4 +13,12 @@ var/global/list/vore_reagent_sounds = list(
|
||||
'sound/vore/walkslosh10.ogg',
|
||||
"None" = null)
|
||||
|
||||
/var/global/list/existing_metroids = list() //Global variable for tracking metroids for the event announcement. Needs to go here for load order.
|
||||
/var/global/list/existing_metroids = list() //Global variable for tracking metroids for the event announcement. Needs to go here for load order.
|
||||
|
||||
//stuff that only synths can eat
|
||||
var/global/list/edible_tech = list(/obj/item/weapon/cell,
|
||||
/obj/item/weapon/circuitboard,
|
||||
/obj/item/integrated_circuit,
|
||||
/obj/item/broken_device,
|
||||
/obj/item/brokenbug,
|
||||
)
|
||||
|
||||
@@ -2,20 +2,17 @@
|
||||
* VOREStation global lists
|
||||
*/
|
||||
|
||||
var/global/list/ear_styles_list = list() // Stores /datum/sprite_accessory/ears indexed by type
|
||||
var/global/list/hair_accesories_list= list()// Stores /datum/sprite_accessory/hair_accessory indexed by type
|
||||
var/global/list/tail_styles_list = list() // Stores /datum/sprite_accessory/tail indexed by type
|
||||
var/global/list/wing_styles_list = list() // Stores /datum/sprite_accessory/wing indexed by type
|
||||
var/global/list/negative_traits = list() // Negative custom species traits, indexed by path
|
||||
var/global/list/neutral_traits = list() // Neutral custom species traits, indexed by path
|
||||
var/global/list/everyone_traits = list() // Neutral traits available to all species, indexed by path
|
||||
var/global/list/positive_traits = list() // Positive custom species traits, indexed by path
|
||||
var/global/list/traits_costs = list() // Just path = cost list, saves time in char setup
|
||||
var/global/list/all_traits = list() // All of 'em at once (same instances)
|
||||
var/global/list/active_ghost_pods = list()
|
||||
|
||||
var/global/list/sensorpreflist = list("Off", "Binary", "Vitals", "Tracking", "No Preference") //TFF 5/8/19 - Suit Sensors global list
|
||||
|
||||
var/global/list/custom_species_bases = list() // Species that can be used for a Custom Species icon base
|
||||
|
||||
//stores numeric player size options indexed by name
|
||||
var/global/list/player_sizes_list = list(
|
||||
"Macro" = RESIZE_HUGE,
|
||||
@@ -106,30 +103,74 @@ var/global/list/fancy_release_sounds = list(
|
||||
)
|
||||
|
||||
var/global/list/global_vore_egg_types = list(
|
||||
"Unathi" = UNATHI_EGG,
|
||||
"Tajaran" = TAJARAN_EGG,
|
||||
"Akula" = AKULA_EGG,
|
||||
"Skrell" = SKRELL_EGG,
|
||||
"Nevrean" = NEVREAN_EGG,
|
||||
"Sergal" = SERGAL_EGG,
|
||||
"Human" = HUMAN_EGG,
|
||||
"Slime" = SLIME_EGG,
|
||||
"Egg" = EGG_EGG,
|
||||
"Xenochimera" = XENOCHIMERA_EGG,
|
||||
"Xenomorph" = XENOMORPH_EGG)
|
||||
"Unathi",
|
||||
"Tajara",
|
||||
"Akula",
|
||||
"Skrell",
|
||||
"Sergal",
|
||||
"Nevrean",
|
||||
"Human",
|
||||
"Slime",
|
||||
"Egg",
|
||||
"Xenochimera",
|
||||
"Xenomorph",
|
||||
"Chocolate",
|
||||
"Boney",
|
||||
"Slime glob",
|
||||
"Chicken",
|
||||
"Synthetic",
|
||||
"Bluespace Floppy",
|
||||
"Bluespace Compressed File",
|
||||
"Bluespace CD",
|
||||
"Escape pod",
|
||||
"Cooking error",
|
||||
"Web cocoon",
|
||||
"Honeycomb",
|
||||
"Bug cocoon",
|
||||
"Rock",
|
||||
"Yellow",
|
||||
"Blue",
|
||||
"Green",
|
||||
"Orange",
|
||||
"Purple",
|
||||
"Red",
|
||||
"Rainbow",
|
||||
"Spotted pink")
|
||||
|
||||
var/global/list/tf_vore_egg_types = list(
|
||||
"Unathi" = /obj/structure/closet/secure_closet/egg/unathi,
|
||||
"Tajara" = /obj/structure/closet/secure_closet/egg/tajaran,
|
||||
"Akula" = /obj/structure/closet/secure_closet/egg/shark,
|
||||
"Skrell" = /obj/structure/closet/secure_closet/egg/skrell,
|
||||
"Sergal" = /obj/structure/closet/secure_closet/egg/sergal,
|
||||
"Nevrean" = /obj/structure/closet/secure_closet/egg/nevrean,
|
||||
"Human" = /obj/structure/closet/secure_closet/egg/human,
|
||||
"Slime" = /obj/structure/closet/secure_closet/egg/slime,
|
||||
"Egg" = /obj/structure/closet/secure_closet/egg,
|
||||
"Xenochimera" = /obj/structure/closet/secure_closet/egg/scree,
|
||||
"Xenomorph" = /obj/structure/closet/secure_closet/egg/xenomorph)
|
||||
"Unathi" = /obj/item/weapon/storage/vore_egg/unathi,
|
||||
"Tajara" = /obj/item/weapon/storage/vore_egg/tajaran,
|
||||
"Akula" = /obj/item/weapon/storage/vore_egg/shark,
|
||||
"Skrell" = /obj/item/weapon/storage/vore_egg/skrell,
|
||||
"Sergal" = /obj/item/weapon/storage/vore_egg/sergal,
|
||||
"Nevrean" = /obj/item/weapon/storage/vore_egg/nevrean,
|
||||
"Human" = /obj/item/weapon/storage/vore_egg/human,
|
||||
"Slime" = /obj/item/weapon/storage/vore_egg/slime,
|
||||
"Egg" = /obj/item/weapon/storage/vore_egg,
|
||||
"Xenochimera" = /obj/item/weapon/storage/vore_egg/scree,
|
||||
"Xenomorph" = /obj/item/weapon/storage/vore_egg/xenomorph,
|
||||
"Chocolate" = /obj/item/weapon/storage/vore_egg/chocolate,
|
||||
"Boney" = /obj/item/weapon/storage/vore_egg/owlpellet,
|
||||
"Slime glob" = /obj/item/weapon/storage/vore_egg/slimeglob,
|
||||
"Chicken" = /obj/item/weapon/storage/vore_egg/chicken,
|
||||
"Synthetic" = /obj/item/weapon/storage/vore_egg/synthetic,
|
||||
"Bluespace Floppy" = /obj/item/weapon/storage/vore_egg/floppy,
|
||||
"Bluespace Compressed File" = /obj/item/weapon/storage/vore_egg/file,
|
||||
"Bluespace CD" = /obj/item/weapon/storage/vore_egg/cd,
|
||||
"Escape pod" = /obj/item/weapon/storage/vore_egg/escapepod,
|
||||
"Cooking error" = /obj/item/weapon/storage/vore_egg/badrecipe,
|
||||
"Web cocoon" = /obj/item/weapon/storage/vore_egg/cocoon,
|
||||
"Honeycomb" = /obj/item/weapon/storage/vore_egg/honeycomb,
|
||||
"Bug cocoon" = /obj/item/weapon/storage/vore_egg/bugcocoon,
|
||||
"Rock" = /obj/item/weapon/storage/vore_egg/rock,
|
||||
"Yellow" = /obj/item/weapon/storage/vore_egg/yellow,
|
||||
"Blue" = /obj/item/weapon/storage/vore_egg/blue,
|
||||
"Green" = /obj/item/weapon/storage/vore_egg/green,
|
||||
"Orange" = /obj/item/weapon/storage/vore_egg/orange,
|
||||
"Purple" = /obj/item/weapon/storage/vore_egg/purple,
|
||||
"Red" = /obj/item/weapon/storage/vore_egg/red,
|
||||
"Rainbow" = /obj/item/weapon/storage/vore_egg/rainbow,
|
||||
"Spotted pink" = /obj/item/weapon/storage/vore_egg/pinkspots)
|
||||
|
||||
var/global/list/edible_trash = list(/obj/item/broken_device,
|
||||
/obj/item/clothing/accessory/collar, //TFF 10/7/19 - add option to nom collars,
|
||||
@@ -145,6 +186,7 @@ var/global/list/edible_trash = list(/obj/item/broken_device,
|
||||
/obj/item/device/paicard,
|
||||
/obj/item/device/pda,
|
||||
/obj/item/device/radio/headset,
|
||||
/obj/item/device/starcaster_news, //chompstation addition
|
||||
/obj/item/inflatable/torn,
|
||||
/obj/item/organ,
|
||||
/obj/item/stack/material/cardboard,
|
||||
@@ -180,7 +222,9 @@ var/global/list/edible_trash = list(/obj/item/broken_device,
|
||||
/obj/item/weapon/storage/fancy/cigarettes,
|
||||
/obj/item/weapon/storage/fancy/crayons,
|
||||
/obj/item/weapon/storage/fancy/egg_box,
|
||||
/obj/item/weapon/storage/wallet)
|
||||
/obj/item/weapon/storage/wallet,
|
||||
/obj/item/weapon/storage/vore_egg,
|
||||
/obj/item/weapon/material/kitchen) //chompstation addition
|
||||
|
||||
var/global/list/contamination_flavors = list(
|
||||
"Generic" = contamination_flavors_generic,
|
||||
@@ -434,30 +478,12 @@ var/global/list/remainless_species = list(SPECIES_PROMETHEAN,
|
||||
/hook/startup/proc/init_vore_datum_ref_lists()
|
||||
var/paths
|
||||
|
||||
// Custom Ears
|
||||
paths = typesof(/datum/sprite_accessory/ears) - /datum/sprite_accessory/ears
|
||||
for(var/path in paths)
|
||||
var/obj/item/clothing/head/instance = new path()
|
||||
ear_styles_list[path] = instance
|
||||
|
||||
// Custom Tails
|
||||
paths = typesof(/datum/sprite_accessory/tail) - /datum/sprite_accessory/tail - /datum/sprite_accessory/tail/taur
|
||||
for(var/path in paths)
|
||||
var/datum/sprite_accessory/tail/instance = new path()
|
||||
tail_styles_list[path] = instance
|
||||
|
||||
// Custom Wings
|
||||
paths = typesof(/datum/sprite_accessory/wing) - /datum/sprite_accessory/wing
|
||||
for(var/path in paths)
|
||||
var/datum/sprite_accessory/wing/instance = new path()
|
||||
wing_styles_list[path] = instance
|
||||
|
||||
// Custom Hair Accessories
|
||||
paths = typesof(/datum/sprite_accessory/hair_accessory) - /datum/sprite_accessory/hair_accessory
|
||||
for(var/path in paths)
|
||||
var/datum/sprite_accessory/hair_accessory/instance = new path()
|
||||
hair_accesories_list[path] = instance
|
||||
|
||||
|
||||
// Custom species traits
|
||||
paths = typesof(/datum/trait) - /datum/trait
|
||||
for(var/path in paths)
|
||||
@@ -472,20 +498,27 @@ var/global/list/remainless_species = list(SPECIES_PROMETHEAN,
|
||||
negative_traits[path] = instance
|
||||
if(0)
|
||||
neutral_traits[path] = instance
|
||||
if(!(instance.custom_only))
|
||||
everyone_traits[path] = instance
|
||||
if(0.1 to INFINITY)
|
||||
positive_traits[path] = instance
|
||||
|
||||
// Custom species icon bases
|
||||
var/list/blacklisted_icons = list(SPECIES_CUSTOM,SPECIES_PROMETHEAN) //Just ones that won't work well.
|
||||
var/list/whitelisted_icons = list(SPECIES_FENNEC,SPECIES_XENOHYBRID) //Include these anyway
|
||||
for(var/species_name in GLOB.playable_species)
|
||||
if(species_name in blacklisted_icons)
|
||||
continue
|
||||
var/datum/species/S = GLOB.all_species[species_name]
|
||||
if(S.spawn_flags & SPECIES_IS_WHITELISTED)
|
||||
continue
|
||||
custom_species_bases += species_name
|
||||
for(var/species_name in whitelisted_icons)
|
||||
custom_species_bases += species_name
|
||||
// Weaver recipe stuff
|
||||
paths = typesof(/datum/weaver_recipe/structure) - /datum/weaver_recipe/structure
|
||||
for(var/path in paths)
|
||||
var/datum/weaver_recipe/instance = new path()
|
||||
if(!instance.title)
|
||||
continue //A prototype or something
|
||||
weavable_structures[instance.title] = instance
|
||||
|
||||
paths = typesof(/datum/weaver_recipe/item) - /datum/weaver_recipe/item
|
||||
for(var/path in paths)
|
||||
var/datum/weaver_recipe/instance = new path()
|
||||
if(!instance.title)
|
||||
continue //A prototype or something
|
||||
weavable_items[instance.title] = instance
|
||||
|
||||
return 1 // Hooks must return 1
|
||||
|
||||
var/global/list/weavable_structures = list()
|
||||
var/global/list/weavable_items = list()
|
||||
|
||||
@@ -65,45 +65,110 @@
|
||||
if (config.log_say)
|
||||
WRITE_LOG(diary, "SAY: [speaker.simple_info_line()]: [html_decode(text)]")
|
||||
|
||||
//Log the message to in-game dialogue logs, as well.
|
||||
//Log the message to in-game dialogue logs, as well. //CHOMPEdit Begin
|
||||
if(speaker.client)
|
||||
speaker.dialogue_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>SAY:</u> - <span style=\"color:#32cd32\">[text]</span>"
|
||||
GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>SAY:</u> - <span style=\"color:#32cd32\">[text]</span>"
|
||||
//speaker.dialogue_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>SAY:</u> - <span style=\"color:#32cd32\">[text]</span>"
|
||||
if(!SSdbcore.IsConnected())
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = speaker.ckey, "sender_mob" = speaker.real_name, "message_type" = "say", "message_content" = text))
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
//GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>SAY:</u> - <span style=\"color:#32cd32\">[text]</span>"
|
||||
//CHOMPEdit End
|
||||
|
||||
/proc/log_ooc(text, client/user)
|
||||
if (config.log_ooc)
|
||||
WRITE_LOG(diary, "OOC: [user.simple_info_line()]: [html_decode(text)]")
|
||||
|
||||
GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[user]</b>) <u>OOC:</u> - <span style=\"color:blue\"><b>[text]</b></span>"
|
||||
if(!SSdbcore.IsConnected())
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = user.ckey, "sender_mob" = user.mob.real_name, "message_type" = "ooc", "message_content" = text))
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
//GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[user]</b>) <u>OOC:</u> - <span style=\"color:blue\"><b>[text]</b></span>"
|
||||
|
||||
/proc/log_aooc(text, client/user)
|
||||
if (config.log_ooc)
|
||||
WRITE_LOG(diary, "AOOC: [user.simple_info_line()]: [html_decode(text)]")
|
||||
|
||||
GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[user]</b>) <u>AOOC:</u> - <span style=\"color:red\"><b>[text]</b></span>"
|
||||
if(!SSdbcore.IsConnected())
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = user.ckey, "sender_mob" = user.mob.real_name, "message_type" = "aooc", "message_content" = text))
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
//GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[user]</b>) <u>AOOC:</u> - <span style=\"color:red\"><b>[text]</b></span>"
|
||||
|
||||
/proc/log_looc(text, client/user)
|
||||
if (config.log_ooc)
|
||||
WRITE_LOG(diary, "LOOC: [user.simple_info_line()]: [html_decode(text)]")
|
||||
|
||||
GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[user]</b>) <u>LOOC:</u> - <span style=\"color:orange\"><b>[text]</b></span>"
|
||||
if(!SSdbcore.IsConnected())
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = user.ckey, "sender_mob" = user.mob.real_name, "message_type" = "looc", "message_content" = text))
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
//GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[user]</b>) <u>LOOC:</u> - <span style=\"color:orange\"><b>[text]</b></span>"
|
||||
|
||||
/proc/log_whisper(text, mob/speaker)
|
||||
if (config.log_whisper)
|
||||
WRITE_LOG(diary, "WHISPER: [speaker.simple_info_line()]: [html_decode(text)]")
|
||||
|
||||
if(speaker.client)
|
||||
speaker.dialogue_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>SAY:</u> - <span style=\"color:gray\"><i>[text]</i></span>"
|
||||
GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>SAY:</u> - <span style=\"color:gray\"><i>[text]</i></span>"
|
||||
//speaker.dialogue_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>SAY:</u> - <span style=\"color:gray\"><i>[text]</i></span>"
|
||||
//GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>SAY:</u> - <span style=\"color:gray\"><i>[text]</i></span>"
|
||||
if(!SSdbcore.IsConnected())
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = speaker.ckey, "sender_mob" = speaker.real_name, "message_type" = "whisper", "message_content" = text))
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
|
||||
|
||||
/proc/log_emote(text, mob/speaker)
|
||||
if (config.log_emote)
|
||||
WRITE_LOG(diary, "EMOTE: [speaker.simple_info_line()]: [html_decode(text)]")
|
||||
|
||||
//CHOMPEdit Begin
|
||||
if(speaker.client)
|
||||
speaker.dialogue_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>EMOTE:</u> - <span style=\"color:#CCBADC\">[text]</span>"
|
||||
GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>EMOTE:</u> - <span style=\"color:#CCBADC\">[text]</span>"
|
||||
//speaker.dialogue_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>EMOTE:</u> - <span style=\"color:#CCBADC\">[text]</span>"
|
||||
//GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>EMOTE:</u> - <span style=\"color:#CCBADC\">[text]</span>"
|
||||
if(!SSdbcore.IsConnected())
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = speaker.ckey, "sender_mob" = speaker.real_name, "message_type" = "emote", "message_content" = text))
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
//CHOMPEdit End
|
||||
|
||||
/proc/log_attack(attacker, defender, message)
|
||||
if (config.log_attack)
|
||||
@@ -124,14 +189,40 @@
|
||||
/proc/log_ghostsay(text, mob/speaker)
|
||||
if (config.log_say)
|
||||
WRITE_LOG(diary, "DEADCHAT: [speaker.simple_info_line()]: [html_decode(text)]")
|
||||
|
||||
speaker.dialogue_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>DEADSAY:</u> - <span style=\"color:green\">[text]</span>"
|
||||
GLOB.round_text_log += "<font size=1><span style=\"color:#7e668c\"><b>([time_stamp()])</b> (<b>[src]/[speaker.client]</b>) <u>DEADSAY:</u> - [text]</span></font>"
|
||||
|
||||
//CHOMPEdit Begin
|
||||
if(speaker.client)
|
||||
if(!SSdbcore.IsConnected())
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = speaker.ckey, "sender_mob" = speaker.real_name, "message_type" = "deadsay", "message_content" = text))
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
//speaker.dialogue_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>DEADSAY:</u> - <span style=\"color:green\">[text]</span>"
|
||||
//GLOB.round_text_log += "<font size=1><span style=\"color:#7e668c\"><b>([time_stamp()])</b> (<b>[src]/[speaker.client]</b>) <u>DEADSAY:</u> - [text]</span></font>"
|
||||
//CHOMPEdit End
|
||||
|
||||
/proc/log_ghostemote(text, mob/speaker)
|
||||
if (config.log_emote)
|
||||
WRITE_LOG(diary, "DEADEMOTE: [speaker.simple_info_line()]: [html_decode(text)]")
|
||||
//CHOMPEdit Begin
|
||||
if(speaker.client)
|
||||
if(!SSdbcore.IsConnected())
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = speaker.ckey, "sender_mob" = speaker.real_name, "message_type" = "deademote", "message_content" = text))
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
//CHOMPEdit End
|
||||
|
||||
/proc/log_adminwarn(text)
|
||||
if (config.log_adminwarn)
|
||||
@@ -140,10 +231,23 @@
|
||||
/proc/log_pda(text, mob/speaker)
|
||||
if (config.log_pda)
|
||||
WRITE_LOG(diary, "PDA: [speaker.simple_info_line()]: [html_decode(text)]")
|
||||
//CHOMPEdit Begin
|
||||
if(speaker.client)
|
||||
if(!SSdbcore.IsConnected())
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = speaker.ckey, "sender_mob" = speaker.real_name, "message_type" = "pda", "message_content" = text))
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
|
||||
speaker.dialogue_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>MSG:</u> - <span style=\"color:[COLOR_GREEN]\">[text]</span>"
|
||||
GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>MSG:</u> - <span style=\"color:[COLOR_GREEN]\">[text]</span>"
|
||||
|
||||
//speaker.dialogue_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>MSG:</u> - <span style=\"color:[COLOR_GREEN]\">[text]</span>"
|
||||
//GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>MSG:</u> - <span style=\"color:[COLOR_GREEN]\">[text]</span>"
|
||||
//CHOMPEdit End
|
||||
|
||||
/proc/log_to_dd(text)
|
||||
to_world_log(text) //this comes before the config check because it can't possibly runtime
|
||||
|
||||
@@ -1,11 +1,53 @@
|
||||
/proc/log_nsay(text, inside, mob/speaker)
|
||||
if (config.log_say)
|
||||
WRITE_LOG(diary, "NSAY (NIF:[inside]): [speaker.simple_info_line()]: [html_decode(text)]")
|
||||
//CHOMPEdit Begin
|
||||
if(speaker.client)
|
||||
if(!SSdbcore.IsConnected())
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = speaker.ckey, "sender_mob" = speaker.real_name, "message_type" = "nsay", "message_content" = text))
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
//CHOMPEdit End
|
||||
|
||||
/proc/log_nme(text, inside, mob/speaker)
|
||||
if (config.log_emote)
|
||||
WRITE_LOG(diary, "NME (NIF:[inside]): [speaker.simple_info_line()]: [html_decode(text)]")
|
||||
//CHOMPEdit Begin
|
||||
if(speaker.client)
|
||||
if(!SSdbcore.IsConnected())
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = speaker.ckey, "sender_mob" = speaker.real_name, "message_type" = "nme", "message_content" = text))
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
//CHOMPEdit End
|
||||
|
||||
/proc/log_subtle(text, mob/speaker)
|
||||
if (config.log_emote)
|
||||
WRITE_LOG(diary, "SUBTLE: [speaker.simple_info_line()]: [html_decode(text)]")
|
||||
//CHOMPEdit Begin
|
||||
if(speaker.client)
|
||||
if(!SSdbcore.IsConnected())
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = speaker.ckey, "sender_mob" = speaker.real_name, "message_type" = "subtle", "message_content" = text))
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
//CHOMPEdit End
|
||||
|
||||
@@ -110,7 +110,7 @@ Proc for attack log creation, because really why not
|
||||
6 is additional information, anything that needs to be added
|
||||
*/
|
||||
|
||||
/proc/add_attack_logs(mob/user, mob/target, what_done, var/admin_notify = TRUE)
|
||||
/proc/add_attack_logs(mob/user, mob/target, what_done, var/admin_notify = TRUE, var/use_async = TRUE) //CHOMPEdit
|
||||
if(islist(target)) //Multi-victim adding
|
||||
var/list/targets = target
|
||||
for(var/mob/M in targets)
|
||||
@@ -120,10 +120,21 @@ Proc for attack log creation, because really why not
|
||||
var/user_str = key_name(user)
|
||||
var/target_str = key_name(target)
|
||||
|
||||
if(ismob(user))
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Attacked [target_str]: [what_done]</font>")
|
||||
if(ismob(user)) //CHOMPEdit Begin
|
||||
//user.attack_log += text("\[[time_stamp()]\] <font color='red'>Attacked [target_str]: [what_done]</font>")
|
||||
//var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_attacklog (id, time, ckey, mob, message) VALUES (null, NOW(), :t_ckey, :t_mob, :t_content)", list("t_ckey" = user.ckey, "t_mob" = user.real_name, "t_content" = "<font color='red'>Attacked [target_str]: [what_done]</font>"))
|
||||
//query_insert.Execute(async=use_async)
|
||||
//qdel(query_insert)
|
||||
if(SSdbcore.Connect())
|
||||
rustg_sql_query_async(SSdbcore.connection, "INSERT INTO erro_attacklog (id, time, ckey, mob, message) VALUES (null, NOW(), :t_ckey, :t_mob, :t_content)", json_encode(list("t_ckey" = user.ckey, "t_mob" = user.real_name, "t_content" = "<font color='red'>Attacked [target_str]: [what_done]</font>")))
|
||||
if(ismob(target))
|
||||
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Attacked by [user_str]: [what_done]</font>")
|
||||
//target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Attacked by [user_str]: [what_done]</font>")
|
||||
//var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_attacklog (id, time, ckey, mob, message) VALUES (null, NOW(), :t_ckey, :t_mob, :t_content)", list("t_ckey" = target.ckey, "t_mob" = target.real_name, "t_content" = "<font color='orange'>Attacked by [user_str]: [what_done]</font>"))
|
||||
//query_insert.Execute(async=use_async)
|
||||
//qdel(query_insert)
|
||||
if(SSdbcore.Connect())
|
||||
rustg_sql_query_async(SSdbcore.connection, "INSERT INTO erro_attacklog (id, time, ckey, mob, message) VALUES (null, NOW(), :t_ckey, :t_mob, :t_content)", json_encode(list("t_ckey" = target.ckey, "t_mob" = target.real_name, "t_content" = "<font color='orange'>Attacked by [user_str]: [what_done]</font>")))
|
||||
//CHOMPEdit End
|
||||
log_attack(user_str,target_str,what_done)
|
||||
if(admin_notify)
|
||||
msg_admin_attack("[key_name_admin(user)] vs [target_str]: [what_done]")
|
||||
|
||||
@@ -14,9 +14,11 @@
|
||||
*/
|
||||
|
||||
// Run all strings to be used in an SQL query through this proc first to properly escape out injection attempts.
|
||||
/proc/sanitizeSQL(var/t as text)
|
||||
var/sqltext = dbcon.Quote(t);
|
||||
return copytext(sqltext, 2, length(sqltext));//Quote() adds quotes around input, we already do that
|
||||
/proc/sanitizeSQL(var/t as text)
|
||||
//var/sqltext = dbcon.Quote(t); //CHOMPEdit Begin
|
||||
//return copytext(sqltext, 2, length(sqltext));//Quote() adds quotes around input, we already do that
|
||||
return t
|
||||
//CHOMPEdit End
|
||||
|
||||
/*
|
||||
* Text sanitization
|
||||
@@ -402,9 +404,9 @@ proc/TextPreview(var/string,var/len=40)
|
||||
t = replacetext(t, "\[/grid\]", "</td></tr></table>")
|
||||
t = replacetext(t, "\[row\]", "</td><tr>")
|
||||
t = replacetext(t, "\[cell\]", "<td>")
|
||||
t = replacetext(t, "\[logo\]", "<img src = ntlogo.png>")
|
||||
t = replacetext(t, "\[redlogo\]", "<img src = redntlogo.png>")
|
||||
t = replacetext(t, "\[sglogo\]", "<img src = sglogo.png>")
|
||||
t = replacetext(t, "\[logo\]", "<img src = https://raw.githubusercontent.com/CHOMPStation2/CHOMPStation2/master/html/images/ntlogo.png>") //CHOMPEdit
|
||||
t = replacetext(t, "\[redlogo\]", "<img src = https://raw.githubusercontent.com/CHOMPStation2/CHOMPStation2/master/html/images/redntlogo.png>") //CHOMPEdit
|
||||
t = replacetext(t, "\[sglogo\]", "<img src = https://raw.githubusercontent.com/CHOMPStation2/CHOMPStation2/master/html/images/sglogo.png>") //CHOMPEdit
|
||||
t = replacetext(t, "\[editorbr\]", "")
|
||||
return t
|
||||
|
||||
|
||||
@@ -1277,6 +1277,10 @@ var/list/WALLITEMS = list(
|
||||
colour += temp_col
|
||||
return colour
|
||||
|
||||
/proc/color_square(red, green, blue, hex)
|
||||
var/color = hex ? hex : "#[num2hex(red, 2)][num2hex(green, 2)][num2hex(blue, 2)]"
|
||||
return "<span style='font-face: fixedsys; font-size: 14px; background-color: [color]; color: [color]'>___</span>"
|
||||
|
||||
var/mob/dview/dview_mob = new
|
||||
|
||||
//Version of view() which ignores darkness, because BYOND doesn't have it.
|
||||
@@ -1609,6 +1613,46 @@ GLOBAL_REAL_VAR(list/stack_trace_storage)
|
||||
/proc/href(href_src, list/href_params, href_text)
|
||||
return "<a href='?src=\ref[href_src];[list2params(href_params)]'>[href_text]</a>"
|
||||
|
||||
// This is a helper for anything that wants to render the map in TGUI
|
||||
/proc/get_tgui_plane_masters()
|
||||
. = list()
|
||||
// 'Utility' planes
|
||||
. += new /obj/screen/plane_master/fullbright //Lighting system (lighting_overlay objects)
|
||||
. += new /obj/screen/plane_master/lighting //Lighting system (but different!)
|
||||
. += new /obj/screen/plane_master/ghosts //Ghosts!
|
||||
. += new /obj/screen/plane_master{plane = PLANE_AI_EYE} //AI Eye!
|
||||
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_STATUS} //Status is the synth/human icon left side of medhuds
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_HEALTH} //Health bar
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_LIFE} //Alive-or-not icon
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_ID} //Job ID icon
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_WANTED} //Wanted status
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_IMPLOYAL} //Loyalty implants
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_IMPTRACK} //Tracking implants
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_IMPCHEM} //Chemical implants
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_SPECIAL} //"Special" role stuff
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_STATUS_OOC} //OOC status HUD
|
||||
|
||||
. += new /obj/screen/plane_master{plane = PLANE_ADMIN1} //For admin use
|
||||
. += new /obj/screen/plane_master{plane = PLANE_ADMIN2} //For admin use
|
||||
. += new /obj/screen/plane_master{plane = PLANE_ADMIN3} //For admin use
|
||||
|
||||
. += new /obj/screen/plane_master{plane = PLANE_MESONS} //Meson-specific things like open ceilings.
|
||||
. += new /obj/screen/plane_master{plane = PLANE_BUILDMODE} //Things that only show up while in build mode
|
||||
|
||||
// Real tangible stuff planes
|
||||
. += new /obj/screen/plane_master/main{plane = TURF_PLANE}
|
||||
. += new /obj/screen/plane_master/main{plane = OBJ_PLANE}
|
||||
. += new /obj/screen/plane_master/main{plane = MOB_PLANE}
|
||||
. += new /obj/screen/plane_master/cloaked //Cloaked atoms!
|
||||
|
||||
//VOREStation Add - Random other plane masters
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_STATUS_R} //Right-side status icon
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_HEALTH_VR} //Health bar but transparent at 100
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_BACKUP} //Backup implant status
|
||||
. += new /obj/screen/plane_master{plane = PLANE_CH_VANTAG} //Vore Antags
|
||||
. += new /obj/screen/plane_master{plane = PLANE_AUGMENTED} //Augmented reality
|
||||
//VOREStation Add End
|
||||
/proc/CallAsync(datum/source, proctype, list/arguments)
|
||||
set waitfor = FALSE
|
||||
return call(source, proctype)(arglist(arguments))
|
||||
return call(source, proctype)(arglist(arguments))
|
||||
|
||||
@@ -10,3 +10,7 @@
|
||||
viewX = text2num(viewrangelist[1])
|
||||
viewY = text2num(viewrangelist[2])
|
||||
return list(viewX, viewY)
|
||||
|
||||
// Used to get `atom/O as obj|mob|turf in view()` to match against strings containing apostrophes immediately after substrings that match to other objects. Somehow. - Ater
|
||||
/proc/_validate_atom(atom/A)
|
||||
return view()
|
||||
25
code/_helpers/widelists_ch.dm
Normal file
25
code/_helpers/widelists_ch.dm
Normal file
@@ -0,0 +1,25 @@
|
||||
GLOBAL_LIST_EMPTY(widelists)
|
||||
|
||||
/proc/widelist(var/list/input_list)
|
||||
var/list_hash = gen_hash_list(input_list)
|
||||
if(!(list_hash in GLOB.widelists))
|
||||
GLOB.widelists[list_hash] = input_list
|
||||
return GLOB.widelists[list_hash]
|
||||
|
||||
/proc/gen_hash_list(var/list/input_list)
|
||||
var/string = ""
|
||||
for(var/item in input_list)
|
||||
var/p1 = ""
|
||||
if(islist(item))
|
||||
p1 = ">>>::-;[gen_hash_list(item)];-::<<<"
|
||||
else
|
||||
p1 = "[item]"
|
||||
|
||||
var/p2 = ""
|
||||
if(islist(input_list[item]))
|
||||
p2 = ">>>::-;[gen_hash_list(input_list[item])];-::<<<"
|
||||
else
|
||||
p2 = "[input_list[item]]"
|
||||
|
||||
string += "[p1]::--::[p2]::;;;"
|
||||
return md5(string)
|
||||
@@ -37,4 +37,7 @@
|
||||
|
||||
#define random_id(key,min_id,max_id) uniqueness_repository.Generate(/datum/uniqueness_generator/id_random, key, min_id, max_id)
|
||||
|
||||
#define ARGS_DEBUG log_debug("[__FILE__] - [__LINE__]") ; for(var/arg in args) { log_debug("\t[log_info_line(arg)]") }
|
||||
#define ARGS_DEBUG log_debug("[__FILE__] - [__LINE__]") ; for(var/arg in args) { log_debug("\t[log_info_line(arg)]") }
|
||||
|
||||
#define isitem(A) istype(A, /obj/item)
|
||||
#define isTaurTail(A) istype(A, /datum/sprite_accessory/tail/taur)
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
#define isbelly(A) istype(A, /obj/belly)
|
||||
#define isitem(A) istype(A, /obj/item)
|
||||
#define isTaurTail(A) istype(A, /datum/sprite_accessory/tail/taur)
|
||||
|
||||
@@ -354,19 +354,13 @@
|
||||
facedir(direction)
|
||||
|
||||
/obj/screen/click_catcher
|
||||
name = "Darkness"
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "click_catcher"
|
||||
plane = CLICKCATCHER_PLANE
|
||||
layer = LAYER_HUD_UNDER
|
||||
mouse_opacity = 2
|
||||
screen_loc = "CENTER-7,CENTER-7"
|
||||
|
||||
/obj/screen/click_catcher/proc/MakeGreed()
|
||||
. = list()
|
||||
for(var/i = 0, i<15, i++)
|
||||
for(var/j = 0, j<15, j++)
|
||||
var/obj/screen/click_catcher/CC = new()
|
||||
CC.screen_loc = "NORTH-[i],EAST-[j]"
|
||||
. += CC
|
||||
screen_loc = "SOUTHWEST to NORTHEAST"
|
||||
|
||||
/obj/screen/click_catcher/Click(location, control, params)
|
||||
var/list/modifiers = params2list(params)
|
||||
@@ -374,7 +368,11 @@
|
||||
var/mob/living/carbon/C = usr
|
||||
C.swap_hand()
|
||||
else
|
||||
var/turf/T = screen_loc2turf(screen_loc, get_turf(usr))
|
||||
var/list/P = params2list(params)
|
||||
var/turf/T = screen_loc2turf(P["screen-loc"], get_turf(usr))
|
||||
if(T)
|
||||
if(modifiers["shift"])
|
||||
usr.face_atom(T)
|
||||
return 1
|
||||
T.Click(location, control, params)
|
||||
. = 1
|
||||
return 1
|
||||
|
||||
@@ -60,6 +60,8 @@
|
||||
|
||||
// Cyborgs have no range-checking unless there is item use
|
||||
if(!W)
|
||||
if(bolt && !bolt.malfunction && A.loc != module)
|
||||
return
|
||||
A.add_hiddenprint(src)
|
||||
A.attack_robot(src)
|
||||
return
|
||||
@@ -119,35 +121,56 @@
|
||||
/atom/proc/BorgCtrlShiftClick(var/mob/living/silicon/robot/user) //forward to human click if not overriden
|
||||
CtrlShiftClick(user)
|
||||
|
||||
/obj/machinery/door/airlock/BorgCtrlShiftClick(mob/user)
|
||||
/obj/machinery/door/airlock/BorgCtrlShiftClick(var/mob/living/silicon/robot/user)
|
||||
if(user.bolt && !user.bolt.malfunction)
|
||||
return
|
||||
|
||||
AICtrlShiftClick(user)
|
||||
|
||||
/atom/proc/BorgShiftClick(var/mob/living/silicon/robot/user) //forward to human click if not overriden
|
||||
ShiftClick(user)
|
||||
|
||||
/obj/machinery/door/airlock/BorgShiftClick(mob/user) // Opens and closes doors! Forwards to AI code.
|
||||
/obj/machinery/door/airlock/BorgShiftClick(var/mob/living/silicon/robot/user) // Opens and closes doors! Forwards to AI code.
|
||||
if(user.bolt && !user.bolt.malfunction)
|
||||
return
|
||||
|
||||
AIShiftClick(user)
|
||||
|
||||
/atom/proc/BorgCtrlClick(var/mob/living/silicon/robot/user) //forward to human click if not overriden
|
||||
CtrlClick(user)
|
||||
|
||||
/obj/machinery/door/airlock/BorgCtrlClick(mob/user) // Bolts doors. Forwards to AI code.
|
||||
/obj/machinery/door/airlock/BorgCtrlClick(var/mob/living/silicon/robot/user) // Bolts doors. Forwards to AI code.
|
||||
if(user.bolt && !user.bolt.malfunction)
|
||||
return
|
||||
|
||||
AICtrlClick(user)
|
||||
|
||||
/obj/machinery/power/apc/BorgCtrlClick(mob/user) // turns off/on APCs. Forwards to AI code.
|
||||
/obj/machinery/power/apc/BorgCtrlClick(var/mob/living/silicon/robot/user) // turns off/on APCs. Forwards to AI code.
|
||||
if(user.bolt && !user.bolt.malfunction)
|
||||
return
|
||||
|
||||
AICtrlClick(user)
|
||||
|
||||
/obj/machinery/turretid/BorgCtrlClick(mob/user) //turret control on/off. Forwards to AI code.
|
||||
/obj/machinery/turretid/BorgCtrlClick(var/mob/living/silicon/robot/user) //turret control on/off. Forwards to AI code.
|
||||
if(user.bolt && !user.bolt.malfunction)
|
||||
return
|
||||
|
||||
AICtrlClick(user)
|
||||
|
||||
/atom/proc/BorgAltClick(var/mob/living/silicon/robot/user)
|
||||
AltClick(user)
|
||||
return
|
||||
|
||||
/obj/machinery/door/airlock/BorgAltClick(mob/user) // Eletrifies doors. Forwards to AI code.
|
||||
/obj/machinery/door/airlock/BorgAltClick(var/mob/living/silicon/robot/user) // Eletrifies doors. Forwards to AI code.
|
||||
if(user.bolt && !user.bolt.malfunction)
|
||||
return
|
||||
|
||||
AIAltClick(user)
|
||||
|
||||
/obj/machinery/turretid/BorgAltClick(mob/user) //turret lethal on/off. Forwards to AI code.
|
||||
/obj/machinery/turretid/BorgAltClick(var/mob/living/silicon/robot/user) //turret lethal on/off. Forwards to AI code.
|
||||
if(user.bolt && !user.bolt.malfunction)
|
||||
return
|
||||
|
||||
AIAltClick(user)
|
||||
|
||||
/*
|
||||
|
||||
@@ -161,6 +161,13 @@
|
||||
#define ui_ghost_pai "SOUTH: 6,CENTER+2:24"
|
||||
#define ui_ghost_updown "SOUTH: 6,CENTER+3:24"
|
||||
|
||||
// NIF Soulcatcher guest ones
|
||||
#define ui_nifsc_reenter "SOUTH:6,CENTER-3:24"
|
||||
#define ui_nifsc_arproj "SOUTH:6,CENTER-2:24"
|
||||
#define ui_nifsc_jumptoowner "SOUTH:6,CENTER-1:24"
|
||||
#define ui_nifsc_nme "SOUTH:6,CENTER:24"
|
||||
#define ui_nifsc_nsay "SOUTH:6,CENTER+1:24"
|
||||
|
||||
// Rig panel
|
||||
#define ui_rig_deco1 "WEST:-7, SOUTH+5"
|
||||
#define ui_rig_deco2 "WEST:-7, SOUTH+6"
|
||||
|
||||
30
code/_onclick/hud/screen_objects_zz_ch.dm
Normal file
30
code/_onclick/hud/screen_objects_zz_ch.dm
Normal file
@@ -0,0 +1,30 @@
|
||||
//Invesitgating a runtime made me discover that all simplemobs have HUD on hands set to themselves
|
||||
//Which cause this original code to die because the mob does not have a mymob var...
|
||||
//So yeah this is why we now check if it is type of mob first...
|
||||
//Is this pretty? Fuck no, but its how i know to fix it -shark
|
||||
//Oh also the swap button on simple mob hands has hud set to null so we also need to catch that.
|
||||
/obj/screen/inventory/add_overlays()
|
||||
if(!hud) //Simplemob swap hands button has this set to null :)
|
||||
return
|
||||
var/mob/user
|
||||
if(istype(hud,/mob )) //Simplemob hands directly reference the mob in hud, dont ask me.
|
||||
user = hud
|
||||
else
|
||||
user = hud.mymob //original intended behaviour
|
||||
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)
|
||||
102
code/_onclick/hud/soulcatcher_guest.dm
Normal file
102
code/_onclick/hud/soulcatcher_guest.dm
Normal file
@@ -0,0 +1,102 @@
|
||||
/obj/screen/nifsc
|
||||
icon = 'icons/mob/screen_nifsc.dmi'
|
||||
|
||||
/obj/screen/nifsc/MouseEntered(location,control,params)
|
||||
flick(icon_state + "_anim", src)
|
||||
openToolTip(usr, src, params, title = name, content = desc)
|
||||
|
||||
/obj/screen/nifsc/MouseExited()
|
||||
closeToolTip(usr)
|
||||
|
||||
/obj/screen/nifsc/Click()
|
||||
closeToolTip(usr)
|
||||
|
||||
/obj/screen/nifsc/reenter
|
||||
name = "Re-enter NIF"
|
||||
desc = "Return into the NIF"
|
||||
icon_state = "reenter"
|
||||
|
||||
/obj/screen/nifsc/reenter/Click()
|
||||
..()
|
||||
var/mob/living/carbon/brain/caught_soul/CS = usr
|
||||
CS.reenter_soulcatcher()
|
||||
|
||||
/obj/screen/nifsc/arproj
|
||||
name = "AR project"
|
||||
desc = "Project your form into Augmented Reality for those around your predator with the appearance of your loaded character."
|
||||
icon_state = "arproj"
|
||||
|
||||
/obj/screen/nifsc/arproj/Click()
|
||||
..()
|
||||
var/mob/living/carbon/brain/caught_soul/CS = usr
|
||||
CS.ar_project()
|
||||
|
||||
/obj/screen/nifsc/jumptoowner
|
||||
name = "Jump back to host"
|
||||
desc = "Jumb back to the Soulcather host"
|
||||
icon_state = "jump"
|
||||
|
||||
/obj/screen/nifsc/jumptoowner/Click()
|
||||
..()
|
||||
var/mob/living/carbon/brain/caught_soul/CS = usr
|
||||
CS.jump_to_owner()
|
||||
|
||||
/obj/screen/nifsc/nme
|
||||
name = "Emote into Soulcatcher"
|
||||
desc = "Emote into the NIF's Soulcatcher (circumventing AR emoting)"
|
||||
icon_state = "nme"
|
||||
|
||||
/obj/screen/nifsc/nme/Click()
|
||||
..()
|
||||
var/mob/living/carbon/brain/caught_soul/CS = usr
|
||||
CS.nme()
|
||||
|
||||
/obj/screen/nifsc/nsay
|
||||
name = "Speak into Soulcatcher"
|
||||
desc = "Speak into the NIF's Soulcatcher (circumventing AR speaking)"
|
||||
icon_state = "nsay"
|
||||
|
||||
/obj/screen/nifsc/nsay/Click()
|
||||
..()
|
||||
var/mob/living/carbon/brain/caught_soul/CS = usr
|
||||
CS.nsay()
|
||||
|
||||
|
||||
/mob/living/carbon/brain/caught_soul/create_mob_hud(datum/hud/HUD, apply_to_client = TRUE)
|
||||
..()
|
||||
|
||||
var/list/adding = list()
|
||||
HUD.adding = adding
|
||||
|
||||
var/obj/screen/using
|
||||
|
||||
using = new /obj/screen/nifsc/reenter()
|
||||
using.screen_loc = ui_nifsc_reenter
|
||||
using.hud = src
|
||||
adding += using
|
||||
|
||||
using = new /obj/screen/nifsc/arproj()
|
||||
using.screen_loc = ui_nifsc_arproj
|
||||
using.hud = src
|
||||
adding += using
|
||||
|
||||
using = new /obj/screen/nifsc/jumptoowner()
|
||||
using.screen_loc = ui_nifsc_jumptoowner
|
||||
using.hud = src
|
||||
adding += using
|
||||
|
||||
using = new /obj/screen/nifsc/nme()
|
||||
using.screen_loc = ui_nifsc_nme
|
||||
using.hud = src
|
||||
adding += using
|
||||
|
||||
using = new /obj/screen/nifsc/nsay()
|
||||
using.screen_loc = ui_nifsc_nsay
|
||||
using.hud = src
|
||||
adding += using
|
||||
|
||||
|
||||
if(client && apply_to_client)
|
||||
client.screen = list()
|
||||
client.screen += HUD.adding
|
||||
client.screen += client.void
|
||||
@@ -9,6 +9,14 @@
|
||||
|
||||
var/vorefootstep_volume = 75 //In future see about making a function to adjust volume serverside in config.txt, easy to do with reenable values. - Jack
|
||||
|
||||
var/nodebot_enabled = 0 //So, nodebot is a supplement to the TGS discord bot pretty much. For things likes faxes and the manifest it's very helpful because it's able to render html into an image and post it.
|
||||
var/nodebot_location //We need to print the manifest to this location so nodebot can render it to chat. //NOTE: TO BE REPLACED BY BETTER CODE FOR FETCHING MANIFEST
|
||||
var/ahelp_channel_tag //This is for tgs4 channels, if you're not running on tgs4, this won't work anyways. If it's not set, it will default to the admin channel.
|
||||
var/discord_faxes_autoprint = 0 //Only turn this on if you're not using the nodebot.
|
||||
var/discord_faxes_disabled = 0 //Turn this off if you don't want the TGS bot sending you messages whenever a fax is sent to central.
|
||||
var/discord_ahelps_disabled = 0 //Turn this off if you don't want the TGS bot sending you messages whenever an ahelp ticket is created.
|
||||
var/discord_ahelps_all = 0 //Turn this on if you want all admin-PMs to go to be sent to discord, and not only the first message of a ticket.
|
||||
|
||||
/hook/startup/proc/read_ch_config()
|
||||
var/list/Lines = file2list("config/config.txt")
|
||||
for(var/t in Lines)
|
||||
@@ -22,11 +30,11 @@
|
||||
|
||||
var/pos = findtext(t, " ")
|
||||
var/name = null
|
||||
// var/value = null //Commenting out because config doesn't contain any values at the moment. - Jonathan
|
||||
var/value = null
|
||||
|
||||
if (pos)
|
||||
name = lowertext(copytext(t, 1, pos))
|
||||
// value = copytext(t, pos + 1) //Commenting out because config doesn't contain any values at the moment. - Jonathan
|
||||
value = copytext(t, pos + 1)
|
||||
else
|
||||
name = lowertext(t)
|
||||
|
||||
@@ -40,4 +48,18 @@
|
||||
config.use_jobwhitelist = 1
|
||||
if ("disable_emojis")
|
||||
config.emojis = 0
|
||||
if ("nodebot_enabled")
|
||||
config.nodebot_enabled = 1
|
||||
if ("discord_faxes_autoprint")
|
||||
config.discord_faxes_autoprint = 1
|
||||
if ("discord_faxes_disabled")
|
||||
config.discord_faxes_disabled = 1
|
||||
if ("discord_ahelps_disabled")
|
||||
config.discord_ahelps_disabled = 1
|
||||
if ("discord_ahelps_all")
|
||||
config.discord_ahelps_all = 1
|
||||
if ("nodebot_location")
|
||||
config.nodebot_location = value
|
||||
if ("ahelp_channel_tag")
|
||||
config.ahelp_channel_tag = value
|
||||
return 1
|
||||
|
||||
370
code/controllers/subsystems/dbcore.dm
Normal file
370
code/controllers/subsystems/dbcore.dm
Normal file
@@ -0,0 +1,370 @@
|
||||
SUBSYSTEM_DEF(dbcore)
|
||||
name = "Database"
|
||||
flags = SS_BACKGROUND
|
||||
wait = 1 MINUTES
|
||||
init_order = INIT_ORDER_DBCORE
|
||||
var/failed_connection_timeout = 0
|
||||
|
||||
var/schema_mismatch = 0
|
||||
var/db_minor = 0
|
||||
var/db_major = 0
|
||||
var/failed_connections = 0
|
||||
|
||||
var/last_error
|
||||
var/list/active_queries = list()
|
||||
|
||||
var/connection // Arbitrary handle returned from rust_g.
|
||||
|
||||
/datum/controller/subsystem/dbcore/Initialize()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/dbcore/fire()
|
||||
for(var/I in active_queries)
|
||||
var/DBQuery/Q = I
|
||||
if(world.time - Q.last_activity_time > (5 MINUTES))
|
||||
message_admins("Found undeleted query, please check the server logs and notify coders.")
|
||||
log_debug("Undeleted query: \"[Q.sql]\" LA: [Q.last_activity] LAT: [Q.last_activity_time]")
|
||||
qdel(Q)
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/dbcore/Recover()
|
||||
connection = SSdbcore.connection
|
||||
|
||||
/datum/controller/subsystem/dbcore/Shutdown()
|
||||
//This is as close as we can get to the true round end before Disconnect() without changing where it's called, defeating the reason this is a subsystem
|
||||
if(IsConnected())
|
||||
Disconnect()
|
||||
|
||||
//nu
|
||||
/datum/controller/subsystem/dbcore/can_vv_get(var_name)
|
||||
return var_name != NAMEOF(src, connection) && var_name != NAMEOF(src, active_queries) && ..()
|
||||
|
||||
/datum/controller/subsystem/dbcore/vv_edit_var(var_name, var_value)
|
||||
if(var_name == NAMEOF(src, connection))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/Connect()
|
||||
if(IsConnected())
|
||||
return TRUE
|
||||
|
||||
if(failed_connection_timeout <= world.time) //it's been more than 5 seconds since we failed to connect, reset the counter
|
||||
failed_connections = 0
|
||||
|
||||
if(failed_connections > 5) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to connect for 5 seconds.
|
||||
failed_connection_timeout = world.time + 50
|
||||
return FALSE
|
||||
|
||||
if(!config.sql_enabled)
|
||||
return FALSE
|
||||
|
||||
var/user = sqlfdbklogin
|
||||
var/pass = sqlfdbkpass
|
||||
var/db = sqlfdbkdb
|
||||
var/address = sqladdress
|
||||
var/port = text2num(sqlport)
|
||||
var/timeout = 10
|
||||
var/thread_limit = 50
|
||||
|
||||
var/result = json_decode(rustg_sql_connect_pool(json_encode(list(
|
||||
"host" = address,
|
||||
"port" = port,
|
||||
"user" = user,
|
||||
"pass" = pass,
|
||||
"db_name" = db,
|
||||
"read_timeout" = timeout,
|
||||
"write_timeout" = timeout,
|
||||
"max_threads" = thread_limit,
|
||||
))))
|
||||
. = (result["status"] == "ok")
|
||||
if (.)
|
||||
connection = result["handle"]
|
||||
else
|
||||
connection = null
|
||||
last_error = result["data"]
|
||||
log_world("Connect() failed | [last_error]")
|
||||
++failed_connections
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/CheckSchemaVersion()
|
||||
if(config.sql_enabled)
|
||||
if(Connect())
|
||||
log_world("Database connection established.")
|
||||
else
|
||||
log_debug("Your server failed to establish a connection with the database.")
|
||||
else
|
||||
log_debug("Database is not enabled in configuration.")
|
||||
|
||||
/*/datum/controller/subsystem/dbcore/proc/SetRoundID()
|
||||
if(!Connect())
|
||||
return
|
||||
var/DBQuery/query_round_initialize = SSdbcore.NewQuery(
|
||||
"INSERT INTO [format_table_name("round")] (initialize_datetime, server_ip, server_port) VALUES (Now(), INET_ATON(:internet_address), :port)",
|
||||
list("internet_address" = world.internet_address || "0", "port" = "[world.port]")
|
||||
)
|
||||
query_round_initialize.Execute(async = FALSE)
|
||||
GLOB.round_id = "[query_round_initialize.last_insert_id]"
|
||||
qdel(query_round_initialize)
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/SetRoundStart()
|
||||
if(!Connect())
|
||||
return
|
||||
var/DBQuery/query_round_start = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("round")] SET start_datetime = Now() WHERE id = :round_id",
|
||||
list("round_id" = GLOB.round_id)
|
||||
)
|
||||
query_round_start.Execute()
|
||||
qdel(query_round_start)
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/SetRoundEnd()
|
||||
if(!Connect())
|
||||
return
|
||||
var/DBQuery/query_round_end = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("round")] SET end_datetime = Now(), game_mode_result = :game_mode_result, station_name = :station_name WHERE id = :round_id",
|
||||
list("game_mode_result" = SSticker.mode_result, "station_name" = station_name(), "round_id" = GLOB.round_id)
|
||||
)
|
||||
query_round_end.Execute()
|
||||
qdel(query_round_end)*/
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/Disconnect()
|
||||
failed_connections = 0
|
||||
if (connection)
|
||||
rustg_sql_disconnect_pool(connection)
|
||||
connection = null
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/IsConnected()
|
||||
if (!config.sql_enabled)
|
||||
return FALSE
|
||||
if (!connection)
|
||||
return FALSE
|
||||
return json_decode(rustg_sql_connected(connection))["status"] == "online"
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/ErrorMsg()
|
||||
if(!config.sql_enabled)
|
||||
return "Database disabled by configuration"
|
||||
return last_error
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/ReportError(error)
|
||||
last_error = error
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/NewQuery(sql_query, arguments)
|
||||
if(IsAdminAdvancedProcCall())
|
||||
message_admins("ERROR: Advanced admin proc call led to sql query. Query has been blocked")
|
||||
return FALSE
|
||||
return new /DBQuery(connection, sql_query, arguments)
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/QuerySelect(list/querys, warn = FALSE, qdel = FALSE)
|
||||
if (!islist(querys))
|
||||
if (!istype(querys, /DBQuery))
|
||||
CRASH("Invalid query passed to QuerySelect: [querys]")
|
||||
querys = list(querys)
|
||||
|
||||
for (var/thing in querys)
|
||||
var/DBQuery/query = thing
|
||||
if (warn)
|
||||
INVOKE_ASYNC(query, /DBQuery.proc/warn_execute)
|
||||
else
|
||||
INVOKE_ASYNC(query, /DBQuery.proc/Execute)
|
||||
|
||||
for (var/thing in querys)
|
||||
var/DBQuery/query = thing
|
||||
UNTIL(!query.in_progress)
|
||||
if (qdel)
|
||||
qdel(query)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Takes a list of rows (each row being an associated list of column => value) and inserts them via a single mass query.
|
||||
Rows missing columns present in other rows will resolve to SQL NULL
|
||||
You are expected to do your own escaping of the data, and expected to provide your own quotes for strings.
|
||||
The duplicate_key arg can be true to automatically generate this part of the query
|
||||
or set to a string that is appended to the end of the query
|
||||
Ignore_errors instructes mysql to continue inserting rows if some of them have errors.
|
||||
the erroneous row(s) aren't inserted and there isn't really any way to know why or why errored
|
||||
Delayed insert mode was removed in mysql 7 and only works with MyISAM type tables,
|
||||
It was included because it is still supported in mariadb.
|
||||
It does not work with duplicate_key and the mysql server ignores it in those cases
|
||||
*/
|
||||
/datum/controller/subsystem/dbcore/proc/MassInsert(table, list/rows, duplicate_key = FALSE, ignore_errors = FALSE, delayed = FALSE, warn = FALSE, async = TRUE, special_columns = null)
|
||||
if (!table || !rows || !istype(rows))
|
||||
return
|
||||
|
||||
// Prepare column list
|
||||
var/list/columns = list()
|
||||
var/list/has_question_mark = list()
|
||||
for (var/list/row in rows)
|
||||
for (var/column in row)
|
||||
columns[column] = "?"
|
||||
has_question_mark[column] = TRUE
|
||||
for (var/column in special_columns)
|
||||
columns[column] = special_columns[column]
|
||||
has_question_mark[column] = findtext(special_columns[column], "?")
|
||||
|
||||
// Prepare SQL query full of placeholders
|
||||
var/list/query_parts = list("INSERT")
|
||||
if (delayed)
|
||||
query_parts += " DELAYED"
|
||||
if (ignore_errors)
|
||||
query_parts += " IGNORE"
|
||||
query_parts += " INTO "
|
||||
query_parts += table
|
||||
query_parts += "\n([columns.Join(", ")])\nVALUES"
|
||||
|
||||
var/list/arguments = list()
|
||||
var/has_row = FALSE
|
||||
for (var/list/row in rows)
|
||||
if (has_row)
|
||||
query_parts += ","
|
||||
query_parts += "\n ("
|
||||
var/has_col = FALSE
|
||||
for (var/column in columns)
|
||||
if (has_col)
|
||||
query_parts += ", "
|
||||
if (has_question_mark[column])
|
||||
var/name = "p[arguments.len]"
|
||||
query_parts += replacetext(columns[column], "?", ":[name]")
|
||||
arguments[name] = row[column]
|
||||
else
|
||||
query_parts += columns[column]
|
||||
has_col = TRUE
|
||||
query_parts += ")"
|
||||
has_row = TRUE
|
||||
|
||||
if (duplicate_key == TRUE)
|
||||
var/list/column_list = list()
|
||||
for (var/column in columns)
|
||||
column_list += "[column] = VALUES([column])"
|
||||
query_parts += "\nON DUPLICATE KEY UPDATE [column_list.Join(", ")]"
|
||||
else if (duplicate_key != FALSE)
|
||||
query_parts += duplicate_key
|
||||
|
||||
var/DBQuery/Query = NewQuery(query_parts.Join(), arguments)
|
||||
if (warn)
|
||||
. = Query.warn_execute(async)
|
||||
else
|
||||
. = Query.Execute(async)
|
||||
qdel(Query)
|
||||
|
||||
/DBQuery
|
||||
// Inputs
|
||||
var/connection
|
||||
var/sql
|
||||
var/arguments
|
||||
|
||||
// Status information
|
||||
var/in_progress
|
||||
var/last_error
|
||||
var/last_activity
|
||||
var/last_activity_time
|
||||
|
||||
// Output
|
||||
var/list/list/rows
|
||||
var/next_row_to_take = 1
|
||||
var/affected
|
||||
var/last_insert_id
|
||||
|
||||
var/list/item //list of data values populated by NextRow()
|
||||
|
||||
/DBQuery/New(connection, sql, arguments)
|
||||
SSdbcore.active_queries[src] = TRUE
|
||||
Activity("Created")
|
||||
item = list()
|
||||
|
||||
src.connection = connection
|
||||
src.sql = sql
|
||||
src.arguments = arguments
|
||||
|
||||
/DBQuery/Destroy()
|
||||
Close()
|
||||
SSdbcore.active_queries -= src
|
||||
return ..()
|
||||
|
||||
/DBQuery/CanProcCall(proc_name)
|
||||
//fuck off kevinz
|
||||
return FALSE
|
||||
|
||||
/DBQuery/proc/Activity(activity)
|
||||
last_activity = activity
|
||||
last_activity_time = world.time
|
||||
|
||||
/DBQuery/proc/warn_execute(async = TRUE)
|
||||
. = Execute(async)
|
||||
if(!.)
|
||||
to_chat(usr, "<span class='danger'>A SQL error occurred during this operation, check the server logs.</span>")
|
||||
|
||||
/DBQuery/proc/Execute(async = TRUE, log_error = TRUE)
|
||||
Activity("Execute")
|
||||
if(in_progress)
|
||||
CRASH("Attempted to start a new query while waiting on the old one")
|
||||
|
||||
if(!SSdbcore.IsConnected())
|
||||
last_error = "No connection!"
|
||||
return FALSE
|
||||
|
||||
var/start_time
|
||||
if(!async)
|
||||
start_time = REALTIMEOFDAY
|
||||
Close()
|
||||
. = run_query(async)
|
||||
var/timed_out = !. && findtext(last_error, "Operation timed out")
|
||||
if(!. && log_error)
|
||||
log_debug("[last_error] | Query used: [sql] | Arguments: [json_encode(arguments)]")
|
||||
if(!async && timed_out)
|
||||
log_debug("Query execution started at [start_time]")
|
||||
log_debug("Query execution ended at [REALTIMEOFDAY]")
|
||||
log_debug("Slow query timeout detected.")
|
||||
log_debug("Query used: [sql]")
|
||||
slow_query_check()
|
||||
|
||||
/DBQuery/proc/run_query(async)
|
||||
var/job_result_str
|
||||
|
||||
if (async)
|
||||
var/job_id = rustg_sql_query_async(connection, sql, json_encode(arguments))
|
||||
in_progress = TRUE
|
||||
UNTIL((job_result_str = rustg_sql_check_query(job_id)) != RUSTG_JOB_NO_RESULTS_YET)
|
||||
in_progress = FALSE
|
||||
|
||||
if (job_result_str == RUSTG_JOB_ERROR)
|
||||
last_error = job_result_str
|
||||
return FALSE
|
||||
else
|
||||
job_result_str = rustg_sql_query_blocking(connection, sql, json_encode(arguments))
|
||||
|
||||
var/result = json_decode(job_result_str)
|
||||
switch (result["status"])
|
||||
if ("ok")
|
||||
rows = result["rows"]
|
||||
affected = result["affected"]
|
||||
last_insert_id = result["last_insert_id"]
|
||||
return TRUE
|
||||
if ("err")
|
||||
last_error = result["data"]
|
||||
return FALSE
|
||||
if ("offline")
|
||||
last_error = "offline"
|
||||
return FALSE
|
||||
|
||||
/DBQuery/proc/RowCount()
|
||||
return rows.len
|
||||
|
||||
/DBQuery/proc/slow_query_check()
|
||||
message_admins("HEY! A database query timed out.")
|
||||
|
||||
/DBQuery/proc/NextRow(async = TRUE)
|
||||
Activity("NextRow")
|
||||
|
||||
if (rows && next_row_to_take <= rows.len)
|
||||
item = rows[next_row_to_take]
|
||||
next_row_to_take++
|
||||
return !!item
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/DBQuery/proc/ErrorMsg()
|
||||
return last_error
|
||||
|
||||
/DBQuery/proc/Close()
|
||||
rows = null
|
||||
item = null
|
||||
@@ -5,7 +5,6 @@ SUBSYSTEM_DEF(overlays)
|
||||
priority = FIRE_PRIORITY_OVERLAYS
|
||||
init_order = INIT_ORDER_OVERLAY
|
||||
|
||||
var/initialized = FALSE
|
||||
var/list/queue // Queue of atoms needing overlay compiling (TODO-VERIFY!)
|
||||
var/list/stats
|
||||
var/list/overlay_icon_state_caches // Cache thing
|
||||
@@ -22,7 +21,6 @@ var/global/image/appearance_bro = new() // Temporarily super-global because of B
|
||||
stats = list()
|
||||
|
||||
/datum/controller/subsystem/overlays/Initialize()
|
||||
initialized = TRUE
|
||||
fire(mc_check = FALSE)
|
||||
..()
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ SUBSYSTEM_DEF(persist)
|
||||
return
|
||||
|
||||
establish_db_connection()
|
||||
if(!dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected()) //CHOMPEdit TGSQL
|
||||
src.currentrun.Cut()
|
||||
return
|
||||
if(!resumed)
|
||||
@@ -84,10 +84,11 @@ SUBSYSTEM_DEF(persist)
|
||||
var/sql_dpt = sql_sanitize_text(department_earning)
|
||||
var/sql_bal = text2num("[C.department_hours[department_earning]]")
|
||||
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)")
|
||||
var/list/sqlargs = list("t_ckey" = sql_ckey, "t_department" = sql_dpt) //CHOMPEdit TGSQL
|
||||
var/DBQuery/query = SSdbcore.NewQuery("INSERT INTO vr_player_hours (ckey, department, hours, total_hours) VALUES (:t_ckey, :t_department, [sql_bal], [sql_total]) ON DUPLICATE KEY UPDATE hours = VALUES(hours), total_hours = VALUES(total_hours)", sqlargs) //CHOMPEdit TGSQL
|
||||
if(!query.Execute()) //CHOMPEdit
|
||||
log_admin(query.ErrorMsg()) //CHOMPEdit
|
||||
|
||||
qdel(query) //CHOMPEdit TGSQL
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ PROCESSING_SUBSYSTEM_DEF(chemistry)
|
||||
/datum/controller/subsystem/processing/chemistry/Initialize()
|
||||
initialize_chemical_reactions()
|
||||
initialize_chemical_reagents()
|
||||
..()
|
||||
|
||||
//Chemical Reactions - Initialises all /datum/chemical_reaction into a list
|
||||
// It is filtered into multiple lists within a list.
|
||||
|
||||
@@ -4,9 +4,6 @@
|
||||
// Also handles initialization and processing of overmap sectors.
|
||||
//
|
||||
|
||||
// This global variable exists for legacy support so we don't have to rename every shuttle_controller to SSshuttles yet.
|
||||
var/global/datum/controller/subsystem/shuttles/shuttle_controller
|
||||
|
||||
SUBSYSTEM_DEF(shuttles)
|
||||
name = "Shuttles"
|
||||
wait = 2 SECONDS
|
||||
@@ -35,9 +32,6 @@ SUBSYSTEM_DEF(shuttles)
|
||||
|
||||
var/tmp/list/current_run // Shuttles remaining to process this fire() tick
|
||||
|
||||
/datum/controller/subsystem/shuttles/PreInit()
|
||||
global.shuttle_controller = src // TODO - Remove this! Change everything to point at SSshuttles intead
|
||||
|
||||
/datum/controller/subsystem/shuttles/Initialize(timeofday)
|
||||
last_landmark_registration_time = world.time
|
||||
// Find all declared shuttle datums and initailize them. (Okay, queue them for initialization a few lines further down)
|
||||
|
||||
@@ -49,10 +49,7 @@ var/global/datum/controller/subsystem/ticker/ticker
|
||||
/datum/controller/subsystem/ticker/Initialize()
|
||||
pregame_timeleft = config.pregame_time
|
||||
send2mainirc("Server lobby is loaded and open at byond://[config.serverurl ? config.serverurl : (config.server ? config.server : "[world.address]:[world.port]")]")
|
||||
|
||||
// Set up the global announcer
|
||||
GLOB.autospeaker = new (null, null, null, 1)
|
||||
|
||||
GLOB.autospeaker = new (null, null, null, 1) //Set up Global Announcer
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/ticker/fire(resumed = FALSE)
|
||||
@@ -186,11 +183,6 @@ var/global/datum/controller/subsystem/ticker/ticker
|
||||
if(adm["total"] == 0)
|
||||
send2adminirc("A round has started with no admins online.")
|
||||
|
||||
/* supply_controller.process() //Start the supply shuttle regenerating points -- TLE // handled in scheduler
|
||||
master_controller.process() //Start master_controller.process()
|
||||
lighting_controller.process() //Start processing DynamicAreaLighting updates
|
||||
*/
|
||||
|
||||
current_state = GAME_STATE_PLAYING
|
||||
Master.SetRunLevel(RUNLEVEL_GAME)
|
||||
|
||||
|
||||
@@ -326,6 +326,15 @@
|
||||
category = list("Arms and Ammunition")
|
||||
hidden = 1*/
|
||||
|
||||
/*
|
||||
* High Caliber
|
||||
*/
|
||||
|
||||
/datum/category_item/autolathe/arms/rifle_145
|
||||
name = "14.5mm round (sabot)"
|
||||
path = /obj/item/ammo_casing/a145/highvel
|
||||
hidden = 1
|
||||
|
||||
///////////////////////////////
|
||||
/*Ammo clips and Speedloaders*/
|
||||
///////////////////////////////
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
/datum/category_item/autolathe/New()
|
||||
..()
|
||||
var/obj/item/I = new path()
|
||||
var/obj/item/I
|
||||
if(path)
|
||||
I = new path()
|
||||
|
||||
if(!I) // Something has gone horribly wrong, or right.
|
||||
log_debug("[name] created an Autolathe design without an assigned path. This is expected for only the Material Sheet generation.")
|
||||
return
|
||||
|
||||
if(I.matter && !resources)
|
||||
resources = list()
|
||||
for(var/material in I.matter)
|
||||
@@ -57,6 +64,42 @@
|
||||
name = "Tools"
|
||||
category_item_type = /datum/category_item/autolathe/tools
|
||||
|
||||
/datum/category_group/autolathe/materials
|
||||
name = "Materials"
|
||||
category_item_type = /datum/category_item/autolathe/materials
|
||||
|
||||
/datum/category_group/autolathe/materials/New()
|
||||
..()
|
||||
|
||||
for(var/Name in name_to_material)
|
||||
var/datum/material/M = name_to_material[Name]
|
||||
|
||||
if(!M.stack_type) // Shouldn't happen, but might. Never know.
|
||||
continue
|
||||
|
||||
if(istype(M, /datum/material/alienalloy))
|
||||
continue
|
||||
|
||||
var/obj/item/stack/material/Mat = new M.stack_type()
|
||||
|
||||
if(Mat.name in items_by_name)
|
||||
qdel(Mat)
|
||||
continue
|
||||
|
||||
var/datum/category_item/autolathe/materials/WorkDat = new(src)
|
||||
|
||||
WorkDat.name = "[Mat.name]"
|
||||
WorkDat.resources = Mat.matter.Copy()
|
||||
WorkDat.is_stack = TRUE
|
||||
WorkDat.no_scale = TRUE
|
||||
WorkDat.max_stack = Mat.max_amount
|
||||
WorkDat.path = M.stack_type
|
||||
|
||||
qdel(Mat)
|
||||
|
||||
items |= WorkDat
|
||||
items_by_name[WorkDat.name] = WorkDat
|
||||
|
||||
/*******************
|
||||
* Category entries *
|
||||
*******************/
|
||||
|
||||
@@ -26,6 +26,12 @@
|
||||
name = "mechanical trap"
|
||||
path =/obj/item/weapon/beartrap
|
||||
|
||||
/datum/category_item/autolathe/devices/barbedwire
|
||||
name = "barbed wire"
|
||||
path = /obj/item/weapon/material/barbedwire
|
||||
hidden = 1
|
||||
resources = list(DEFAULT_WALL_MATERIAL = 10000)
|
||||
|
||||
/datum/category_item/autolathe/devices/electropack
|
||||
name = "electropack"
|
||||
path =/obj/item/device/radio/electropack
|
||||
|
||||
@@ -4,4 +4,24 @@
|
||||
|
||||
/datum/category_item/autolathe/engineering/id_restorer
|
||||
name = "ID restoration console electronics"
|
||||
path =/obj/item/weapon/circuitboard/id_restorer
|
||||
path =/obj/item/weapon/circuitboard/id_restorer
|
||||
|
||||
/datum/category_item/autolathe/engineering/oven
|
||||
name = "oven electronics"
|
||||
path =/obj/item/weapon/circuitboard/oven
|
||||
|
||||
/datum/category_item/autolathe/engineering/fryer
|
||||
name = "fryer electronics"
|
||||
path =/obj/item/weapon/circuitboard/fryer
|
||||
|
||||
/datum/category_item/autolathe/engineering/grill
|
||||
name = "grill electronics"
|
||||
path =/obj/item/weapon/circuitboard/grill
|
||||
|
||||
/datum/category_item/autolathe/engineering/cerealmaker
|
||||
name = "cereal maker electronics"
|
||||
path =/obj/item/weapon/circuitboard/cerealmaker
|
||||
|
||||
/datum/category_item/autolathe/engineering/candymachine
|
||||
name = "candy machine electronics"
|
||||
path =/obj/item/weapon/circuitboard/candymachine
|
||||
@@ -85,44 +85,6 @@
|
||||
name = "welding mask"
|
||||
path =/obj/item/clothing/head/welding
|
||||
|
||||
/datum/category_item/autolathe/general/metal
|
||||
name = "steel sheets"
|
||||
path =/obj/item/stack/material/steel
|
||||
is_stack = TRUE
|
||||
no_scale = TRUE //prevents material duplication exploits
|
||||
|
||||
/datum/category_item/autolathe/general/glass
|
||||
name = "glass sheets"
|
||||
path =/obj/item/stack/material/glass
|
||||
is_stack = TRUE
|
||||
no_scale = TRUE //prevents material duplication exploits
|
||||
|
||||
/datum/category_item/autolathe/general/rglass
|
||||
name = "reinforced glass sheets"
|
||||
path =/obj/item/stack/material/glass/reinforced
|
||||
is_stack = TRUE
|
||||
no_scale = TRUE //prevents material duplication exploits
|
||||
|
||||
/datum/category_item/autolathe/general/rods
|
||||
name = "metal rods"
|
||||
path =/obj/item/stack/rods
|
||||
is_stack = TRUE
|
||||
no_scale = TRUE //prevents material duplication exploits
|
||||
|
||||
/datum/category_item/autolathe/general/plasteel
|
||||
name = "plasteel sheets"
|
||||
path =/obj/item/stack/material/plasteel
|
||||
is_stack = TRUE
|
||||
no_scale = TRUE //prevents material duplication exploits
|
||||
resources = list(MAT_PLASTEEL = 2000)
|
||||
|
||||
/datum/category_item/autolathe/general/plastic
|
||||
name = "plastic sheets"
|
||||
path =/obj/item/stack/material/plastic
|
||||
is_stack = TRUE
|
||||
no_scale = TRUE //prevents material duplication exploits
|
||||
resources = list(MAT_PLASTIC = 2000)
|
||||
|
||||
//TFF 24/12/19 - Let people print more spray bottles if needed.
|
||||
/datum/category_item/autolathe/general/spraybottle
|
||||
name = "spray bottle"
|
||||
|
||||
38
code/datums/autolathe/materials.dm
Normal file
38
code/datums/autolathe/materials.dm
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
/datum/category_item/autolathe/materials/metal
|
||||
name = "steel sheets"
|
||||
path =/obj/item/stack/material/steel
|
||||
is_stack = TRUE
|
||||
no_scale = TRUE //prevents material duplication exploits
|
||||
|
||||
/datum/category_item/autolathe/materials/glass
|
||||
name = "glass sheets"
|
||||
path =/obj/item/stack/material/glass
|
||||
is_stack = TRUE
|
||||
no_scale = TRUE //prevents material duplication exploits
|
||||
|
||||
/datum/category_item/autolathe/materials/rglass
|
||||
name = "reinforced glass sheets"
|
||||
path =/obj/item/stack/material/glass/reinforced
|
||||
is_stack = TRUE
|
||||
no_scale = TRUE //prevents material duplication exploits
|
||||
|
||||
/datum/category_item/autolathe/materials/rods
|
||||
name = "metal rods"
|
||||
path =/obj/item/stack/rods
|
||||
is_stack = TRUE
|
||||
no_scale = TRUE //prevents material duplication exploits
|
||||
|
||||
/datum/category_item/autolathe/materials/plasteel
|
||||
name = "plasteel sheets"
|
||||
path =/obj/item/stack/material/plasteel
|
||||
is_stack = TRUE
|
||||
no_scale = TRUE //prevents material duplication exploits
|
||||
resources = list(MAT_PLASTEEL = 2000)
|
||||
|
||||
/datum/category_item/autolathe/materials/plastic
|
||||
name = "plastic sheets"
|
||||
path =/obj/item/stack/material/plastic
|
||||
is_stack = TRUE
|
||||
no_scale = TRUE //prevents material duplication exploits
|
||||
resources = list(MAT_PLASTIC = 2000)
|
||||
@@ -48,6 +48,11 @@
|
||||
path = /obj/item/weapon/reagent_containers/spray
|
||||
resources = list(MAT_PLASTIC = 2000)
|
||||
|
||||
/datum/category_item/autolathe/devices/slowwire
|
||||
name = "snare wire"
|
||||
path = /obj/item/weapon/material/barbedwire/plastic
|
||||
resources = list(MAT_PLASTIC = 10000)
|
||||
|
||||
/datum/category_item/autolathe/tools/spraynozzle
|
||||
name = "spray nozzle"
|
||||
path = /obj/item/weapon/reagent_containers/spray
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
var/static/list/locked = list()
|
||||
|
||||
|
||||
/datum/datacore/proc/get_manifest(monochrome, OOC)
|
||||
/datum/datacore/proc/get_manifest(monochrome, OOC,var/snowflake = FALSE) //CHOMPStation Edit
|
||||
var/list/heads = new()
|
||||
var/list/sec = new()
|
||||
var/list/eng = new()
|
||||
@@ -40,8 +40,9 @@
|
||||
.manifest tr.alt td {[monochrome?"border-top-width: 2px":"background-color: [OOC?"#373737; color:white":"#DEF"]"]}
|
||||
</style></head>
|
||||
<table class="manifest" width='350px'>
|
||||
[snowflake?"<tr><th colspan=3 style = \"background-color: #026e6a\"><b>Online players:</b> [TGS_CLIENT_COUNT]</th></tr><tr><th colspan=3 style = \"background-color: #027a76\"><b>Crew members:</b> [data_core.general.len]</th></tr><tr class='head'>":""]
|
||||
<tr class='head'><th>Name</th><th>Rank</th><th>Activity</th></tr>
|
||||
"}
|
||||
"} //Also a chompstation edit with the snowflake stuff on line 43
|
||||
var/even = 0
|
||||
// sort mobs
|
||||
for(var/datum/data/record/t in data_core.general)
|
||||
@@ -329,7 +330,7 @@ var/global/list/PDA_Manifest = list()
|
||||
if(H.mind && !player_is_antag(H.mind, only_offstation_roles = 1))
|
||||
var/assignment = GetAssignment(H)
|
||||
var/hidden
|
||||
var/datum/job/J = SSjob.get_job(assignment)
|
||||
var/datum/job/J = SSjob.get_job(H.mind.assigned_role)
|
||||
hidden = J?.offmap_spawn
|
||||
|
||||
/* Note: Due to cached_character_icon, a number of emergent properties occur due to the initialization
|
||||
|
||||
@@ -47,7 +47,7 @@ GLOBAL_DATUM(revdata, /datum/getrev)
|
||||
. += "The following pull requests are currently test merged:"
|
||||
for(var/line in testmerge)
|
||||
var/datum/tgs_revision_information/test_merge/tm = line
|
||||
var/cm = tm.pull_request_commit
|
||||
var/cm = tm.head_commit //CHOMPStation Edit TGS4
|
||||
var/details = ": '" + html_encode(tm.title) + "' by " + html_encode(tm.author) + " at commit " + html_encode(copytext_char(cm, 1, 11))
|
||||
if(details && findtext(details, "\[s\]") && (!usr || !usr.client.holder))
|
||||
continue
|
||||
|
||||
@@ -55,6 +55,9 @@
|
||||
|
||||
var/rev_cooldown = 0
|
||||
var/tcrystals = 0
|
||||
var/list/purchase_log = new
|
||||
var/used_TC = 0
|
||||
|
||||
|
||||
// the world.time since the mob has been brigged, or -1 if not at all
|
||||
var/brigged_since = -1
|
||||
@@ -73,7 +76,7 @@
|
||||
|
||||
/datum/mind/New(var/key)
|
||||
src.key = key
|
||||
|
||||
purchase_log = list()
|
||||
..()
|
||||
|
||||
/datum/mind/proc/transfer_to(mob/living/new_character)
|
||||
@@ -510,8 +513,9 @@
|
||||
|
||||
//HUMAN
|
||||
/mob/living/carbon/human/mind_initialize()
|
||||
..()
|
||||
if(!mind.assigned_role) mind.assigned_role = USELESS_JOB //defualt //VOREStation Edit - Visitor not Assistant
|
||||
. = ..()
|
||||
if(!mind.assigned_role)
|
||||
mind.assigned_role = USELESS_JOB //defualt //VOREStation Edit - Visitor not Assistant
|
||||
|
||||
//slime
|
||||
/mob/living/simple_mob/slime/mind_initialize()
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
//VOREStation Edit - More cyberpunky
|
||||
/decl/hierarchy/outfit/job/security/detective/forensic
|
||||
name = OUTFIT_JOB_NAME("Forensic technician")
|
||||
head = /obj/item/clothing/head/helmet/detective_alt
|
||||
head = null
|
||||
suit = /datum/gear/uniform/detective_alt2
|
||||
uniform = /obj/item/clothing/under/det
|
||||
//VOREStation Edit End
|
||||
|
||||
@@ -39,7 +39,9 @@ var/list/outfits_decls_by_type_
|
||||
var/suit_store = null
|
||||
var/r_hand = null
|
||||
var/l_hand = null
|
||||
var/list/backpack_contents = list() // In the list(path=count,otherpath=count) format
|
||||
// In the list(path=count,otherpath=count) format
|
||||
var/list/uniform_accessories = list() // webbing, armbands etc - fits in slot_tie
|
||||
var/list/backpack_contents = list()
|
||||
|
||||
var/id_type
|
||||
var/id_desc
|
||||
@@ -145,6 +147,12 @@ var/list/outfits_decls_by_type_
|
||||
H.put_in_l_hand(new l_hand(H))
|
||||
if(r_hand)
|
||||
H.put_in_r_hand(new r_hand(H))
|
||||
|
||||
for(var/path in uniform_accessories)
|
||||
var/number = uniform_accessories[path]
|
||||
for(var/i=0,i<number,i++)
|
||||
H.equip_to_slot_or_del(new path(H), slot_tie)
|
||||
|
||||
if(H.species)
|
||||
H.species.equip_survival_gear(H, flags&OUTFIT_EXTENDED_SURVIVAL, flags&OUTFIT_COMPREHENSIVE_SURVIVAL)
|
||||
|
||||
|
||||
@@ -123,11 +123,12 @@ Keep outfits simple. Spawn with basic uniforms and minimal gear. Gear instead go
|
||||
/decl/hierarchy/outfit/job/pilot
|
||||
name = OUTFIT_JOB_NAME("Pilot")
|
||||
shoes = /obj/item/clothing/shoes/black
|
||||
uniform = /obj/item/clothing/under/rank/pilot1
|
||||
uniform = /obj/item/clothing/under/rank/pilot1/no_webbing
|
||||
suit = /obj/item/clothing/suit/storage/toggle/bomber/pilot
|
||||
gloves = /obj/item/clothing/gloves/fingerless
|
||||
glasses = /obj/item/clothing/glasses/fakesunglasses/aviator
|
||||
l_ear = /obj/item/device/radio/headset/pilot/alt
|
||||
uniform_accessories = list(/obj/item/clothing/accessory/storage/webbing/pilot1 = 1)
|
||||
id_slot = slot_wear_id
|
||||
pda_slot = slot_belt
|
||||
pda_type = /obj/item/device/pda
|
||||
|
||||
101
code/datums/roundstats/departmentgoal.dm
Normal file
101
code/datums/roundstats/departmentgoal.dm
Normal file
@@ -0,0 +1,101 @@
|
||||
|
||||
GLOBAL_LIST(department_goals)
|
||||
GLOBAL_LIST(active_department_goals)
|
||||
|
||||
/hook/startup/proc/initializeDepartmentGoals()
|
||||
GLOB.department_goals = list(GOAL_GENERAL, GOAL_MEDICAL, GOAL_SECURITY, GOAL_ENGINEERING, GOAL_CARGO, GOAL_RESEARCH)
|
||||
GLOB.active_department_goals = list(GOAL_GENERAL, GOAL_MEDICAL, GOAL_SECURITY, GOAL_ENGINEERING, GOAL_CARGO, GOAL_RESEARCH)
|
||||
|
||||
for(var/category in GLOB.department_goals)
|
||||
GLOB.department_goals[category] = list()
|
||||
|
||||
for(var/subtype in subtypesof(/datum/goal))
|
||||
var/datum/goal/SG = new subtype()
|
||||
|
||||
if(SG.name == "goal")
|
||||
continue
|
||||
|
||||
if(SG.category == category)
|
||||
GLOB.department_goals[category] |= SG
|
||||
|
||||
for(var/category in GLOB.active_department_goals)
|
||||
GLOB.active_department_goals[category] = list()
|
||||
var/list/cat_goals = GLOB.department_goals[category]
|
||||
|
||||
var/goal_count = rand(2,4)
|
||||
|
||||
for(var/count = 1 to goal_count)
|
||||
var/datum/goal/G
|
||||
|
||||
if(LAZYLEN(cat_goals))
|
||||
G = pick(cat_goals)
|
||||
|
||||
if(G)
|
||||
G.active_goal = TRUE
|
||||
cat_goals -= G
|
||||
|
||||
GLOB.active_department_goals[category] |= G
|
||||
return 1
|
||||
|
||||
/hook/roundend/proc/checkDepartmentGoals()
|
||||
for(var/category in GLOB.active_department_goals)
|
||||
var/list/cat_goals = GLOB.active_department_goals[category]
|
||||
|
||||
to_world("<span class='filter_system'><b>[category]</b></span>")
|
||||
|
||||
if(!LAZYLEN(cat_goals))
|
||||
to_world("<span class='filter_system'>There were no assigned goals!</span>")
|
||||
|
||||
else
|
||||
for(var/datum/goal/G in cat_goals)
|
||||
var/success = G.check_completion()
|
||||
to_world("<span class='filter_system'>[success ? "<span class='notice'>[G.name]</span>" : "<span class='warning'>[G.name]</span>"]</span>")
|
||||
to_world("<span class='filter_system'>[G.goal_text]</span>")
|
||||
return 1
|
||||
|
||||
/datum/goal
|
||||
var/name = "goal"
|
||||
|
||||
var/goal_text = "Do nothing! Congratulations."
|
||||
|
||||
var/active_goal = FALSE
|
||||
|
||||
var/category = GOAL_GENERAL
|
||||
|
||||
/datum/goal/proc/check_completion()
|
||||
return FALSE
|
||||
|
||||
/datum/goal/common
|
||||
name = "goal"
|
||||
|
||||
goal_text = "Congratulations, you still do nothing."
|
||||
|
||||
/datum/goal/medical
|
||||
name = "goal"
|
||||
|
||||
goal_text = "Congratulations, you still do nothing."
|
||||
category = GOAL_MEDICAL
|
||||
|
||||
/datum/goal/security
|
||||
name = "goal"
|
||||
|
||||
goal_text = "Congratulations, you still do nothing."
|
||||
category = GOAL_SECURITY
|
||||
|
||||
/datum/goal/engineering
|
||||
name = "goal"
|
||||
|
||||
goal_text = "Congratulations, you still do nothing."
|
||||
category = GOAL_ENGINEERING
|
||||
|
||||
/datum/goal/cargo
|
||||
name = "goal"
|
||||
|
||||
goal_text = "Congratulations, you still do nothing."
|
||||
category = GOAL_CARGO
|
||||
|
||||
/datum/goal/research
|
||||
name = "goal"
|
||||
|
||||
goal_text = "Congratulations, you still do nothing."
|
||||
category = GOAL_RESEARCH
|
||||
@@ -17,6 +17,7 @@
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/patron,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/goldschlager,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/specialwhiskey,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/jager,
|
||||
/obj/item/weapon/storage/fancy/cigarettes/dromedaryco,
|
||||
/obj/item/weapon/lipstick/random,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale = 2,
|
||||
|
||||
@@ -35,6 +35,13 @@
|
||||
containertype = /obj/structure/closet/crate/grayson
|
||||
containername = "Plastic sheets crate"
|
||||
|
||||
/datum/supply_pack/materials/copper50
|
||||
name = "50 copper ingots"
|
||||
contains = list(/obj/fiftyspawner/copper)
|
||||
cost = 60
|
||||
containertype = /obj/structure/closet/crate/grayson
|
||||
containername = "Copper ingots crate"
|
||||
|
||||
/datum/supply_pack/materials/cardboard_sheets
|
||||
contains = list(/obj/fiftyspawner/cardboard)
|
||||
name = "50 cardboard sheets"
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
/obj/item/weapon/reagent_containers/glass/paint/purple,
|
||||
/obj/item/weapon/reagent_containers/glass/paint/black,
|
||||
/obj/item/weapon/reagent_containers/glass/paint/white,
|
||||
/obj/item/weapon/contraband/poster,
|
||||
/obj/item/weapon/contraband/poster/custom,
|
||||
/obj/item/weapon/wrapping_paper = 3
|
||||
)
|
||||
cost = 10
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
/obj/item/clothing/suit/straight_jacket,
|
||||
/obj/item/weapon/handcuffs/legcuffs/fuzzy,
|
||||
/obj/item/weapon/melee/fluff/holochain/mass,
|
||||
/obj/item/weapon/material/twohanded/fluff/riding_crop,
|
||||
/obj/item/weapon/material/twohanded/riding_crop,
|
||||
/obj/item/clothing/under/fluff/latexmaid
|
||||
)
|
||||
containertype = /obj/structure/closet/crate
|
||||
|
||||
@@ -189,6 +189,17 @@
|
||||
containername = "Jumper kit crate"
|
||||
access = access_robotics
|
||||
|
||||
/datum/supply_pack/robotics/restrainingbolt
|
||||
name = "Restraining bolt crate"
|
||||
contains = list(
|
||||
/obj/item/weapon/implanter = 1,
|
||||
/obj/item/weapon/implantcase/restrainingbolt = 2
|
||||
)
|
||||
cost = 40
|
||||
containertype = /obj/structure/closet/crate/secure/cybersolutions
|
||||
containername = "Restraining bolt crate"
|
||||
access = access_robotics
|
||||
|
||||
/datum/supply_pack/robotics/bike
|
||||
name = "Spacebike Crate"
|
||||
contains = list()
|
||||
|
||||
@@ -281,10 +281,7 @@
|
||||
name = "Armor - Riot plates"
|
||||
contains = list(
|
||||
/obj/item/clothing/head/helmet/riot,
|
||||
/obj/item/clothing/suit/armor/pcarrier,
|
||||
/obj/item/clothing/accessory/armor/armorplate/riot,
|
||||
/obj/item/clothing/accessory/armor/armguards/riot,
|
||||
/obj/item/clothing/accessory/armor/legguards/riot
|
||||
/obj/item/clothing/suit/armor/pcarrier/riot/full
|
||||
)
|
||||
cost = 40
|
||||
containertype = /obj/structure/closet/crate/secure/lawson
|
||||
@@ -308,10 +305,7 @@
|
||||
name = "Armor - Ablative plates"
|
||||
contains = list(
|
||||
/obj/item/clothing/head/helmet/laserproof,
|
||||
/obj/item/clothing/suit/armor/pcarrier,
|
||||
/obj/item/clothing/accessory/armor/armorplate/laserproof,
|
||||
/obj/item/clothing/accessory/armor/armguards/laserproof,
|
||||
/obj/item/clothing/accessory/armor/legguards/laserproof
|
||||
/obj/item/clothing/suit/armor/pcarrier/laserproof/full
|
||||
)
|
||||
cost = 50
|
||||
containertype = /obj/structure/closet/crate/secure/lawson
|
||||
@@ -336,10 +330,7 @@
|
||||
name = "Armor - Ballistic plates"
|
||||
contains = list(
|
||||
/obj/item/clothing/head/helmet/bulletproof,
|
||||
/obj/item/clothing/suit/armor/pcarrier,
|
||||
/obj/item/clothing/accessory/armor/armorplate/bulletproof,
|
||||
/obj/item/clothing/accessory/armor/armguards/bulletproof,
|
||||
/obj/item/clothing/accessory/armor/legguards/bulletproof
|
||||
/obj/item/clothing/suit/armor/pcarrier/bulletproof/full
|
||||
)
|
||||
cost = 50
|
||||
containertype = /obj/structure/closet/crate/secure/heph
|
||||
|
||||
@@ -186,4 +186,14 @@
|
||||
|
||||
/datum/category_item/underwear/undershirt/pinkblack_tshirt
|
||||
name = "Pink and Black T-Shirt"
|
||||
icon_state = "pinkblack_tshirt"
|
||||
icon_state = "pinkblack_tshirt"
|
||||
|
||||
/datum/category_item/underwear/undershirt/turtle
|
||||
name = "Turtleneck"
|
||||
icon_state = "turtleneck"
|
||||
has_color = TRUE
|
||||
|
||||
/datum/category_item/underwear/undershirt/sleevelessturtle
|
||||
name = "Turtleneck, Sleeveless"
|
||||
icon_state = "sleevelessturtle"
|
||||
has_color = TRUE
|
||||
@@ -22,22 +22,22 @@
|
||||
desc = "Buys you one random item."
|
||||
|
||||
/datum/uplink_item/item/badassery/random_one/buy(var/obj/item/device/uplink/U, var/mob/user)
|
||||
var/datum/uplink_item/item = default_uplink_selection.get_random_item(U.uses)
|
||||
var/datum/uplink_item/item = default_uplink_selection.get_random_item((user ? user.mind.tcrystals : DEFAULT_TELECRYSTAL_AMOUNT), U)
|
||||
return item.buy(U, user)
|
||||
|
||||
/datum/uplink_item/item/badassery/random_one/can_buy(obj/item/device/uplink/U)
|
||||
return default_uplink_selection.get_random_item(U.uses, U) != null
|
||||
/datum/uplink_item/item/badassery/random_one/can_buy(var/obj/item/device/uplink/U, var/telecrystals)
|
||||
return default_uplink_selection.get_random_item(telecrystals, U) != null
|
||||
|
||||
/datum/uplink_item/item/badassery/random_many
|
||||
name = "Random Items"
|
||||
desc = "Buys you as many random items you can afford. Convenient packaging NOT included."
|
||||
|
||||
/datum/uplink_item/item/badassery/random_many/cost(var/telecrystals)
|
||||
/datum/uplink_item/item/badassery/random_many/cost(obj/item/device/uplink/U, var/telecrystals)
|
||||
return max(1, telecrystals)
|
||||
|
||||
/datum/uplink_item/item/badassery/random_many/get_goods(var/obj/item/device/uplink/U, var/loc)
|
||||
/datum/uplink_item/item/badassery/random_many/get_goods(var/obj/item/device/uplink/U, var/loc, var/mob/M)
|
||||
var/list/bought_items = list()
|
||||
for(var/datum/uplink_item/UI in get_random_uplink_items(U, U.uses, loc))
|
||||
for(var/datum/uplink_item/UI in get_random_uplink_items(U, M.mind.tcrystals, loc))
|
||||
UI.purchase_log(U)
|
||||
var/obj/item/I = UI.get_goods(U, loc)
|
||||
if(istype(I))
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
/datum/uplink_item/item/badassery/random_many/purchase_log(obj/item/device/uplink/U)
|
||||
feedback_add_details("traitor_uplink_items_bought", "[src]")
|
||||
log_and_message_admins("used \the [U.loc] to buy \a [src]")
|
||||
log_and_message_admins("used \the [U.loc] to buy \a [src] at random")
|
||||
|
||||
/****************
|
||||
* Surplus Crate *
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
category = /datum/uplink_category/telecrystals
|
||||
blacklisted = 1
|
||||
|
||||
/datum/uplink_item/item/telecrystal/get_goods(var/obj/item/device/uplink/U, var/loc)
|
||||
return new /obj/item/stack/telecrystal(loc, cost(U.uses))
|
||||
/datum/uplink_item/item/telecrystal/get_goods(var/obj/item/device/uplink/U, var/loc, var/mob/M)
|
||||
return new /obj/item/stack/telecrystal(loc, cost(U, M.mind.tcrystals))
|
||||
|
||||
/datum/uplink_item/item/telecrystal/one
|
||||
name = "Telecrystal - 01"
|
||||
@@ -35,5 +35,5 @@
|
||||
/datum/uplink_item/item/telecrystal/all
|
||||
name = "Telecrystals - Empty Uplink"
|
||||
|
||||
/datum/uplink_item/item/telecrystal/all/cost(var/telecrystals)
|
||||
return max(1, telecrystals)
|
||||
/datum/uplink_item/item/telecrystal/all/cost(obj/item/device/uplink/U, mob/M)
|
||||
return max(1, M.mind.tcrystals)
|
||||
@@ -92,6 +92,12 @@
|
||||
desc = "A device which is capable of disrupting subspace communications, preventing the use of headsets, PDAs, and communicators within \
|
||||
a radius of seven meters. It runs off weapon cells, which can be replaced as needed. One cell will last for approximately ten minutes."
|
||||
|
||||
/datum/uplink_item/item/tools/wall_elecrtifier
|
||||
name = "Wall Electrifier"
|
||||
item_cost = 10
|
||||
path = /obj/item/weapon/cell/spike
|
||||
desc = "A modified powercell which will electrify walls and reinforced floors in a 3x3 tile range around it. Always active."
|
||||
|
||||
/datum/uplink_item/item/tools/emag
|
||||
name = "Cryptographic Sequencer"
|
||||
item_cost = 30
|
||||
|
||||
@@ -36,6 +36,11 @@
|
||||
item_cost = 10
|
||||
path = /obj/item/clothing/suit/space/void/autolok
|
||||
|
||||
/datum/uplink_item/item/tools/inflatable
|
||||
name = "Inflatables"
|
||||
item_cost = 10
|
||||
path = /obj/item/weapon/storage/briefcase/inflatable
|
||||
|
||||
/datum/uplink_item/item/tools/elitetablet
|
||||
name = "Tablet (Advanced)"
|
||||
item_cost = 15
|
||||
|
||||
@@ -6,12 +6,6 @@
|
||||
..()
|
||||
items = list()
|
||||
|
||||
/datum/uplink_category/proc/can_view(obj/item/device/uplink/U)
|
||||
for(var/datum/uplink_item/item in items)
|
||||
if(item.can_view(U))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
datum/uplink_category/ammunition
|
||||
name = "Ammunition"
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ var/datum/uplink/uplink = new()
|
||||
var/item_cost = 0
|
||||
var/datum/uplink_category/category // Item category
|
||||
var/list/datum/antagonist/antag_roles // Antag roles this item is displayed to. If empty, display to all.
|
||||
var/blacklisted = 0
|
||||
var/blacklisted = FALSE
|
||||
|
||||
/datum/uplink_item/item
|
||||
var/path = null
|
||||
@@ -48,50 +48,34 @@ var/datum/uplink/uplink = new()
|
||||
if(!extra_args)
|
||||
return
|
||||
|
||||
if(!can_buy(U))
|
||||
if(!can_buy(U, user.mind.tcrystals))
|
||||
return
|
||||
|
||||
if(U.tgui_status(user, GLOB.tgui_inventory_state) != STATUS_INTERACTIVE)
|
||||
if(U.tgui_status(user, GLOB.tgui_deep_inventory_state) != STATUS_INTERACTIVE)
|
||||
return
|
||||
|
||||
var/cost = cost(U.uses, U)
|
||||
var/cost = cost(U, user.mind.tcrystals)
|
||||
|
||||
var/goods = get_goods(U, get_turf(user), user, extra_args)
|
||||
if(!goods)
|
||||
return
|
||||
|
||||
purchase_log(U)
|
||||
purchase_log(user)
|
||||
user.mind.tcrystals -= cost
|
||||
U.used_TC += cost
|
||||
user.mind.used_TC += cost
|
||||
return goods
|
||||
|
||||
// Any additional arguments you wish to send to the get_goods
|
||||
/datum/uplink_item/proc/extra_args(var/mob/user)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/datum/uplink_item/proc/can_buy(obj/item/device/uplink/U)
|
||||
if(cost(U.uses, U) > U.uses)
|
||||
return 0
|
||||
/datum/uplink_item/proc/can_buy(var/obj/item/device/uplink/U, var/telecrystals)
|
||||
if(cost(U, telecrystals) > telecrystals)
|
||||
return FALSE
|
||||
|
||||
return can_view(U)
|
||||
return TRUE
|
||||
|
||||
/datum/uplink_item/proc/can_view(obj/item/device/uplink/U)
|
||||
// Making the assumption that if no uplink was supplied, then we don't care about antag roles
|
||||
if(!U || !antag_roles.len)
|
||||
return 1
|
||||
|
||||
// With no owner, there's no need to check antag status.
|
||||
if(!U.uplink_owner)
|
||||
return 0
|
||||
|
||||
for(var/antag_role in antag_roles)
|
||||
var/datum/antagonist/antag = all_antag_types[antag_role]
|
||||
if(!isnull(antag))
|
||||
if(antag.is_antagonist(U.uplink_owner))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/uplink_item/proc/cost(var/telecrystals, obj/item/device/uplink/U)
|
||||
/datum/uplink_item/proc/cost(obj/item/device/uplink/U, mob/M)
|
||||
. = item_cost
|
||||
if(U)
|
||||
. = U.get_item_cost(src, .)
|
||||
@@ -100,19 +84,19 @@ var/datum/uplink/uplink = new()
|
||||
return desc
|
||||
|
||||
// get_goods does not necessarily return physical objects, it is simply a way to acquire the uplink item without paying
|
||||
/datum/uplink_item/proc/get_goods(var/obj/item/device/uplink/U, var/loc)
|
||||
return 0
|
||||
/datum/uplink_item/proc/get_goods(var/obj/item/device/uplink/U, var/loc, mob/user)
|
||||
return FALSE
|
||||
|
||||
/datum/uplink_item/proc/log_icon()
|
||||
return
|
||||
|
||||
/datum/uplink_item/proc/purchase_log(obj/item/device/uplink/U)
|
||||
/datum/uplink_item/proc/purchase_log(mob/M)
|
||||
feedback_add_details("traitor_uplink_items_bought", "[src]")
|
||||
log_and_message_admins("used \the [U.loc] to buy \a [src]")
|
||||
U.purchase_log[src] = U.purchase_log[src] + 1
|
||||
log_and_message_admins("\the [M] bought \a [src] through the uplink")
|
||||
M.mind.purchase_log[src] += 1
|
||||
|
||||
datum/uplink_item/dd_SortValue()
|
||||
return cost(INFINITY)
|
||||
return item_cost
|
||||
|
||||
/********************************
|
||||
* *
|
||||
@@ -133,7 +117,7 @@ datum/uplink_item/dd_SortValue()
|
||||
A.put_in_any_hand_if_possible(I)
|
||||
return I
|
||||
|
||||
/datum/uplink_item/item/get_goods(var/obj/item/device/uplink/U, var/loc)
|
||||
/datum/uplink_item/item/get_goods(var/obj/item/device/uplink/U, var/loc, var/mob/user)
|
||||
var/obj/item/I = new path(loc)
|
||||
return I
|
||||
|
||||
@@ -208,7 +192,7 @@ datum/uplink_item/dd_SortValue()
|
||||
|
||||
/proc/get_surplus_items(var/obj/item/device/uplink/U, var/remaining_TC, var/loc)
|
||||
var/list/bought_items = list()
|
||||
var/override = 1
|
||||
var/override = TRUE
|
||||
while(remaining_TC)
|
||||
var/datum/uplink_item/I = all_uplink_selection.get_random_item(remaining_TC, U, bought_items, override)
|
||||
if(!I)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/datum/wires/mines
|
||||
wire_count = 6
|
||||
wire_count = 7
|
||||
randomize = TRUE
|
||||
holder_type = /obj/effect/mine
|
||||
proper_name = "Explosive Wires"
|
||||
@@ -7,6 +7,7 @@
|
||||
/datum/wires/mines/New(atom/_holder)
|
||||
wires = list(WIRE_EXPLODE, WIRE_EXPLODE_DELAY, WIRE_DISARM, WIRE_BADDISARM)
|
||||
return ..()
|
||||
#define WIRE_TRAP 64
|
||||
|
||||
/datum/wires/mines/get_status()
|
||||
. = ..()
|
||||
@@ -29,7 +30,13 @@
|
||||
|
||||
if(WIRE_DISARM)
|
||||
C.visible_message("[bicon(C)] *click!*", "[bicon(C)] *click!*")
|
||||
new C.mineitemtype(get_turf(C))
|
||||
var/obj/effect/mine/MI = new C.mineitemtype(get_turf(C))
|
||||
|
||||
if(C.trap)
|
||||
MI.trap = C.trap
|
||||
C.trap = null
|
||||
MI.trap.forceMove(MI)
|
||||
|
||||
spawn(0)
|
||||
qdel(C)
|
||||
|
||||
@@ -37,6 +44,15 @@
|
||||
C.visible_message("[bicon(C)] *BEEPBEEPBEEP*", "[bicon(C)] *BEEPBEEPBEEP*")
|
||||
spawn(20)
|
||||
C.explode()
|
||||
|
||||
if(WIRE_TRAP)
|
||||
C.visible_message("[bicon(C)] *click!*", "[bicon(C)] *click!*")
|
||||
|
||||
if(mend)
|
||||
C.visible_message("[bicon(C)] - The mine recalibrates[C.camo_net ? ", revealing \the [C.trap] inside." : "."]")
|
||||
|
||||
C.alpha = 255
|
||||
|
||||
..()
|
||||
|
||||
/datum/wires/mines/on_pulse(wire)
|
||||
@@ -57,6 +73,10 @@
|
||||
|
||||
if(WIRE_BADDISARM)
|
||||
C.visible_message("[bicon(C)] *ping*", "[bicon(C)] *ping*")
|
||||
|
||||
if(WIRE_TRAP)
|
||||
C.visible_message("[bicon(C)] *ping*", "[bicon(C)] *ping*")
|
||||
|
||||
..()
|
||||
|
||||
/datum/wires/mines/interactable(mob/user)
|
||||
|
||||
@@ -7,14 +7,15 @@ proc/sql_poll_population()
|
||||
if(M.client)
|
||||
playercount += 1
|
||||
establish_db_connection()
|
||||
if(!dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected()) //CHOMPEdit TGSQL
|
||||
log_game("SQL ERROR during population polling. Failed to connect.")
|
||||
else
|
||||
var/sqltime = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
|
||||
var/DBQuery/query = dbcon_old.NewQuery("INSERT INTO `tgstation`.`population` (`playercount`, `admincount`, `time`) VALUES ([playercount], [admincount], '[sqltime]')")
|
||||
var/DBQuery/query = SSdbcore.NewQuery("INSERT INTO `population` (`playercount`, `admincount`, `time`) VALUES ([playercount], [admincount], '[sqltime]')") //CHOMPEdit TGSQL
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during population polling. Error : \[[err]\]\n")
|
||||
qdel(query) //CHOMPEdit TGSQL
|
||||
|
||||
proc/sql_report_round_start()
|
||||
// TODO
|
||||
@@ -50,13 +51,14 @@ proc/sql_report_death(var/mob/living/carbon/human/H)
|
||||
var/coord = "[H.x], [H.y], [H.z]"
|
||||
//to_world("INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.bruteloss], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()])")
|
||||
establish_db_connection()
|
||||
if(!dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected()) //CHOMPEdit TGSQL
|
||||
log_game("SQL ERROR during death reporting. Failed to connect.")
|
||||
else
|
||||
var/DBQuery/query = dbcon.NewQuery("INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.getBruteLoss()], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()], '[coord]')")
|
||||
var/DBQuery/query = SSdbcore.NewQuery("INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) VALUES (:t_name, :t_byondkey, :t_job, :t_special, :t_pod, '[sqltime]', :t_laname, :t_lakey, '[H.gender]', [H.getBruteLoss()], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()], '[coord]')", list("t_name" = sqlname,"t_byondkey" = sqlkey, "t_job" = sqljob, "t_special" = sqlspecial, "t_pod" = sqlpod, "t_laname" = laname, "t_lakey" = lakey)) //CHOMPEdit TGSQL
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during death reporting. Error : \[[err]\]\n")
|
||||
qdel(query) //CHOMPEdit TGSQL
|
||||
|
||||
|
||||
proc/sql_report_cyborg_death(var/mob/living/silicon/robot/H)
|
||||
@@ -84,13 +86,14 @@ proc/sql_report_cyborg_death(var/mob/living/silicon/robot/H)
|
||||
var/coord = "[H.x], [H.y], [H.z]"
|
||||
//to_world("INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.bruteloss], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()])")
|
||||
establish_db_connection()
|
||||
if(!dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected()) //CHOMPEdit TGSQL
|
||||
log_game("SQL ERROR during death reporting. Failed to connect.")
|
||||
else
|
||||
var/DBQuery/query = dbcon.NewQuery("INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[sqltime]', '[laname]', '[lakey]', '[H.gender]', [H.getBruteLoss()], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()], '[coord]')")
|
||||
var/DBQuery/query = SSdbcore.NewQuery("INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) VALUES (:t_name, :t_byondkey, :t_job, :t_special, :t_pod, '[sqltime]', :t_laname, :t_lakey, '[H.gender]', [H.getBruteLoss()], [H.getFireLoss()], [H.brainloss], [H.getOxyLoss()], '[coord]')", list("t_name" = sqlname,"t_byondkey" = sqlkey, "t_job" = sqljob, "t_special" = sqlspecial, "t_pod" = sqlpod, "t_laname" = laname, "t_lakey" = lakey)) //CHOMPEdit TGSQL
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during death reporting. Error : \[[err]\]\n")
|
||||
qdel(query) //CHOMPEdit TGSQL
|
||||
|
||||
|
||||
proc/statistic_cycle()
|
||||
@@ -115,18 +118,18 @@ proc/sql_commit_feedback()
|
||||
return
|
||||
|
||||
establish_db_connection()
|
||||
if(!dbcon.IsConnected())
|
||||
if(!SSdbcore.IsConnected()) //CHOMPEdit TGSQL
|
||||
log_game("SQL ERROR during feedback reporting. Failed to connect.")
|
||||
else
|
||||
|
||||
var/DBQuery/max_query = dbcon.NewQuery("SELECT MAX(roundid) AS max_round_id FROM erro_feedback")
|
||||
var/DBQuery/max_query = SSdbcore.NewQuery("SELECT MAX(roundid) AS max_round_id FROM erro_feedback") //CHOMPEdit TGSQL
|
||||
max_query.Execute()
|
||||
|
||||
var/newroundid
|
||||
|
||||
while(max_query.NextRow())
|
||||
newroundid = max_query.item[1]
|
||||
|
||||
qdel(max_query) //CHOMPEdit TGSQL
|
||||
if(!(isnum(newroundid)))
|
||||
newroundid = text2num(newroundid)
|
||||
|
||||
@@ -139,7 +142,8 @@ proc/sql_commit_feedback()
|
||||
var/variable = item.get_variable()
|
||||
var/value = item.get_value()
|
||||
|
||||
var/DBQuery/query = dbcon.NewQuery("INSERT INTO erro_feedback (id, roundid, time, variable, value) VALUES (null, [newroundid], Now(), '[variable]', '[value]')")
|
||||
var/DBQuery/query = SSdbcore.NewQuery("INSERT INTO erro_feedback (id, roundid, time, variable, value) VALUES (null, [newroundid], Now(), '[variable]', '[value]')") //CHOMPEdit TGSQL
|
||||
if(!query.Execute())
|
||||
var/err = query.ErrorMsg()
|
||||
log_game("SQL ERROR during death reporting. Error : \[[err]\]\n")
|
||||
qdel(query) //CHOMPEdit TGSQL
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/antagonist/proc/print_player_summary()
|
||||
|
||||
if(!current_antagonists.len)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
var/text = "<br><br><font size = 2><b>The [current_antagonists.len == 1 ? "[role_text] was" : "[role_text_plural] were"]:</b></font>"
|
||||
for(var/datum/mind/P in current_antagonists)
|
||||
@@ -21,7 +21,7 @@
|
||||
else
|
||||
text += "<font color='red'>Fail.</font>"
|
||||
feedback_add_details(feedback_tag,"[O.type]|FAIL")
|
||||
failed = 1
|
||||
failed = TRUE
|
||||
num++
|
||||
if(failed)
|
||||
text += "<br><font color='red'><B>The [role_text] has failed.</B></font>"
|
||||
@@ -32,7 +32,7 @@
|
||||
text += "<BR><FONT size = 2>Their objectives were:</FONT>"
|
||||
var/num = 1
|
||||
for(var/datum/objective/O in global_objectives)
|
||||
text += print_objective(O, num, 1)
|
||||
text += print_objective(O, num, TRUE)
|
||||
num++
|
||||
|
||||
// Display the results.
|
||||
@@ -68,14 +68,14 @@
|
||||
/datum/antagonist/proc/print_player_full(var/datum/mind/ply)
|
||||
var/text = print_player_lite(ply)
|
||||
|
||||
var/TC_uses = 0
|
||||
var/uplink_true = 0
|
||||
var/TC_uses = FALSE
|
||||
var/uplink_true = FALSE
|
||||
var/purchases = ""
|
||||
for(var/obj/item/device/uplink/H in GLOB.world_uplinks)
|
||||
if(H && H.uplink_owner && H.uplink_owner == ply)
|
||||
TC_uses += H.used_TC
|
||||
uplink_true = 1
|
||||
purchases += get_uplink_purchases(H)
|
||||
for(var/mob/M in player_list)
|
||||
if(M.mind && M.mind.used_TC)
|
||||
TC_uses += M.mind.used_TC
|
||||
uplink_true = TRUE
|
||||
purchases += get_uplink_purchases(M.mind)
|
||||
if(uplink_true)
|
||||
text += " (used [TC_uses] TC)"
|
||||
if(purchases)
|
||||
@@ -83,18 +83,8 @@
|
||||
|
||||
return text
|
||||
|
||||
/proc/print_ownerless_uplinks()
|
||||
var/has_printed = 0
|
||||
for(var/obj/item/device/uplink/H in GLOB.world_uplinks)
|
||||
if(isnull(H.uplink_owner) && H.used_TC)
|
||||
if(!has_printed)
|
||||
has_printed = 1
|
||||
to_world("<b>Ownerless Uplinks</b>")
|
||||
to_world("[H.loc] (used [H.used_TC] TC)")
|
||||
to_world(get_uplink_purchases(H))
|
||||
|
||||
/proc/get_uplink_purchases(var/obj/item/device/uplink/H)
|
||||
/proc/get_uplink_purchases(var/datum/mind/M)
|
||||
var/list/refined_log = new()
|
||||
for(var/datum/uplink_item/UI in H.purchase_log)
|
||||
refined_log.Add("[H.purchase_log[UI]]x[UI.log_icon()][UI.name]")
|
||||
for(var/datum/uplink_item/UI in M.purchase_log)
|
||||
refined_log.Add("[M.purchase_log[UI]]x[UI.log_icon()][UI.name]")
|
||||
. = english_list(refined_log, nothing_text = "")
|
||||
|
||||
@@ -50,13 +50,12 @@
|
||||
var/turf/base_turf //The base turf type of the area, which can be used to override the z-level's base turf
|
||||
var/forbid_events = FALSE // If true, random events will not start inside this area.
|
||||
var/no_spoilers = FALSE // If true, makes it much more difficult to see what is inside an area with things like mesons.
|
||||
var/soundproofed = FALSE // If true, blocks sounds from other areas and prevents hearers on other areas from hearing the sounds within.
|
||||
|
||||
/area/Initialize()
|
||||
. = ..()
|
||||
|
||||
luminosity = !(dynamic_lighting)
|
||||
icon_state = ""
|
||||
|
||||
return INITIALIZE_HINT_LATELOAD // Areas tradiationally are initialized AFTER other atoms.
|
||||
|
||||
/area/LateInitialize()
|
||||
@@ -67,7 +66,6 @@
|
||||
power_change() // all machines set to current power level, also updates lighting icon
|
||||
if(no_spoilers)
|
||||
set_spoiler_obfuscation(TRUE)
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
// Changes the area of T to A. Do not do this manually.
|
||||
// Area is expected to be a non-null instance.
|
||||
@@ -379,9 +377,9 @@ var/list/mob/living/forced_ambiance_list = new
|
||||
// Ambience goes down here -- make sure to list each area seperately for ease of adding things in later, thanks! Note: areas adjacent to each other should have the same sounds to prevent cutoff when possible.- LastyScratch
|
||||
if(!(L && L.is_preference_enabled(/datum/client_preference/play_ambiance)))
|
||||
return
|
||||
|
||||
|
||||
var/volume_mod = L.get_preference_volume_channel(VOLUME_CHANNEL_AMBIENCE)
|
||||
|
||||
|
||||
// If we previously were in an area with force-played ambiance, stop it.
|
||||
if((L in forced_ambiance_list) && initial)
|
||||
L << sound(null, channel = CHANNEL_AMBIENCE_FORCED)
|
||||
@@ -399,7 +397,7 @@ var/list/mob/living/forced_ambiance_list = new
|
||||
L << chosen_ambiance
|
||||
else
|
||||
L << sound(null, channel = CHANNEL_AMBIENCE_FORCED)
|
||||
else if(src.ambience.len)
|
||||
else if(src.ambience && src.ambience.len)
|
||||
var/ambience_odds = L?.client.prefs.ambience_chance
|
||||
if(prob(ambience_odds) && (world.time >= L.client.time_last_ambience_played + 1 MINUTE))
|
||||
var/sound = pick(ambience)
|
||||
|
||||
@@ -627,7 +627,7 @@
|
||||
speech_bubble_hearers += M.client
|
||||
|
||||
if(length(speech_bubble_hearers))
|
||||
var/image/I = image('icons/mob/talk.dmi', src, "[bubble_icon][say_test(message)]", FLY_LAYER)
|
||||
var/image/I = generate_speech_bubble(src, "[bubble_icon][say_test(message)]", FLY_LAYER)
|
||||
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, speech_bubble_hearers, 30)
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
for(var/i in loc)
|
||||
var/atom/movable/thing = i
|
||||
// We don't call parent so we are calling this for byond
|
||||
thing.Crossed(src)
|
||||
thing.Crossed(src, oldloc)
|
||||
|
||||
// We're a multi-tile object (multiple locs)
|
||||
else if(. && newloc)
|
||||
@@ -303,6 +303,8 @@
|
||||
if(AM == src)
|
||||
continue
|
||||
AM.Uncrossed(src)
|
||||
if(loc != destination) // Uncrossed() triggered a separate movement
|
||||
return
|
||||
|
||||
// Information about turf and z-levels for source and dest collected
|
||||
var/turf/oldturf = get_turf(oldloc)
|
||||
@@ -327,6 +329,8 @@
|
||||
if(AM == src)
|
||||
continue
|
||||
AM.Crossed(src, oldloc)
|
||||
if(loc != destination) // Crossed triggered a separate movement
|
||||
return
|
||||
|
||||
// Call our thingy to inform everyone we moved
|
||||
Moved(oldloc, NONE, TRUE)
|
||||
@@ -462,6 +466,8 @@
|
||||
minor_dir = dx
|
||||
minor_dist = dist_x
|
||||
|
||||
range = min(dist_x + dist_y, range)
|
||||
|
||||
while(src && target && src.throwing && istype(src.loc, /turf) \
|
||||
&& ((abs(target.x - src.x)+abs(target.y - src.y) > 0 && dist_travelled < range) \
|
||||
|| (a && a.has_gravity == 0) \
|
||||
|
||||
@@ -118,6 +118,10 @@ var/global/list/datum/dna/gene/dna_genes[0]
|
||||
var/base_species = "Human"
|
||||
var/list/species_traits = list()
|
||||
var/blood_color = "#A10808"
|
||||
var/custom_say
|
||||
var/custom_ask
|
||||
var/custom_whisper
|
||||
var/custom_exclaim
|
||||
// VOREStation
|
||||
|
||||
// New stuff
|
||||
@@ -139,6 +143,10 @@ var/global/list/datum/dna/gene/dna_genes[0]
|
||||
new_dna.custom_species=custom_species //VOREStaton Edit
|
||||
new_dna.species_traits=species_traits.Copy() //VOREStation Edit
|
||||
new_dna.blood_color=blood_color //VOREStation Edit
|
||||
new_dna.custom_say=custom_say //VOREStaton Edit
|
||||
new_dna.custom_ask=custom_ask //VOREStaton Edit
|
||||
new_dna.custom_whisper=custom_whisper //VOREStaton Edit
|
||||
new_dna.custom_exclaim=custom_exclaim //VOREStaton Edit
|
||||
for(var/b=1;b<=DNA_SE_LENGTH;b++)
|
||||
new_dna.SE[b]=SE[b]
|
||||
if(b<=DNA_UI_LENGTH)
|
||||
@@ -200,29 +208,15 @@ var/global/list/datum/dna/gene/dna_genes[0]
|
||||
size_multiplier = player_sizes_list.Find(N)
|
||||
break
|
||||
|
||||
var/taurtype = /datum/sprite_accessory/tail/taur/spider
|
||||
if(istype(character.tail_style, taurtype))
|
||||
character.verbs += /mob/living/proc/weaveWebBindings
|
||||
|
||||
// Technically custom_species is not part of the UI, but this place avoids merge problems.
|
||||
src.custom_species = character.custom_species
|
||||
if(istype(character.species,/datum/species/custom))
|
||||
var/datum/species/custom/CS = character.species
|
||||
src.species_traits = CS.traits.Copy()
|
||||
src.base_species = CS.base_species
|
||||
src.blood_color = CS.blood_color
|
||||
|
||||
if(istype(character.species,/datum/species/xenochimera))
|
||||
var/datum/species/xenochimera/CS = character.species
|
||||
//src.species_traits = CS.traits.Copy() //No traits
|
||||
src.base_species = CS.base_species
|
||||
src.blood_color = CS.blood_color
|
||||
|
||||
if(istype(character.species,/datum/species/alraune))
|
||||
var/datum/species/alraune/CS = character.species
|
||||
//src.species_traits = CS.traits.Copy() //No traits
|
||||
src.base_species = CS.base_species
|
||||
src.blood_color = CS.blood_color
|
||||
src.base_species = character.species.base_species
|
||||
src.blood_color = character.species.blood_color
|
||||
src.species_traits = character.species.traits.Copy()
|
||||
src.custom_say = character.custom_say
|
||||
src.custom_ask = character.custom_ask
|
||||
src.custom_whisper = character.custom_whisper
|
||||
src.custom_exclaim = character.custom_exclaim
|
||||
|
||||
// +1 to account for the none-of-the-above possibility
|
||||
SetUIValueRange(DNA_UI_EAR_STYLE, ear_style + 1, ear_styles_list.len + 1, 1)
|
||||
|
||||
@@ -237,20 +237,13 @@
|
||||
|
||||
// Technically custom_species is not part of the UI, but this place avoids merge problems.
|
||||
H.custom_species = dna.custom_species
|
||||
if(istype(H.species,/datum/species/custom))
|
||||
var/datum/species/custom/CS = H.species
|
||||
var/datum/species/custom/new_CS = CS.produceCopy(dna.base_species,dna.species_traits,src)
|
||||
new_CS.blood_color = dna.blood_color
|
||||
|
||||
if(istype(H.species,/datum/species/xenochimera))
|
||||
var/datum/species/xenochimera/CS = H.species
|
||||
var/datum/species/xenochimera/new_CS = CS.produceCopy(dna.base_species,dna.species_traits,src)
|
||||
new_CS.blood_color = dna.blood_color
|
||||
|
||||
if(istype(H.species,/datum/species/alraune))
|
||||
var/datum/species/alraune/CS = H.species
|
||||
var/datum/species/alraune/new_CS = CS.produceCopy(dna.base_species,dna.species_traits,src)
|
||||
new_CS.blood_color = dna.blood_color
|
||||
H.custom_say = dna.custom_say
|
||||
H.custom_ask = dna.custom_ask
|
||||
H.custom_whisper = dna.custom_whisper
|
||||
H.custom_exclaim = dna.custom_exclaim
|
||||
H.species.blood_color = dna.blood_color
|
||||
var/datum/species/S = H.species
|
||||
S.produceCopy(dna.base_species,dna.species_traits,src)
|
||||
// VOREStation Edit End
|
||||
|
||||
H.force_update_organs() //VOREStation Add - Gotta do this too
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
var/last_activation = 0
|
||||
|
||||
/obj/structure/cult/pylon/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/structure/cult/pylon/attack_hand(mob/M as mob)
|
||||
|
||||
@@ -292,7 +292,6 @@ var/global/list/additional_antag_types = list()
|
||||
antag.check_victory()
|
||||
antag.print_player_summary()
|
||||
sleep(10)
|
||||
print_ownerless_uplinks()
|
||||
|
||||
var/clients = 0
|
||||
var/surviving_humans = 0
|
||||
@@ -303,10 +302,16 @@ var/global/list/additional_antag_types = list()
|
||||
var/escaped_on_pod_1 = 0
|
||||
var/escaped_on_pod_2 = 0
|
||||
var/escaped_on_pod_3 = 0
|
||||
var/escaped_on_pod_4 = 0 //CHOMP Add
|
||||
var/escaped_on_pod_5 = 0
|
||||
var/escaped_on_pod_6 = 0 //CHOMP Add
|
||||
var/escaped_on_shuttle = 0
|
||||
var/escaped_on_pod_large_1 = 0 //CHOMP Add
|
||||
var/escaped_on_pod_large_2 = 0 //CHOMP Add
|
||||
var/escaped_on_cryopod = 0 //CHOMP Add
|
||||
|
||||
var/list/area/escape_locations = list(/area/shuttle/escape, /area/shuttle/escape_pod1/centcom, /area/shuttle/escape_pod2/centcom, /area/shuttle/escape_pod3/centcom, /area/shuttle/escape_pod5/centcom) //VOREStation Edit
|
||||
var/list/area/escape_locations = list(/area/shuttle/escape/centcom, /area/shuttle/cryo/centcom, /area/shuttle/escape_pod1/centcom, /area/shuttle/escape_pod2/centcom, /area/shuttle/escape_pod3/centcom, /area/shuttle/escape_pod5/centcom, /area/shuttle/escape_pod6/centcom, /area/shuttle/large_escape_pod1/centcom
|
||||
, /area/shuttle/large_escape_pod2/centcom) //CHOMP Edit: Appended /centcom to the escape shuttle again to fix transfer message. Added some escape pods to the list.
|
||||
|
||||
for(var/mob/M in player_list)
|
||||
if(M.client)
|
||||
@@ -330,8 +335,20 @@ var/global/list/additional_antag_types = list()
|
||||
escaped_on_pod_2++
|
||||
if(M.loc && M.loc.loc && M.loc.loc.type == /area/shuttle/escape_pod3/centcom)
|
||||
escaped_on_pod_3++
|
||||
if(M.loc && M.loc.loc && M.loc.loc.type == /area/shuttle/escape_pod4/centcom) //CHOMP Add
|
||||
escaped_on_pod_4++
|
||||
if(M.loc && M.loc.loc && M.loc.loc.type == /area/shuttle/escape_pod5/centcom)
|
||||
escaped_on_pod_5++
|
||||
if(M.loc && M.loc.loc && M.loc.loc.type == /area/shuttle/escape_pod6/centcom) //CHOMP Add
|
||||
escaped_on_pod_6++
|
||||
if(M.loc && M.loc.loc && M.loc.loc.type == /area/shuttle/large_escape_pod1/centcom) //CHOMP Add
|
||||
escaped_on_pod_large_1++
|
||||
if(M.loc && M.loc.loc && M.loc.loc.type == /area/shuttle/large_escape_pod2/centcom) //CHOMP Add
|
||||
escaped_on_pod_large_2++
|
||||
if(M.loc && M.loc.loc && M.loc.loc.type == /area/shuttle/cryo/centcom) //CHOMP Add
|
||||
escaped_on_cryopod++
|
||||
|
||||
|
||||
|
||||
if(isobserver(M))
|
||||
ghosts++
|
||||
@@ -364,8 +381,18 @@ var/global/list/additional_antag_types = list()
|
||||
feedback_set("escaped_on_pod_2",escaped_on_pod_2)
|
||||
if(escaped_on_pod_3 > 0)
|
||||
feedback_set("escaped_on_pod_3",escaped_on_pod_3)
|
||||
if(escaped_on_pod_4 > 0) //CHOMP Add
|
||||
feedback_set("escaped_on_pod_4",escaped_on_pod_4)
|
||||
if(escaped_on_pod_5 > 0)
|
||||
feedback_set("escaped_on_pod_5",escaped_on_pod_5)
|
||||
if(escaped_on_pod_6 > 0) //CHOMP Add
|
||||
feedback_set("escaped_on_pod_6",escaped_on_pod_6)
|
||||
if(escaped_on_pod_large_1 > 0) //CHOMP Add
|
||||
feedback_set("escaped_on_pod_large_1",escaped_on_pod_large_1)
|
||||
if(escaped_on_pod_large_2 > 0) //CHOMP Add
|
||||
feedback_set("escaped_on_pod_large_2",escaped_on_pod_large_2)
|
||||
if(escaped_on_cryopod > 0) //CHOMP Add
|
||||
feedback_set("escaped_on_cryopod",escaped_on_cryopod)
|
||||
|
||||
send2mainirc("A round of [src.name] has ended - [surviving_total] survivors, [ghosts] ghosts.")
|
||||
|
||||
|
||||
@@ -273,6 +273,7 @@
|
||||
var/outgoing_instability = (amount) * ( 1 / (radius**2) )
|
||||
|
||||
L.receive_radiated_instability(outgoing_instability)
|
||||
src.adjust_instability(-outgoing_instability) //This should prevent feedback loops
|
||||
|
||||
// This should only be used for EXTERNAL sources of instability, such as from someone or something glowing.
|
||||
/mob/living/proc/receive_radiated_instability(amount)
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
src.loc = null
|
||||
user.put_in_hands(I)
|
||||
user.visible_message("<span class='notice'>\A [I] appears in \the [user]'s hand!</span>")
|
||||
log_and_message_admins("has stolen [I] with [src].")
|
||||
add_attack_logs(user,I,"Stolen with [src]")
|
||||
qdel(src)
|
||||
//Now let's try to teleport a living mob.
|
||||
else if(istype(hit_atom, /mob/living))
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
else
|
||||
safe_blink(AM, calculate_spell_power(3))
|
||||
adjust_instability(3)
|
||||
log_and_message_admins("has blinked [AM] away.")
|
||||
add_attack_logs(user,AM,"Blinked")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need more energy to blink [AM] away!</span>")
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
else
|
||||
safe_blink(user, calculate_spell_power(6))
|
||||
adjust_instability(1)
|
||||
log_and_message_admins("has blinked themselves away.")
|
||||
add_attack_logs(user,user,"Blinked")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need more energy to blink yourself away!</span>")
|
||||
|
||||
@@ -99,6 +99,6 @@
|
||||
else
|
||||
safe_blink(AM, 6)
|
||||
adjust_instability(2)
|
||||
log_and_message_admins("has blinked [AM] away.")
|
||||
add_attack_logs(user,AM,"Blinked")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need more energy to blink [AM] away!</span>")
|
||||
@@ -36,9 +36,9 @@
|
||||
var/turf/simulated/frozen = desired_turf
|
||||
frozen.freeze_floor()
|
||||
if(check_for_scepter())
|
||||
log_and_message_admins("has iced the floor with [src] at [T.x],[T.y],[T.z].")
|
||||
add_attack_logs(user,hit_atom,"Iced the floor with [src] at [T.x],[T.y],[T.z]")
|
||||
else
|
||||
log_and_message_admins("has wetted the floor with [src] at [T.x],[T.y],[T.z].")
|
||||
add_attack_logs(user,hit_atom,"Wetted the floor with [src] at [T.x],[T.y],[T.z]")
|
||||
else if(hit_atom.reagents && !ismob(hit_atom)) //TODO: Something for the scepter
|
||||
hit_atom.reagents.add_reagent(id = "water", amount = 60, data = null, safety = 0)
|
||||
adjust_instability(5)
|
||||
@@ -125,7 +125,7 @@
|
||||
return 0
|
||||
if(pay_energy(25 * controlled_mobs.len))
|
||||
attack_all(L)
|
||||
log_and_message_admins("has commanded their army of [controlled_mobs.len] to attack [L].")
|
||||
add_attack_logs(user,L,"Commanded their army of [controlled_mobs.len]")
|
||||
to_chat(user, "<span class='notice'>You command your [controlled_mobs.len > 1 ? "entities" : "[controlled_mobs[1]]"] to \
|
||||
attack \the [L].</span>")
|
||||
//This is to stop someone from controlling beepsky and getting him to stun someone 5 times a second.
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
return 0
|
||||
siphoning = AM
|
||||
update_icon()
|
||||
log_and_message_admins("is siphoning energy from \a [AM].")
|
||||
add_attack_logs(user,AM,"Siphoned energy from [src]")
|
||||
else
|
||||
stop_siphoning()
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
visible_message("<span class='danger'>\The [user] reaches out towards \the [L] with the flaming hand, and they ignite!</span>")
|
||||
to_chat(L, "<span class='danger'>You ignite!</span>")
|
||||
L.fire_act()
|
||||
log_and_message_admins("has ignited [L] with [src].")
|
||||
add_attack_logs(user,L,"Ignited with [src]")
|
||||
adjust_instability(12)
|
||||
else
|
||||
//This is needed in order for the welder to work, and works similarly to grippers.
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
if(pay_energy(500))
|
||||
illusion = new(T)
|
||||
illusion.copy_appearance(copied)
|
||||
illusion.copy_overlays(copied, TRUE)
|
||||
to_chat(user, "<span class='notice'>An illusion of \the [copied] is made on \the [T].</span>")
|
||||
user << 'sound/effects/pop.ogg'
|
||||
return 1
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
return
|
||||
var/obj/item/weapon/inserted_spell/inserted = new inserting(L,user,src)
|
||||
inserted.spell_power_at_creation = calculate_spell_power(1.0)
|
||||
log_and_message_admins("has casted [src] on [L].")
|
||||
add_attack_logs(user,L,"Casted [src]")
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weapon/spell/insert/on_melee_cast(atom/hit_atom, mob/user)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
var/obj/item/projectile/new_projectile = make_projectile(spell_projectile, user)
|
||||
new_projectile.old_style_target(hit_atom)
|
||||
new_projectile.fire()
|
||||
log_and_message_admins("has casted [src] at \the [hit_atom].")
|
||||
add_attack_logs(user,hit_atom,"Casted [src]")
|
||||
if(fire_sound)
|
||||
playsound(src, fire_sound, 75, 1)
|
||||
adjust_instability(instability_per_shot)
|
||||
@@ -39,4 +39,4 @@
|
||||
return TRUE
|
||||
return FALSE // We got dropped before the firing occured.
|
||||
return TRUE // No delay, no need to check.
|
||||
return FALSE
|
||||
return FALSE
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
spark_system.start()
|
||||
playsound(src, 'sound/weapons/blade1.ogg', 50, 1)
|
||||
// now send a log so that admins don't think they're shooting themselves on purpose.
|
||||
log_and_message_admins("[user] reflected [attacker]'s attack back at them.")
|
||||
add_attack_logs(user,attacker,"Reflected [attacker]'s attack")
|
||||
|
||||
if(!reflecting)
|
||||
reflecting = 1
|
||||
@@ -82,7 +82,7 @@
|
||||
spark_system.start()
|
||||
playsound(src, 'sound/weapons/blade1.ogg', 50, 1)
|
||||
|
||||
log_and_message_admins("[user] reflected [attacker]'s attack back at them.")
|
||||
add_attack_logs(user,attacker,"Reflected [attacker]'s attack")
|
||||
|
||||
if(!reflecting)
|
||||
reflecting = 1
|
||||
|
||||
@@ -76,5 +76,5 @@
|
||||
I.afterattack(chosen_target, user)
|
||||
else
|
||||
chosen_target.attack_hand(user)
|
||||
log_and_message_admins("has warp striked [chosen_target].")
|
||||
add_attack_logs(user,chosen_target,"Warp striked")
|
||||
|
||||
|
||||
@@ -27,4 +27,22 @@ var/const/access_pilot = 67
|
||||
/datum/access/entertainment
|
||||
id = access_entertainment
|
||||
desc = "Entertainment Backstage"
|
||||
region = ACCESS_REGION_GENERAL
|
||||
region = ACCESS_REGION_GENERAL
|
||||
|
||||
/var/const/access_mime = 138
|
||||
/datum/access/mime
|
||||
id = access_mime
|
||||
desc = "Mime Office"
|
||||
region = ACCESS_REGION_GENERAL
|
||||
|
||||
/var/const/access_clown = 136
|
||||
/datum/access/clown
|
||||
id = access_clown
|
||||
desc = "Clown Office"
|
||||
region = ACCESS_REGION_GENERAL
|
||||
|
||||
/var/const/access_tomfoolery = 137
|
||||
/datum/access/tomfoolery
|
||||
id = access_tomfoolery
|
||||
desc = "Tomfoolery Closet"
|
||||
region = ACCESS_REGION_GENERAL
|
||||
|
||||
@@ -26,13 +26,13 @@
|
||||
access_all_personal_lockers, access_maint_tunnels, access_bar, access_janitor, access_construction, access_morgue,
|
||||
access_crematorium, access_kitchen, access_cargo, access_cargo_bot, access_mailsorting, access_qm, access_hydroponics, access_lawyer,
|
||||
access_chapel_office, access_library, access_research, access_mining, access_heads_vault, access_mining_station,
|
||||
access_hop, access_RC_announce, access_keycard_auth)
|
||||
access_hop, access_RC_announce, access_clown, access_tomfoolery, access_mime, access_keycard_auth, access_gateway)
|
||||
minimal_access = list(access_security, access_sec_doors, access_brig, access_forensics_lockers,
|
||||
access_medical, access_engine, access_change_ids, access_ai_upload, access_eva, access_heads,
|
||||
access_all_personal_lockers, access_maint_tunnels, access_bar, access_janitor, access_construction, access_morgue,
|
||||
access_crematorium, access_kitchen, access_cargo, access_cargo_bot, access_mailsorting, access_qm, access_hydroponics, access_lawyer,
|
||||
access_chapel_office, access_library, access_research, access_mining, access_heads_vault, access_mining_station,
|
||||
access_hop, access_RC_announce, access_keycard_auth)
|
||||
access_hop, access_RC_announce, access_clown, access_tomfoolery, access_mime, access_keycard_auth, access_gateway)
|
||||
|
||||
/datum/alt_title/deputy_director
|
||||
title = "Deputy Director"
|
||||
|
||||
@@ -198,7 +198,9 @@
|
||||
job_description = "An entertainer does just that, entertains! Put on plays, play music, sing songs, tell stories, or read your favorite fanfic."
|
||||
alt_titles = list("Performer" = /datum/alt_title/performer, "Musician" = /datum/alt_title/musician, "Stagehand" = /datum/alt_title/stagehand,
|
||||
"Actor" = /datum/alt_title/actor, "Dancer" = /datum/alt_title/dancer, "Singer" = /datum/alt_title/singer,
|
||||
"Magician" = /datum/alt_title/magician, "Comedian" = /datum/alt_title/comedian, "Tragedian" = /datum/alt_title/tragedian)
|
||||
"Magician" = /datum/alt_title/magician, "Comedian" = /datum/alt_title/comedian, "Tragedian" = /datum/alt_title/tragedian,
|
||||
"Clown" = /datum/alt_title/clown, "Jester" = /datum/alt_title/clown/jester,"Fool" = /datum/alt_title/clown/fool,
|
||||
"Mime"= /datum/alt_title/mime,"Poseur"= /datum/alt_title/mime/poseur) //CHOMPEDIT: Adding clown + mime and their alts as alts of entertainer
|
||||
|
||||
// Entertainer Alt Titles
|
||||
/datum/alt_title/actor
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
access = list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels,
|
||||
access_teleporter, access_external_airlocks, access_atmospherics, access_emergency_storage, access_eva,
|
||||
access_heads, access_construction,
|
||||
access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_ai_upload)
|
||||
access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_ai_upload, access_gateway)
|
||||
|
||||
minimal_access = list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels,
|
||||
access_teleporter, access_external_airlocks, access_atmospherics, access_emergency_storage, access_eva,
|
||||
access_heads, access_construction,
|
||||
access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_ai_upload)
|
||||
access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_ai_upload, access_gateway)
|
||||
alt_titles = list("Head Engineer" = /datum/alt_title/head_engineer, "Foreman" = /datum/alt_title/foreman, "Maintenance Manager" = /datum/alt_title/maintenance_manager)
|
||||
|
||||
/datum/alt_title/head_engineer
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
var/const/PATHFINDER =(1<<11)
|
||||
var/const/EXPLORER =(1<<12)
|
||||
var/const/PILOT =(1<<13)
|
||||
var/const/SAR =(1<<14)
|
||||
|
||||
/obj/item/weapon/card/id/medical/sar
|
||||
assignment = "Field Medic"
|
||||
rank = "Field Medic"
|
||||
@@ -41,7 +36,7 @@ var/const/SAR =(1<<14)
|
||||
faction = "Station"
|
||||
total_positions = 1
|
||||
spawn_positions = 1
|
||||
supervisors = "the Head of Personnel"
|
||||
supervisors = "the Research Director" //CHOMPedit
|
||||
selection_color = "#d6d05c"
|
||||
economic_modifier = 8
|
||||
minimal_player_age = 7
|
||||
@@ -64,20 +59,20 @@ var/const/SAR =(1<<14)
|
||||
/datum/job/pilot
|
||||
title = "Pilot"
|
||||
flag = PILOT
|
||||
departments = list(DEPARTMENT_PLANET)
|
||||
department_flag = MEDSCI
|
||||
departments = list(DEPARTMENT_PLANET) //CHOMPedit: keep them part of exploration
|
||||
department_flag = MEDSCI //CHOMPedit
|
||||
faction = "Station"
|
||||
total_positions = 4
|
||||
spawn_positions = 4
|
||||
supervisors = "the Pathfinder and the Head of Personnel"
|
||||
selection_color = "#999440"
|
||||
total_positions = 5
|
||||
spawn_positions = 5
|
||||
supervisors = "the Pathfinder" //CHOMPedit
|
||||
selection_color = "#515151"
|
||||
economic_modifier = 5
|
||||
minimal_player_age = 3
|
||||
pto_type = PTO_EXPLORATION
|
||||
access = list(access_pilot)
|
||||
minimal_access = list(access_pilot)
|
||||
outfit_type = /decl/hierarchy/outfit/job/pilot
|
||||
job_description = "A Pilot flies the various shuttles in the Virgo-Erigone System."
|
||||
job_description = "A Pilot flies the various shuttles in the Vir System." //CHOMPedit: Replaces Virgo reference with Vir.
|
||||
alt_titles = list("Co-Pilot" = /datum/alt_title/co_pilot, "Navigator" = /datum/alt_title/navigator)
|
||||
|
||||
/datum/alt_title/co_pilot
|
||||
@@ -96,7 +91,7 @@ var/const/SAR =(1<<14)
|
||||
faction = "Station"
|
||||
total_positions = 3
|
||||
spawn_positions = 3
|
||||
supervisors = "the Pathfinder and the Head of Personnel"
|
||||
supervisors = "the Pathfinder" //CHOMPedit
|
||||
selection_color = "#999440"
|
||||
economic_modifier = 6
|
||||
pto_type = PTO_EXPLORATION
|
||||
@@ -121,7 +116,7 @@ var/const/SAR =(1<<14)
|
||||
faction = "Station"
|
||||
total_positions = 2
|
||||
spawn_positions = 2
|
||||
supervisors = "the Pathfinder and the Chief Medical Officer"
|
||||
supervisors = "the Pathfinder" //CHOMPedit
|
||||
selection_color = "#999440"
|
||||
economic_modifier = 6
|
||||
minimal_player_age = 3
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
|
||||
access = list(access_medical, access_medical_equip, access_morgue, access_genetics, access_heads,
|
||||
access_chemistry, access_virology, access_cmo, access_surgery, access_RC_announce, access_teleporter, //CHOMPEdit
|
||||
access_keycard_auth, access_psychiatrist, access_eva, access_external_airlocks, access_maint_tunnels)
|
||||
access_keycard_auth, access_psychiatrist, access_eva, access_external_airlocks, access_maint_tunnels, access_gateway)
|
||||
|
||||
minimal_access = list(access_medical, access_medical_equip, access_morgue, access_genetics, access_heads,
|
||||
access_chemistry, access_virology, access_cmo, access_surgery, access_RC_announce, access_teleporter,//CHOMPEdit
|
||||
access_keycard_auth, access_psychiatrist, access_eva, access_external_airlocks, access_maint_tunnels)
|
||||
access_keycard_auth, access_psychiatrist, access_eva, access_external_airlocks, access_maint_tunnels, access_gateway)
|
||||
alt_titles = list("Chief Physician" = /datum/alt_title/chief_physician, "Medical Director" = /datum/alt_title/medical_director, /*CHOMPEdit Removal"Healthcare Manager" = /datum/alt_title/healthcare_manager*/)
|
||||
|
||||
/datum/alt_title/chief_physician
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
access_research, access_robotics, access_xenobiology, access_ai_upload, access_tech_storage,
|
||||
access_RC_announce, access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_eva, access_network,
|
||||
access_explorer, access_pathfinder, access_xenobotany) //YW Edit access_gateway, _explorer, _pathfinder, and _xenobotany
|
||||
alt_titles = list("Research Supervisor" = /datum/alt_title/research_supervisor, "Research Manager" = /datum/alt_title/research_manager,
|
||||
"Head of Development" = /datum/alt_title/head_of_development,"Head Scientist" = /datum/alt_title/head_scientist)
|
||||
|
||||
/datum/alt_title/research_manager
|
||||
title = "Research Manager"
|
||||
|
||||
|
||||
@@ -77,16 +77,16 @@
|
||||
title = "Clown"
|
||||
flag = CLOWN
|
||||
departments = list(DEPARTMENT_CIVILIAN)
|
||||
department_flag = CIVILIAN
|
||||
department_flag = ENGSEC
|
||||
faction = "Station"
|
||||
total_positions = -1
|
||||
spawn_positions = -1
|
||||
total_positions = -1 //CHOMP Edit: Disable. Change to + integer to enable.
|
||||
spawn_positions = -1 //CHOMP Edit: Disable. Change to + integer to enable.
|
||||
supervisors = "the spirit of laughter"
|
||||
selection_color = "#515151"
|
||||
economic_modifier = 1
|
||||
job_description = "A Clown is there to entertain the crew and keep high morale using various harmless pranks and ridiculous jokes!"
|
||||
whitelist_only = 1
|
||||
latejoin_only = 1
|
||||
latejoin_only = 0
|
||||
outfit_type = /decl/hierarchy/outfit/job/clown
|
||||
pto_type = PTO_CIVILIAN
|
||||
alt_titles = list("Jester" = /datum/alt_title/jester, "Fool" = /datum/alt_title/fool)
|
||||
@@ -99,25 +99,25 @@
|
||||
|
||||
/datum/job/clown/get_access()
|
||||
if(config.assistant_maint)
|
||||
return list(access_maint_tunnels, access_entertainment)
|
||||
return list(access_maint_tunnels, access_entertainment, access_clown, access_tomfoolery)
|
||||
else
|
||||
return list(access_entertainment)
|
||||
return list(access_entertainment, access_clown, access_tomfoolery)
|
||||
|
||||
/datum/job/mime
|
||||
title = "Mime"
|
||||
flag = MIME
|
||||
departments = list(DEPARTMENT_CIVILIAN)
|
||||
department_flag = CIVILIAN
|
||||
department_flag = ENGSEC
|
||||
faction = "Station"
|
||||
total_positions = -1
|
||||
spawn_positions = -1
|
||||
total_positions = -1 //CHOMP Edit: Disable. Change to + integer to enable.
|
||||
spawn_positions = -1 //CHOMP Edit: Disable. Change to + integer to enable.
|
||||
supervisors = "the spirit of performance"
|
||||
selection_color = "#515151"
|
||||
economic_modifier = 1
|
||||
job_description = "A Mime is there to entertain the crew and keep high morale using unbelievable performances and acting skills!"
|
||||
alt_titles = list("Poseur" = /datum/alt_title/poseur)
|
||||
whitelist_only = 1
|
||||
latejoin_only = 1
|
||||
latejoin_only = 0
|
||||
outfit_type = /decl/hierarchy/outfit/job/mime
|
||||
pto_type = PTO_CIVILIAN
|
||||
|
||||
@@ -126,6 +126,6 @@
|
||||
|
||||
/datum/job/mime/get_access()
|
||||
if(config.assistant_maint)
|
||||
return list(access_maint_tunnels, access_entertainment)
|
||||
return list(access_maint_tunnels, access_entertainment, access_tomfoolery, access_mime)
|
||||
else
|
||||
return list(access_entertainment)
|
||||
return list(access_entertainment, access_tomfoolery, access_mime)
|
||||
|
||||
31
code/game/jobs/job/zz_alt_titles_ch.dm
Normal file
31
code/game/jobs/job/zz_alt_titles_ch.dm
Normal file
@@ -0,0 +1,31 @@
|
||||
/datum/job/entertainer
|
||||
alt_titles = list("Performer" = /datum/alt_title/performer, "Musician" = /datum/alt_title/musician, "Stagehand" = /datum/alt_title/stagehand,
|
||||
"Actor" = /datum/alt_title/actor, "Dancer" = /datum/alt_title/dancer, "Singer" = /datum/alt_title/singer,
|
||||
"Magician" = /datum/alt_title/magician, "Comedian" = /datum/alt_title/comedian, "Tragedian" = /datum/alt_title/tragedian,
|
||||
"Clown" = /datum/alt_title/clown, "Jester" = /datum/alt_title/clown/jester,"Fool" = /datum/alt_title/clown/fool,
|
||||
"Mime"= /datum/alt_title/mime,"Poseur"= /datum/alt_title/mime/poseur, "Fitness Instructor" = /datum/alt_title/fitness) //CHOMPEDIT: Adding clown + mime and their alts as alts of entertainer, as well as fitness instructor
|
||||
|
||||
/datum/alt_title/fitness
|
||||
title = "Fitness Instructor"
|
||||
title_blurb = "A Fitness Instructor's goal is to keep the station in shape. Get the crew shaving up those built up pounds and get them to eat something other than chocolate bars and burgers for once"
|
||||
|
||||
//Below, well sort off, these are the clown and mime returning! as entertainer alts
|
||||
//They even get their respective outfits.
|
||||
/datum/alt_title/clown
|
||||
title = "Clown"
|
||||
title_blurb = "A Clown is there to entertain the crew and keep high morale using various harmless pranks and ridiculous jokes!"
|
||||
title_outfit = /decl/hierarchy/outfit/job/clown
|
||||
|
||||
/datum/alt_title/clown/jester
|
||||
title = "Jester"
|
||||
|
||||
/datum/alt_title/clown/fool
|
||||
title = "Fool"
|
||||
|
||||
/datum/alt_title/mime
|
||||
title = "Mime"
|
||||
title_blurb = "A Mime is there to entertain the crew and keep high morale using unbelievable performances and acting skills!"
|
||||
title_outfit = /decl/hierarchy/outfit/job/mime
|
||||
|
||||
/datum/alt_title/mime/poseur
|
||||
title = "Poseur"
|
||||
@@ -414,7 +414,7 @@ var/global/datum/controller/occupations/job_master
|
||||
|
||||
// Implants get special treatment
|
||||
if(G.slot == "implant")
|
||||
var/obj/item/weapon/implant/I = G.spawn_item(H)
|
||||
var/obj/item/weapon/implant/I = G.spawn_item(H, H.client.prefs.gear[G.display_name])
|
||||
I.invisibility = 100
|
||||
I.implant_loadout(H)
|
||||
continue
|
||||
@@ -510,22 +510,23 @@ var/global/datum/controller/occupations/job_master
|
||||
to_chat(H, "<span class='danger'>Failed to locate a storage object on your mob, either you spawned with no arms and no backpack or this is a bug.</span>")
|
||||
|
||||
if(istype(H)) //give humans wheelchairs, if they need them.
|
||||
if(istype(H.loc, /obj/belly)) //unless in a gut
|
||||
if(istype(H.loc, /obj/belly)) //CHOMPedit start unless in a gut
|
||||
var/obj/item/organ/external/l_foot = H.get_organ("l_foot")
|
||||
var/obj/item/organ/external/r_foot = H.get_organ("r_foot")
|
||||
var/obj/item/weapon/storage/S = locate() in H.contents
|
||||
var/obj/item/wheelchair/R = null
|
||||
var/obj/item/wheelchair/R
|
||||
if(S)
|
||||
R = locate() in S.contents
|
||||
if(!l_foot || !r_foot || R)
|
||||
var/obj/structure/bed/chair/wheelchair/W = new /obj/structure/bed/chair/wheelchair(H.loc)
|
||||
var/wheelchair_type = R?.unfolded_type || /obj/structure/bed/chair/wheelchair
|
||||
var/obj/structure/bed/chair/wheelchair/W = new wheelchair_type(H.loc)
|
||||
W.buckle_mob(H)
|
||||
H.update_canmove()
|
||||
W.set_dir(H.dir)
|
||||
W.add_fingerprint(H)
|
||||
if(R)
|
||||
W.color = R.color
|
||||
qdel(R)
|
||||
qdel(R) //CHOMPedit end
|
||||
|
||||
to_chat(H, "<B>You are [job.total_positions == 1 ? "the" : "a"] [alt_title ? alt_title : rank].</B>")
|
||||
|
||||
@@ -745,7 +746,7 @@ var/global/datum/controller/occupations/job_master
|
||||
to_chat(C, "Your chosen spawnpoint ([spawnpos.display_name]) is unavailable for your chosen job. Spawning you at the Arrivals shuttle instead.")
|
||||
var/spawning = pick(latejoin)
|
||||
.["turf"] = get_turf(spawning)
|
||||
.["msg"] = "will arrive at the station shortly" //VOREStation Edit - Grammar but mostly 'shuttle' reference removal, and this also applies to notified spawn-character verb use
|
||||
.["msg"] = "will arrive at the station shortly"
|
||||
else if(!fail_deadly)
|
||||
var/spawning = pick(latejoin)
|
||||
.["turf"] = get_turf(spawning)
|
||||
|
||||
@@ -11,8 +11,8 @@ var/const/ENGINEER =(1<<6)
|
||||
var/const/ATMOSTECH =(1<<7)
|
||||
var/const/AI =(1<<8)
|
||||
var/const/CYBORG =(1<<9)
|
||||
var/const/BLUESHIELD =(1<<13) //YW addition
|
||||
var/const/SECPILOT =(1<<14) //YW addition
|
||||
var/const/CLOWN =(1<<13) //VOREStation Add
|
||||
var/const/MIME =(1<<14) //VOREStation Add
|
||||
var/const/INTERN =(1<<15) //VOREStation Add
|
||||
|
||||
var/const/MEDSCI =(1<<1)
|
||||
@@ -28,7 +28,10 @@ var/const/PSYCHIATRIST =(1<<7)
|
||||
var/const/ROBOTICIST =(1<<8)
|
||||
var/const/XENOBIOLOGIST =(1<<9)
|
||||
var/const/PARAMEDIC =(1<<10)
|
||||
var/const/XENOBOTANIST =(1<<15) //VOREStation Add
|
||||
var/const/PATHFINDER =(1<<11) //VOREStation Add
|
||||
var/const/EXPLORER =(1<<12) //VOREStation Add
|
||||
var/const/SAR =(1<<13) //VOREStation Add
|
||||
var/const/XENOBOTANIST =(1<<14) //VOREStation Add
|
||||
|
||||
var/const/CIVILIAN =(1<<2)
|
||||
|
||||
@@ -45,9 +48,8 @@ var/const/LAWYER =(1<<9)
|
||||
var/const/CHAPLAIN =(1<<10)
|
||||
var/const/ASSISTANT =(1<<11)
|
||||
var/const/BRIDGE =(1<<12)
|
||||
var/const/CLOWN =(1<<13) //VOREStation Add
|
||||
var/const/MIME =(1<<14) //VOREStation Add
|
||||
var/const/ENTERTAINER =(1<<15) //VOREStation Add
|
||||
var/const/PILOT =(1<<13) //VOREStation Add
|
||||
var/const/ENTERTAINER =(1<<14) //VOREStation Add
|
||||
|
||||
var/list/assistant_occupations = list(
|
||||
)
|
||||
|
||||
@@ -529,5 +529,5 @@
|
||||
stasis_level = 100 //Just one setting
|
||||
|
||||
/obj/machinery/sleeper/survival_pod/Initialize()
|
||||
..()
|
||||
. = ..()
|
||||
RefreshParts(1)
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
active_power_usage = 10000 //10 kW. It's a big all-body scanner.
|
||||
light_color = "#00FF00"
|
||||
var/obj/machinery/body_scanconsole/console
|
||||
var/known_implants = list(/obj/item/weapon/implant/health, /obj/item/weapon/implant/chem, /obj/item/weapon/implant/death_alarm, /obj/item/weapon/implant/loyalty, /obj/item/weapon/implant/tracking, /obj/item/weapon/implant/language, /obj/item/weapon/implant/language/eal, /obj/item/weapon/implant/backup, /obj/item/device/nif) //VOREStation Add - Backup Implant, NIF
|
||||
var/printing_text = null
|
||||
|
||||
/obj/machinery/bodyscanner/Initialize()
|
||||
@@ -255,12 +254,11 @@
|
||||
organData["broken"] = E.min_broken_damage
|
||||
|
||||
var/implantData[0]
|
||||
for(var/obj/I in E.implants)
|
||||
for(var/obj/thing in E.implants)
|
||||
var/implantSubData[0]
|
||||
implantSubData["name"] = I.name
|
||||
if(is_type_in_list(I, known_implants))
|
||||
implantSubData["known"] = 1
|
||||
|
||||
var/obj/item/weapon/implant/I = thing
|
||||
implantSubData["name"] = I.name
|
||||
implantSubData["known"] = istype(I) && I.known_implant
|
||||
implantData.Add(list(implantSubData))
|
||||
|
||||
organData["implants"] = implantData
|
||||
@@ -464,8 +462,9 @@
|
||||
infected = "Gangrene Detected:"
|
||||
|
||||
var/unknown_body = 0
|
||||
for(var/I in e.implants)
|
||||
if(is_type_in_list(I,known_implants))
|
||||
for(var/thing in e.implants)
|
||||
var/obj/item/weapon/implant/I = thing
|
||||
if(istype(I) && I.known_implant)
|
||||
imp += "[I] implanted:"
|
||||
else
|
||||
unknown_body++
|
||||
|
||||
@@ -39,6 +39,14 @@
|
||||
if(!autolathe_recipes)
|
||||
autolathe_recipes = new()
|
||||
wires = new(src)
|
||||
|
||||
for(var/Name in name_to_material)
|
||||
if(Name in stored_material)
|
||||
continue
|
||||
|
||||
stored_material[Name] = 0
|
||||
storage_capacity[Name] = 0
|
||||
|
||||
default_apply_parts()
|
||||
RefreshParts()
|
||||
|
||||
@@ -273,6 +281,15 @@
|
||||
|
||||
//Create the desired item.
|
||||
var/obj/item/I = new making.path(src.loc)
|
||||
|
||||
if(LAZYLEN(I.matter)) // Sadly we must obey the laws of equivalent exchange.
|
||||
I.matter.Cut()
|
||||
else
|
||||
I.matter = list()
|
||||
|
||||
for(var/material in making.resources) // Handle the datum's autoscaling for waste, so we're properly wasting material, but not so much if we have efficiency.
|
||||
I.matter[material] = round(making.resources[material] / (making.no_scale ? 1 : 1.25)) * (making.no_scale ? 1 : mat_efficiency)
|
||||
|
||||
flick("[initial(icon_state)]_finish", src)
|
||||
if(multiplier > 1)
|
||||
if(istype(I, /obj/item/stack))
|
||||
@@ -280,7 +297,16 @@
|
||||
S.amount = multiplier
|
||||
else
|
||||
for(multiplier; multiplier > 1; --multiplier) // Create multiple items if it's not a stack.
|
||||
new making.path(src.loc)
|
||||
I = new making.path(src.loc)
|
||||
// We've already deducted the cost of multiple items. Process the matter the same.
|
||||
if(LAZYLEN(I.matter))
|
||||
I.matter.Cut()
|
||||
|
||||
else
|
||||
I.matter = list()
|
||||
|
||||
for(var/material in making.resources)
|
||||
I.matter[material] = round(making.resources[material] / (making.no_scale ? 1 : 1.25)) * (making.no_scale ? 1 : mat_efficiency)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -306,10 +332,9 @@
|
||||
for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
|
||||
man_rating += M.rating
|
||||
|
||||
storage_capacity[DEFAULT_WALL_MATERIAL] = mb_rating * 25000
|
||||
storage_capacity[MAT_PLASTIC] = mb_rating * 20000
|
||||
storage_capacity[MAT_PLASTEEL] = mb_rating * 16250
|
||||
storage_capacity["glass"] = mb_rating * 12500
|
||||
for(var/mat_name in storage_capacity)
|
||||
storage_capacity[mat_name] = mb_rating * 25000
|
||||
|
||||
build_time = 50 / man_rating
|
||||
mat_efficiency = 1.1 - man_rating * 0.1// Normally, price is 1.25 the amount of material, so this shouldn't go higher than 0.6. Maximum rating of parts is 5
|
||||
update_tgui_static_data(usr)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user