Merge branch 'master' into upstream-merge-33246

This commit is contained in:
LetterJay
2017-12-20 00:27:06 -06:00
committed by GitHub
808 changed files with 14650 additions and 10287 deletions
+16 -13
View File
@@ -94,19 +94,22 @@
#define BANTYPE_ANY_JOB 9 //used to remove jobbans
//Admin Permissions
#define R_BUILDMODE 1
#define R_ADMIN 2
#define R_BAN 4
#define R_FUN 8
#define R_SERVER 16
#define R_DEBUG 32
#define R_POSSESS 64
#define R_PERMISSIONS 128
#define R_STEALTH 256
#define R_POLL 512
#define R_VAREDIT 1024
#define R_SOUNDS 2048
#define R_SPAWN 4096
#define R_BUILDMODE 0x1
#define R_ADMIN 0x2
#define R_BAN 0x4
#define R_FUN 0x8
#define R_SERVER 0x10
#define R_DEBUG 0x20
#define R_POSSESS 0x40
#define R_PERMISSIONS 0x80
#define R_STEALTH 0x100
#define R_POLL 0x200
#define R_VAREDIT 0x400
#define R_SOUNDS 0x800
#define R_SPAWN 0x1000
#define R_AUTOLOGIN 0x2000
#define R_DEFAULT R_AUTOLOGIN
#if DM_VERSION > 512
#error Remove the flag below , its been long enough
+6
View File
@@ -12,6 +12,12 @@
//ATMOS
//stuff you should probably leave well alone!
#define R_IDEAL_GAS_EQUATION 8.31 //kPa*L/(K*mol)
#define ONE_ATMOSPHERE 101.325 //kPa
#define T0C 273.15 // 0degC
#define T20C 293.15 // 20degC
#define TCMB 2.7 // -270.3degC
#define MOLES_CELLSTANDARD (ONE_ATMOSPHERE*CELL_VOLUME/(T20C*R_IDEAL_GAS_EQUATION)) //moles in a 2.5 m^3 cell at 101.325 Pa and 20 degC
#define M_CELL_WITH_RATIO (MOLES_CELLSTANDARD * 0.005) //compared against for superconductivity
#define O2STANDARD 0.21 //percentage of oxygen in a normal mixture of air
+17 -15
View File
@@ -17,8 +17,9 @@
#define DIAG_TRACK_HUD "13"// Mech tracking beacon
#define DIAG_AIRLOCK_HUD "14"//Airlock shock overlay
#define DIAG_PATH_HUD "15"//Bot path indicators
#define GLAND_HUD "16"//Gland indicators for abductors
//for antag huds. these are used at the /mob level
#define ANTAG_HUD "16"
#define ANTAG_HUD "17"
//by default everything in the hud_list of an atom is an image
//a value in hud_list with one of these will change that behavior
@@ -32,21 +33,22 @@
#define DATA_HUD_MEDICAL_ADVANCED 4
#define DATA_HUD_DIAGNOSTIC_BASIC 5
#define DATA_HUD_DIAGNOSTIC_ADVANCED 6
#define DATA_HUD_ABDUCTOR 7
//antag HUD defines
#define ANTAG_HUD_CULT 7
#define ANTAG_HUD_REV 8
#define ANTAG_HUD_OPS 9
#define ANTAG_HUD_WIZ 10
#define ANTAG_HUD_SHADOW 11
#define ANTAG_HUD_TRAITOR 12
#define ANTAG_HUD_NINJA 13
#define ANTAG_HUD_CHANGELING 14
#define ANTAG_HUD_ABDUCTOR 15
#define ANTAG_HUD_DEVIL 16
#define ANTAG_HUD_SINTOUCHED 17
#define ANTAG_HUD_SOULLESS 18
#define ANTAG_HUD_CLOCKWORK 19
#define ANTAG_HUD_BROTHER 20
#define ANTAG_HUD_CULT 8
#define ANTAG_HUD_REV 9
#define ANTAG_HUD_OPS 10
#define ANTAG_HUD_WIZ 11
#define ANTAG_HUD_SHADOW 12
#define ANTAG_HUD_TRAITOR 13
#define ANTAG_HUD_NINJA 14
#define ANTAG_HUD_CHANGELING 15
#define ANTAG_HUD_ABDUCTOR 16
#define ANTAG_HUD_DEVIL 17
#define ANTAG_HUD_SINTOUCHED 18
#define ANTAG_HUD_SOULLESS 19
#define ANTAG_HUD_CLOCKWORK 20
#define ANTAG_HUD_BROTHER 21
// Notification action types
#define NOTIFY_JUMP "jump"
+2 -1
View File
@@ -61,6 +61,8 @@
#define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user)
#define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (/mob)
#define COMSIG_ITEM_ATTACK_OBJ "item_attack_obj" //from base of obj/item/attack_obj(): (/obj, /mob)
#define COMSIG_ITEM_EQUIPPED "item_equip" //from base of obj/item/equipped(): (/mob/equipper, slot)
#define COMSIG_ITEM_DROPPED "item_drop" //from base of obj/item/dropped(): (/mob/dropper)
// /obj/item/clothing signals
#define COMSIG_SHOES_STEP_ACTION "shoes_step_action" //from base of obj/item/clothing/shoes/proc/step_action(): ()
@@ -77,7 +79,6 @@
#define COMSIG_MACHINE_PROCESS "machine_process" //from machinery subsystem fire(): ()
#define COMSIG_MACHINE_PROCESS_ATMOS "machine_process_atmos" //from air subsystem process_atmos_machinery(): ()
// /mob/living/carbon/human signals
#define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target)
#define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker)
-2
View File
@@ -1,8 +1,6 @@
//config files
#define CONFIG_DEF(X) /datum/config_entry/##X { resident_file = CURRENT_RESIDENT_FILE }; /datum/config_entry/##X
#define CONFIG_GET(X) global.config.Get(/datum/config_entry/##X)
#define CONFIG_SET(X, Y) global.config.Set(/datum/config_entry/##X, ##Y)
#define CONFIG_TWEAK(X) /datum/config_entry/##X
#define CONFIG_MAPS_FILE "maps.txt"
+1
View File
@@ -10,6 +10,7 @@
#define INVESTIGATE_TELESCI "telesci"
#define INVESTIGATE_WIRES "wires"
#define INVESTIGATE_PORTAL "portals"
#define INVESTIGATE_RESEARCH "research"
#define INVESTIGATE_HALLUCINATIONS "hallucinations"
#define INVESTIGATE_RADIATION "radiation"
#define INVESTIGATE_EXONET "exonet"
-27
View File
@@ -1,27 +0,0 @@
#define PI 3.1415
#define SPEED_OF_LIGHT 3e8 //not exact but hey!
#define SPEED_OF_LIGHT_SQ 9e+16
#define INFINITY 1e31 //closer then enough
//atmos
#define R_IDEAL_GAS_EQUATION 8.31 //kPa*L/(K*mol)
#define ONE_ATMOSPHERE 101.325 //kPa
#define T0C 273.15 // 0degC
#define T20C 293.15 // 20degC
#define TCMB 2.7 // -270.3degC
#define SHORT_REAL_LIMIT 16777216
//"fancy" math for calculating time in ms from tick_usage percentage and the length of ticks
//percent_of_tick_used * (ticklag * 100(to convert to ms)) / 100(percent ratio)
//collapsed to percent_of_tick_used * tick_lag
#define TICK_DELTA_TO_MS(percent_of_tick_used) ((percent_of_tick_used) * world.tick_lag)
#define TICK_USAGE_TO_MS(starting_tickusage) (TICK_DELTA_TO_MS(TICK_USAGE_REAL - starting_tickusage))
#define PERCENT(val) (round(val*100, 0.1))
#define CLAMP01(x) (Clamp(x, 0, 1))
//time of day but automatically adjusts to the server going into the next day within the same round.
//for when you need a reliable time number that doesn't depend on byond time.
#define REALTIMEOFDAY (world.timeofday + (MIDNIGHT_ROLLOVER * MIDNIGHT_ROLLOVER_CHECK))
#define MIDNIGHT_ROLLOVER_CHECK ( GLOB.rollovercheck_last_timeofday != world.timeofday ? update_midnight_rollover() : GLOB.midnight_rollovers )
+209
View File
@@ -0,0 +1,209 @@
// Credits to Nickr5 for the useful procs I've taken from his library resource.
// This file is quadruple wrapped for your pleasure
// (
#define NUM_E 2.71828183
#define NUM_SQRT2 1.41421356
#define PI 3.1415
#define SPEED_OF_LIGHT 3e8 //not exact but hey!
#define SPEED_OF_LIGHT_SQ 9e+16
#define INFINITY 1e31 //closer then enough
#define SHORT_REAL_LIMIT 16777216
//"fancy" math for calculating time in ms from tick_usage percentage and the length of ticks
//percent_of_tick_used * (ticklag * 100(to convert to ms)) / 100(percent ratio)
//collapsed to percent_of_tick_used * tick_lag
#define TICK_DELTA_TO_MS(percent_of_tick_used) ((percent_of_tick_used) * world.tick_lag)
#define TICK_USAGE_TO_MS(starting_tickusage) (TICK_DELTA_TO_MS(TICK_USAGE_REAL - starting_tickusage))
#define PERCENT(val) (round((val)*100, 0.1))
#define CLAMP01(x) (CLAMP(x, 0, 1))
//time of day but automatically adjusts to the server going into the next day within the same round.
//for when you need a reliable time number that doesn't depend on byond time.
#define REALTIMEOFDAY (world.timeofday + (MIDNIGHT_ROLLOVER * MIDNIGHT_ROLLOVER_CHECK))
#define MIDNIGHT_ROLLOVER_CHECK ( GLOB.rollovercheck_last_timeofday != world.timeofday ? update_midnight_rollover() : GLOB.midnight_rollovers )
#define SIGN(x) ( (x)!=0 ? (x) / abs(x) : 0 )
#define CEILING(x, y) ( -round(-(x) / (y)) * (y) )
// round() acts like floor(x, 1) by default but can't handle other values
#define FLOOR(x, y) ( round((x) / (y)) * (y) )
#define CLAMP(CLVALUE,CLMIN,CLMAX) ( max( (CLMIN), min((CLVALUE), (CLMAX)) ) )
// Similar to clamp but the bottom rolls around to the top and vice versa. min is inclusive, max is exclusive
#define WRAP(val, min, max) ( min == max ? min : (val) - (round(((val) - (min))/((max) - (min))) * ((max) - (min))) )
// Real modulus that handles decimals
#define MODULUS(x, y) ( (x) - (y) * round((x) / (y)) )
// Tangent
#define TAN(x) (sin(x) / cos(x))
// Cotangent
#define COT(x) (1 / TAN(x))
// Secant
#define SEC(x) (1 / cos(x))
// Cosecant
#define CSC(x) (1 / sin(x))
#define ATAN2(x, y) ( !(x) && !(y) ? 0 : (y) >= 0 ? arccos((x) / sqrt((x)*(x) + (y)*(y))) : -arccos((x) / sqrt((x)*(x) + (y)*(y))) )
// Greatest Common Divisor - Euclid's algorithm
/proc/Gcd(a, b)
return b ? Gcd(b, (a) % (b)) : a
// Least Common Multiple
#define Lcm(a, b) (abs(a) / Gcd(a, b) * abs(b))
#define INVERSE(x) ( 1/(x) )
// Used for calculating the radioactive strength falloff
#define INVERSE_SQUARE(initial_strength,cur_distance,initial_distance) ( (initial_strength)*((initial_distance)**2/(cur_distance)**2) )
#define ISABOUTEQUAL(a, b, deviation) (deviation ? abs((a) - (b)) <= deviation : abs((a) - (b)) <= 0.1)
#define ISEVEN(x) (x % 2 == 0)
#define ISODD(x) (x % 2 != 0)
// Returns true if val is from min to max, inclusive.
#define ISINRANGE(val, min, max) (min <= val && val <= max)
// Same as above, exclusive.
#define ISINRANGE_EX(val, min, max) (min < val && val > max)
#define ISINTEGER(x) (round(x) == x)
#define ISMULTIPLE(x, y) ((x) % (y) == 0)
// Performs a linear interpolation between a and b.
// Note that amount=0 returns a, amount=1 returns b, and
// amount=0.5 returns the mean of a and b.
#define LERP(a, b, amount) (amount ? ((a) + ((b) - (a)) * (amount)) : ((a) + ((b) - (a)) * 0.5)
// Returns the nth root of x.
#define ROOT(n, x) ((x) ** (1 / (n)))
// The quadratic formula. Returns a list with the solutions, or an empty list
// if they are imaginary.
/proc/SolveQuadratic(a, b, c)
ASSERT(a)
. = list()
var/d = b*b - 4 * a * c
var/bottom = 2 * a
if(d < 0)
return
var/root = sqrt(d)
. += (-b + root) / bottom
if(!d)
return
. += (-b - root) / bottom
#define TODEGREES(radians) ((radians) * 57.2957795)
#define TORADIANS(degrees) ((degrees) * 0.0174532925)
// Will filter out extra rotations and negative rotations
// E.g: 540 becomes 180. -180 becomes 180.
#define SIMPLIFY_DEGREES(degrees) (MODULUS((degrees), 360))
#define GET_ANGLE_OF_INCIDENCE(face, input) (MODULUS((face) - (input), 360))
//A logarithm that converts an integer to a number scaled between 0 and 1.
//Currently, this is used for hydroponics-produce sprite transforming, but could be useful for other transform functions.
#define TRANSFORM_USING_VARIABLE(input, max) ( sin((90*(input))/(max))**2 )
//converts a uniform distributed random number into a normal distributed one
//since this method produces two random numbers, one is saved for subsequent calls
//(making the cost negligble for every second call)
//This will return +/- decimals, situated about mean with standard deviation stddev
//68% chance that the number is within 1stddev
//95% chance that the number is within 2stddev
//98% chance that the number is within 3stddev...etc
#define ACCURACY 10000
/proc/gaussian(mean, stddev)
var/static/gaussian_next
var/R1;var/R2;var/working
if(gaussian_next != null)
R1 = gaussian_next
gaussian_next = null
else
do
R1 = rand(-ACCURACY,ACCURACY)/ACCURACY
R2 = rand(-ACCURACY,ACCURACY)/ACCURACY
working = R1*R1 + R2*R2
while(working >= 1 || working==0)
working = sqrt(-2 * log(working) / working)
R1 *= working
gaussian_next = R2 * working
return (mean + stddev * R1)
#undef ACCURACY
/proc/mouse_angle_from_client(client/client)
var/list/mouse_control = params2list(client.mouseParams)
if(mouse_control["screen-loc"] && client)
var/list/screen_loc_params = splittext(mouse_control["screen-loc"], ",")
var/list/screen_loc_X = splittext(screen_loc_params[1],":")
var/list/screen_loc_Y = splittext(screen_loc_params[2],":")
var/x = (text2num(screen_loc_X[1]) * 32 + text2num(screen_loc_X[2]) - 32)
var/y = (text2num(screen_loc_Y[1]) * 32 + text2num(screen_loc_Y[2]) - 32)
var/list/screenview = getviewsize(client.view)
var/screenviewX = screenview[1] * world.icon_size
var/screenviewY = screenview[2] * world.icon_size
var/ox = round(screenviewX/2) - client.pixel_x //"origin" x
var/oy = round(screenviewY/2) - client.pixel_y //"origin" y
var/angle = SIMPLIFY_DEGREES(ATAN2(y - oy, x - ox))
return angle
/proc/get_turf_in_angle(angle, turf/starting, increments)
var/pixel_x = 0
var/pixel_y = 0
for(var/i in 1 to increments)
pixel_x += sin(angle)+16*sin(angle)*2
pixel_y += cos(angle)+16*cos(angle)*2
var/new_x = starting.x
var/new_y = starting.y
while(pixel_x > 16)
pixel_x -= 32
new_x++
while(pixel_x < -16)
pixel_x += 32
new_x--
while(pixel_y > 16)
pixel_y -= 32
new_y++
while(pixel_y < -16)
pixel_y += 32
new_y--
new_x = CLAMP(new_x, 0, world.maxx)
new_y = CLAMP(new_y, 0, world.maxy)
return locate(new_x, new_y, starting.z)
// Returns a list where [1] is all x values and [2] is all y values that overlap between the given pair of rectangles
/proc/get_overlap(x1, y1, x2, y2, x3, y3, x4, y4)
var/list/region_x1 = list()
var/list/region_y1 = list()
var/list/region_x2 = list()
var/list/region_y2 = list()
// These loops create loops filled with x/y values that the boundaries inhabit
// ex: list(5, 6, 7, 8, 9)
for(var/i in min(x1, x2) to max(x1, x2))
region_x1["[i]"] = TRUE
for(var/i in min(y1, y2) to max(y1, y2))
region_y1["[i]"] = TRUE
for(var/i in min(x3, x4) to max(x3, x4))
region_x2["[i]"] = TRUE
for(var/i in min(y3, y4) to max(y3, y4))
region_y2["[i]"] = TRUE
return list(region_x1 & region_x2, region_y1 & region_y2)
// )
+3
View File
@@ -484,6 +484,9 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
#define SYRINGE_DRAW 0
#define SYRINGE_INJECT 1
#define RESEARCH_MATERIAL_RECLAMATION_ID "0"
//gold slime core spawning
#define NO_SPAWN 0
#define HOSTILE_SPAWN 1
+61
View File
@@ -0,0 +1,61 @@
//RDSCREEN screens
#define RDSCREEN_MENU 0
#define RDSCREEN_TECHDISK 1
#define RDSCREEN_DESIGNDISK 20
#define RDSCREEN_DESIGNDISK_UPLOAD 21
#define RDSCREEN_DECONSTRUCT 3
#define RDSCREEN_PROTOLATHE 40
#define RDSCREEN_PROTOLATHE_MATERIALS 41
#define RDSCREEN_PROTOLATHE_CHEMICALS 42
#define RDSCREEN_PROTOLATHE_CATEGORY_VIEW 43
#define RDSCREEN_PROTOLATHE_SEARCH 44
#define RDSCREEN_IMPRINTER 50
#define RDSCREEN_IMPRINTER_MATERIALS 51
#define RDSCREEN_IMPRINTER_CHEMICALS 52
#define RDSCREEN_IMPRINTER_CATEGORY_VIEW 53
#define RDSCREEN_IMPRINTER_SEARCH 54
#define RDSCREEN_SETTINGS 61
#define RDSCREEN_DEVICE_LINKING 62
#define RDSCREEN_TECHWEB 70
#define RDSCREEN_TECHWEB_NODEVIEW 71
#define RDSCREEN_TECHWEB_DESIGNVIEW 72
#define RDSCREEN_NOBREAK "<NO_HTML_BREAK>"
#define RDSCREEN_TEXT_NO_PROTOLATHE "<div><h3>No Protolathe Linked!</h3></div><br>"
#define RDSCREEN_TEXT_NO_IMPRINTER "<div><h3>No Circuit Imprinter Linked!</h3></div><br>"
#define RDSCREEN_TEXT_NO_DECONSTRUCT "<div><h3>No Deconstructive Analyzer Linked!</h3></div><br>"
#define RDSCREEN_TEXT_NO_TDISK "<div><h3>No Technology Disk Inserted!</h3></div><br>"
#define RDSCREEN_TEXT_NO_DDISK "<div><h3>No Design Disk Inserted!</h3></div><br>"
#define RDSCREEN_TEXT_NO_SNODE "<div><h3>No Technology Node Selected!</h3></div><br>"
#define RDSCREEN_TEXT_NO_SDESIGN "<div><h3>No Design Selected!</h3></div><br>"
#define RDSCREEN_UI_LATHE_CHECK if(!linked_lathe) { return RDSCREEN_TEXT_NO_PROTOLATHE }
#define RDSCREEN_UI_IMPRINTER_CHECK if(!linked_imprinter) { return RDSCREEN_TEXT_NO_IMPRINTER }
#define RDSCREEN_UI_DECONSTRUCT_CHECK if(!linked_destroy) { return RDSCREEN_TEXT_NO_DECONSTRUCT }
#define RDSCREEN_UI_TDISK_CHECK if(!t_disk) { return RDSCREEN_TEXT_NO_TDISK }
#define RDSCREEN_UI_DDISK_CHECK if(!d_disk) { return RDSCREEN_TEXT_NO_DDISK }
#define RDSCREEN_UI_SNODE_CHECK if(!selected_node) { return RDSCREEN_TEXT_NO_SNODE }
#define RDSCREEN_UI_SDESIGN_CHECK if(!selected_design) { return RDSCREEN_TEXT_NO_SDESIGN }
#define DEPLATHE_SCREEN_PRIMARY 1
#define DEPLATHE_SCREEN_SEARCH 2
#define DEPLATHE_SCREEN_MATERIALS 3
#define DEPLATHE_SCREEN_CHEMICALS 4
#define DEPPRINTER_SCREEN_PRIMARY 1
#define DEPPRINTER_SCREEN_SEARCH 2
#define DEPPRINTER_SCREEN_MATERIALS 3
#define DEPPRINTER_SCREEN_CHEMICALS 4
#define DEPARTMENTAL_FLAG_SECURITY 1
#define DEPARTMENTAL_FLAG_MEDICAL 2
#define DEPARTMENTAL_FLAG_CARGO 4
#define DEPARTMENTAL_FLAG_SCIENCE 8
#define DEPARTMENTAL_FLAG_ENGINEERING 16
#define DEPARTMENTAL_FLAG_SERVICE 32
#define DEPARTMENTAL_FLAG_ALL 64 //NO THIS DOESN'T ALLOW YOU TO PRINT EVERYTHING, IT'S FOR ALL DEPARTMENTS!
//#define DEPARTMENTAL_FLAG_MINING 128
#define DESIGN_ID_IGNORE "IGNORE_THIS_DESIGN"
+8
View File
@@ -0,0 +1,8 @@
#define SERVER_TOOLS_EXTERNAL_CONFIGURATION
#define SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(Name, Value) GLOBAL_VAR_INIT(##Name, ##Value); GLOBAL_PROTECT(##Name)
#define SERVER_TOOLS_READ_GLOBAL(Name) GLOB.##Name
#define SERVER_TOOLS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value
#define SERVER_TOOLS_WORLD_ANNOUNCE(message) to_chat(world, "<span class='boldannounce'>[html_encode(##message)]</span>")
#define SERVER_TOOLS_LOG(message) log_world("SERVICE: [##message]")
#define SERVER_TOOLS_NOTIFY_ADMINS(event) message_admins(##event)
#define SERVER_TOOLS_CLIENT_COUNT GLOB.clients.len
+14 -13
View File
@@ -1,4 +1,5 @@
// /tg/station 13 server tools API v3.1.0.2
// /tg/station 13 server tools API
#define SERVICE_API_VERSION_STRING "3.2.0.1"
//CONFIGURATION
//use this define if you want to do configuration outside of this file
@@ -10,19 +11,19 @@
//create a global variable named `Name` and set it to `Value`
//These globals must not be modifiable from anywhere outside of the server tools
#define SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(Name, Value) GLOBAL_VAR_INIT(##Name, ##Value); GLOBAL_PROTECT(##Name)
#define SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(Name, Value)
//Read the value in the global variable `Name`
#define SERVER_TOOLS_READ_GLOBAL(Name) GLOB.##Name
#define SERVER_TOOLS_READ_GLOBAL(Name)
//Set the value in the global variable `Name` to `Value`
#define SERVER_TOOLS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value
#define SERVER_TOOLS_WRITE_GLOBAL(Name, Value)
//display an announcement `message` from the server to all players
#define SERVER_TOOLS_WORLD_ANNOUNCE(message) to_chat(world, "<span class='boldannounce'>[html_encode(##message)]</span>")
#define SERVER_TOOLS_WORLD_ANNOUNCE(message)
//Write a string `message` to a server log
#define SERVER_TOOLS_LOG(message) log_world("SERVICE: [##message]")
#define SERVER_TOOLS_LOG(message)
//Notify current in-game administrators of a string `event`
#define SERVER_TOOLS_NOTIFY_ADMINS(event) message_admins(##event)
#define SERVER_TOOLS_NOTIFY_ADMINS(event)
//The current amount of connected clients
#define SERVER_TOOLS_CLIENT_COUNT GLOB.clients.len
#define SERVER_TOOLS_CLIENT_COUNT
#endif
//Required hooks:
@@ -64,16 +65,15 @@
//IMPLEMENTATION
#define SERVICE_API_VERSION_STRING "3.1.0.2"
#define REBOOT_MODE_NORMAL 0
#define REBOOT_MODE_HARD 1
#define REBOOT_MODE_SHUTDOWN 2
#define SERVICE_WORLD_PARAM "server_service"
#define SERVICE_VERSION_PARAM "server_service_version"
#define SERVICE_INSTANCE_PARAM "server_instance"
#define SERVICE_PR_TEST_JSON "prtestjob.json"
#define SERVICE_INTERFACE_DLL "TGServiceInterface.dll"
#define SERVICE_INTERFACE_DLL "TGDreamDaemonBridge.dll"
#define SERVICE_INTERFACE_FUNCTION "DDEntryPoint"
#define SERVICE_CMD_HARD_REBOOT "hard_reboot"
@@ -98,11 +98,12 @@
#define SERVICE_REQUEST_WORLD_REBOOT "worldreboot"
#define SERVICE_REQUEST_API_VERSION "api_ver"
#define SERVICE_RETURN_SUCCESS "SUCCESS"
/*
The MIT License
Copyright (c) 2011 Dominic Tarr
Copyright (c) 2017 Jordan Brown
Permission is hereby granted, free of charge,
to any person obtaining a copy of this software and
associated documentation files (the "Software"), to
+12 -11
View File
@@ -23,8 +23,8 @@
#define FLIGHTSUIT_PROCESSING_FULL 1
#define INITIALIZATION_INSSATOMS 0 //New should not call Initialize
#define INITIALIZATION_INNEW_MAPLOAD 1 //New should call Initialize(TRUE)
#define INITIALIZATION_INNEW_REGULAR 2 //New should call Initialize(FALSE)
#define INITIALIZATION_INNEW_MAPLOAD 2 //New should call Initialize(TRUE)
#define INITIALIZATION_INNEW_REGULAR 1 //New should call Initialize(FALSE)
#define INITIALIZE_HINT_NORMAL 0 //Nothing happens
#define INITIALIZE_HINT_LATELOAD 1 //Call LateInitialize
@@ -46,15 +46,16 @@
#define INIT_ORDER_DBCORE 18
#define INIT_ORDER_BLACKBOX 17
#define INIT_ORDER_SERVER_MAINT 16
#define INIT_ORDER_EVENTS 15
#define INIT_ORDER_JOBS 14
#define INIT_ORDER_TICKER 13
#define INIT_ORDER_MAPPING 12
#define INIT_ORDER_ATOMS 11
#define INIT_ORDER_NETWORKS 10
#define INIT_ORDER_LANGUAGE 9
#define INIT_ORDER_MACHINES 8
#define INIT_ORDER_CIRCUIT 7
#define INIT_ORDER_RESEARCH 15
#define INIT_ORDER_EVENTS 14
#define INIT_ORDER_JOBS 13
#define INIT_ORDER_TICKER 12
#define INIT_ORDER_MAPPING 11
#define INIT_ORDER_ATOMS 10
#define INIT_ORDER_NETWORKS 9
#define INIT_ORDER_LANGUAGE 8
#define INIT_ORDER_MACHINES 7
#define INIT_ORDER_CIRCUIT 6
#define INIT_ORDER_TIMER 1
#define INIT_ORDER_DEFAULT 0
#define INIT_ORDER_AIR -1
+2 -2
View File
@@ -43,8 +43,8 @@
//Returns list element or null. Should prevent "index out of bounds" error.
/proc/listgetindex(list/L, index)
if(LAZYLEN(L))
if(isnum(index) && IsInteger(index))
if(IsInRange(index,1,L.len))
if(isnum(index) && ISINTEGER(index))
if(ISINRANGE(index,1,L.len))
return L[index]
else if(index in L)
return L[index]
-5
View File
@@ -72,11 +72,6 @@
var/datum/material/D = new path()
GLOB.materials_list[D.id] = D
//Techs
for(var/path in subtypesof(/datum/tech))
var/datum/tech/D = new path()
GLOB.tech_list[D.id] = D
//Emotes
for(var/path in subtypesof(/datum/emote))
var/datum/emote/E = new path()
-257
View File
@@ -1,257 +0,0 @@
// Credits to Nickr5 for the useful procs I've taken from his library resource.
GLOBAL_VAR_INIT(E, 2.71828183)
GLOBAL_VAR_INIT(Sqrt2, 1.41421356)
// List of square roots for the numbers 1-100.
GLOBAL_LIST_INIT(sqrtTable, list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10))
/proc/sign(x)
return x!=0?x/abs(x):0
/proc/Atan2(x, y)
if(!x && !y)
return 0
var/a = arccos(x / sqrt(x*x + y*y))
return y >= 0 ? a : -a
/proc/Ceiling(x, y=1)
return -round(-x / y) * y
/proc/Floor(x, y=1)
return round(x / y) * y
#define Clamp(CLVALUE,CLMIN,CLMAX) ( max( (CLMIN), min((CLVALUE), (CLMAX)) ) )
/proc/Modulus(x, y) //Byond's modulus doesn't work with decimals.
return x - y * round(x / y)
// cotangent
/proc/Cot(x)
return 1 / Tan(x)
// cosecant
/proc/Csc(x)
return 1 / sin(x)
/proc/Default(a, b)
return a ? a : b
// Greatest Common Divisor - Euclid's algorithm
/proc/Gcd(a, b)
return b ? Gcd(b, a % b) : a
/proc/Inverse(x)
return 1 / x
#define InverseSquareLaw(initial_strength,cur_distance,initial_distance) (initial_strength*(initial_distance**2/cur_distance**2))
/proc/IsAboutEqual(a, b, deviation = 0.1)
return abs(a - b) <= deviation
/proc/IsEven(x)
return x % 2 == 0
// Returns true if val is from min to max, inclusive.
/proc/IsInRange(val, min, max)
return min <= val && val <= max
/proc/IsInteger(x)
return round(x) == x
/proc/IsOdd(x)
return !IsEven(x)
/proc/IsMultiple(x, y)
return x % y == 0
// Least Common Multiple
/proc/Lcm(a, b)
return abs(a) / Gcd(a, b) * abs(b)
// Performs a linear interpolation between a and b.
// Note that amount=0 returns a, amount=1 returns b, and
// amount=0.5 returns the mean of a and b.
/proc/Lerp(a, b, amount = 0.5)
return a + (b - a) * amount
//Calculates the sum of a list of numbers.
/proc/Sum(var/list/data)
. = 0
for(var/val in data)
.+= val
//Calculates the mean of a list of numbers.
/proc/Mean(var/list/data)
. = Sum(data) / (data.len)
// Returns the nth root of x.
/proc/Root(n, x)
return x ** (1 / n)
// secant
/proc/Sec(x)
return 1 / cos(x)
// The quadratic formula. Returns a list with the solutions, or an empty list
// if they are imaginary.
/proc/SolveQuadratic(a, b, c)
ASSERT(a)
. = list()
var/d = b*b - 4 * a * c
var/bottom = 2 * a
if(d < 0)
return
var/root = sqrt(d)
. += (-b + root) / bottom
if(!d)
return
. += (-b - root) / bottom
// tangent
/proc/Tan(x)
return sin(x) / cos(x)
/proc/ToDegrees(radians)
// 180 / Pi
return radians * 57.2957795
/proc/ToRadians(degrees)
// Pi / 180
return degrees * 0.0174532925
// Will filter out extra rotations and negative rotations
// E.g: 540 becomes 180. -180 becomes 180.
/proc/SimplifyDegrees(degrees)
degrees = degrees % 360
if(degrees < 0)
degrees += 360
return degrees
// min is inclusive, max is exclusive
/proc/Wrap(val, min, max)
var/d = max - min
var/t = round((val - min) / d)
return val - (t * d)
#define NORM_ROT(rot) ((((rot % 360) + (rot - round(rot, 1))) >= 0) ? ((rot % 360) + (rot - round(rot, 1))) : (((rot % 360) + (rot - round(rot, 1))) + 360))
/proc/get_angle_of_incidence(face_angle, angle_in, auto_normalize = TRUE)
var/angle_in_s = NORM_ROT(angle_in)
var/face_angle_s = NORM_ROT(face_angle)
var/incidence = face_angle_s - angle_in_s
var/incidence_s = incidence
while(incidence_s < -90)
incidence_s += 180
while(incidence_s > 90)
incidence_s -= 180
if(auto_normalize)
return incidence_s
else
return incidence
//A logarithm that converts an integer to a number scaled between 0 and 1 (can be tweaked to be higher).
//Currently, this is used for hydroponics-produce sprite transforming, but could be useful for other transform functions.
/proc/TransformUsingVariable(input, inputmaximum, scaling_modifier = 0)
var/inputToDegrees = (input/inputmaximum)*180 //Converting from a 0 -> 100 scale to a 0 -> 180 scale. The 0 -> 180 scale corresponds to degrees
var/size_factor = ((-cos(inputToDegrees) +1) /2) //returns a value from 0 to 1
return size_factor + scaling_modifier //scale mod of 0 results in a number from 0 to 1. A scale modifier of +0.5 returns 0.5 to 1.5
//converts a uniform distributed random number into a normal distributed one
//since this method produces two random numbers, one is saved for subsequent calls
//(making the cost negligble for every second call)
//This will return +/- decimals, situated about mean with standard deviation stddev
//68% chance that the number is within 1stddev
//95% chance that the number is within 2stddev
//98% chance that the number is within 3stddev...etc
#define ACCURACY 10000
/proc/gaussian(mean, stddev)
var/static/gaussian_next
var/R1;var/R2;var/working
if(gaussian_next != null)
R1 = gaussian_next
gaussian_next = null
else
do
R1 = rand(-ACCURACY,ACCURACY)/ACCURACY
R2 = rand(-ACCURACY,ACCURACY)/ACCURACY
working = R1*R1 + R2*R2
while(working >= 1 || working==0)
working = sqrt(-2 * log(working) / working)
R1 *= working
gaussian_next = R2 * working
return (mean + stddev * R1)
#undef ACCURACY
/proc/mouse_angle_from_client(client/client)
var/list/mouse_control = params2list(client.mouseParams)
if(mouse_control["screen-loc"] && client)
var/list/screen_loc_params = splittext(mouse_control["screen-loc"], ",")
var/list/screen_loc_X = splittext(screen_loc_params[1],":")
var/list/screen_loc_Y = splittext(screen_loc_params[2],":")
var/x = (text2num(screen_loc_X[1]) * 32 + text2num(screen_loc_X[2]) - 32)
var/y = (text2num(screen_loc_Y[1]) * 32 + text2num(screen_loc_Y[2]) - 32)
var/list/screenview = getviewsize(client.view)
var/screenviewX = screenview[1] * world.icon_size
var/screenviewY = screenview[2] * world.icon_size
var/ox = round(screenviewX/2) - client.pixel_x //"origin" x
var/oy = round(screenviewY/2) - client.pixel_y //"origin" y
var/angle = NORM_ROT(Atan2(y - oy, x - ox))
return angle
/proc/get_turf_in_angle(angle, turf/starting, increments)
var/pixel_x = 0
var/pixel_y = 0
for(var/i in 1 to increments)
pixel_x += sin(angle)+16*sin(angle)*2
pixel_y += cos(angle)+16*cos(angle)*2
var/new_x = starting.x
var/new_y = starting.y
while(pixel_x > 16)
pixel_x -= 32
new_x++
while(pixel_x < -16)
pixel_x += 32
new_x--
while(pixel_y > 16)
pixel_y -= 32
new_y++
while(pixel_y < -16)
pixel_y += 32
new_y--
new_x = Clamp(new_x, 0, world.maxx)
new_y = Clamp(new_y, 0, world.maxy)
return locate(new_x, new_y, starting.z)
/proc/round_down(num)
if(round(num) != num)
return round(num--)
else return num
//proc/get_overlap()
// Returns a list where [1] is all x values and [2] is all y values that overlap between the given pair of rectangles
/proc/get_overlap(x1, y1, x2, y2, x3, y3, x4, y4)
var/list/region_x1 = list()
var/list/region_y1 = list()
var/list/region_x2 = list()
var/list/region_y2 = list()
// These loops create loops filled with x/y values that the boundaries inhabit
// ex: list(5, 6, 7, 8, 9)
for(var/i in min(x1, x2) to max(x1, x2))
region_x1["[i]"] = TRUE
for(var/i in min(y1, y2) to max(y1, y2))
region_y1["[i]"] = TRUE
for(var/i in min(x3, x4) to max(x3, x4))
region_x2["[i]"] = TRUE
for(var/i in min(y3, y4) to max(y3, y4))
region_y2["[i]"] = TRUE
return list(region_x1 & region_x2, region_y1 & region_y2)
+1 -5
View File
@@ -121,9 +121,6 @@ GLOBAL_VAR(command_name)
return new_station_name
/proc/syndicate_name()
var/static/syndicate_name
if (syndicate_name)
return syndicate_name
var/name = ""
@@ -146,8 +143,7 @@ GLOBAL_VAR(command_name)
else
name += pick("-", "*", "")
name += pick("Tech", "Sun", "Co", "Tek", "X", "Inc", "Gen", "Star", "Dyne", "Code", "Hive")
syndicate_name = name
return name
+14 -14
View File
@@ -1,14 +1,14 @@
// Ensure the frequency is within bounds of what it should be sending/recieving at
/proc/sanitize_frequency(frequency, free = FALSE)
. = round(frequency)
if(free)
. = Clamp(frequency, MIN_FREE_FREQ, MAX_FREE_FREQ)
else
. = Clamp(frequency, MIN_FREQ, MAX_FREQ)
if(!(. % 2)) // Ensure the last digit is an odd number
. += 1
// Format frequency by moving the decimal.
/proc/format_frequency(frequency)
frequency = text2num(frequency)
return "[round(frequency / 10)].[frequency % 10]"
// Ensure the frequency is within bounds of what it should be sending/recieving at
/proc/sanitize_frequency(frequency, free = FALSE)
. = round(frequency)
if(free)
. = CLAMP(frequency, MIN_FREE_FREQ, MAX_FREE_FREQ)
else
. = CLAMP(frequency, MIN_FREQ, MAX_FREQ)
if(!(. % 2)) // Ensure the last digit is an odd number
. += 1
// Format frequency by moving the decimal.
/proc/format_frequency(frequency)
frequency = text2num(frequency)
return "[round(frequency / 10)].[frequency % 10]"
+3 -3
View File
@@ -60,7 +60,7 @@ GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0)
if(!second)
return "0 seconds"
if(second >= 60)
minute = round_down(second/60)
minute = FLOOR(second/60, 1)
second = round(second - (minute*60), 0.1)
second_rounded = TRUE
if(second) //check if we still have seconds remaining to format, or if everything went into minute.
@@ -91,7 +91,7 @@ GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0)
if(!minute)
return "[second]"
if(minute >= 60)
hour = round_down(minute/60,1)
hour = FLOOR(minute/60, 1)
minute = (minute - (hour*60))
if(minute) //alot simpler from here since you don't have to worry about fractions
if(minute != 1)
@@ -114,7 +114,7 @@ GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0)
if(!hour)
return "[minute][second]"
if(hour >= 24)
day = round_down(hour/24,1)
day = FLOOR(hour/24, 1)
hour = (hour - (day*24))
if(hour)
if(hour != 1)
+1 -1
View File
@@ -117,7 +117,7 @@
//Converts an angle (degrees) into an ss13 direction
/proc/angle2dir(degree)
degree = SimplifyDegrees(degree)
degree = SIMPLIFY_DEGREES(degree)
switch(degree)
if(0 to 22.5) //north requires two angle ranges
return NORTH
+9 -9
View File
@@ -147,10 +147,10 @@ Turf and target are separate in case you want to teleport some distance from a t
var/line[] = list(locate(px,py,M.z))
var/dx=N.x-px //x distance
var/dy=N.y-py
var/dxabs=abs(dx)//Absolute value of x distance
var/dyabs=abs(dy)
var/sdx=sign(dx) //Sign of x distance (+ or -)
var/sdy=sign(dy)
var/dxabs = abs(dx)//Absolute value of x distance
var/dyabs = abs(dy)
var/sdx = SIGN(dx) //Sign of x distance (+ or -)
var/sdy = SIGN(dy)
var/x=dxabs>>1 //Counters for steps taken, setting to distance/2
var/y=dyabs>>1 //Bit-shifting makes me l33t. It also makes getline() unnessecarrily fast.
var/j //Generic integer for counting
@@ -953,8 +953,8 @@ GLOBAL_LIST_INIT(WALLITEMS_INVERSE, typecacheof(list(
tY = tY[1]
tX = splittext(tX[1], ":")
tX = tX[1]
tX = Clamp(origin.x + text2num(tX) - world.view - 1, 1, world.maxx)
tY = Clamp(origin.y + text2num(tY) - world.view - 1, 1, world.maxy)
tX = CLAMP(origin.x + text2num(tX) - world.view - 1, 1, world.maxx)
tY = CLAMP(origin.y + text2num(tY) - world.view - 1, 1, world.maxy)
return locate(tX, tY, tZ)
/proc/screen_loc2turf(text, turf/origin)
@@ -966,8 +966,8 @@ GLOBAL_LIST_INIT(WALLITEMS_INVERSE, typecacheof(list(
tX = splittext(tZ[2], "-")
tX = text2num(tX[2])
tZ = origin.z
tX = Clamp(origin.x + 7 - tX, 1, world.maxx)
tY = Clamp(origin.y + 7 - tY, 1, world.maxy)
tX = CLAMP(origin.x + 7 - tX, 1, world.maxx)
tY = CLAMP(origin.y + 7 - tY, 1, world.maxy)
return locate(tX, tY, tZ)
/proc/IsValidSrc(datum/D)
@@ -1272,7 +1272,7 @@ proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types())
. = 0
var/i = DS2TICKS(initial_delay)
do
. += Ceiling(i*DELTA_CALC)
. += CEILING(i*DELTA_CALC, 1)
sleep(i*world.tick_lag*DELTA_CALC)
i *= 2
while (TICK_USAGE > min(TICK_LIMIT_TO_RUN, Master.current_ticklimit))
+2 -2
View File
@@ -257,8 +257,8 @@
view = world.view
var/list/viewscales = getviewsize(view)
var/countx = Ceiling((viewscales[1]/2)/(480/world.icon_size))+1
var/county = Ceiling((viewscales[2]/2)/(480/world.icon_size))+1
var/countx = CEILING((viewscales[1]/2)/(480/world.icon_size), 1)+1
var/county = CEILING((viewscales[2]/2)/(480/world.icon_size), 1)+1
var/list/new_overlays = new
for(var/x in -countx to countx)
for(var/y in -county to county)
+277 -277
View File
@@ -1,277 +1,277 @@
/obj/screen/robot
icon = 'icons/mob/screen_cyborg.dmi'
/obj/screen/robot/module
name = "cyborg module"
icon_state = "nomod"
/obj/screen/robot/Click()
if(isobserver(usr))
return 1
/obj/screen/robot/module/Click()
if(..())
return
var/mob/living/silicon/robot/R = usr
if(R.module.type != /obj/item/robot_module)
R.hud_used.toggle_show_robot_modules()
return 1
R.pick_module()
/obj/screen/robot/module1
name = "module1"
icon_state = "inv1"
/obj/screen/robot/module1/Click()
if(..())
return
var/mob/living/silicon/robot/R = usr
R.toggle_module(1)
/obj/screen/robot/module2
name = "module2"
icon_state = "inv2"
/obj/screen/robot/module2/Click()
if(..())
return
var/mob/living/silicon/robot/R = usr
R.toggle_module(2)
/obj/screen/robot/module3
name = "module3"
icon_state = "inv3"
/obj/screen/robot/module3/Click()
if(..())
return
var/mob/living/silicon/robot/R = usr
R.toggle_module(3)
/obj/screen/robot/radio
name = "radio"
icon_state = "radio"
/obj/screen/robot/radio/Click()
if(..())
return
var/mob/living/silicon/robot/R = usr
R.radio.interact(R)
/obj/screen/robot/store
name = "store"
icon_state = "store"
/obj/screen/robot/store/Click()
if(..())
return
var/mob/living/silicon/robot/R = usr
R.uneq_active()
/obj/screen/robot/lamp
name = "headlamp"
icon_state = "lamp0"
/obj/screen/robot/lamp/Click()
if(..())
return
var/mob/living/silicon/robot/R = usr
R.control_headlamp()
/obj/screen/robot/thrusters
name = "ion thrusters"
icon_state = "ionpulse0"
/obj/screen/robot/thrusters/Click()
if(..())
return
var/mob/living/silicon/robot/R = usr
R.toggle_ionpulse()
/datum/hud/robot
ui_style_icon = 'icons/mob/screen_cyborg.dmi'
/datum/hud/robot/New(mob/owner, ui_style = 'icons/mob/screen_cyborg.dmi')
..()
var/mob/living/silicon/robot/mymobR = mymob
var/obj/screen/using
using = new/obj/screen/language_menu
using.screen_loc = ui_borg_language_menu
static_inventory += using
//Radio
using = new /obj/screen/robot/radio()
using.screen_loc = ui_borg_radio
static_inventory += using
//Module select
using = new /obj/screen/robot/module1()
using.screen_loc = ui_inv1
static_inventory += using
mymobR.inv1 = using
using = new /obj/screen/robot/module2()
using.screen_loc = ui_inv2
static_inventory += using
mymobR.inv2 = using
using = new /obj/screen/robot/module3()
using.screen_loc = ui_inv3
static_inventory += using
mymobR.inv3 = using
//End of module select
//Photography stuff
using = new /obj/screen/ai/image_take()
using.screen_loc = ui_borg_camera
static_inventory += using
using = new /obj/screen/ai/image_view()
using.screen_loc = ui_borg_album
static_inventory += using
//Sec/Med HUDs
using = new /obj/screen/ai/sensors()
using.screen_loc = ui_borg_sensor
static_inventory += using
//Headlamp control
using = new /obj/screen/robot/lamp()
using.screen_loc = ui_borg_lamp
static_inventory += using
mymobR.lamp_button = using
//Thrusters
using = new /obj/screen/robot/thrusters()
using.screen_loc = ui_borg_thrusters
static_inventory += using
mymobR.thruster_button = using
//Intent
action_intent = new /obj/screen/act_intent/robot()
action_intent.icon_state = mymob.a_intent
static_inventory += action_intent
//Health
healths = new /obj/screen/healths/robot()
infodisplay += healths
//Installed Module
mymobR.hands = new /obj/screen/robot/module()
mymobR.hands.screen_loc = ui_borg_module
static_inventory += mymobR.hands
//Store
module_store_icon = new /obj/screen/robot/store()
module_store_icon.screen_loc = ui_borg_store
pull_icon = new /obj/screen/pull()
pull_icon.icon = 'icons/mob/screen_cyborg.dmi'
pull_icon.update_icon(mymob)
pull_icon.screen_loc = ui_borg_pull
hotkeybuttons += pull_icon
zone_select = new /obj/screen/zone_sel/robot()
zone_select.update_icon(mymob)
static_inventory += zone_select
/datum/hud/proc/toggle_show_robot_modules()
if(!iscyborg(mymob))
return
var/mob/living/silicon/robot/R = mymob
R.shown_robot_modules = !R.shown_robot_modules
update_robot_modules_display()
/datum/hud/proc/update_robot_modules_display(mob/viewer)
if(!iscyborg(mymob))
return
var/mob/living/silicon/robot/R = mymob
var/mob/screenmob = viewer || R
if(!R.module)
return
if(!R.client)
return
if(R.shown_robot_modules && screenmob.hud_used.hud_shown)
//Modules display is shown
screenmob.client.screen += module_store_icon //"store" icon
if(!R.module.modules)
to_chat(usr, "<span class='danger'>Selected module has no modules to select</span>")
return
if(!R.robot_modules_background)
return
var/display_rows = Ceiling(length(R.module.get_inactive_modules()) / 8)
R.robot_modules_background.screen_loc = "CENTER-4:16,SOUTH+1:7 to CENTER+3:16,SOUTH+[display_rows]:7"
screenmob.client.screen += R.robot_modules_background
var/x = -4 //Start at CENTER-4,SOUTH+1
var/y = 1
for(var/atom/movable/A in R.module.get_inactive_modules())
//Module is not currently active
screenmob.client.screen += A
if(x < 0)
A.screen_loc = "CENTER[x]:16,SOUTH+[y]:7"
else
A.screen_loc = "CENTER+[x]:16,SOUTH+[y]:7"
A.layer = ABOVE_HUD_LAYER
A.plane = ABOVE_HUD_PLANE
x++
if(x == 4)
x = -4
y++
else
//Modules display is hidden
screenmob.client.screen -= module_store_icon //"store" icon
for(var/atom/A in R.module.get_inactive_modules())
//Module is not currently active
screenmob.client.screen -= A
R.shown_robot_modules = 0
screenmob.client.screen -= R.robot_modules_background
/mob/living/silicon/robot/create_mob_hud()
if(client && !hud_used)
hud_used = new /datum/hud/robot(src)
/datum/hud/robot/persistent_inventory_update(mob/viewer)
if(!mymob)
return
var/mob/living/silicon/robot/R = mymob
var/mob/screenmob = viewer || R
if(screenmob.hud_used)
if(screenmob.hud_used.hud_shown)
for(var/i in 1 to R.held_items.len)
var/obj/item/I = R.held_items[i]
if(I)
switch(i)
if(1)
I.screen_loc = ui_inv1
if(2)
I.screen_loc = ui_inv2
if(3)
I.screen_loc = ui_inv3
else
return
screenmob.client.screen += I
else
for(var/obj/item/I in R.held_items)
screenmob.client.screen -= I
/obj/screen/robot
icon = 'icons/mob/screen_cyborg.dmi'
/obj/screen/robot/module
name = "cyborg module"
icon_state = "nomod"
/obj/screen/robot/Click()
if(isobserver(usr))
return 1
/obj/screen/robot/module/Click()
if(..())
return
var/mob/living/silicon/robot/R = usr
if(R.module.type != /obj/item/robot_module)
R.hud_used.toggle_show_robot_modules()
return 1
R.pick_module()
/obj/screen/robot/module1
name = "module1"
icon_state = "inv1"
/obj/screen/robot/module1/Click()
if(..())
return
var/mob/living/silicon/robot/R = usr
R.toggle_module(1)
/obj/screen/robot/module2
name = "module2"
icon_state = "inv2"
/obj/screen/robot/module2/Click()
if(..())
return
var/mob/living/silicon/robot/R = usr
R.toggle_module(2)
/obj/screen/robot/module3
name = "module3"
icon_state = "inv3"
/obj/screen/robot/module3/Click()
if(..())
return
var/mob/living/silicon/robot/R = usr
R.toggle_module(3)
/obj/screen/robot/radio
name = "radio"
icon_state = "radio"
/obj/screen/robot/radio/Click()
if(..())
return
var/mob/living/silicon/robot/R = usr
R.radio.interact(R)
/obj/screen/robot/store
name = "store"
icon_state = "store"
/obj/screen/robot/store/Click()
if(..())
return
var/mob/living/silicon/robot/R = usr
R.uneq_active()
/obj/screen/robot/lamp
name = "headlamp"
icon_state = "lamp0"
/obj/screen/robot/lamp/Click()
if(..())
return
var/mob/living/silicon/robot/R = usr
R.control_headlamp()
/obj/screen/robot/thrusters
name = "ion thrusters"
icon_state = "ionpulse0"
/obj/screen/robot/thrusters/Click()
if(..())
return
var/mob/living/silicon/robot/R = usr
R.toggle_ionpulse()
/datum/hud/robot
ui_style_icon = 'icons/mob/screen_cyborg.dmi'
/datum/hud/robot/New(mob/owner, ui_style = 'icons/mob/screen_cyborg.dmi')
..()
var/mob/living/silicon/robot/mymobR = mymob
var/obj/screen/using
using = new/obj/screen/language_menu
using.screen_loc = ui_borg_language_menu
static_inventory += using
//Radio
using = new /obj/screen/robot/radio()
using.screen_loc = ui_borg_radio
static_inventory += using
//Module select
using = new /obj/screen/robot/module1()
using.screen_loc = ui_inv1
static_inventory += using
mymobR.inv1 = using
using = new /obj/screen/robot/module2()
using.screen_loc = ui_inv2
static_inventory += using
mymobR.inv2 = using
using = new /obj/screen/robot/module3()
using.screen_loc = ui_inv3
static_inventory += using
mymobR.inv3 = using
//End of module select
//Photography stuff
using = new /obj/screen/ai/image_take()
using.screen_loc = ui_borg_camera
static_inventory += using
using = new /obj/screen/ai/image_view()
using.screen_loc = ui_borg_album
static_inventory += using
//Sec/Med HUDs
using = new /obj/screen/ai/sensors()
using.screen_loc = ui_borg_sensor
static_inventory += using
//Headlamp control
using = new /obj/screen/robot/lamp()
using.screen_loc = ui_borg_lamp
static_inventory += using
mymobR.lamp_button = using
//Thrusters
using = new /obj/screen/robot/thrusters()
using.screen_loc = ui_borg_thrusters
static_inventory += using
mymobR.thruster_button = using
//Intent
action_intent = new /obj/screen/act_intent/robot()
action_intent.icon_state = mymob.a_intent
static_inventory += action_intent
//Health
healths = new /obj/screen/healths/robot()
infodisplay += healths
//Installed Module
mymobR.hands = new /obj/screen/robot/module()
mymobR.hands.screen_loc = ui_borg_module
static_inventory += mymobR.hands
//Store
module_store_icon = new /obj/screen/robot/store()
module_store_icon.screen_loc = ui_borg_store
pull_icon = new /obj/screen/pull()
pull_icon.icon = 'icons/mob/screen_cyborg.dmi'
pull_icon.update_icon(mymob)
pull_icon.screen_loc = ui_borg_pull
hotkeybuttons += pull_icon
zone_select = new /obj/screen/zone_sel/robot()
zone_select.update_icon(mymob)
static_inventory += zone_select
/datum/hud/proc/toggle_show_robot_modules()
if(!iscyborg(mymob))
return
var/mob/living/silicon/robot/R = mymob
R.shown_robot_modules = !R.shown_robot_modules
update_robot_modules_display()
/datum/hud/proc/update_robot_modules_display(mob/viewer)
if(!iscyborg(mymob))
return
var/mob/living/silicon/robot/R = mymob
var/mob/screenmob = viewer || R
if(!R.module)
return
if(!R.client)
return
if(R.shown_robot_modules && screenmob.hud_used.hud_shown)
//Modules display is shown
screenmob.client.screen += module_store_icon //"store" icon
if(!R.module.modules)
to_chat(usr, "<span class='danger'>Selected module has no modules to select</span>")
return
if(!R.robot_modules_background)
return
var/display_rows = CEILING(length(R.module.get_inactive_modules()) / 8, 1)
R.robot_modules_background.screen_loc = "CENTER-4:16,SOUTH+1:7 to CENTER+3:16,SOUTH+[display_rows]:7"
screenmob.client.screen += R.robot_modules_background
var/x = -4 //Start at CENTER-4,SOUTH+1
var/y = 1
for(var/atom/movable/A in R.module.get_inactive_modules())
//Module is not currently active
screenmob.client.screen += A
if(x < 0)
A.screen_loc = "CENTER[x]:16,SOUTH+[y]:7"
else
A.screen_loc = "CENTER+[x]:16,SOUTH+[y]:7"
A.layer = ABOVE_HUD_LAYER
A.plane = ABOVE_HUD_PLANE
x++
if(x == 4)
x = -4
y++
else
//Modules display is hidden
screenmob.client.screen -= module_store_icon //"store" icon
for(var/atom/A in R.module.get_inactive_modules())
//Module is not currently active
screenmob.client.screen -= A
R.shown_robot_modules = 0
screenmob.client.screen -= R.robot_modules_background
/mob/living/silicon/robot/create_mob_hud()
if(client && !hud_used)
hud_used = new /datum/hud/robot(src)
/datum/hud/robot/persistent_inventory_update(mob/viewer)
if(!mymob)
return
var/mob/living/silicon/robot/R = mymob
var/mob/screenmob = viewer || R
if(screenmob.hud_used)
if(screenmob.hud_used.hud_shown)
for(var/i in 1 to R.held_items.len)
var/obj/item/I = R.held_items[i]
if(I)
switch(i)
if(1)
I.screen_loc = ui_inv1
if(2)
I.screen_loc = ui_inv2
if(3)
I.screen_loc = ui_inv3
else
return
screenmob.client.screen += I
else
for(var/obj/item/I in R.held_items)
screenmob.client.screen -= I
+2 -2
View File
@@ -119,9 +119,9 @@
/obj/item/proc/get_clamped_volume()
if(w_class)
if(force)
return Clamp((force + w_class) * 4, 30, 100)// Add the item's force to its weight class and multiply by 4, then clamp the value between 30 and 100
return CLAMP((force + w_class) * 4, 30, 100)// Add the item's force to its weight class and multiply by 4, then clamp the value between 30 and 100
else
return Clamp(w_class * 6, 10, 100) // Multiply the item's weight class by 6, then clamp the value between 10 and 100
return CLAMP(w_class * 6, 10, 100) // Multiply the item's weight class by 6, then clamp the value between 10 and 100
/mob/living/proc/send_item_attack_message(obj/item/I, mob/living/user, hit_area)
var/message_verb = "attacked"
+1 -1
View File
@@ -14,7 +14,7 @@
// Otherwise jump
else if(A.loc)
loc = get_turf(A)
forceMove(get_turf(A))
update_parallax_contents()
/mob/dead/observer/ClickOn(var/atom/A, var/params)
+2 -2
View File
@@ -62,14 +62,14 @@
/mob/living/proc/adjustArousalLoss(amount, updating_arousal=1)
if(status_flags & GODMODE || !canbearoused)
return 0
arousalloss = Clamp(arousalloss + amount, min_arousal, max_arousal)
arousalloss = CLAMP(arousalloss + amount, min_arousal, max_arousal)
if(updating_arousal)
updatearousal()
/mob/living/proc/setArousalLoss(amount, updating_arousal=1)
if(status_flags & GODMODE || !canbearoused)
return 0
arousalloss = Clamp(amount, min_arousal, max_arousal)
arousalloss = CLAMP(amount, min_arousal, max_arousal)
if(updating_arousal)
updatearousal()
-1
View File
@@ -8,7 +8,6 @@
throw_speed = 3
throw_range = 5
w_class = WEIGHT_CLASS_TINY
origin_tech = "biotech=3"
var/applied_region = "chest"
var/list/add_mutations = list()
var/list/remove_mutations = list()
-30
View File
@@ -4,7 +4,6 @@
icon = 'icons/obj/guns/cit_guns.dmi'
icon_state = "lasernew"
item_state = "laser"
origin_tech = "combat=4;magnets=4"
force = 10
throwforce = 10
ammo_type = list(/obj/item/ammo_casing/energy/lasergun)
@@ -22,7 +21,6 @@
name = "Laser Carbine"
desc = "Beefed up version of a standard laser gun."
id = "lasercarbine"
req_tech = list("combat" = 5, "magnets" = 5, "powerstorage" = 4)
build_type = PROTOLATHE
materials = list(MAT_GOLD = 2500, MAT_METAL = 5000, MAT_GLASS = 5000)
build_path = /obj/item/gun/energy/laser/carbine/nopin
@@ -40,7 +38,6 @@
mag_type = /obj/item/ammo_box/magazine/sniper_rounds
fire_delay = 50
burst_size = 1
origin_tech = "combat=7"
can_suppress = 0
w_class = WEIGHT_CLASS_NORMAL
actions_types = list()
@@ -60,7 +57,6 @@
name = "Syndicate Anti Tank Pistol"
desc = "A massively impractical and silly monstrosity of a pistol that fires .50 calliber rounds. The recoil is likely to dislocate a variety of joints without proper bracing."
pin = /obj/item/device/firing_pin/implant/pindicate
origin_tech = "combat=7;syndicate=6"
/////////////spinfusor stuff////////////////
@@ -115,7 +111,6 @@
select = 0
actions_types = list()
casing_ejector = 0
origin_tech = "combat=6;magnets=6"
/obj/item/gun/ballistic/automatic/spinfusor/attackby(obj/item/A, mob/user, params)
var/num_loaded = magazine.attackby(A, user, params, 1)
@@ -163,7 +158,6 @@
icon_state = "x9"
item_state = "arg"
slot_flags = 0
origin_tech = "combat=7;engineering=7"
mag_type = /obj/item/ammo_box/magazine/m556 //Uses the m90gl's magazine, just like the NT-ARG
fire_sound = 'sound/weapons/gunshot_smg.ogg'
can_suppress = 0
@@ -194,7 +188,6 @@
spread = 90 //MAXIMUM XCOM MEMES (actually that'd be 180 spread)
w_class = WEIGHT_CLASS_BULKY
weapon_weight = WEAPON_HEAVY
origin_tech = "combat=1;magnets=1"
/datum/design/foam_x9
name = "Foam Force X9 Rifle"
@@ -254,7 +247,6 @@
name = "magpistol magazine (non-lethal disabler)"
icon = 'icons/obj/guns/cit_guns.dmi'
icon_state = "nlmagmag"
origin_tech = "magnets=5"
ammo_type = /obj/item/ammo_casing/caseless/anlmags
caliber = "mags"
max_ammo = 15
@@ -264,7 +256,6 @@
name = "magpistol magazine (lethal)"
icon = 'icons/obj/guns/cit_guns.dmi'
icon_state = "smallmagmag"
origin_tech = "combat=5"
ammo_type = /obj/item/ammo_casing/caseless/amags
//////the gun itself//////
@@ -280,7 +271,6 @@
can_suppress = 0
casing_ejector = 0
fire_delay = 2
origin_tech = "combat=4;magnets=4"
/obj/item/gun/ballistic/automatic/pistol/mag/update_icon()
..()
@@ -301,7 +291,6 @@
name = "Magpistol"
desc = "A weapon which fires ferromagnetic slugs."
id = "magpisol"
req_tech = list("combat" = 5, "magnets" = 6, "powerstorage" = 5)
build_type = PROTOLATHE
materials = list(MAT_METAL = 7500, MAT_GLASS = 1000, MAT_URANIUM = 1000, MAT_TITANIUM = 5000, MAT_SILVER = 2000)
build_path = /obj/item/gun/ballistic/automatic/pistol/mag/nopin
@@ -311,7 +300,6 @@
name = "Magpistol Magazine"
desc = "A 7 round magazine for the Magpistol."
id = "mag_magpistol"
req_tech = list("combat" = 5, "magnets" = 6, "materials" = 5, "syndicate" = 3)
build_type = PROTOLATHE
materials = list(MAT_METAL = 4000, MAT_SILVER = 500)
build_path = /obj/item/ammo_box/magazine/mmag/small/lethal
@@ -321,7 +309,6 @@
name = "Magpistol Magazine (Non-Lethal)"
desc = "A 7 round non-lethal magazine for the Magpistol."
id = "mag_magpistol_nl"
req_tech = list("combat" = 5, "magnets" = 6, "materials" = 5)
materials = list(MAT_METAL = 3000, MAT_SILVER = 250, MAT_TITANIUM = 250)
build_path = /obj/item/ammo_box/magazine/mmag/small
@@ -354,7 +341,6 @@
fire_sound = 'sound/weapons/magpistol.ogg'
slot_flags = SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
origin_tech = "combat=1;magnets=1"
/obj/item/ammo_box/foambox/mag
name = "ammo box (Magnetic Foam Darts)"
@@ -427,7 +413,6 @@
name = "magrifle magazine (non-lethal disabler)"
icon = 'icons/obj/guns/cit_guns.dmi'
icon_state = "mediummagmag"
origin_tech = "magnets=6"
ammo_type = /obj/item/ammo_casing/caseless/anlmagm
caliber = "magm"
max_ammo = 27
@@ -437,7 +422,6 @@
name = "magrifle magazine (lethal)"
icon = 'icons/obj/guns/cit_guns.dmi'
icon_state = "mediummagmag"
origin_tech = "combat=6"
ammo_type = /obj/item/ammo_casing/caseless/amagm
max_ammo = 21
@@ -450,7 +434,6 @@
icon_state = "magrifle"
item_state = "arg"
slot_flags = 0
origin_tech = "combat=6;engineering=6;magnets=6"
mag_type = /obj/item/ammo_box/magazine/mmag
fire_sound = 'sound/weapons/magrifle.ogg'
can_suppress = 0
@@ -470,7 +453,6 @@
name = "Magrifle"
desc = "An upscaled Magpistol in rifle form."
id = "magrifle"
req_tech = list("combat" = 7, "magnets" = 7, "powerstorage" = 7)
build_type = PROTOLATHE
materials = list(MAT_METAL = 10000, MAT_GLASS = 2000, MAT_URANIUM = 2000, MAT_TITANIUM = 10000, MAT_SILVER = 4000, MAT_GOLD = 2000)
build_path = /obj/item/gun/ballistic/automatic/magrifle/nopin
@@ -480,7 +462,6 @@
name = "Magrifle Magazine (Lethal)"
desc = "A 15 round magazine for the Magrifle."
id = "mag_magrifle"
req_tech = list("combat" = 7, "magnets" = 7, "materials" = 5, "syndicate" = 4)
build_type = PROTOLATHE
materials = list(MAT_METAL = 8000, MAT_SILVER = 1000)
build_path = /obj/item/ammo_box/magazine/mmag/lethal
@@ -490,7 +471,6 @@
name = "Magrifle Magazine (Non-Lethal)"
desc = "A 15 round non-lethal magazine for the Magrifle."
id = "mag_magrifle_nl"
req_tech = list("combat" = 7, "magnets" = 7, "materials" = 5)
materials = list(MAT_METAL = 6000, MAT_SILVER = 500, MAT_TITANIUM = 500)
build_path = /obj/item/ammo_box/magazine/mmag
@@ -512,7 +492,6 @@
needs_permit = FALSE
mag_type = /obj/item/ammo_box/magazine/toy/foamag
casing_ejector = FALSE
origin_tech = "combat=1;engineering=1;magnets=1"
spread = 60
w_class = WEIGHT_CLASS_BULKY
weapon_weight = WEAPON_HEAVY
@@ -598,7 +577,6 @@
icon_state = "hyperburst"
item_state = "arg"
slot_flags = 0
origin_tech = "combat=6;engineering=6;magnets=6;syndicate=6"
mag_type = /obj/item/ammo_box/magazine/mhyper
fire_sound = 'sound/weapons/magburst.ogg'
can_suppress = 0
@@ -646,7 +624,6 @@
charge_delay = 2
recoil = 2
cell_type = /obj/item/stock_parts/cell/toymagburst
origin_tech = "combat=1;magnets=1"
/obj/item/stock_parts/cell/toymagburst
name = "toy mag burst rifle power supply"
@@ -669,7 +646,6 @@
icon = 'icons/obj/guns/cit_guns.dmi'
icon_state = "stealthpistol"
w_class = WEIGHT_CLASS_SMALL
origin_tech = "combat=3;materials=3;syndicate=4"
mag_type = /obj/item/ammo_box/magazine/m10mm
can_suppress = 0
fire_sound = 'sound/weapons/gunshot_silenced.ogg'
@@ -703,7 +679,6 @@
fire_delay = 0
spread = 60
actions_types = list()
origin_tech = "combat=1;magnets=1"
/obj/item/gun/ballistic/automatic/toy/pistol/stealth/update_icon()
..()
@@ -805,7 +780,6 @@ obj/item/projectile/bullet/c10mm/soporific
name = "flechette magazine (armor piercing)"
icon = 'icons/obj/guns/cit_guns.dmi'
icon_state = "flechettemag"
origin_tech = "combat=5;syndicate=1"
ammo_type = /obj/item/ammo_casing/caseless/flechetteap
caliber = "flechette"
max_ammo = 40
@@ -826,7 +800,6 @@ obj/item/projectile/bullet/c10mm/soporific
w_class = WEIGHT_CLASS_NORMAL
slot_flags = 0
/obj/item/device/firing_pin/implant/pindicate
origin_tech = "combat=6;materials=2;syndicate=5"
mag_type = /obj/item/ammo_box/magazine/flechette/
fire_sound = 'sound/weapons/gunshot_smg.ogg'
can_suppress = 0
@@ -930,7 +903,6 @@ obj/item/projectile/bullet/c10mm/soporific
desc = "A toy laser with a classic, retro feel and look. Compatible with existing laser tag systems."
ammo_type = list(/obj/item/ammo_casing/energy/laser/raytag)
selfcharge = TRUE
origin_tech = "combat=1;magnets=1"
/datum/design/toyray
name = "RayTag Gun"
@@ -1186,7 +1158,6 @@ obj/item/projectile/bullet/c10mm/soporific
mag_type = /obj/item/ammo_box/magazine/toy/pistol
can_suppress = FALSE
actions_types = list(/datum/action/item_action/pick_color)
origin_tech = "combat=1;magnets=1"
/datum/design/foam_p37
name = "Foam Force Mk.37F"
@@ -1209,7 +1180,6 @@ obj/item/gun/energy/e_gun/cx
lefthand_file = 'icons/mob/citadel/guns_lefthand.dmi'
righthand_file = 'icons/mob/citadel/guns_righthand.dmi'
ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser)
origin_tech = "combat=4;magnets=3"
flight_x_offset = 15
flight_y_offset = 10
actions_types = list(/datum/action/item_action/pick_color)
-242
View File
@@ -1,242 +0,0 @@
/obj/item/toy/sword/cx
name = "\improper DX Non-Euplastic LightSword"
desc = "A deluxe toy replica of an energy sword. Realistic visuals and sounds! Ages 8 and up."
icon = 'icons/obj/cit_weapons.dmi'
icon_state = "cxsword_hilt"
item_state = "cxsword"
lefthand_file = 'icons/mob/citadel/melee_lefthand.dmi'
righthand_file = 'icons/mob/citadel/melee_righthand.dmi'
active = FALSE
w_class = WEIGHT_CLASS_SMALL
attack_verb = list("poked", "jabbed", "hit")
light_color = "#37FFF7"
var/light_brightness = 3
actions_types = list()
/obj/item/toy/sword/cx/attack_self(mob/user)
active = !( active )
if (active)
to_chat(user, "<span class='notice'>You activate the holographic blade with a press of a button.</span>")
playsound(user, 'sound/weapons/nebon.ogg', 50, 1)
w_class = WEIGHT_CLASS_BULKY
attack_verb = list("slashed", "stabbed", "ravaged")
set_light(light_brightness)
update_icon()
else
to_chat(user, "<span class='notice'>You deactivate the holographic blade with a press of a button.</span>")
playsound(user, 'sound/weapons/neboff.ogg', 50, 1)
w_class = WEIGHT_CLASS_SMALL
attack_verb = list("poked", "jabbed", "hit")
set_light(0)
update_icon()
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
add_fingerprint(user)
/obj/item/toy/sword/cx/update_icon()
var/mutable_appearance/blade_overlay = mutable_appearance('icons/obj/cit_weapons.dmi', "cxsword_blade")
var/mutable_appearance/gem_overlay = mutable_appearance('icons/obj/cit_weapons.dmi', "cxsword_gem")
if(light_color)
blade_overlay.color = light_color
gem_overlay.color = light_color
cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
add_overlay(gem_overlay)
if(active)
add_overlay(blade_overlay)
if(ismob(loc))
var/mob/M = loc
M.update_inv_hands()
/obj/item/toy/sword/cx/AltClick(mob/living/user)
if(user.incapacitated() || !istype(user))
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
return
if(!in_range(src, user))
return
if(user.incapacitated() || !istype(user) || !in_range(src, user))
return
if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
var/energy_color_input = input(usr,"Choose Energy Color") as color|null
if(energy_color_input)
light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
update_icon()
update_light()
/obj/item/toy/sword/cx/worn_overlays(isinhands, icon_file)
. = ..()
if(active)
if(isinhands)
var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade")
blade_inhand.color = light_color
. += blade_inhand
/obj/item/toy/sword/cx/attackby(obj/item/W, mob/living/user, params)
if(istype(W, /obj/item/toy/sword/cx))
if((W.flags_1 & NODROP_1) || (flags_1 & NODROP_1))
to_chat(user, "<span class='warning'>\the [flags_1 & NODROP_1 ? src : W] is stuck to your hand, you can't attach it to \the [flags_1 & NODROP_1 ? W : src]!</span>")
return
else
to_chat(user, "<span class='notice'>You combine the two plastic swords, making a single supermassive toy! You're fake-cool.</span>")
new /obj/item/twohanded/hypereutactic/toy(user.loc)
qdel(W)
qdel(src)
else
return ..()
/obj/item/toy/sword/cx/examine(mob/user)
..()
to_chat(user, "<span class='notice'>Alt-click to recolor it.</span>")
/*///autolathe memes/// I really need to stop doing this and find a proper way of adding in my toys
/datum/design/toyneb
name = "Non-Euplastic Blade"
id = "toyneb"
build_type = AUTOLATHE
materials = list(MAT_METAL = 10000, MAT_GLASS = 1000)
build_path = /obj/item/toy/sword/cx
category = list("hacked", "Misc")
*/ // There, I stopped doing it
/datum/crafting_recipe/toyneb
name = "Non-Euplastic Blade"
reqs = list(/obj/item/light/bulb = 1, /obj/item/stack/cable_coil = 1, /obj/item/toy/sword = 1)
result = /obj/item/toy/sword/cx
category = CAT_MISC
/*/////////////////////////////////////////////////////////////////////////
///////////// The TRUE Energy Sword ///////////////////////////
*//////////////////////////////////////////////////////////////////////////
/obj/item/melee/transforming/energy/sword/cx
name = "non-eutactic blade"
desc = "The CX Armories Type-69 Non-Eutactic Blade utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable."
icon_state = "cxsword_hilt"
icon = 'icons/obj/cit_weapons.dmi'
item_state = "cxsword"
lefthand_file = 'icons/mob/citadel/melee_lefthand.dmi'
righthand_file = 'icons/mob/citadel/melee_righthand.dmi'
force = 3
throwforce = 5
hitsound = "swing_hit" //it starts deactivated
hitsound_on = 'sound/weapons/nebhit.ogg'
attack_verb_off = list("tapped", "poked")
throw_speed = 3
throw_range = 5
sharpness = IS_SHARP
embed_chance = 40
embedded_impact_pain_multiplier = 10
armour_penetration = 0
origin_tech = "combat=3;magnets=4"
block_chance = 60
light_color = "#37FFF7"
actions_types = list()
/obj/item/melee/transforming/energy/sword/cx/transform_weapon(mob/living/user, supress_message_text)
active = !active //I'd use a ..() here but it'd inherit from the regular esword's proc instead, so SPAGHETTI CODE
if(active) //also I need to rip out the iconstate changing bits
force = force_on
throwforce = throwforce_on
hitsound = hitsound_on
throw_speed = 4
if(attack_verb_on.len)
attack_verb = attack_verb_on
w_class = w_class_on
START_PROCESSING(SSobj, src)
set_light(brightness_on)
update_icon()
else
force = initial(force)
throwforce = initial(throwforce)
hitsound = initial(hitsound)
throw_speed = initial(throw_speed)
if(attack_verb_off.len)
attack_verb = attack_verb_off
w_class = initial(w_class)
STOP_PROCESSING(SSobj, src)
set_light(0)
update_icon()
transform_messages(user, supress_message_text)
add_fingerprint(user)
return TRUE
/obj/item/melee/transforming/energy/sword/cx/transform_messages(mob/living/user, supress_message_text)
playsound(user, active ? 'sound/weapons/nebon.ogg' : 'sound/weapons/neboff.ogg', 65, 1)
if(!supress_message_text)
to_chat(user, "<span class='notice'>[src] [active ? "is now active":"can now be concealed"].</span>")
/obj/item/melee/transforming/energy/sword/cx/update_icon()
var/mutable_appearance/blade_overlay = mutable_appearance('icons/obj/cit_weapons.dmi', "cxsword_blade")
var/mutable_appearance/gem_overlay = mutable_appearance('icons/obj/cit_weapons.dmi', "cxsword_gem")
if(light_color)
blade_overlay.color = light_color
gem_overlay.color = light_color
cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
add_overlay(gem_overlay)
if(active)
add_overlay(blade_overlay)
if(ismob(loc))
var/mob/M = loc
M.update_inv_hands()
/obj/item/melee/transforming/energy/sword/cx/AltClick(mob/living/user)
if(user.incapacitated() || !istype(user))
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
return
if(!in_range(src, user))
return
if(user.incapacitated() || !istype(user) || !in_range(src, user))
return
if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
var/energy_color_input = input(usr,"Choose Energy Color") as color|null
if(energy_color_input)
light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
update_icon()
update_light()
/obj/item/melee/transforming/energy/sword/cx/examine(mob/user)
..()
to_chat(user, "<span class='notice'>Alt-click to recolor it.</span>")
/obj/item/melee/transforming/energy/sword/cx/worn_overlays(isinhands, icon_file)
. = ..()
if(active)
if(isinhands)
var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade")
blade_inhand.color = light_color
. += blade_inhand
/obj/item/melee/transforming/energy/sword/cx/traitor
name = "\improper Dragon's Tooth Sword"
desc = "The Dragon's Tooth sword is a blackmarket modification of the CX Armouries Type-69 NEB, \
which utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable. \
It appears to have a wooden grip and a shaved down guard."
icon_state = "cxsword_hilt_traitor"
armour_penetration = 35
embed_chance = 75
block_chance = 50
origin_tech = "combat=3;magnets=4;syndicate=4"
hitsound_on = 'sound/weapons/blade1.ogg'
light_color = "#37F0FF"
/obj/item/melee/transforming/energy/sword/cx/traitor/transform_messages(mob/living/user, supress_message_text)
playsound(user, active ? 'sound/weapons/saberon.ogg' : 'sound/weapons/saberoff.ogg', 35, 1)
if(!supress_message_text)
to_chat(user, "<span class='notice'>[src] [active ? "is now active":"can now be concealed"].</span>")
@@ -38,8 +38,8 @@
explanation_text = "Make sure the research required to produce a [initial(targetdesign.name)] is available on the R&D server by the end of the shift."
/datum/objective/crew/research/check_completion()
for(var/obj/machinery/r_n_d/server/S in GLOB.machines)
if(S && S.files && S.files.known_designs)
if(targetdesign in S.files.known_designs)
for(var/obj/machinery/rnd/server/S in GLOB.machines)
if(S && S.stored_research)
if(S.stored_research.researched_designs[initial(targetdesign.id)])
return TRUE
return FALSE
+40 -40
View File
@@ -17,9 +17,9 @@
name = "Kiara's Cloak"
desc = "The design on this seems a little too familiar."
icon = 'icons/obj/custom.dmi'
icon_state = "infcloak-i"
icon_override = 'icons/obj/custom.dmi'
item_state = "infcloak-w"
icon_state = "infcloak"
icon_override = 'icons/mob/custom_w.dmi'
item_state = "infcloak"
w_class = WEIGHT_CLASS_SMALL
body_parts_covered = CHEST|GROIN|LEGS|ARMS
@@ -27,9 +27,9 @@
name = "Kiara's Collar"
desc = "A soft black collar that seems to stretch to fit whoever wears it."
icon = 'icons/obj/custom.dmi'
icon_state = "infcollar-i"
icon_override = 'icons/obj/custom.dmi'
item_state = "infcollar-w"
icon_state = "infcollar"
icon_override = 'icons/mob/custom_w.dmi'
item_state = "infcollar"
item_color = null
tagname = null
@@ -62,19 +62,19 @@
/obj/item/clothing/neck/scarf/zomb //Default white color, same functionality as beanies.
name = "A special scarf"
icon = 'icons/obj/custom.dmi'
icon_state = "zombscarf-i"
icon_state = "zombscarf"
desc = "A fashionable collar"
icon_override = 'icons/obj/custom.dmi'
item_color = "zombscarf-w"
icon_override = 'icons/mob/custom_w.dmi'
item_color = "zombscarf"
dog_fashion = /datum/dog_fashion/head
/obj/item/clothing/suit/toggle/labcoat/mad/red
name = "\improper The Mad's labcoat"
desc = "An oddly special looking coat."
icon = 'icons/obj/custom.dmi'
icon_state = "labred-i"
icon_override = 'icons/obj/custom.dmi'
item_state = "labred-w"
icon_state = "labred"
icon_override = 'icons/mob/custom_w.dmi'
item_state = "labred"
/*PLACEHOLDER*/
@@ -94,9 +94,9 @@
name = "carrot cloak"
desc = "A cloak in the shape and color of a carrot!"
icon = 'icons/obj/custom.dmi'
icon_override = 'icons/obj/custom.dmi'
icon_state = "carrotcloak-i"
item_state = "carrotcloak-w"
icon_override = 'icons/mob/custom_w.dmi'
icon_state = "carrotcloak"
item_state = "carrotcloak"
w_class = WEIGHT_CLASS_SMALL
body_parts_covered = CHEST|GROIN|LEGS|ARMS
@@ -115,9 +115,9 @@
name = "Celebratory Cloak of Morozko"
desc = " It probably will protect from snow, charcoal or elves."
icon = 'icons/obj/custom.dmi'
icon_state = "festive-i"
item_state = "festive-w"
icon_override = 'icons/obj/custom.dmi'
icon_state = "festive"
item_state = "festive"
icon_override = 'icons/mob/custom_w.dmi'
w_class = WEIGHT_CLASS_SMALL
body_parts_covered = CHEST|GROIN|LEGS|ARMS
@@ -127,9 +127,9 @@
/obj/item/clothing/mask/luchador/zigfie
name = "Alboroto Rosa mask"
icon = 'icons/obj/custom.dmi'
icon_state = "lucharzigfie-i"
icon_override = 'icons/obj/custom.dmi'
item_state = "lucharzigfie-w"
icon_state = "lucharzigfie"
icon_override = 'icons/mob/custom_w.dmi'
item_state = "lucharzigfie"
/*PLACEHOLDER*/
@@ -168,9 +168,9 @@
name = "Reece's Great Coat"
desc = "You would swear this was in your nightmares after eating too many veggies."
icon = 'icons/obj/custom.dmi'
icon_state = "hos-g-i"
icon_override = 'icons/obj/custom.dmi'
item_state = "hos-g-w"
icon_state = "hos-g"
icon_override = 'icons/mob/custom_w.dmi'
item_state = "hos-g"
body_parts_covered = CHEST|GROIN|ARMS|LEGS
@@ -186,9 +186,9 @@
name = "S.T.A.L.K.E.R. mask"
desc = "Smells like reactor four."
icon = 'icons/obj/custom.dmi'
item_state = "stalker-w"
icon_override = 'icons/obj/custom.dmi'
icon_state = "stalker-i"
item_state = "stalker"
icon_override = 'icons/mob/custom_w.dmi'
icon_state = "stalker"
/*Sylas*/
@@ -196,9 +196,9 @@
name = "collar"
desc = "It's a collar..."
icon = 'icons/obj/custom.dmi'
icon_state = "petcollar-stripe-i"
icon_override = 'icons/obj/custom.dmi'
item_state = "petcollar-stripe-w"
icon_state = "petcollar-stripe"
icon_override = 'icons/mob/custom_w.dmi'
item_state = "petcollar-stripe"
tagname = null
@@ -207,10 +207,10 @@
name = "bluish performer's outfit"
desc = "Just looking at this makes you want to sing."
icon = 'icons/obj/custom.dmi'
icon_state = "singer-i"
icon_override = 'icons/obj/custom.dmi'
item_state = "singer-w"
item_color = "singer-i"
icon_state = "singer"
icon_override = 'icons/mob/custom_w.dmi'
item_state = "singer"
item_color = "singer"
fitted = NO_FEMALE_UNIFORM
alternate_worn_layer = ABOVE_SHOES_LAYER
can_adjust = 0
@@ -218,9 +218,9 @@
/obj/item/clothing/shoes/sneakers/pink
icon = 'icons/obj/custom.dmi'
icon_state = "pink-i"
icon_override = 'icons/obj/custom.dmi'
item_state = "pink-w"
icon_state = "pink"
icon_override = 'icons/mob/custom_w.dmi'
item_state = "pink"
/*Fractious*/
@@ -228,8 +228,8 @@
/obj/item/clothing/suit/vermillion
name = "vermillion clothing"
desc = "Some clothing."
icon_state = "vermillion-i"
item_state = "vermillion-w"
icon_state = "vermillion"
item_state = "vermillion"
body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS
icon = 'icons/obj/custom.dmi'
icon_override = 'icons/obj/custom.dmi'
icon_override = 'icons/mob/custom_w.dmi'
@@ -9,7 +9,7 @@
var/value
var/default //read-only, just set value directly
var/resident_file //the file which this belongs to, must be set
var/resident_file //the file which this was loaded from, if any
var/modified = FALSE //set to TRUE if the default has been overridden by a config entry
var/protection = NONE
@@ -18,8 +18,6 @@
var/dupes_allowed = FALSE
/datum/config_entry/New()
if(!resident_file)
CRASH("Config entry [type] has no resident_file set")
if(type == abstract_type)
CRASH("Abstract config entry [type] instatiated!")
name = lowertext(type2top(type))
@@ -110,7 +108,7 @@
/datum/config_entry/number/ValidateAndSet(str_val)
var/temp = text2num(trim(str_val))
if(!isnull(temp))
value = Clamp(integer ? round(temp) : temp, min_val, max_val)
value = CLAMP(integer ? round(temp) : temp, min_val, max_val)
if(value != temp && !var_edited)
log_config("Changing [name] from [temp] to [value]!")
return TRUE
+29 -15
View File
@@ -20,10 +20,13 @@ GLOBAL_PROTECT(config_dir)
/datum/controller/configuration/New()
config = src
var/list/config_files = InitEntries()
InitEntries()
LoadModes()
for(var/I in config_files)
LoadEntries(I)
if(!LoadEntries("config.txt"))
log_config("No $include directives found in config.txt! Loading legacy game_options/dbconfig/comms files...")
LoadEntries("game_options.txt")
LoadEntries("dbconfig.txt")
LoadEntries("comms.txt")
loadmaplist(CONFIG_MAPS_FILE)
/datum/controller/configuration/Destroy()
@@ -42,8 +45,6 @@ GLOBAL_PROTECT(config_dir)
var/list/_entries_by_type = list()
entries_by_type = _entries_by_type
. = list()
for(var/I in typesof(/datum/config_entry)) //typesof is faster in this case
var/datum/config_entry/E = I
if(initial(E.abstract_type) == I)
@@ -57,24 +58,30 @@ GLOBAL_PROTECT(config_dir)
continue
_entries[esname] = E
_entries_by_type[I] = E
.[E.resident_file] = TRUE
/datum/controller/configuration/proc/RemoveEntry(datum/config_entry/CE)
entries -= CE.name
entries_by_type -= CE.type
/datum/controller/configuration/proc/LoadEntries(filename)
/datum/controller/configuration/proc/LoadEntries(filename, list/stack = list())
var/filename_to_test = world.system_type == MS_WINDOWS ? lowertext(filename) : filename
if(filename_to_test in stack)
log_config("Warning: Config recursion detected ([english_list(stack)]), breaking!")
return
stack = stack + filename_to_test
log_config("Loading config file [filename]...")
var/list/lines = world.file2list("[GLOB.config_dir][filename]")
var/list/_entries = entries
for(var/L in lines)
if(!L)
continue
if(copytext(L, 1, 2) == "#")
var/firstchar = copytext(L, 1, 2)
if(firstchar == "#")
continue
var/lockthis = copytext(L, 1, 2) == "@"
var/lockthis = firstchar == "@"
if(lockthis)
L = copytext(L, 2)
@@ -91,14 +98,17 @@ GLOBAL_PROTECT(config_dir)
if(!entry)
continue
if(entry == "$include")
if(!value)
log_config("Warning: Invalid $include directive: [value]")
else
LoadEntries(value, stack)
continue
var/datum/config_entry/E = _entries[entry]
if(!E)
log_config("Unknown setting in configuration: '[entry]'")
continue
if(filename != E.resident_file)
log_config("Found [entry] in [filename] when it should have been in [E.resident_file]! Ignoring.")
continue
if(lockthis)
E.protection |= CONFIG_ENTRY_LOCKED
@@ -107,10 +117,14 @@ GLOBAL_PROTECT(config_dir)
if(!validated)
log_config("Failed to validate setting \"[value]\" for [entry]")
else if(E.modified && !E.dupes_allowed)
log_config("Duplicate setting for [entry] ([value]) detected! Using latest.")
log_config("Duplicate setting for [entry] ([value], [E.resident_file]) detected! Using latest.")
E.resident_file = filename
if(validated)
E.modified = TRUE
. = TRUE
/datum/controller/configuration/can_vv_get(var_name)
return (var_name != "entries_by_type" || !hiding_entries_by_type) && ..()
@@ -1,22 +1,20 @@
#define CURRENT_RESIDENT_FILE "comms.txt"
CONFIG_DEF(string/comms_key)
/datum/config_entry/string/comms_key
protection = CONFIG_ENTRY_HIDDEN
/datum/config_entry/string/comms_key/ValidateAndSet(str_val)
return str_val != "default_pwd" && length(str_val) > 6 && ..()
CONFIG_DEF(string/cross_server_address)
/datum/config_entry/keyed_string_list/cross_server
protection = CONFIG_ENTRY_LOCKED
/datum/config_entry/string/cross_server_address/ValidateAndSet(str_val)
return str_val != "byond:\\address:port" && ..()
CONFIG_DEF(string/cross_comms_name)
/datum/config_entry/string/cross_comms_name
GLOBAL_VAR_INIT(medals_enabled, TRUE) //will be auto set to false if the game fails contacting the medal hub to prevent unneeded calls.
CONFIG_DEF(string/medal_hub_address)
/datum/config_entry/string/medal_hub_address
CONFIG_DEF(string/medal_hub_password)
protection = CONFIG_ENTRY_HIDDEN
/datum/config_entry/string/medal_hub_password
protection = CONFIG_ENTRY_HIDDEN
@@ -1,390 +0,0 @@
#define CURRENT_RESIDENT_FILE "config.txt"
CONFIG_DEF(flag/autoadmin) // if autoadmin is enabled
protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(string/autoadmin_rank) // the rank for autoadmins
value = "Game Master"
protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(string/servername) // server name (the name of the game window)
CONFIG_DEF(string/serversqlname) // short form server name used for the DB
CONFIG_DEF(string/stationname) // station name (the name of the station in-game)
CONFIG_DEF(number/lobby_countdown) // In between round countdown.
value = 120
min_val = 0
CONFIG_DEF(number/round_end_countdown) // Post round murder death kill countdown
value = 25
min_val = 0
CONFIG_DEF(flag/hub) // if the game appears on the hub or not
CONFIG_DEF(flag/log_ooc) // log OOC channel
CONFIG_DEF(flag/log_access) // log login/logout
CONFIG_DEF(flag/log_say) // log client say
CONFIG_DEF(flag/log_admin) // log admin actions
protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/log_prayer) // log prayers
CONFIG_DEF(flag/log_law) // log lawchanges
CONFIG_DEF(flag/log_game) // log game events
CONFIG_DEF(flag/log_vote) // log voting
CONFIG_DEF(flag/log_whisper) // log client whisper
CONFIG_DEF(flag/log_attack) // log attack messages
CONFIG_DEF(flag/log_emote) // log emotes
CONFIG_DEF(flag/log_adminchat) // log admin chat messages
protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/log_pda) // log pda messages
CONFIG_DEF(flag/log_twitter) // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases.
CONFIG_DEF(flag/log_world_topic) // log all world.Topic() calls
CONFIG_DEF(flag/log_manifest) // log crew manifest to seperate file
CONFIG_DEF(flag/allow_admin_ooccolor) // Allows admins with relevant permissions to have their own ooc colour
CONFIG_DEF(flag/allow_vote_restart) // allow votes to restart
CONFIG_DEF(flag/allow_vote_mode) // allow votes to change mode
CONFIG_DEF(number/vote_delay) // minimum time between voting sessions (deciseconds, 10 minute default)
value = 6000
min_val = 0
CONFIG_DEF(number/vote_period) // length of voting period (deciseconds, default 1 minute)
value = 600
min_val = 0
CONFIG_DEF(flag/default_no_vote) // vote does not default to nochange/norestart
CONFIG_DEF(flag/no_dead_vote) // dead people can't vote
CONFIG_DEF(flag/allow_metadata) // Metadata is supported.
CONFIG_DEF(flag/popup_admin_pm) // adminPMs to non-admins show in a pop-up 'reply' window when set
CONFIG_DEF(number/fps)
value = 20
min_val = 1
max_val = 100 //byond will start crapping out at 50, so this is just ridic
var/sync_validate = FALSE
/datum/config_entry/number/fps/ValidateAndSet(str_val)
. = ..()
if(.)
sync_validate = TRUE
var/datum/config_entry/number/ticklag/TL = config.entries_by_type[/datum/config_entry/number/ticklag]
if(!TL.sync_validate)
TL.ValidateAndSet(10 / value)
sync_validate = FALSE
CONFIG_DEF(number/ticklag)
integer = FALSE
var/sync_validate = FALSE
/datum/config_entry/number/ticklag/New() //ticklag weirdly just mirrors fps
var/datum/config_entry/CE = /datum/config_entry/number/fps
value = 10 / initial(CE.value)
..()
/datum/config_entry/number/ticklag/ValidateAndSet(str_val)
. = text2num(str_val) > 0 && ..()
if(.)
sync_validate = TRUE
var/datum/config_entry/number/fps/FPS = config.entries_by_type[/datum/config_entry/number/fps]
if(!FPS.sync_validate)
FPS.ValidateAndSet(10 / value)
sync_validate = FALSE
CONFIG_DEF(flag/allow_holidays)
CONFIG_DEF(number/tick_limit_mc_init) //SSinitialization throttling
value = TICK_LIMIT_MC_INIT_DEFAULT
min_val = 0 //oranges warned us
integer = FALSE
CONFIG_DEF(flag/admin_legacy_system) //Defines whether the server uses the legacy admin system with admins.txt or the SQL system
protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(string/hostedby)
CONFIG_DEF(flag/norespawn)
CONFIG_DEF(flag/guest_jobban)
CONFIG_DEF(flag/usewhitelist)
CONFIG_DEF(flag/ban_legacy_system) //Defines whether the server uses the legacy banning system with the files in /data or the SQL system.
protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/use_age_restriction_for_jobs) //Do jobs use account age restrictions? --requires database
CONFIG_DEF(flag/use_account_age_for_jobs) //Uses the time they made the account for the job restriction stuff. New player joining alerts should be unaffected.
CONFIG_DEF(flag/use_exp_tracking)
CONFIG_DEF(flag/use_exp_restrictions_heads)
CONFIG_DEF(number/use_exp_restrictions_heads_hours)
value = 0
min_val = 0
CONFIG_DEF(flag/use_exp_restrictions_heads_department)
CONFIG_DEF(flag/use_exp_restrictions_other)
CONFIG_DEF(flag/use_exp_restrictions_admin_bypass)
CONFIG_DEF(string/server)
CONFIG_DEF(string/banappeals)
CONFIG_DEF(string/wikiurl)
value = "http://www.tgstation13.org/wiki"
CONFIG_DEF(string/forumurl)
value = "http://tgstation13.org/phpBB/index.php"
CONFIG_DEF(string/rulesurl)
value = "http://www.tgstation13.org/wiki/Rules"
CONFIG_DEF(string/githuburl)
value = "https://www.github.com/tgstation/-tg-station"
CONFIG_DEF(number/githubrepoid)
value = null
min_val = 0
CONFIG_DEF(flag/guest_ban)
CONFIG_DEF(number/id_console_jobslot_delay)
value = 30
min_val = 0
CONFIG_DEF(number/inactivity_period) //time in ds until a player is considered inactive)
value = 3000
min_val = 0
/datum/config_entry/number/inactivity_period/ValidateAndSet(str_val)
. = ..()
if(.)
value *= 10 //documented as seconds in config.txt
CONFIG_DEF(number/afk_period) //time in ds until a player is considered inactive)
value = 3000
min_val = 0
/datum/config_entry/number/afk_period/ValidateAndSet(str_val)
. = ..()
if(.)
value *= 10 //documented as seconds in config.txt
CONFIG_DEF(flag/kick_inactive) //force disconnect for inactive players
CONFIG_DEF(flag/load_jobs_from_txt)
CONFIG_DEF(flag/forbid_singulo_possession)
CONFIG_DEF(flag/automute_on) //enables automuting/spam prevention
CONFIG_DEF(string/panic_server_name)
/datum/config_entry/string/panic_server_name/ValidateAndSet(str_val)
return str_val != "\[Put the name here\]" && ..()
CONFIG_DEF(string/panic_server_address) //Reconnect a player this linked server if this server isn't accepting new players
/datum/config_entry/string/panic_server_address/ValidateAndSet(str_val)
return str_val != "byond://address:port" && ..()
CONFIG_DEF(string/invoke_youtubedl)
protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN
CONFIG_DEF(flag/show_irc_name)
CONFIG_DEF(flag/see_own_notes) //Can players see their own admin notes (read-only)?
CONFIG_DEF(number/note_fresh_days)
value = null
min_val = 0
integer = FALSE
CONFIG_DEF(number/note_stale_days)
value = null
min_val = 0
integer = FALSE
CONFIG_DEF(flag/maprotation)
CONFIG_DEF(number/maprotatechancedelta)
value = 0.75
min_val = 0
max_val = 1
integer = FALSE
CONFIG_DEF(number/soft_popcap)
value = null
min_val = 0
CONFIG_DEF(number/hard_popcap)
value = null
min_val = 0
CONFIG_DEF(number/extreme_popcap)
value = null
min_val = 0
CONFIG_DEF(string/soft_popcap_message)
value = "Be warned that the server is currently serving a high number of users, consider using alternative game servers."
CONFIG_DEF(string/hard_popcap_message)
value = "The server is currently serving a high number of users, You cannot currently join. You may wait for the number of living crew to decline, observe, or find alternative servers."
CONFIG_DEF(string/extreme_popcap_message)
value = "The server is currently serving a high number of users, find alternative servers."
CONFIG_DEF(flag/panic_bunker) // prevents people the server hasn't seen before from connecting
CONFIG_DEF(number/notify_new_player_age) // how long do we notify admins of a new player
min_val = -1
CONFIG_DEF(number/notify_new_player_account_age) // how long do we notify admins of a new byond account
min_val = 0
CONFIG_DEF(flag/irc_first_connection_alert) // do we notify the irc channel when somebody is connecting for the first time?
CONFIG_DEF(flag/check_randomizer)
CONFIG_DEF(string/ipintel_email)
/datum/config_entry/string/ipintel_email/ValidateAndSet(str_val)
return str_val != "ch@nge.me" && ..()
CONFIG_DEF(number/ipintel_rating_bad)
value = 1
integer = FALSE
min_val = 0
max_val = 1
CONFIG_DEF(number/ipintel_save_good)
value = 12
min_val = 0
CONFIG_DEF(number/ipintel_save_bad)
value = 1
min_val = 0
CONFIG_DEF(string/ipintel_domain)
value = "check.getipintel.net"
CONFIG_DEF(flag/aggressive_changelog)
CONFIG_DEF(flag/autoconvert_notes) //if all connecting player's notes should attempt to be converted to the database
protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(flag/allow_webclient)
CONFIG_DEF(flag/webclient_only_byond_members)
CONFIG_DEF(flag/announce_admin_logout)
CONFIG_DEF(flag/announce_admin_login)
CONFIG_DEF(flag/allow_map_voting)
CONFIG_DEF(flag/generate_minimaps)
CONFIG_DEF(number/client_warn_version)
value = null
min_val = 500
max_val = DM_VERSION - 1
CONFIG_DEF(string/client_warn_message)
value = "Your version of byond may have issues or be blocked from accessing this server in the future."
CONFIG_DEF(flag/client_warn_popup)
CONFIG_DEF(number/client_error_version)
value = null
min_val = 500
max_val = DM_VERSION - 1
CONFIG_DEF(string/client_error_message)
value = "Your version of byond is too old, may have issues, and is blocked from accessing this server."
CONFIG_DEF(number/minute_topic_limit)
value = null
min_val = 0
CONFIG_DEF(number/second_topic_limit)
value = null
min_val = 0
CONFIG_DEF(number/error_cooldown) // The "cooldown" time for each occurrence of a unique error)
value = 600
min_val = 0
CONFIG_DEF(number/error_limit) // How many occurrences before the next will silence them
value = 50
CONFIG_DEF(number/error_silence_time) // How long a unique error will be silenced for
value = 6000
CONFIG_DEF(number/error_msg_delay) // How long to wait between messaging admins about occurrences of a unique error
value = 50
CONFIG_DEF(flag/irc_announce_new_game)
CONFIG_DEF(flag/debug_admin_hrefs)
CONFIG_DEF(number/mc_tick_rate/base_mc_tick_rate)
integer = FALSE
value = 1
CONFIG_DEF(number/mc_tick_rate/high_pop_mc_tick_rate)
integer = FALSE
value = 1.1
CONFIG_DEF(number/mc_tick_rate/high_pop_mc_mode_amount)
value = 65
CONFIG_DEF(number/mc_tick_rate/disable_high_pop_mc_mode_amount)
value = 60
CONFIG_TWEAK(number/mc_tick_rate)
abstract_type = /datum/config_entry/number/mc_tick_rate
CONFIG_TWEAK(number/mc_tick_rate/ValidateAndSet(str_val))
. = ..()
if (.)
Master.UpdateTickRate()
CONFIG_DEF(flag/resume_after_initializations)
CONFIG_TWEAK(flag/resume_after_initializations/ValidateAndSet(str_val))
. = ..()
if(. && Master.current_runlevel)
world.sleep_offline = !value
CONFIG_DEF(number/rounds_until_hard_restart)
value = -1
min_val = 0
CONFIG_DEF(string/default_view)
value = "15x15"
@@ -1,28 +1,26 @@
#define CURRENT_RESIDENT_FILE "dbconfig.txt"
CONFIG_DEF(flag/sql_enabled) // for sql switching
/datum/config_entry/flag/sql_enabled // for sql switching
protection = CONFIG_ENTRY_LOCKED
CONFIG_DEF(string/address)
/datum/config_entry/string/address
value = "localhost"
protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN
CONFIG_DEF(number/port)
/datum/config_entry/number/port
value = 3306
min_val = 0
max_val = 65535
protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN
CONFIG_DEF(string/feedback_database)
/datum/config_entry/string/feedback_database
value = "test"
protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN
CONFIG_DEF(string/feedback_login)
/datum/config_entry/string/feedback_login
value = "root"
protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN
CONFIG_DEF(string/feedback_password)
/datum/config_entry/string/feedback_password
protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN
CONFIG_DEF(string/feedback_tableprefix)
/datum/config_entry/string/feedback_tableprefix
protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN
@@ -1,253 +1,255 @@
#define CURRENT_RESIDENT_FILE "game_options.txt"
/datum/config_entry/number_list/repeated_mode_adjust
CONFIG_DEF(number_list/repeated_mode_adjust)
CONFIG_DEF(keyed_number_list/probability)
/datum/config_entry/keyed_number_list/probability
/datum/config_entry/keyed_number_list/probability/ValidateKeyName(key_name)
return key_name in config.modes
CONFIG_DEF(keyed_number_list/max_pop)
/datum/config_entry/keyed_number_list/max_pop
/datum/config_entry/keyed_number_list/max_pop/ValidateKeyName(key_name)
return key_name in config.modes
CONFIG_DEF(keyed_number_list/min_pop)
/datum/config_entry/keyed_number_list/min_pop
/datum/config_entry/keyed_number_list/min_pop/ValidateKeyName(key_name)
return key_name in config.modes
CONFIG_DEF(keyed_flag_list/continuous) // which roundtypes continue if all antagonists die
/datum/config_entry/keyed_flag_list/continuous // which roundtypes continue if all antagonists die
/datum/config_entry/keyed_flag_list/continuous/ValidateKeyName(key_name)
return key_name in config.modes
CONFIG_DEF(keyed_flag_list/midround_antag) // which roundtypes use the midround antagonist system
/datum/config_entry/keyed_flag_list/midround_antag // which roundtypes use the midround antagonist system
/datum/config_entry/keyed_flag_list/midround_antag/ValidateKeyName(key_name)
return key_name in config.modes
CONFIG_DEF(keyed_string_list/policy)
/datum/config_entry/keyed_string_list/policy
CONFIG_DEF(number/damage_multiplier)
/datum/config_entry/number/damage_multiplier
value = 1
integer = FALSE
CONFIG_DEF(number/minimal_access_threshold) //If the number of players is larger than this threshold, minimal access will be turned on.
/datum/config_entry/number/minimal_access_threshold //If the number of players is larger than this threshold, minimal access will be turned on.
min_val = 0
CONFIG_DEF(flag/jobs_have_minimal_access) //determines whether jobs use minimal access or expanded access.
/datum/config_entry/flag/jobs_have_minimal_access //determines whether jobs use minimal access or expanded access.
CONFIG_DEF(flag/assistants_have_maint_access)
/datum/config_entry/flag/assistants_have_maint_access
CONFIG_DEF(flag/security_has_maint_access)
/datum/config_entry/flag/security_has_maint_access
CONFIG_DEF(flag/everyone_has_maint_access)
/datum/config_entry/flag/everyone_has_maint_access
CONFIG_DEF(flag/sec_start_brig) //makes sec start in brig instead of dept sec posts
/datum/config_entry/flag/sec_start_brig //makes sec start in brig instead of dept sec posts
CONFIG_DEF(flag/force_random_names)
/datum/config_entry/flag/force_random_names
CONFIG_DEF(flag/humans_need_surnames)
/datum/config_entry/flag/humans_need_surnames
CONFIG_DEF(flag/allow_ai) // allow ai job
/datum/config_entry/flag/allow_ai // allow ai job
CONFIG_DEF(flag/disable_secborg) // disallow secborg module to be chosen.
/datum/config_entry/flag/disable_secborg // disallow secborg module to be chosen.
CONFIG_DEF(flag/disable_peaceborg)
/datum/config_entry/flag/disable_peaceborg
CONFIG_DEF(number/traitor_scaling_coeff) //how much does the amount of players get divided by to determine traitors
/datum/config_entry/number/traitor_scaling_coeff //how much does the amount of players get divided by to determine traitors
value = 6
min_val = 1
CONFIG_DEF(number/brother_scaling_coeff) //how many players per brother team
/datum/config_entry/number/brother_scaling_coeff //how many players per brother team
value = 25
min_val = 1
CONFIG_DEF(number/changeling_scaling_coeff) //how much does the amount of players get divided by to determine changelings
/datum/config_entry/number/changeling_scaling_coeff //how much does the amount of players get divided by to determine changelings
value = 6
min_val = 1
CONFIG_DEF(number/security_scaling_coeff) //how much does the amount of players get divided by to determine open security officer positions
/datum/config_entry/number/security_scaling_coeff //how much does the amount of players get divided by to determine open security officer positions
value = 8
min_val = 1
CONFIG_DEF(number/abductor_scaling_coeff) //how many players per abductor team
/datum/config_entry/number/abductor_scaling_coeff //how many players per abductor team
value = 15
min_val = 1
CONFIG_DEF(number/traitor_objectives_amount)
/datum/config_entry/number/traitor_objectives_amount
value = 2
min_val = 0
CONFIG_DEF(number/brother_objectives_amount)
/datum/config_entry/number/brother_objectives_amount
value = 2
min_val = 0
CONFIG_DEF(flag/reactionary_explosions) //If we use reactionary explosions, explosions that react to walls and doors
/datum/config_entry/flag/reactionary_explosions //If we use reactionary explosions, explosions that react to walls and doors
CONFIG_DEF(flag/protect_roles_from_antagonist) //If security and such can be traitor/cult/other
/datum/config_entry/flag/protect_roles_from_antagonist //If security and such can be traitor/cult/other
CONFIG_DEF(flag/protect_assistant_from_antagonist) //If assistants can be traitor/cult/other
/datum/config_entry/flag/protect_assistant_from_antagonist //If assistants can be traitor/cult/other
CONFIG_DEF(flag/enforce_human_authority) //If non-human species are barred from joining as a head of staff
/datum/config_entry/flag/enforce_human_authority //If non-human species are barred from joining as a head of staff
CONFIG_DEF(flag/allow_latejoin_antagonists) // If late-joining players can be traitor/changeling
/datum/config_entry/flag/allow_latejoin_antagonists // If late-joining players can be traitor/changeling
CONFIG_DEF(number/midround_antag_time_check) // How late (in minutes) you want the midround antag system to stay on, setting this to 0 will disable the system
/datum/config_entry/number/midround_antag_time_check // How late (in minutes you want the midround antag system to stay on, setting this to 0 will disable the system)
value = 60
min_val = 0
CONFIG_DEF(number/midround_antag_life_check) // A ratio of how many people need to be alive in order for the round not to immediately end in midround antagonist
/datum/config_entry/number/midround_antag_life_check // A ratio of how many people need to be alive in order for the round not to immediately end in midround antagonist
value = 0.7
integer = FALSE
min_val = 0
max_val = 1
CONFIG_DEF(number/shuttle_refuel_delay)
/datum/config_entry/number/shuttle_refuel_delay
value = 12000
min_val = 0
CONFIG_DEF(flag/show_game_type_odds) //if set this allows players to see the odds of each roundtype on the get revision screen
/datum/config_entry/flag/show_game_type_odds //if set this allows players to see the odds of each roundtype on the get revision screen
CONFIG_DEF(keyed_flag_list/roundstart_races) //races you can play as from the get go.
/datum/config_entry/keyed_flag_list/roundstart_races //races you can play as from the get go.
CONFIG_DEF(flag/join_with_mutant_humans) //players can pick mutant bodyparts for humans before joining the game
/datum/config_entry/flag/join_with_mutant_humans //players can pick mutant bodyparts for humans before joining the game
CONFIG_DEF(flag/no_summon_guns) //No
/datum/config_entry/flag/no_summon_guns //No
CONFIG_DEF(flag/no_summon_magic) //Fun
/datum/config_entry/flag/no_summon_magic //Fun
CONFIG_DEF(flag/no_summon_events) //Allowed
/datum/config_entry/flag/no_summon_events //Allowed
CONFIG_DEF(flag/no_intercept_report) //Whether or not to send a communications intercept report roundstart. This may be overriden by gamemodes.
/datum/config_entry/flag/no_intercept_report //Whether or not to send a communications intercept report roundstart. This may be overriden by gamemodes.
CONFIG_DEF(number/arrivals_shuttle_dock_window) //Time from when a player late joins on the arrivals shuttle to when the shuttle docks on the station
/datum/config_entry/number/arrivals_shuttle_dock_window //Time from when a player late joins on the arrivals shuttle to when the shuttle docks on the station
value = 55
min_val = 30
CONFIG_DEF(flag/arrivals_shuttle_require_undocked) //Require the arrivals shuttle to be undocked before latejoiners can join
/datum/config_entry/flag/arrivals_shuttle_require_undocked //Require the arrivals shuttle to be undocked before latejoiners can join
CONFIG_DEF(flag/arrivals_shuttle_require_safe_latejoin) //Require the arrivals shuttle to be operational in order for latejoiners to join
/datum/config_entry/flag/arrivals_shuttle_require_safe_latejoin //Require the arrivals shuttle to be operational in order for latejoiners to join
CONFIG_DEF(string/alert_green)
/datum/config_entry/string/alert_green
value = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced."
CONFIG_DEF(string/alert_blue_upto)
/datum/config_entry/string/alert_blue_upto
value = "The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible, random searches are permitted."
CONFIG_DEF(string/alert_blue_downto)
/datum/config_entry/string/alert_blue_downto
value = "The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed."
CONFIG_DEF(string/alert_red_upto)
/datum/config_entry/string/alert_red_upto
value = "There is an immediate serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised."
CONFIG_DEF(string/alert_red_downto)
/datum/config_entry/string/alert_red_downto
value = "The station's destruction has been averted. There is still however an immediate serious threat to the station. Security may have weapons unholstered at all times, random searches are allowed and advised."
CONFIG_DEF(string/alert_delta)
/datum/config_entry/string/alert_delta
value = "Destruction of the station is imminent. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill."
CONFIG_DEF(flag/revival_pod_plants)
/datum/config_entry/flag/revival_pod_plants
CONFIG_DEF(flag/revival_cloning)
/datum/config_entry/flag/revival_cloning
CONFIG_DEF(number/revival_brain_life)
/datum/config_entry/number/revival_brain_life
value = -1
min_val = -1
CONFIG_DEF(flag/rename_cyborg)
/datum/config_entry/flag/rename_cyborg
CONFIG_DEF(flag/ooc_during_round)
/datum/config_entry/flag/ooc_during_round
CONFIG_DEF(flag/emojis)
/datum/config_entry/flag/emojis
CONFIG_DEF(number/run_delay) //Used for modifying movement speed for mobs.
/datum/config_entry/number/run_delay //Used for modifying movement speed for mobs.
var/static/value_cache = 0
CONFIG_TWEAK(number/run_delay/ValidateAndSet())
/datum/config_entry/number/run_delay/ValidateAndSet()
. = ..()
if(.)
value_cache = value
CONFIG_DEF(number/walk_delay)
/datum/config_entry/number/walk_delay
var/static/value_cache = 0
CONFIG_TWEAK(number/walk_delay/ValidateAndSet())
/datum/config_entry/number/walk_delay/ValidateAndSet()
. = ..()
if(.)
value_cache = value
CONFIG_DEF(number/human_delay) //Mob specific modifiers. NOTE: These will affect different mob types in different ways
CONFIG_DEF(number/robot_delay)
CONFIG_DEF(number/monkey_delay)
CONFIG_DEF(number/alien_delay)
CONFIG_DEF(number/slime_delay)
CONFIG_DEF(number/animal_delay)
/datum/config_entry/number/human_delay //Mob specific modifiers. NOTE: These will affect different mob types in different ways
/datum/config_entry/number/robot_delay
/datum/config_entry/number/monkey_delay
/datum/config_entry/number/alien_delay
/datum/config_entry/number/slime_delay
/datum/config_entry/number/animal_delay
CONFIG_DEF(number/gateway_delay) //How long the gateway takes before it activates. Default is half an hour.
/datum/config_entry/number/gateway_delay //How long the gateway takes before it activates. Default is half an hour.
value = 18000
min_val = 0
CONFIG_DEF(flag/ghost_interaction)
/datum/config_entry/flag/ghost_interaction
CONFIG_DEF(flag/silent_ai)
CONFIG_DEF(flag/silent_borg)
/datum/config_entry/flag/silent_ai
/datum/config_entry/flag/silent_borg
CONFIG_DEF(flag/sandbox_autoclose) // close the sandbox panel after spawning an item, potentially reducing griff
/datum/config_entry/flag/sandbox_autoclose // close the sandbox panel after spawning an item, potentially reducing griff
CONFIG_DEF(number/default_laws) //Controls what laws the AI spawns with.
/datum/config_entry/number/default_laws //Controls what laws the AI spawns with.
value = 0
min_val = 0
max_val = 3
CONFIG_DEF(number/silicon_max_law_amount)
/datum/config_entry/number/silicon_max_law_amount
value = 12
min_val = 0
CONFIG_DEF(keyed_flag_list/random_laws)
/datum/config_entry/keyed_flag_list/random_laws
CONFIG_DEF(keyed_number_list/law_weight)
/datum/config_entry/keyed_number_list/law_weight
splitter = ","
CONFIG_DEF(number/assistant_cap)
/datum/config_entry/number/assistant_cap
value = -1
min_val = -1
CONFIG_DEF(flag/starlight)
CONFIG_DEF(flag/grey_assistants)
/datum/config_entry/flag/starlight
/datum/config_entry/flag/grey_assistants
CONFIG_DEF(number/lavaland_budget)
/datum/config_entry/number/lavaland_budget
value = 60
min_val = 0
CONFIG_DEF(number/space_budget)
/datum/config_entry/number/space_budget
value = 16
min_val = 0
CONFIG_DEF(flag/allow_random_events) // Enables random events mid-round when set
/datum/config_entry/flag/allow_random_events // Enables random events mid-round when set
CONFIG_DEF(number/events_min_time_mul) // Multipliers for random events minimal starting time and minimal players amounts
/datum/config_entry/number/events_min_time_mul // Multipliers for random events minimal starting time and minimal players amounts
value = 1
min_val = 0
integer = FALSE
CONFIG_DEF(number/events_min_players_mul)
/datum/config_entry/number/events_min_players_mul
value = 1
min_val = 0
integer = FALSE
CONFIG_DEF(number/mice_roundstart)
/datum/config_entry/number/mice_roundstart
value = 10
min_val = 0
CONFIG_DEF(number/bombcap)
/datum/config_entry/number/bombcap
value = 14
min_val = 4
CONFIG_DEF(flag/allow_crew_objectives)
CONFIG_DEF(flag/allow_miscreants)
CONFIG_DEF(flag/allow_extended_miscreants)
//Cit changes - Adds config options for crew objectives and miscreants
/datum/config_entry/flag/allow_crew_objectives
/datum/config_entry/flag/allow_miscreants
/datum/config_entry/flag/allow_extended_miscreants
//End of Cit changes
/datum/config_entry/number/bombcap/ValidateAndSet(str_val)
. = ..()
@@ -258,9 +260,9 @@ CONFIG_DEF(flag/allow_extended_miscreants)
GLOB.MAX_EX_FLASH_RANGE = value
GLOB.MAX_EX_FLAME_RANGE = value
CONFIG_DEF(number/emergency_shuttle_autocall_threshold)
/datum/config_entry/number/emergency_shuttle_autocall_threshold
min_val = 0
max_val = 1
integer = FALSE
CONFIG_DEF(flag/ic_printing)
/datum/config_entry/flag/ic_printing
@@ -0,0 +1,388 @@
/datum/config_entry/flag/autoadmin // if autoadmin is enabled
protection = CONFIG_ENTRY_LOCKED
/datum/config_entry/string/autoadmin_rank // the rank for autoadmins
value = "Game Master"
protection = CONFIG_ENTRY_LOCKED
/datum/config_entry/string/servername // server name (the name of the game window)
/datum/config_entry/string/serversqlname // short form server name used for the DB
/datum/config_entry/string/stationname // station name (the name of the station in-game)
/datum/config_entry/number/lobby_countdown // In between round countdown.
value = 120
min_val = 0
/datum/config_entry/number/round_end_countdown // Post round murder death kill countdown
value = 25
min_val = 0
/datum/config_entry/flag/hub // if the game appears on the hub or not
/datum/config_entry/flag/log_ooc // log OOC channel
/datum/config_entry/flag/log_access // log login/logout
/datum/config_entry/flag/log_say // log client say
/datum/config_entry/flag/log_admin // log admin actions
protection = CONFIG_ENTRY_LOCKED
/datum/config_entry/flag/log_prayer // log prayers
/datum/config_entry/flag/log_law // log lawchanges
/datum/config_entry/flag/log_game // log game events
/datum/config_entry/flag/log_vote // log voting
/datum/config_entry/flag/log_whisper // log client whisper
/datum/config_entry/flag/log_attack // log attack messages
/datum/config_entry/flag/log_emote // log emotes
/datum/config_entry/flag/log_adminchat // log admin chat messages
protection = CONFIG_ENTRY_LOCKED
/datum/config_entry/flag/log_pda // log pda messages
/datum/config_entry/flag/log_twitter // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases.
/datum/config_entry/flag/log_world_topic // log all world.Topic() calls
/datum/config_entry/flag/log_manifest // log crew manifest to seperate file
/datum/config_entry/flag/allow_admin_ooccolor // Allows admins with relevant permissions to have their own ooc colour
/datum/config_entry/flag/allow_vote_restart // allow votes to restart
/datum/config_entry/flag/allow_vote_mode // allow votes to change mode
/datum/config_entry/number/vote_delay // minimum time between voting sessions (deciseconds, 10 minute default)
value = 6000
min_val = 0
/datum/config_entry/number/vote_period // length of voting period (deciseconds, default 1 minute)
value = 600
min_val = 0
/datum/config_entry/flag/default_no_vote // vote does not default to nochange/norestart
/datum/config_entry/flag/no_dead_vote // dead people can't vote
/datum/config_entry/flag/allow_metadata // Metadata is supported.
/datum/config_entry/flag/popup_admin_pm // adminPMs to non-admins show in a pop-up 'reply' window when set
/datum/config_entry/number/fps
value = 20
min_val = 1
max_val = 100 //byond will start crapping out at 50, so this is just ridic
var/sync_validate = FALSE
/datum/config_entry/number/fps/ValidateAndSet(str_val)
. = ..()
if(.)
sync_validate = TRUE
var/datum/config_entry/number/ticklag/TL = config.entries_by_type[/datum/config_entry/number/ticklag]
if(!TL.sync_validate)
TL.ValidateAndSet(10 / value)
sync_validate = FALSE
/datum/config_entry/number/ticklag
integer = FALSE
var/sync_validate = FALSE
/datum/config_entry/number/ticklag/New() //ticklag weirdly just mirrors fps
var/datum/config_entry/CE = /datum/config_entry/number/fps
value = 10 / initial(CE.value)
..()
/datum/config_entry/number/ticklag/ValidateAndSet(str_val)
. = text2num(str_val) > 0 && ..()
if(.)
sync_validate = TRUE
var/datum/config_entry/number/fps/FPS = config.entries_by_type[/datum/config_entry/number/fps]
if(!FPS.sync_validate)
FPS.ValidateAndSet(10 / value)
sync_validate = FALSE
/datum/config_entry/flag/allow_holidays
/datum/config_entry/number/tick_limit_mc_init //SSinitialization throttling
value = TICK_LIMIT_MC_INIT_DEFAULT
min_val = 0 //oranges warned us
integer = FALSE
/datum/config_entry/flag/admin_legacy_system //Defines whether the server uses the legacy admin system with admins.txt or the SQL system
protection = CONFIG_ENTRY_LOCKED
/datum/config_entry/string/hostedby
/datum/config_entry/flag/norespawn
/datum/config_entry/flag/guest_jobban
/datum/config_entry/flag/usewhitelist
/datum/config_entry/flag/ban_legacy_system //Defines whether the server uses the legacy banning system with the files in /data or the SQL system.
protection = CONFIG_ENTRY_LOCKED
/datum/config_entry/flag/use_age_restriction_for_jobs //Do jobs use account age restrictions? --requires database
/datum/config_entry/flag/use_account_age_for_jobs //Uses the time they made the account for the job restriction stuff. New player joining alerts should be unaffected.
/datum/config_entry/flag/use_exp_tracking
/datum/config_entry/flag/use_exp_restrictions_heads
/datum/config_entry/number/use_exp_restrictions_heads_hours
value = 0
min_val = 0
/datum/config_entry/flag/use_exp_restrictions_heads_department
/datum/config_entry/flag/use_exp_restrictions_other
/datum/config_entry/flag/use_exp_restrictions_admin_bypass
/datum/config_entry/string/server
/datum/config_entry/string/banappeals
/datum/config_entry/string/wikiurl
value = "http://www.tgstation13.org/wiki"
/datum/config_entry/string/forumurl
value = "http://tgstation13.org/phpBB/index.php"
/datum/config_entry/string/rulesurl
value = "http://www.tgstation13.org/wiki/Rules"
/datum/config_entry/string/githuburl
value = "https://www.github.com/tgstation/-tg-station"
/datum/config_entry/number/githubrepoid
value = null
min_val = 0
/datum/config_entry/flag/guest_ban
/datum/config_entry/number/id_console_jobslot_delay
value = 30
min_val = 0
/datum/config_entry/number/inactivity_period //time in ds until a player is considered inactive
value = 3000
min_val = 0
/datum/config_entry/number/inactivity_period/ValidateAndSet(str_val)
. = ..()
if(.)
value *= 10 //documented as seconds in config.txt
/datum/config_entry/number/afk_period //time in ds until a player is considered inactive
value = 3000
min_val = 0
/datum/config_entry/number/afk_period/ValidateAndSet(str_val)
. = ..()
if(.)
value *= 10 //documented as seconds in config.txt
/datum/config_entry/flag/kick_inactive //force disconnect for inactive players
/datum/config_entry/flag/load_jobs_from_txt
/datum/config_entry/flag/forbid_singulo_possession
/datum/config_entry/flag/automute_on //enables automuting/spam prevention
/datum/config_entry/string/panic_server_name
/datum/config_entry/string/panic_server_name/ValidateAndSet(str_val)
return str_val != "\[Put the name here\]" && ..()
/datum/config_entry/string/panic_server_address //Reconnect a player this linked server if this server isn't accepting new players
/datum/config_entry/string/panic_server_address/ValidateAndSet(str_val)
return str_val != "byond://address:port" && ..()
/datum/config_entry/string/invoke_youtubedl
protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN
/datum/config_entry/flag/show_irc_name
/datum/config_entry/flag/see_own_notes //Can players see their own admin notes
/datum/config_entry/number/note_fresh_days
value = null
min_val = 0
integer = FALSE
/datum/config_entry/number/note_stale_days
value = null
min_val = 0
integer = FALSE
/datum/config_entry/flag/maprotation
/datum/config_entry/number/maprotatechancedelta
value = 0.75
min_val = 0
max_val = 1
integer = FALSE
/datum/config_entry/number/soft_popcap
value = null
min_val = 0
/datum/config_entry/number/hard_popcap
value = null
min_val = 0
/datum/config_entry/number/extreme_popcap
value = null
min_val = 0
/datum/config_entry/string/soft_popcap_message
value = "Be warned that the server is currently serving a high number of users, consider using alternative game servers."
/datum/config_entry/string/hard_popcap_message
value = "The server is currently serving a high number of users, You cannot currently join. You may wait for the number of living crew to decline, observe, or find alternative servers."
/datum/config_entry/string/extreme_popcap_message
value = "The server is currently serving a high number of users, find alternative servers."
/datum/config_entry/flag/panic_bunker // prevents people the server hasn't seen before from connecting
/datum/config_entry/number/notify_new_player_age // how long do we notify admins of a new player
min_val = -1
/datum/config_entry/number/notify_new_player_account_age // how long do we notify admins of a new byond account
min_val = 0
/datum/config_entry/flag/irc_first_connection_alert // do we notify the irc channel when somebody is connecting for the first time?
/datum/config_entry/flag/check_randomizer
/datum/config_entry/string/ipintel_email
/datum/config_entry/string/ipintel_email/ValidateAndSet(str_val)
return str_val != "ch@nge.me" && ..()
/datum/config_entry/number/ipintel_rating_bad
value = 1
integer = FALSE
min_val = 0
max_val = 1
/datum/config_entry/number/ipintel_save_good
value = 12
min_val = 0
/datum/config_entry/number/ipintel_save_bad
value = 1
min_val = 0
/datum/config_entry/string/ipintel_domain
value = "check.getipintel.net"
/datum/config_entry/flag/aggressive_changelog
/datum/config_entry/flag/autoconvert_notes //if all connecting player's notes should attempt to be converted to the database
protection = CONFIG_ENTRY_LOCKED
/datum/config_entry/flag/allow_webclient
/datum/config_entry/flag/webclient_only_byond_members
/datum/config_entry/flag/announce_admin_logout
/datum/config_entry/flag/announce_admin_login
/datum/config_entry/flag/allow_map_voting
/datum/config_entry/flag/generate_minimaps
/datum/config_entry/number/client_warn_version
value = null
min_val = 500
max_val = DM_VERSION - 1
/datum/config_entry/string/client_warn_message
value = "Your version of byond may have issues or be blocked from accessing this server in the future."
/datum/config_entry/flag/client_warn_popup
/datum/config_entry/number/client_error_version
value = null
min_val = 500
max_val = DM_VERSION - 1
/datum/config_entry/string/client_error_message
value = "Your version of byond is too old, may have issues, and is blocked from accessing this server."
/datum/config_entry/number/minute_topic_limit
value = null
min_val = 0
/datum/config_entry/number/second_topic_limit
value = null
min_val = 0
/datum/config_entry/number/error_cooldown // The "cooldown" time for each occurrence of a unique error
value = 600
min_val = 0
/datum/config_entry/number/error_limit // How many occurrences before the next will silence them
value = 50
/datum/config_entry/number/error_silence_time // How long a unique error will be silenced for
value = 6000
/datum/config_entry/number/error_msg_delay // How long to wait between messaging admins about occurrences of a unique error
value = 50
/datum/config_entry/flag/irc_announce_new_game
/datum/config_entry/flag/debug_admin_hrefs
/datum/config_entry/number/mc_tick_rate/base_mc_tick_rate
integer = FALSE
value = 1
/datum/config_entry/number/mc_tick_rate/high_pop_mc_tick_rate
integer = FALSE
value = 1.1
/datum/config_entry/number/mc_tick_rate/high_pop_mc_mode_amount
value = 65
/datum/config_entry/number/mc_tick_rate/disable_high_pop_mc_mode_amount
value = 60
/datum/config_entry/number/mc_tick_rate
abstract_type = /datum/config_entry/number/mc_tick_rate
/datum/config_entry/number/mc_tick_rate/ValidateAndSet(str_val)
. = ..()
if (.)
Master.UpdateTickRate()
/datum/config_entry/flag/resume_after_initializations
/datum/config_entry/flag/resume_after_initializations/ValidateAndSet(str_val)
. = ..()
if(. && Master.current_runlevel)
world.sleep_offline = !value
/datum/config_entry/number/rounds_until_hard_restart
value = -1
min_val = 0
/datum/config_entry/string/default_view
value = "15x15"
+1 -1
View File
@@ -301,7 +301,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
continue
//Byond resumed us late. assume it might have to do the same next tick
if (last_run + Ceiling(world.tick_lag * (processing * sleep_delta), world.tick_lag) < world.time)
if (last_run + CEILING(world.tick_lag * (processing * sleep_delta), world.tick_lag) < world.time)
sleep_delta += 1
sleep_delta = MC_AVERAGE_FAST(sleep_delta, 1) //decay sleep_delta
+3
View File
@@ -8,6 +8,8 @@
var/flags = 0 //see MC.dm in __DEFINES Most flags must be set on world start to take full effect. (You can also restart the mc to force them to process again)
var/initialized = FALSE //set to TRUE after it has been initialized, will obviously never be set if the subsystem doesn't initialize
//set to 0 to prevent fire() calls, mostly for admin use or subsystems that may be resumed later
// use the SS_NO_FIRE flag instead for systems that never fire to keep it from even being added to the list
var/can_fire = TRUE
@@ -156,6 +158,7 @@
//used to initialize the subsystem AFTER the map has loaded
/datum/controller/subsystem/Initialize(start_timeofday)
initialized = TRUE
var/time = (REALTIMEOFDAY - start_timeofday) / 10
var/msg = "Initialized [name] subsystem within [time] second[time == 1 ? "" : "s"]!"
to_chat(world, "<span class='boldannounce'>[msg]</span>")
-1
View File
@@ -8,7 +8,6 @@ SUBSYSTEM_DEF(atoms)
init_order = INIT_ORDER_ATOMS
flags = SS_NO_FIRE
var/initialized = INITIALIZATION_INSSATOMS
var/old_initialized
var/list/late_loaders
+12
View File
@@ -0,0 +1,12 @@
SUBSYSTEM_DEF(input)
name = "Input"
wait = 1 //SS_TICKER means this runs every tick
flags = SS_TICKER | SS_NO_INIT
priority = 1000
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
/datum/controller/subsystem/input/fire()
var/list/clients = GLOB.clients // Let's sing the list cache song
for(var/i in 1 to clients.len)
var/client/C = clients[i]
C.keyLoop()
-2
View File
@@ -8,8 +8,6 @@ SUBSYSTEM_DEF(lighting)
init_order = INIT_ORDER_LIGHTING
flags = SS_TICKER
var/initialized = FALSE
/datum/controller/subsystem/lighting/stat_entry()
..("L:[GLOB.lighting_update_lights.len]|C:[GLOB.lighting_update_corners.len]|O:[GLOB.lighting_update_objects.len]")
+5 -1
View File
@@ -1,14 +1,18 @@
SUBSYSTEM_DEF(mobs)
name = "Mobs"
priority = 100
flags = SS_KEEP_TIMING|SS_NO_INIT
flags = SS_KEEP_TIMING
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
var/list/currentrun = list()
var/static/list/clients_by_zlevel[][]
/datum/controller/subsystem/mobs/stat_entry()
..("P:[GLOB.mob_living_list.len]")
/datum/controller/subsystem/mobs/Initialize(start_timeofday)
clients_by_zlevel = new /list(world.maxz,0)
return ..()
/datum/controller/subsystem/mobs/fire(resumed = 0)
var/seconds = wait * 0.1
-1
View File
@@ -10,7 +10,6 @@ SUBSYSTEM_DEF(overlays)
var/list/stats
var/list/overlay_icon_state_caches
var/list/overlay_icon_cache
var/initialized = FALSE
/datum/controller/subsystem/overlays/PreInit()
overlay_icon_state_caches = list()
@@ -44,10 +44,20 @@ PROCESSING_SUBSYSTEM_DEF(circuit)
circuit_fabricator_recipe_list["Assemblies"] = list(
/obj/item/device/electronic_assembly,
/obj/item/device/electronic_assembly/medium,
/obj/item/device/electronic_assembly/large,
/obj/item/device/electronic_assembly/drone
/obj/item/device/electronic_assembly/default,
/obj/item/device/electronic_assembly/calc,
/obj/item/device/electronic_assembly/clam,
/obj/item/device/electronic_assembly/simple,
/obj/item/device/electronic_assembly/medium/default,
/obj/item/device/electronic_assembly/medium/box,
/obj/item/device/electronic_assembly/medium/clam,
/obj/item/device/electronic_assembly/medium/medical,
/obj/item/device/electronic_assembly/large/default,
/obj/item/device/electronic_assembly/large/scope,
/obj/item/device/electronic_assembly/large/terminal,
/obj/item/device/electronic_assembly/large/arm,
/obj/item/device/electronic_assembly/drone/default,
/obj/item/device/electronic_assembly/drone/arms
///obj/item/weapon/implant/integrated_circuit
)
+75
View File
@@ -0,0 +1,75 @@
SUBSYSTEM_DEF(research)
name = "Research"
flags = SS_KEEP_TIMING
priority = 15 //My powergame is priority.
wait = 10
init_order = INIT_ORDER_RESEARCH
var/list/invalid_design_ids = list() //associative id = number of times
var/list/invalid_node_ids = list() //associative id = number of times
var/list/invalid_node_boost = list() //associative id = error message
var/list/obj/machinery/rnd/server/servers = list()
var/datum/techweb/science/science_tech
var/datum/techweb/admin/admin_tech
var/list/techweb_nodes = list() //associative id = node datum
var/list/techweb_categories = list() //category name = list(node.id = node)
var/list/techweb_designs = list() //associative id = node datum
var/list/techweb_nodes_starting = list() //associative id = node datum
var/list/techweb_boost_items = list() //associative double-layer path = list(id = point_discount)
var/list/techweb_nodes_hidden = list() //Nodes that should be hidden by default.
var/list/techweb_point_items = list() //path = value
var/list/errored_datums = list()
//----------------------------------------------
var/single_server_income = 40.7
var/multiserver_calculation = FALSE
var/last_income = 0
//^^^^^^^^ ALL OF THESE ARE PER SECOND! ^^^^^^^^
//Aiming for 1.5 hours to max R&D
//[88nodes * 5000points/node] / [1.5hr * 90min/hr * 60s/min]
//Around 450000 points max???
var/bomb_research_point_scaling = 1800
/datum/controller/subsystem/research/Initialize()
initialize_all_techweb_designs()
initialize_all_techweb_nodes()
science_tech = new /datum/techweb/science
admin_tech = new /datum/techweb/admin
autosort_categories()
return ..()
/datum/controller/subsystem/research/fire()
handle_research_income()
/datum/controller/subsystem/research/proc/handle_research_income()
var/bitcoins = 0
if(multiserver_calculation)
var/eff = calculate_server_coefficient()
for(var/obj/machinery/rnd/server/miner in servers)
bitcoins += (miner.mine() * eff) //SLAVE AWAY, SLAVE.
else
for(var/obj/machinery/rnd/server/miner in servers)
if(miner.working)
bitcoins = single_server_income
break //Just need one to work.
var/income_time_difference = world.time - last_income
bitcoins *= income_time_difference / 10
science_tech.research_points += bitcoins
last_income = world.time
/datum/controller/subsystem/research/proc/calculate_server_coefficient() //Diminishing returns.
var/amt = servers.len
if(!amt)
return 0
var/coeff = 100
coeff = sqrt(coeff / amt)
return coeff
/datum/controller/subsystem/research/proc/autosort_categories()
for(var/i in techweb_nodes)
var/datum/techweb_node/I = techweb_nodes[i]
if(techweb_categories[I.category])
techweb_categories[I.category][I.id] = I
else
techweb_categories[I.category] = list(I.id = I)
+3
View File
@@ -307,6 +307,9 @@ SUBSYSTEM_DEF(shuttle)
return 1
/datum/controller/subsystem/shuttle/proc/autoEvac()
if (!SSticker.IsRoundInProgress())
return
var/callShuttle = 1
for(var/thing in GLOB.shuttle_caller_list)
+1 -1
View File
@@ -80,7 +80,7 @@ SUBSYSTEM_DEF(throwing)
last_move = world.time
//calculate how many tiles to move, making up for any missed ticks.
var/tilestomove = Ceiling(min(((((world.time+world.tick_lag) - start_time + delayed_time) * speed) - (dist_travelled ? dist_travelled : -1)), speed*MAX_TICKS_TO_MAKE_UP) * (world.tick_lag * SSthrowing.wait))
var/tilestomove = CEILING(min(((((world.time+world.tick_lag) - start_time + delayed_time) * speed) - (dist_travelled ? dist_travelled : -1)), speed*MAX_TICKS_TO_MAKE_UP) * (world.tick_lag * SSthrowing.wait), 1)
while (tilestomove-- > 0)
if ((dist_travelled >= maxrange || AM.loc == target_turf) && AM.has_gravity(AM.loc))
finalize()
+1 -1
View File
@@ -165,7 +165,7 @@ SUBSYSTEM_DEF(vote)
var/admin = FALSE
var/ckey = ckey(initiator_key)
if((GLOB.admin_datums[ckey]) || (ckey in GLOB.deadmins))
if(GLOB.admin_datums[ckey])
admin = TRUE
if(next_allowed_time > world.time && !admin)
+16 -16
View File
@@ -12,7 +12,7 @@
name = "Nuclear Operative"
roundend_category = "syndicate operatives" //just in case
job_rank = ROLE_OPERATIVE
var/datum/objective_team/nuclear/nuke_team
var/datum/team/nuclear/nuke_team
var/always_new_team = FALSE //If not assigned a team by default ops will try to join existing ones, set this to TRUE to always create new team.
var/send_to_spawnpoint = TRUE //Should the user be moved to default spawnpoint.
var/nukeop_outfit = /datum/outfit/syndicate
@@ -39,7 +39,7 @@
if(!ishuman(owner.current))
return
var/mob/living/carbon/human/H = owner.current
H.set_species(/datum/species/human) //Plasamen burn up otherwise, and lizards are vulnerable to asimov AIs
H.equipOutfit(nukeop_outfit)
@@ -103,14 +103,14 @@
/datum/antagonist/nukeop/leader/move_to_spawnpoint()
owner.current.forceMove(pick(GLOB.nukeop_leader_start))
/datum/antagonist/nukeop/create_team(datum/objective_team/nuclear/new_team)
/datum/antagonist/nukeop/create_team(datum/team/nuclear/new_team)
if(!new_team)
if(!always_new_team)
for(var/datum/antagonist/nukeop/N in GLOB.antagonists)
if(N.nuke_team)
nuke_team = N.nuke_team
return
nuke_team = new /datum/objective_team/nuclear
nuke_team = new /datum/team/nuclear
nuke_team.update_objectives()
assign_nuke() //This is bit ugly
return
@@ -158,7 +158,7 @@
return
nuke_team.rename_team(ask_name())
/datum/objective_team/nuclear/proc/rename_team(new_name)
/datum/team/nuclear/proc/rename_team(new_name)
syndicate_name = new_name
name = "[syndicate_name] Team"
for(var/I in members)
@@ -201,40 +201,40 @@
stack_trace("Station self destruct ot found during lone op team creation.")
nuke_team.memorized_code = null
/datum/objective_team/nuclear
/datum/team/nuclear
var/syndicate_name
var/obj/machinery/nuclearbomb/tracked_nuke
var/core_objective = /datum/objective/nuclear
var/memorized_code
/datum/objective_team/nuclear/New()
/datum/team/nuclear/New()
..()
syndicate_name = syndicate_name()
/datum/objective_team/nuclear/proc/update_objectives()
/datum/team/nuclear/proc/update_objectives()
if(core_objective)
var/datum/objective/O = new core_objective
O.team = src
objectives += O
/datum/objective_team/nuclear/proc/disk_rescued()
/datum/team/nuclear/proc/disk_rescued()
for(var/obj/item/disk/nuclear/D in GLOB.poi_list)
if(!D.onCentCom())
return FALSE
return TRUE
/datum/objective_team/nuclear/proc/operatives_dead()
/datum/team/nuclear/proc/operatives_dead()
for(var/I in members)
var/datum/mind/operative_mind = I
if(ishuman(operative_mind.current) && (operative_mind.current.stat != DEAD))
return FALSE
return TRUE
/datum/objective_team/nuclear/proc/syndies_escaped()
/datum/team/nuclear/proc/syndies_escaped()
var/obj/docking_port/mobile/S = SSshuttle.getShuttle("syndicate")
return (S && (S.z == ZLEVEL_CENTCOM || S.z == ZLEVEL_TRANSIT))
/datum/objective_team/nuclear/proc/get_result()
/datum/team/nuclear/proc/get_result()
var/evacuation = SSshuttle.emergency.mode == SHUTTLE_ENDGAME
var/disk_rescued = disk_rescued()
var/syndies_didnt_escape = !syndies_escaped()
@@ -262,10 +262,10 @@
else
return //Undefined result
/datum/objective_team/nuclear/roundend_report()
/datum/team/nuclear/roundend_report()
var/list/parts = list()
parts += "<span class='header'>[syndicate_name] Operatives:</span>"
switch(get_result())
if(NUKE_RESULT_FLUKE)
parts += "<span class='redtext big'>Humiliating Syndicate Defeat</span>"
@@ -306,7 +306,7 @@
for(var/U in GLOB.uplinks)
var/datum/component/uplink/H = U
if(H.owner == syndicate.key)
TC_uses += H.spent_telecrystals
TC_uses += H.purchase_log.total_spent
if(H.purchase_log)
purchases += H.purchase_log.generate_render(show_key = FALSE)
else
@@ -316,7 +316,7 @@
text += "(Syndicates used [TC_uses] TC) [purchases]"
if(TC_uses == 0 && SSticker.mode.station_was_nuked && !operatives_dead())
text += "<BIG>[icon2html('icons/badass.dmi', world, "badass")]</BIG>"
parts += text
return "<div class='panel redborder'>[parts.Join("<br>")]</div>"
+2 -2
View File
@@ -128,11 +128,11 @@
//Position the effect so the beam is one continous line
var/a
if(abs(Pixel_x)>32)
a = Pixel_x > 0 ? round(Pixel_x/32) : Ceiling(Pixel_x/32)
a = Pixel_x > 0 ? round(Pixel_x/32) : CEILING(Pixel_x/32, 1)
X.x += a
Pixel_x %= 32
if(abs(Pixel_y)>32)
a = Pixel_y > 0 ? round(Pixel_y/32) : Ceiling(Pixel_y/32)
a = Pixel_y > 0 ? round(Pixel_y/32) : CEILING(Pixel_y/32, 1)
X.y += a
Pixel_y %= 32
@@ -27,6 +27,8 @@
if(LAZYLEN(candidates))
var/client/C = pick(candidates)
stranger_backseat.key = C.key
log_game("[key_name(stranger_backseat)] became [key_name(owner)]'s split personality.")
message_admins("[key_name_admin(stranger_backseat)] became [key_name_admin(owner)]'s split personality.")
else
qdel(src)
@@ -59,7 +61,7 @@
current_backseat = owner_backseat
free_backseat = stranger_backseat
log_game("[current_backseat]/([current_backseat.ckey]) assumed control of [owner]/([owner.ckey] due to [src]. (Original owner: [current_controller == OWNER ? owner.ckey : current_backseat.ckey])")
log_game("[key_name(current_backseat)] assumed control of [key_name(owner)] due to [src]. (Original owner: [current_controller == OWNER ? owner.ckey : current_backseat.ckey])")
to_chat(owner, "<span class='userdanger'>You feel your control being taken away... your other personality is in charge now!</span>")
to_chat(current_backseat, "<span class='userdanger'>You manage to take control of your body!</span>")
+1 -1
View File
@@ -6,7 +6,7 @@
var/datum/callback/callback
/datum/component/archaeology/Initialize(_prob2drop, list/_archdrops = list(), datum/callback/_callback)
prob2drop = Clamp(_prob2drop, 0, 100)
prob2drop = CLAMP(_prob2drop, 0, 100)
archdrops = _archdrops
callback = _callback
RegisterSignal(COMSIG_PARENT_ATTACKBY,.proc/Dig)
+1 -1
View File
@@ -48,7 +48,7 @@
if(old_dir == new_dir)
return
remove()
var/rotation = SimplifyDegrees(dir2angle(new_dir)-dir2angle(old_dir))
var/rotation = SIMPLIFY_DEGREES(dir2angle(new_dir)-dir2angle(old_dir))
pic.dir = turn(pic.dir, rotation)
apply()
+81
View File
@@ -0,0 +1,81 @@
/datum/component/jousting
var/current_direction = NONE
var/max_tile_charge = 5
var/min_tile_charge = 2 //tiles before this code gets into effect.
var/current_tile_charge = 0
var/movement_reset_tolerance = 2 //deciseconds
var/unmounted_damage_boost_per_tile = 0
var/unmounted_knockdown_chance_per_tile = 0
var/unmounted_knockdown_time = 0
var/mounted_damage_boost_per_tile = 2
var/mounted_knockdown_chance_per_tile = 20
var/mounted_knockdown_time = 20
var/requires_mob_riding = TRUE //whether this only works if the attacker is riding a mob, rather than anything they can buckle to.
var/requires_mount = TRUE //kinda defeats the point of jousting if you're not mounted but whatever.
var/mob/current_holder
var/datum/component/redirect/listener
var/current_timerid
/datum/component/jousting/Initialize()
if(!isitem(parent))
. = COMPONENT_INCOMPATIBLE
stack_trace("Warning: Jousting component incorrectly applied to invalid parent type [parent.type]")
RegisterSignal(COMSIG_ITEM_EQUIPPED, .proc/on_equip)
RegisterSignal(COMSIG_ITEM_DROPPED, .proc/on_drop)
RegisterSignal(COMSIG_ITEM_ATTACK, .proc/on_attack)
/datum/component/jousting/Destroy()
QDEL_NULL(listener)
return ..()
/datum/component/jousting/proc/on_equip(mob/user, slot)
QDEL_NULL(listener)
current_holder = user
listener = new(user, COMSIG_MOVABLE_MOVED, CALLBACK(src, .proc/mob_move))
/datum/component/jousting/proc/on_drop(mob/user)
QDEL_NULL(listener)
current_holder = null
current_direction = NONE
current_tile_charge = 0
/datum/component/jousting/proc/on_attack(mob/living/target, mob/user)
if(user != current_holder)
return
var/current = current_tile_charge
var/obj/item/I = parent
var/target_buckled = target.buckled ? TRUE : FALSE //we don't need the reference of what they're buckled to, just whether they are.
if((requires_mount && ((requires_mob_riding && !ismob(user.buckled)) || (!user.buckled))) || !current_direction || (current_tile_charge < min_tile_charge))
return
var/turf/target_turf = get_step(user, current_direction)
if(target in range(1, target_turf))
var/knockdown_chance = (target_buckled? mounted_knockdown_chance_per_tile : unmounted_knockdown_chance_per_tile) * current
var/knockdown_time = (target_buckled? mounted_knockdown_time : unmounted_knockdown_time)
var/damage = (target_buckled? mounted_damage_boost_per_tile : unmounted_damage_boost_per_tile) * current
var/sharp = I.is_sharp()
var/msg
if(damage)
msg += "[user] [sharp? "impales" : "slams into"] [target] [sharp? "on" : "with"] their [parent]"
target.apply_damage(damage, BRUTE, user.zone_selected, 0)
if(prob(knockdown_chance))
msg += " and knocks [target] [target_buckled? "off of [target.buckled]" : "down"]"
if(target_buckled)
target.buckled.unbuckle_mob(target)
target.Knockdown(knockdown_time)
if(length(msg))
user.visible_message("<span class='danger'>[msg]!</span>")
/datum/component/jousting/proc/mob_move(newloc, dir)
if(!current_holder || (requires_mount && ((requires_mob_riding && !ismob(current_holder.buckled)) || (!current_holder.buckled))))
return
if(dir != current_direction)
current_tile_charge = 0
current_direction = dir
if(current_tile_charge < max_tile_charge)
current_tile_charge++
if(current_timerid)
deltimer(current_timerid)
current_timerid = addtimer(CALLBACK(src, .proc/reset_charge), movement_reset_tolerance, TIMER_STOPPABLE)
/datum/component/jousting/proc/reset_charge()
current_tile_charge = 0
@@ -70,6 +70,7 @@
user_insert(I, user)
/datum/component/material_container/proc/user_insert(obj/item/I, mob/living/user)
set waitfor = FALSE
var/requested_amount
var/Itype = I.type
if(ispath(Itype, /obj/item/stack) && precise_insertion)
+1 -1
View File
@@ -43,7 +43,7 @@
addtimer(CALLBACK(src, .proc/charge), charge_rate)
/datum/action/innate/dash/proc/charge()
current_charges = Clamp(current_charges + 1, 0, max_charges)
current_charges = CLAMP(current_charges + 1, 0, max_charges)
holder.update_action_buttons_icon()
if(recharge_sound)
playsound(dashing_item, recharge_sound, 50, 1)
+4 -4
View File
@@ -185,10 +185,10 @@
if(properties["stealth"] >= 2)
visibility_flags = HIDDEN_SCANNER
SetSpread(Clamp(2 ** (properties["transmittable"] - symptoms.len), VIRUS_SPREAD_BLOOD, VIRUS_SPREAD_AIRBORNE))
SetSpread(CLAMP(2 ** (properties["transmittable"] - symptoms.len), VIRUS_SPREAD_BLOOD, VIRUS_SPREAD_AIRBORNE))
permeability_mod = max(Ceiling(0.4 * properties["transmittable"]), 1)
cure_chance = 15 - Clamp(properties["resistance"], -5, 5) // can be between 10 and 20
permeability_mod = max(CEILING(0.4 * properties["transmittable"], 1), 1)
cure_chance = 15 - CLAMP(properties["resistance"], -5, 5) // can be between 10 and 20
stage_prob = max(properties["stage_rate"], 2)
SetSeverity(properties["severity"])
GenerateCure(properties)
@@ -243,7 +243,7 @@
// Will generate a random cure, the less resistance the symptoms have, the harder the cure.
/datum/disease/advance/proc/GenerateCure()
if(properties && properties.len)
var/res = Clamp(properties["resistance"] - (symptoms.len / 2), 1, advance_cures.len)
var/res = CLAMP(properties["resistance"] - (symptoms.len / 2), 1, advance_cures.len)
cures = list(advance_cures[res])
// Get the cure name from the cure_id
+9 -6
View File
@@ -85,9 +85,16 @@ GLOBAL_LIST_EMPTY(explosions)
var/max_range = max(devastation_range, heavy_impact_range, light_impact_range, flame_range)
var/area/epi_area = get_area(epicenter)
if(adminlog)
message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area: [get_area(epicenter)] [ADMIN_COORDJMP(epicenter)]")
message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area: [epi_area] [ADMIN_COORDJMP(epicenter)]")
log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z])")
var/x0 = epicenter.x
var/y0 = epicenter.y
var/z0 = epicenter.z
SSblackbox.record_feedback("associative", "explosion", 1, list("dev" = devastation_range, "heavy" = heavy_impact_range, "light" = light_impact_range, "flash" = flash_range, "flame" = flame_range, "orig_dev" = orig_dev_range, "orig_heavy" = orig_heavy_range, "orig_light" = orig_light_range, "x" = x0, "y" = y0, "z" = z0, "area" = epi_area.type))
// Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves.
// Stereo users will also hear the direction of the explosion!
@@ -99,10 +106,6 @@ GLOBAL_LIST_EMPTY(explosions)
far_dist += heavy_impact_range * 5
far_dist += devastation_range * 20
var/x0 = epicenter.x
var/y0 = epicenter.y
var/z0 = epicenter.z
if(!silent)
var/frequency = get_rand_frequency()
var/sound/explosion_sound = sound(get_sfx("explosion"))
@@ -118,7 +121,7 @@ GLOBAL_LIST_EMPTY(explosions)
M.playsound_local(epicenter, null, 100, 1, frequency, falloff = 5, S = explosion_sound)
// You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station.
else if(dist <= far_dist)
var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist
var/far_volume = CLAMP(far_dist, 30, 50) // Volume is based on explosion size and dist
far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion
M.playsound_local(epicenter, null, far_volume, 1, frequency, falloff = 5, S = far_explosion_sound)
EX_PREPROCESS_CHECK_TICK
+1
View File
@@ -10,6 +10,7 @@ GLOBAL_LIST_INIT(huds, list(
DATA_HUD_MEDICAL_ADVANCED = new/datum/atom_hud/data/human/medical/advanced(),
DATA_HUD_DIAGNOSTIC_BASIC = new/datum/atom_hud/data/diagnostic/basic(),
DATA_HUD_DIAGNOSTIC_ADVANCED = new/datum/atom_hud/data/diagnostic/advanced(),
DATA_HUD_ABDUCTOR = new/datum/atom_hud/abductor(),
ANTAG_HUD_CULT = new/datum/atom_hud/antag(),
ANTAG_HUD_REV = new/datum/atom_hud/antag(),
ANTAG_HUD_OPS = new/datum/atom_hud/antag(),
@@ -32,7 +32,7 @@
mid_sounds = list('sound/machines/fryer/deep_fryer_1.ogg' = 1, 'sound/machines/fryer/deep_fryer_2.ogg' = 1)
mid_length = 2
end_sound = 'sound/machines/fryer/deep_fryer_emerge.ogg'
volume = 25
volume = 15
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+2 -2
View File
@@ -101,7 +101,7 @@
"<span class='userdanger'>[A] slams your chest! You can't breathe!</span>")
playsound(get_turf(A), 'sound/effects/hit_punch.ogg', 50, 1, -1)
if(D.losebreath <= 10)
D.losebreath = Clamp(D.losebreath + 5, 0, 10)
D.losebreath = CLAMP(D.losebreath + 5, 0, 10)
D.adjustOxyLoss(10)
add_logs(A, D, "quickchoked")
return 1
@@ -112,7 +112,7 @@
playsound(get_turf(A), 'sound/effects/hit_punch.ogg', 50, 1, -1)
D.apply_damage(5, BRUTE)
if(D.silent <= 10)
D.silent = Clamp(D.silent + 10, 0, 10)
D.silent = CLAMP(D.silent + 10, 0, 10)
add_logs(A, D, "neck chopped")
return 1
+13 -72
View File
@@ -201,6 +201,7 @@
remove_antag_datum(ANTAG_DATUM_BROTHER)
SSticker.mode.update_brother_icons_removed(src)
/datum/mind/proc/remove_nukeop()
var/datum/antagonist/nukeop/nuke = has_antag_datum(/datum/antagonist/nukeop,TRUE)
if(nuke)
@@ -320,14 +321,19 @@ special_role = null
SSticker.mode.add_cultist(src)
else if(is_revolutionary(creator))
var/datum/antagonist/rev/converter = creator.mind.has_antag_datum(/datum/antagonist/rev)
var/datum/antagonist/rev/converter = creator.mind.has_antag_datum(/datum/antagonist/rev,TRUE)
converter.add_revolutionary(src,FALSE)
else if(is_servant_of_ratvar(creator))
add_servant_of_ratvar(current)
else if(is_nuclear_operative(creator))
make_Nuke(null, null, 0, FALSE)
var/datum/antagonist/nukeop/converter = creator.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE)
var/datum/antagonist/nukeop/N = new(src)
N.send_to_spawnpoint = FALSE
N.nukeop_outfit = null
add_antag_datum(N,converter.nuke_team)
enslaved_to = creator
@@ -484,7 +490,8 @@ special_role = null
if (SSticker.mode.config_tag=="nuclear")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if (src in SSticker.mode.syndicates)
var/datum/antagonist/nukeop/N = has_antag_datum(/datum/antagonist/nukeop,TRUE)
if(N)
text += "<b>OPERATIVE</b> | <a href='?src=[REF(src)];nuclear=clear'>nanotrasen</a>"
text += "<br><a href='?src=[REF(src)];nuclear=lair'>To shuttle</a>, <a href='?src=[REF(src)];common=undress'>undress</a>, <a href='?src=[REF(src)];nuclear=dressup'>dress up</a>."
var/code
@@ -704,7 +711,7 @@ special_role = null
out += sections[i]+"<br>"
if(((src in SSticker.mode.traitors) || (src in SSticker.mode.syndicates)) && ishuman(current))
if(((src in SSticker.mode.traitors) || is_nuclear_operative(current)) && ishuman(current))
text = "Uplink: <a href='?src=[REF(src)];common=uplink'>give</a>"
var/datum/component/uplink/U = find_syndicate_uplink()
if(U)
@@ -1100,36 +1107,14 @@ special_role = null
message_admins("[key_name_admin(usr)] has de-nuke op'ed [current].")
log_admin("[key_name(usr)] has de-nuke op'ed [current].")
if("nuclear")
if(!(src in SSticker.mode.syndicates))
SSticker.mode.syndicates += src
SSticker.mode.update_synd_icons_added(src)
if (SSticker.mode.syndicates.len==1)
SSticker.mode.prepare_syndicate_leader(src)
else
current.real_name = "[syndicate_name()] Operative #[SSticker.mode.syndicates.len-1]"
if(!has_antag_datum(/datum/antagonist/nukeop,TRUE))
add_antag_datum(/datum/antagonist/nukeop)
special_role = "Syndicate"
assigned_role = "Syndicate"
to_chat(current, "<span class='notice'>You are a [syndicate_name()] agent!</span>")
SSticker.mode.forge_syndicate_objectives(src)
SSticker.mode.greet_syndicate(src)
message_admins("[key_name_admin(usr)] has nuke op'ed [current].")
log_admin("[key_name(usr)] has nuke op'ed [current].")
if("lair")
current.forceMove(pick(GLOB.nukeop_start))
if("dressup")
var/mob/living/carbon/human/H = current
qdel(H.belt)
qdel(H.back)
qdel(H.ears)
qdel(H.gloves)
qdel(H.head)
qdel(H.shoes)
qdel(H.wear_id)
qdel(H.wear_suit)
qdel(H.w_uniform)
if (!SSticker.mode.equip_syndicate(current))
to_chat(usr, "<span class='danger'>Equipping a syndicate failed!</span>")
if("tellcode")
var/code
for (var/obj/machinery/nuclearbomb/bombue in GLOB.machines)
@@ -1377,50 +1362,6 @@ special_role = null
T.should_specialise = TRUE
add_antag_datum(T)
/datum/mind/proc/make_Nuke(turf/spawnloc, nuke_code, leader=0, telecrystals = TRUE)
if(!(src in SSticker.mode.syndicates))
SSticker.mode.syndicates += src
SSticker.mode.update_synd_icons_added(src)
assigned_role = "Syndicate"
special_role = "Syndicate"
SSticker.mode.forge_syndicate_objectives(src)
SSticker.mode.greet_syndicate(src)
current.faction |= "syndicate"
if(spawnloc)
current.forceMove(spawnloc)
if(ishuman(current))
var/mob/living/carbon/human/H = current
qdel(H.belt)
qdel(H.back)
qdel(H.ears)
qdel(H.gloves)
qdel(H.head)
qdel(H.shoes)
qdel(H.wear_id)
qdel(H.wear_suit)
qdel(H.w_uniform)
SSticker.mode.equip_syndicate(current, telecrystals)
if (nuke_code)
store_memory("<B>Syndicate Nuclear Bomb Code</B>: [nuke_code]", 0, 0)
to_chat(current, "The nuclear authorization code is: <B>[nuke_code]</B>")
else
var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list
if(nuke)
store_memory("<B>Syndicate Nuclear Bomb Code</B>: [nuke.r_code]", 0, 0)
to_chat(current, "The nuclear authorization code is: <B>nuke.r_code</B>")
else
to_chat(current, "You were not provided with a nuclear code. Trying asking your team leader or contacting syndicate command.</B>")
if (leader)
SSticker.mode.prepare_syndicate_leader(src,nuke_code)
else
current.real_name = "[syndicate_name()] Operative #[SSticker.mode.syndicates.len-1]"
/datum/mind/proc/make_Changling()
var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling)
if(!C)
+1
View File
@@ -98,6 +98,7 @@
/datum/mutation/human/unintelligible
name = "Unintelligible"
quality = NEGATIVE
dna_block = NON_SCANNABLE
text_gain_indication = "<span class='danger'>You can't seem to form any coherent thoughts!</span>"
text_lose_indication = "<span class='danger'>Your mind feels more clear.</span>"
+1 -1
View File
@@ -38,7 +38,7 @@
if (user.client)
user.client.images += bar
progress = Clamp(progress, 0, goal)
progress = CLAMP(progress, 0, goal)
bar.icon_state = "prog_bar_[round(((progress / goal) * 100), 5)]"
if (!shown)
user.client.images += bar
+2 -2
View File
@@ -34,7 +34,7 @@
var/strength
if(steps>1)
strength = InverseSquareLaw(intensity, max(range_modifier*steps, 1), 1)
strength = INVERSE_SQUARE(intensity, max(range_modifier*steps, 1), 1)
else
strength = intensity
@@ -42,7 +42,7 @@
qdel(src)
return
radiate(atoms, Floor(strength))
radiate(atoms, FLOOR(strength, 1))
check_obstructions(atoms) // reduce our overall strength if there are radiation insulators
+3 -3
View File
@@ -60,8 +60,8 @@
if(istype(L)) //this is probably more safety than actually needed
var/vanguard = L.stun_absorption["vanguard"]
desc = initial(desc)
desc += "<br><b>[Floor(vanguard["stuns_absorbed"] * 0.1)]</b> seconds of stuns held back.\
[GLOB.ratvar_awakens ? "":"<br><b>[Floor(min(vanguard["stuns_absorbed"] * 0.025, 20))]</b> seconds of stun will affect you."]"
desc += "<br><b>[FLOOR(vanguard["stuns_absorbed"] * 0.1, 1)]</b> seconds of stuns held back.\
[GLOB.ratvar_awakens ? "":"<br><b>[FLOOR(min(vanguard["stuns_absorbed"] * 0.025, 20), 1)]</b> seconds of stun will affect you."]"
..()
/datum/status_effect/vanguard_shield/Destroy()
@@ -87,7 +87,7 @@
var/vanguard = owner.stun_absorption["vanguard"]
var/stuns_blocked = 0
if(vanguard)
stuns_blocked = Floor(min(vanguard["stuns_absorbed"] * 0.25, 400))
stuns_blocked = FLOOR(min(vanguard["stuns_absorbed"] * 0.25, 400), 1)
vanguard["end_time"] = 0 //so it doesn't absorb the stuns we're about to apply
if(owner.stat != DEAD)
var/message_to_owner = "<span class='warning'>You feel your Vanguard quietly fade...</span>"
+2 -2
View File
@@ -230,7 +230,7 @@
if(prob(severity * 0.15))
to_chat(owner, "<span class='sevtug[span_part]'>\"[text2ratvar(pick(mania_messages))]\"</span>")
owner.playsound_local(get_turf(motor), hum, severity, 1)
owner.adjust_drugginess(Clamp(max(severity * 0.075, 1), 0, max(0, 50 - owner.druggy))) //7.5% of severity per second, minimum 1
owner.adjust_drugginess(CLAMP(max(severity * 0.075, 1), 0, max(0, 50 - owner.druggy))) //7.5% of severity per second, minimum 1
if(owner.hallucination < 50)
owner.hallucination = min(owner.hallucination + max(severity * 0.075, 1), 50) //7.5% of severity per second, minimum 1
if(owner.dizziness < 50)
@@ -310,7 +310,7 @@
var/icon/I = icon(owner.icon, owner.icon_state, owner.dir)
var/icon_height = I.Height()
bleed_overlay.pixel_x = -owner.pixel_x
bleed_overlay.pixel_y = Floor(icon_height * 0.25)
bleed_overlay.pixel_y = FLOOR(icon_height * 0.25, 1)
bleed_overlay.transform = matrix() * (icon_height/world.icon_size) //scale the bleed overlay's size based on the target's icon size
bleed_underlay.pixel_x = -owner.pixel_x
bleed_underlay.transform = matrix() * (icon_height/world.icon_size) * 3
+11 -11
View File
@@ -1,8 +1,8 @@
/datum/wires/r_n_d
holder_type = /obj/machinery/r_n_d
/datum/wires/rnd
holder_type = /obj/machinery/rnd
randomize = TRUE
/datum/wires/r_n_d/New(atom/holder)
/datum/wires/rnd/New(atom/holder)
wires = list(
WIRE_HACK, WIRE_DISABLE,
WIRE_SHOCK
@@ -10,22 +10,22 @@
add_duds(5)
..()
/datum/wires/r_n_d/interactable(mob/user)
var/obj/machinery/r_n_d/R = holder
/datum/wires/rnd/interactable(mob/user)
var/obj/machinery/rnd/R = holder
if(R.panel_open)
return TRUE
/datum/wires/r_n_d/get_status()
var/obj/machinery/r_n_d/R = holder
/datum/wires/rnd/get_status()
var/obj/machinery/rnd/R = holder
var/list/status = list()
status += "The red light is [R.disabled ? "off" : "on"]."
status += "The green light is [R.shocked ? "off" : "on"]."
status += "The blue light is [R.hacked ? "off" : "on"]."
return status
/datum/wires/r_n_d/on_pulse(wire)
/datum/wires/rnd/on_pulse(wire)
set waitfor = FALSE
var/obj/machinery/r_n_d/R = holder
var/obj/machinery/rnd/R = holder
switch(wire)
if(WIRE_HACK)
R.hacked = !R.hacked
@@ -37,8 +37,8 @@
if(R)
R.shocked = FALSE
/datum/wires/r_n_d/on_cut(wire, mend)
var/obj/machinery/r_n_d/R = holder
/datum/wires/rnd/on_cut(wire, mend)
var/obj/machinery/rnd/R = holder
switch(wire)
if(WIRE_HACK)
R.hacked = !mend
-1
View File
@@ -20,7 +20,6 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances)
var/list/arguments = args.Copy(2)
new type(arglist(arguments))
/datum/atom_hud/alternate_appearance
var/appearance_key
+19 -24
View File
@@ -200,7 +200,7 @@
loc.handle_atom_del(src)
for(var/atom/movable/AM in contents)
qdel(AM)
loc = null
moveToNullspace()
invisibility = INVISIBILITY_ABSTRACT
if(pulledby)
pulledby.stop_pulling()
@@ -254,6 +254,12 @@
loc = destination
if(!same_loc)
var/turf/oldturf = get_turf(oldloc)
var/turf/destturf = get_turf(destination)
var/old_z = (oldturf ? oldturf.z : null)
var/dest_z = (destturf ? destturf.z : null)
if (old_z != dest_z)
onTransitZ(old_z, dest_z)
destination.Entered(src, oldloc)
if(destarea && old_area != destarea)
destarea.Entered(src, oldloc)
@@ -268,30 +274,18 @@
//If no destination, move the atom into nullspace (don't do this unless you know what you're doing)
else
. = TRUE
var/atom/oldloc = loc
var/area/old_area = get_area(oldloc)
oldloc.Exited(src, null)
if(old_area)
old_area.Exited(src, null)
if (loc)
var/atom/oldloc = loc
var/area/old_area = get_area(oldloc)
oldloc.Exited(src, null)
if(old_area)
old_area.Exited(src, null)
loc = null
/mob/living/forceMove(atom/destination)
stop_pulling()
if(buckled)
buckled.unbuckle_mob(src, force = TRUE)
if(has_buckled_mobs())
unbuckle_all_mobs(force = TRUE)
. = ..()
if(.)
if(client)
reset_perspective(destination)
update_canmove() //if the mob was asleep inside a container and then got forceMoved out we need to make them fall.
/mob/living/brain/forceMove(atom/destination)
if(container)
return container.forceMove(destination)
else //something went very wrong.
CRASH("Brainmob without container.")
/atom/movable/proc/onTransitZ(old_z,new_z)
for (var/item in src) // Notify contents of Z-transition. This can be overridden IF we know the items contents do not care.
var/atom/movable/AM = item
AM.onTransitZ(old_z,new_z)
//Called whenever an object moves and by mobs when they attempt to move themselves through space
//And when an object or action applies a force on src, see newtonian_move() below
@@ -420,7 +414,7 @@
for(var/m in buckled_mobs)
var/mob/living/buckled_mob = m
if(!buckled_mob.Move(newloc, direct))
loc = buckled_mob.loc
forceMove(buckled_mob.loc)
last_move = buckled_mob.last_move
inertia_dir = last_move
buckled_mob.inertia_dir = last_move
@@ -522,6 +516,7 @@
. = ..()
. -= "Jump to"
.["Follow"] = "?_src_=holder;[HrefToken()];adminplayerobservefollow=[REF(src)]"
.["Get"] = "?_src=holder;[HrefToken()];admingetmovable=[REF(src)]"
/atom/movable/proc/ex_check(ex_id)
if(!ex_id)
+3
View File
@@ -60,6 +60,9 @@
/datum/atom_hud/data/bot_path
hud_icons = list(DIAG_PATH_HUD)
/datum/atom_hud/abductor
hud_icons = list(GLAND_HUD)
/* MED/SEC/DIAG HUD HOOKS */
/*
+28 -23
View File
@@ -4,7 +4,7 @@
w_class = WEIGHT_CLASS_TINY
var/used = 0
/obj/item/antag_spawner/proc/spawn_antag(client/C, turf/T, type = "")
/obj/item/antag_spawner/proc/spawn_antag(client/C, turf/T, kind = "", datum/mind/user)
return
/obj/item/antag_spawner/proc/equip_antag(mob/target)
@@ -67,18 +67,16 @@
else
to_chat(H, "Unable to reach your apprentice! You can either attack the spellbook with the contract to refund your points, or wait and try again later.")
/obj/item/antag_spawner/contract/spawn_antag(client/C, turf/T, school,datum/mind/user)
/obj/item/antag_spawner/contract/spawn_antag(client/C, turf/T, kind ,datum/mind/user)
new /obj/effect/particle_effect/smoke(T)
var/mob/living/carbon/human/M = new/mob/living/carbon/human(T)
C.prefs.copy_to(M)
M.key = C.key
var/datum/mind/app_mind = M.mind
var/datum/antagonist/wizard/apprentice/app = new(app_mind)
app.master = user
app.school = school
app.school = kind
var/datum/antagonist/wizard/master_wizard = user.has_antag_datum(/datum/antagonist/wizard)
if(master_wizard)
@@ -107,7 +105,7 @@
if(used)
to_chat(user, "<span class='warning'>[src] is out of power!</span>")
return FALSE
if(!(user.mind in SSticker.mode.syndicates))
if(!user.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE))
to_chat(user, "<span class='danger'>AUTHENTICATION FAILURE. ACCESS DENIED.</span>")
return FALSE
if(user.z != ZLEVEL_CENTCOM)
@@ -127,25 +125,25 @@
return
used = TRUE
var/mob/dead/observer/theghost = pick(nuke_candidates)
spawn_antag(theghost.client, get_turf(src), "syndieborg", user)
spawn_antag(theghost.client, get_turf(src), "syndieborg")
do_sparks(4, TRUE, src)
qdel(src)
else
to_chat(user, "<span class='warning'>Unable to connect to Syndicate command. Please wait and try again later or use the teleporter on your uplink to get your points refunded.</span>")
/obj/item/antag_spawner/nuke_ops/spawn_antag(client/C, turf/T)
/obj/item/antag_spawner/nuke_ops/spawn_antag(client/C, turf/T, kind, datum/mind/user)
var/mob/living/carbon/human/M = new/mob/living/carbon/human(T)
C.prefs.copy_to(M)
M.key = C.key
var/code = "BOMB-NOT-FOUND"
var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list
if(nuke)
code = nuke.r_code
M.mind.make_Nuke(null, code, 0, FALSE)
var/newname = M.dna.species.random_name(M.gender,0,SSticker.mode.nukeops_lastname)
M.mind.name = newname
M.real_name = newname
M.name = newname
var/datum/antagonist/nukeop/new_op = new(M.mind)
new_op.send_to_spawnpoint = FALSE
new_op.nukeop_outfit = /datum/outfit/syndicate/no_crystals
var/datum/antagonist/nukeop/creator_op = user.has_antag_datum(/datum/antagonist/nukeop,TRUE)
if(creator_op)
M.mind.add_antag_datum(new_op,creator_op.nuke_team)
M.mind.special_role = "Nuclear Operative"
//////SYNDICATE BORG
/obj/item/antag_spawner/nuke_ops/borg_tele
@@ -162,8 +160,12 @@
name = "syndicate medical teleporter"
borg_to_spawn = "Medical"
/obj/item/antag_spawner/nuke_ops/borg_tele/spawn_antag(client/C, turf/T)
/obj/item/antag_spawner/nuke_ops/borg_tele/spawn_antag(client/C, turf/T, kind, datum/mind/user)
var/mob/living/silicon/robot/R
var/datum/antagonist/nukeop/creator_op = user.has_antag_datum(/datum/antagonist/nukeop,TRUE)
if(!creator_op)
return
switch(borg_to_spawn)
if("Medical")
R = new /mob/living/silicon/robot/modules/syndicate/medical(T)
@@ -174,8 +176,8 @@
if(prob(50))
brainfirstname = pick(GLOB.first_names_female)
var/brainopslastname = pick(GLOB.last_names)
if(SSticker.mode.nukeops_lastname) //the brain inside the syndiborg has the same last name as the other ops.
brainopslastname = SSticker.mode.nukeops_lastname
if(creator_op.nuke_team.syndicate_name) //the brain inside the syndiborg has the same last name as the other ops.
brainopslastname = creator_op.nuke_team.syndicate_name
var/brainopsname = "[brainfirstname] [brainopslastname]"
R.mmi.name = "Man-Machine Interface: [brainopsname]"
@@ -185,7 +187,11 @@
R.real_name = R.name
R.key = C.key
R.mind.make_Nuke(null, nuke_code = null,leader=0, telecrystals = TRUE)
var/datum/antagonist/nukeop/new_borg = new(R.mind)
new_borg.send_to_spawnpoint = FALSE
R.mind.add_antag_datum(new_borg,creator_op.nuke_team)
R.mind.special_role = "Syndicate Cyborg"
///////////SLAUGHTER DEMON
@@ -222,8 +228,7 @@
to_chat(user, "<span class='notice'>You can't seem to work up the nerve to shatter the bottle. Perhaps you should try again later.</span>")
/obj/item/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, type = "")
/obj/item/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, kind = "", datum/mind/user)
var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(T)
var/mob/living/simple_animal/slaughter/S = new demon_type(holder)
S.holder = holder
+1 -1
View File
@@ -42,7 +42,7 @@
/mob/living/simple_animal/hostile/blob/fire_act(exposed_temperature, exposed_volume)
..()
if(exposed_temperature)
adjustFireLoss(Clamp(0.01 * exposed_temperature, 1, 5))
adjustFireLoss(CLAMP(0.01 * exposed_temperature, 1, 5))
else
adjustFireLoss(5)
+3 -3
View File
@@ -153,7 +153,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
B.hud_used.blobpwrdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#82ed00'>[round(blob_core.obj_integrity)]</font></div>"
/mob/camera/blob/proc/add_points(points)
blob_points = Clamp(blob_points + points, 0, max_blob_points)
blob_points = CLAMP(blob_points + points, 0, max_blob_points)
hud_used.blobpwrdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='#82ed00'>[round(blob_points)]</font></div>"
/mob/camera/blob/say(message)
@@ -215,12 +215,12 @@ GLOBAL_LIST_EMPTY(blob_nodes)
if(placed)
var/obj/structure/blob/B = locate() in range("3x3", NewLoc)
if(B)
loc = NewLoc
forceMove(NewLoc)
else
return 0
else
var/area/A = get_area(NewLoc)
if(isspaceturf(NewLoc) || istype(A, /area/shuttle)) //if unplaced, can't go on shuttles or space tiles
return 0
loc = NewLoc
forceMove(NewLoc)
return 1
+2 -2
View File
@@ -42,7 +42,7 @@
return 0
else if(placement_override == 1)
var/turf/T = pick(GLOB.blobstart)
loc = T //got overrided? you're somewhere random, motherfucker
forceMove(T) //got overrided? you're somewhere random, motherfucker
if(placed && blob_core)
blob_core.forceMove(loc)
else
@@ -74,7 +74,7 @@
var/node_name = input(src, "Choose a node to jump to.", "Node Jump") in nodes
var/obj/structure/blob/node/chosen_node = nodes[node_name]
if(chosen_node)
loc = chosen_node.loc
forceMove(chosen_node.loc)
/mob/camera/blob/proc/createSpecial(price, blobType, nearEquals, needsNode, turf/T)
if(!T)
@@ -207,7 +207,7 @@
to_chat(cyborg, "<span class='brass'>You start to charge from the [sigil_name]...</span>")
if(!do_after(cyborg, 50, target = src, extra_checks = CALLBACK(src, .proc/cyborg_checks, cyborg, TRUE)))
return
var/giving_power = min(Floor(cyborg.cell.maxcharge - cyborg.cell.charge, MIN_CLOCKCULT_POWER), get_clockwork_power()) //give the borg either all our power or their missing power floored to MIN_CLOCKCULT_POWER
var/giving_power = min(FLOOR(cyborg.cell.maxcharge - cyborg.cell.charge, MIN_CLOCKCULT_POWER), get_clockwork_power()) //give the borg either all our power or their missing power floored to MIN_CLOCKCULT_POWER
if(adjust_clockwork_power(-giving_power))
cyborg.visible_message("<span class='warning'>[cyborg] glows a brilliant orange!</span>")
var/previous_color = cyborg.color
@@ -310,7 +310,7 @@
else
if(L.stat == DEAD)
var/revival_cost = revive_cost
if(GLOB.ratvar_awakens)
if(GLOB.ratvar_awakens || L.suiciding) // No cost if Ratvar is summoned or if you're reviving a convert who suicided
revival_cost = 0
var/mob/dead/observer/ghost = L.get_ghost(TRUE)
if(GLOB.clockwork_vitality >= revival_cost && (ghost || (L.mind && L.mind.active)))
@@ -323,6 +323,20 @@
L.visible_message("<span class='warning'>[L] suddenly gets back up, [L.p_their()] body dripping blue ichor!</span>", "<span class='inathneq'>\"[text2ratvar("You will be okay, child.")]\"</span>")
GLOB.clockwork_vitality -= revival_cost
break
if(!L.client || L.client.is_afk())
set waitfor = FALSE
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [L.name], an inactive clock cultist?", "[name]", null, "Clock Cultist", 50, L)
var/mob/dead/observer/theghost = null
if(candidates.len)
to_chat(L, "Your physical form has been taken over by another soul due to your inactivity! Ahelp if you wish to regain your form!")
message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(L)]) to replace an inactive clock cultist.")
L.ghostize(0)
L.key = theghost.key
var/obj/effect/temp_visual/ratvar/sigil/vitality/V = new /obj/effect/temp_visual/ratvar/sigil/vitality(get_turf(src))
animate(V, alpha = 0, transform = matrix()*2, time = 8)
playsound(L, 'sound/magic/staff_healing.ogg', 50, 1)
L.visible_message("<span class='warning'>[L]'s eyes suddenly open wide, gleaming with renewed vigor for the cause!</span>", "<span class='inathneq'>\"[text2ratvar("Awaken!")]\"</span>")
break
var/vitality_for_cycle = 3
if(!GLOB.ratvar_awakens)
if(L.stat == CONSCIOUS)
@@ -90,7 +90,7 @@
if(amount_temp < 2)
to_chat(user, "<span class='warning'>You need at least <b>2</b> floor tiles to convert into power.</span>")
return TRUE
if(IsOdd(amount_temp))
if(ISODD(amount_temp))
amount_temp--
no_delete = TRUE
use(amount_temp)
@@ -239,7 +239,7 @@
if(!do_after(user, repair_values["healing_for_cycle"] * fabricator.speed_multiplier, target = src, \
extra_checks = CALLBACK(fabricator, /obj/item/clockwork/replica_fabricator.proc/fabricator_repair_checks, repair_values, src, user, TRUE)))
break
obj_integrity = Clamp(obj_integrity + repair_values["healing_for_cycle"], 0, max_integrity)
obj_integrity = CLAMP(obj_integrity + repair_values["healing_for_cycle"], 0, max_integrity)
adjust_clockwork_power(-repair_values["power_required"])
playsound(src, 'sound/machines/click.ogg', 50, 1)
@@ -10,12 +10,15 @@
for(var/obj/effect/clockwork/sigil/transmission/T in GLOB.all_clockwork_objects)
T.update_icon()
var/power_overwhelming = GLOB.clockwork_power
var/unlock_message
if(power_overwhelming >= SCRIPT_UNLOCK_THRESHOLD && !GLOB.script_scripture_unlocked)
GLOB.script_scripture_unlocked = TRUE
hierophant_message("<span class='large_brass bold'>The Ark swells as a key power threshold is reached. Script scriptures are now available.</span>")
unlock_message = "<span class='large_brass bold'>The Ark swells as a key power threshold is reached. Script scriptures are now available.</span>"
if(power_overwhelming >= APPLICATION_UNLOCK_THRESHOLD && !GLOB.application_scripture_unlocked)
GLOB.application_scripture_unlocked = TRUE
hierophant_message("<span class='large_brass bold'>The Ark surges as a key power threshold is reached. Application scriptures are now available.</span>")
unlock_message = "<span class='large_brass bold'>The Ark surges as a key power threshold is reached. Application scriptures are now available.</span>"
if(GLOB.servants_active)
hierophant_message(unlock_message)
return TRUE
/proc/can_access_clockwork_power(atom/movable/access_point, amount) //Returns true if the access point has access to clockwork power (and optionally, a number of watts for it)
@@ -11,6 +11,8 @@
//reports to servants when scripture is locked or unlocked
/proc/scripture_unlock_alert(list/previous_states)
if(!GLOB.servants_active)
return
. = scripture_unlock_check()
for(var/i in .)
if(.[i] != previous_states[i])
@@ -67,7 +67,6 @@
name = "replicant manacles"
desc = "Heavy manacles made out of freezing-cold metal. It looks like brass, but feels much more solid."
icon_state = "brass_manacles"
origin_tech = "materials=2;magnets=5"
flags_1 = DROPDEL_1
/obj/item/restraints/handcuffs/clockwork/dropped(mob/user)
@@ -1,13 +1,13 @@
#define MARAUDER_SLOWDOWN_PERCENTAGE 0.40 //Below this percentage of health, marauders will become slower
#define MARAUDER_SHIELD_REGEN_TIME 100 //In deciseconds, how long it takes for shields to regenerate after breaking
#define MARAUDER_SHIELD_REGEN_TIME 200 //In deciseconds, how long it takes for shields to regenerate after breaking
//Clockwork marauder: A well-rounded frontline construct. Only one can exist for every two human servants.
/mob/living/simple_animal/hostile/clockwork/marauder
name = "clockwork marauder"
desc = "The stalwart apparition of a soldier, blazing with crimson flames. It's armed with a gladius and shield."
icon_state = "clockwork_marauder"
health = 150
maxHealth = 150
health = 120
maxHealth = 120
force_threshold = 8
speed = 0
obj_damage = 40
@@ -39,10 +39,11 @@
speed = initial(speed) + 1 //Yes, this slows them down
else
speed = initial(speed)
if(shield_health != max_shield_health && world.time >= shield_health_regen)
to_chat(src, "<span class='neovgre'>Your shield has recovered. <b>[max_shield_health]</b> blocks remaining!</span>")
if(shield_health < max_shield_health && world.time >= shield_health_regen)
shield_health_regen = world.time + MARAUDER_SHIELD_REGEN_TIME
to_chat(src, "<span class='neovgre'>Your shield has recovered, <b>[shield_health]</b> blocks remaining!</span>")
playsound_local(src, "shatter", 75, TRUE, frequency = -1)
shield_health = max_shield_health
shield_health++
/mob/living/simple_animal/hostile/clockwork/marauder/update_values()
if(GLOB.ratvar_awakens) //Massive attack damage bonuses and health increase, because Ratvar
@@ -97,7 +97,7 @@
if(ishuman(M.current))
human_servants++
construct_limit = human_servants / 4 //1 per 4 human servants, and a maximum of 3 marauders
construct_limit = Clamp(construct_limit, 1, 3)
construct_limit = CLAMP(construct_limit, 1, 3)
/datum/clockwork_scripture/create_object/construct/clockwork_marauder/pre_recital()
channel_time = initial(channel_time)
@@ -60,4 +60,4 @@
break
if(!M)
M = H.apply_status_effect(STATUS_EFFECT_MANIAMOTOR, src)
M.severity = Clamp(M.severity + ((11 - get_dist(src, H)) * efficiency * efficiency), 0, MAX_MANIA_SEVERITY)
M.severity = CLAMP(M.severity + ((11 - get_dist(src, H)) * efficiency * efficiency), 0, MAX_MANIA_SEVERITY)
@@ -57,5 +57,5 @@
L.confused = min(L.confused + 15, 50)
L.dizziness = min(L.dizziness + 15, 50)
if(L.confused >= 25)
L.Knockdown(Floor(L.confused * 0.8))
L.Knockdown(FLOOR(L.confused * 0.8, 1))
take_damage(max_integrity)
+24 -13
View File
@@ -510,10 +510,10 @@ structure_check() searches for nearby cultist structures required for the invoca
message_admins("[key_name_admin(user)] erased a Narsie rune with a null rod")
..()
//Rite of Resurrection: Requires the corpse of a cultist and that there have been less revives than the number of people GLOB.sacrificed
//Rite of Resurrection: Requires a dead or inactive cultist. When reviving the dead, you can only perform one revival for every sacrifice your cult has carried out.
/obj/effect/rune/raise_dead
cultist_name = "Resurrect Cultist"
cultist_desc = "requires the corpse of a cultist placed upon the rune. Provided there have been sufficient sacrifices, they will be revived."
cultist_name = "Revive Cultist"
cultist_desc = "requires a dead, mindless, or inactive cultist placed upon the rune. Provided there have been sufficient sacrifices, they will be given a new life."
invocation = "Pasnar val'keriam usinar. Savrae ines amutan. Yam'toth remium il'tarat!" //Depends on the name of the user - see below
icon_state = "1"
color = RUNE_COLOR_MEDIUMRED
@@ -534,16 +534,11 @@ structure_check() searches for nearby cultist structures required for the invoca
return
rune_in_use = TRUE
for(var/mob/living/M in T.contents)
if(iscultist(M) && M.stat == DEAD)
if(iscultist(M) && (M.stat == DEAD || !M.client || M.client.is_afk()))
potential_revive_mobs |= M
if(!potential_revive_mobs.len)
to_chat(user, "<span class='cultitalic'>There are no dead cultists on the rune!</span>")
log_game("Raise Dead rune failed - no corpses to revive")
fail_invoke()
rune_in_use = FALSE
return
if(LAZYLEN(GLOB.sacrificed) <= revives_used)
to_chat(user, "<span class='warning'>You have sacrificed too few people to revive a cultist!</span>")
log_game("Raise Dead rune failed - no cultists to revive")
fail_invoke()
rune_in_use = FALSE
return
@@ -559,9 +554,25 @@ structure_check() searches for nearby cultist structures required for the invoca
else
invocation = initial(invocation)
..()
revives_used++
mob_to_revive.revive(1, 1) //This does remove disabilities and such, but the rune might actually see some use because of it!
mob_to_revive.grab_ghost()
if(mob_to_revive.stat == DEAD)
if(LAZYLEN(GLOB.sacrificed) <= revives_used)
to_chat(user, "<span class='warning'>Your cult must carry out another sacrifice before it can revive a cultist!</span>")
fail_invoke()
rune_in_use = FALSE
return
revives_used++
mob_to_revive.revive(1, 1) //This does remove disabilities and such, but the rune might actually see some use because of it!
mob_to_revive.grab_ghost()
else if(!mob_to_revive.client || mob_to_revive.client.is_afk())
set waitfor = FALSE
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [mob_to_revive.name], an inactive blood cultist?", "[name]", null, "Blood Cultist", 50, mob_to_revive)
var/mob/dead/observer/theghost = null
if(candidates.len)
theghost = pick(candidates)
to_chat(mob_to_revive.mind, "Your physical form has been taken over by another soul due to your inactivity! Ahelp if you wish to regain your form.")
message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(mob_to_revive)]) to replace an AFK player.")
mob_to_revive.ghostize(0)
mob_to_revive.key = theghost.key
to_chat(mob_to_revive, "<span class='cultlarge'>\"PASNAR SAVRAE YAM'TOTH. Arise.\"</span>")
mob_to_revive.visible_message("<span class='warning'>[mob_to_revive] draws in a huge breath, red light shining from [mob_to_revive.p_their()] eyes.</span>", \
"<span class='cultlarge'>You awaken suddenly from the void. You're alive!</span>")
-1
View File
@@ -338,7 +338,6 @@
name = "cult shackles"
desc = "Shackles that bind the wrists with sinister magic."
trashtype = /obj/item/restraints/handcuffs/energy/used
origin_tech = "materials=2;magnets=5"
flags_1 = DROPDEL_1
/obj/item/restraints/handcuffs/energy/cult/used/dropped(mob/user)
+2
View File
@@ -19,6 +19,7 @@
var/probability = 0
var/false_report_weight = 0 //How often will this show up incorrectly in a centcom report?
var/station_was_nuked = 0 //see nuclearbomb.dm and malfunction.dm
var/nuke_off_station = 0 //Used for tracking where the nuke hit
var/round_ends_with_antag_death = 0 //flags the "one verse the station" antags as such
var/list/datum/mind/antag_candidates = list() // List of possible starting antags goes here
var/list/restricted_jobs = list() // Jobs it doesn't make sense to be. I.E chaplain or AI cultist
@@ -448,6 +449,7 @@
//By default nuke just ends the round
/datum/game_mode/proc/OnNukeExplosion(off_station)
nuke_off_station = off_station
if(off_station < 2)
station_was_nuked = TRUE //Will end the round on next check.
-1
View File
@@ -2,7 +2,6 @@
* Gang Boss Pens
*/
/obj/item/pen/gang
origin_tech = "materials=2;syndicate=3"
var/cooldown
var/last_used = 0
var/charges = 1
-1
View File
@@ -11,7 +11,6 @@
throw_speed = 3
throw_range = 7
flags_1 = CONDUCT_1
origin_tech = "programming=5;bluespace=2;syndicate=5"
var/datum/gang/gang //Which gang uses this?
var/recalling = 0
var/outfits = 2
+1 -1
View File
@@ -25,7 +25,7 @@
if (prob(meteorminutes/2))
wavetype = GLOB.meteors_catastrophic
var/ramp_up_final = Clamp(round(meteorminutes/rampupdelta), 1, 10)
var/ramp_up_final = CLAMP(round(meteorminutes/rampupdelta), 1, 10)
spawn_meteors(ramp_up_final, wavetype)
@@ -2,6 +2,8 @@
#define VEST_COMBAT 2
#define GIZMO_SCAN 1
#define GIZMO_MARK 2
#define MIND_DEVICE_MESSAGE 1
#define MIND_DEVICE_CONTROL 2
//AGENT VEST
/obj/item/clothing/suit/armor/abductor/vest
@@ -11,7 +13,6 @@
icon_state = "vest_stealth"
item_state = "armor"
blood_overlay_type = "armor"
origin_tech = "magnets=7;biotech=4;powerstorage=4;abductor=4"
armor = list(melee = 15, bullet = 15, laser = 15, energy = 15, bomb = 15, bio = 15, rad = 15, fire = 70, acid = 70)
actions_types = list(/datum/action/item_action/hands_free/activate)
allowed = list(
@@ -155,7 +156,6 @@
item_state = "silencer"
lefthand_file = 'icons/mob/inhands/antag/abductor_lefthand.dmi'
righthand_file = 'icons/mob/inhands/antag/abductor_righthand.dmi'
origin_tech = "engineering=7;magnets=4;bluespace=4;abductor=3"
var/mode = GIZMO_SCAN
var/mob/living/marked = null
var/obj/machinery/abductor/console/console
@@ -244,7 +244,6 @@
item_state = "gizmo"
lefthand_file = 'icons/mob/inhands/antag/abductor_lefthand.dmi'
righthand_file = 'icons/mob/inhands/antag/abductor_righthand.dmi'
origin_tech = "materials=4;programming=7;abductor=3"
/obj/item/device/abductor/silencer/attack(mob/living/M, mob/user)
if(!AbductorCheck(user))
@@ -281,6 +280,84 @@
if(!istype(I, /obj/item/device/radio/headset))
r.broadcasting = 0 //goddamned headset hacks
/obj/item/device/abductor/mind_device
name = "mental interface device"
desc = "A dual-mode tool for directly communicating with sentient brains. It can be used to send a direct message to a target, \
or to send a command to a test subject with a charged gland."
icon_state = "mind_device_message"
item_state = "silencer"
lefthand_file = 'icons/mob/inhands/antag/abductor_lefthand.dmi'
righthand_file = 'icons/mob/inhands/antag/abductor_righthand.dmi'
var/mode = MIND_DEVICE_MESSAGE
/obj/item/device/abductor/mind_device/attack_self(mob/user)
if(!ScientistCheck(user))
return
if(mode == MIND_DEVICE_MESSAGE)
mode = MIND_DEVICE_CONTROL
icon_state = "mind_device_control"
else
mode = MIND_DEVICE_MESSAGE
icon_state = "mind_device_message"
to_chat(user, "<span class='notice'>You switch the device to [mode==MIND_DEVICE_MESSAGE? "TRANSMISSION": "COMMAND"] MODE</span>")
/obj/item/device/abductor/mind_device/afterattack(atom/target, mob/living/user, flag, params)
if(!ScientistCheck(user))
return
switch(mode)
if(MIND_DEVICE_CONTROL)
mind_control(target, user)
if(MIND_DEVICE_MESSAGE)
mind_message(target, user)
/obj/item/device/abductor/mind_device/proc/mind_control(atom/target, mob/living/user)
if(iscarbon(target))
var/mob/living/carbon/C = target
var/obj/item/organ/heart/gland/G = C.getorganslot("heart")
if(!istype(G))
to_chat(user, "<span class='warning'>Your target does not have an experimental gland!</span>")
return
if(!G.mind_control_uses)
to_chat(user, "<span class='warning'>Your target's gland is spent!</span>")
return
if(G.active_mind_control)
to_chat(user, "<span class='warning'>Your target is already under a mind-controlling influence!</span>")
return
var/command = stripped_input(user, "Enter the command for your target to follow.\
Uses Left: [G.mind_control_uses], Duration: [G.mind_control_duration / 10] seconds","Enter command")
if(!command)
return
if(QDELETED(user) || user.get_active_held_item() != src || loc != user)
return
if(QDELETED(G))
return
G.mind_control(command, user)
to_chat(user, "<span class='notice'>You send the command to your target.</span>")
/obj/item/device/abductor/mind_device/proc/mind_message(atom/target, mob/living/user)
if(isliving(target))
var/mob/living/L = target
if(L.stat == DEAD)
to_chat(user, "<span class='warning'>Your target is dead!</span>")
return
var/message = stripped_input(user, "Write a message to send to your target's brain.","Enter message")
if(!message)
return
if(QDELETED(L) || L.stat == DEAD)
return
to_chat(L, "<span class='italics'>You hear a voice in your head saying: </span><span class='abductor'>[message]</span>")
to_chat(user, "<span class='notice'>You send the message to your target.</span>")
log_talk(user,"[key_name(user)] sent an abductor mind message to [L]/[L.ckey]: '[message]'", LOGSAY)
/obj/item/device/firing_pin/abductor
name = "alien firing pin"
icon_state = "firing_pin_ayy"
@@ -299,7 +376,6 @@
pin = /obj/item/device/firing_pin/abductor
icon_state = "alienpistol"
item_state = "alienpistol"
origin_tech = "combat=4;magnets=7;powerstorage=3;abductor=3"
trigger_guard = TRIGGER_GUARD_ALLOW_ALL
/obj/item/paper/guides/antag/abductor
@@ -346,7 +422,6 @@ Congratulations! You are now trained for invasive xenobiology research!"}
lefthand_file = 'icons/mob/inhands/antag/abductor_lefthand.dmi'
righthand_file = 'icons/mob/inhands/antag/abductor_righthand.dmi'
slot_flags = SLOT_BELT
origin_tech = "materials=4;combat=4;biotech=7;abductor=4"
force = 7
w_class = WEIGHT_CLASS_NORMAL
actions_types = list(/datum/action/item_action/toggle_mode)
@@ -496,7 +571,6 @@ Congratulations! You are now trained for invasive xenobiology research!"}
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
breakouttime = 450
trashtype = /obj/item/restraints/handcuffs/energy/used
origin_tech = "materials=4;magnets=5;abductor=2"
/obj/item/restraints/handcuffs/energy/used
flags_1 = DROPDEL_1
@@ -524,7 +598,6 @@ Congratulations! You are now trained for invasive xenobiology research!"}
/obj/item/device/radio/headset/abductor
name = "alien headset"
desc = "An advanced alien headset designed to monitor communications of human space stations. Why does it have a microphone? No one knows."
origin_tech = "magnets=2;abductor=3"
icon = 'icons/obj/abductor.dmi'
icon_state = "abductor_headset"
item_state = "abductor_headset"
@@ -545,35 +618,30 @@ Congratulations! You are now trained for invasive xenobiology research!"}
name = "alien scalpel"
desc = "It's a gleaming sharp knife made out of silvery-green metal."
icon = 'icons/obj/abductor.dmi'
origin_tech = "materials=2;biotech=2;abductor=2"
toolspeed = 0.25
/obj/item/hemostat/alien
name = "alien hemostat"
desc = "You've never seen this before."
icon = 'icons/obj/abductor.dmi'
origin_tech = "materials=2;biotech=2;abductor=2"
toolspeed = 0.25
/obj/item/retractor/alien
name = "alien retractor"
desc = "You're not sure if you want the veil pulled back."
icon = 'icons/obj/abductor.dmi'
origin_tech = "materials=2;biotech=2;abductor=2"
toolspeed = 0.25
/obj/item/circular_saw/alien
name = "alien saw"
desc = "Do the aliens also lose this, and need to find an alien hatchet?"
icon = 'icons/obj/abductor.dmi'
origin_tech = "materials=2;biotech=2;abductor=2"
toolspeed = 0.25
/obj/item/surgicaldrill/alien
name = "alien drill"
desc = "Maybe alien surgeons have finally found a use for the drill."
icon = 'icons/obj/abductor.dmi'
origin_tech = "materials=2;biotech=2;abductor=2"
toolspeed = 0.25
/obj/item/cautery/alien
@@ -581,7 +649,6 @@ Congratulations! You are now trained for invasive xenobiology research!"}
desc = "Why would bloodless aliens have a tool to stop bleeding? \
Unless..."
icon = 'icons/obj/abductor.dmi'
origin_tech = "materials=2;biotech=2;abductor=2"
toolspeed = 0.25
/obj/item/clothing/head/helmet/abductor
@@ -590,7 +657,6 @@ Congratulations! You are now trained for invasive xenobiology research!"}
icon_state = "alienhelmet"
item_state = "alienhelmet"
blockTracking = 1
origin_tech = "materials=7;magnets=4;abductor=3"
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
// Operating Table / Beds / Lockers
@@ -4,7 +4,6 @@
icon = 'icons/obj/abductor.dmi'
icon_state = "gland"
status = ORGAN_ROBOTIC
origin_tech = "materials=4;biotech=7;abductor=3"
beating = TRUE
var/cooldown_low = 300
var/cooldown_high = 300
@@ -13,28 +12,68 @@
var/human_only = 0
var/active = 0
var/mind_control_uses = 1
var/mind_control_duration = 1800
var/active_mind_control = FALSE
/obj/item/organ/heart/gland/proc/ownerCheck()
if(ishuman(owner))
return 1
return TRUE
if(!human_only && iscarbon(owner))
return 1
return 0
return TRUE
return FALSE
/obj/item/organ/heart/gland/proc/Start()
active = 1
next_activation = world.time + rand(cooldown_low,cooldown_high)
/obj/item/organ/heart/gland/proc/update_gland_hud()
if(!owner)
return
var/image/holder = owner.hud_list[GLAND_HUD]
var/icon/I = icon(owner.icon, owner.icon_state, owner.dir)
holder.pixel_y = I.Height() - world.icon_size
if(active_mind_control)
holder.icon_state = "hudgland_active"
else if(mind_control_uses)
holder.icon_state = "hudgland_ready"
else
holder.icon_state = "hudgland_spent"
/obj/item/organ/heart/gland/Remove(var/mob/living/carbon/M, special = 0)
/obj/item/organ/heart/gland/proc/mind_control(command, mob/living/user)
if(!ownerCheck() || !mind_control_uses || active_mind_control)
return
mind_control_uses--
to_chat(owner, "<span class='userdanger'>You suddenly feel an irresistible compulsion to follow an order...</span>")
to_chat(owner, "<span class='mind_control'>[command]</span>")
active_mind_control = TRUE
log_admin("[key_name(user)] sent an abductor mind control message to [key_name(owner)]: [command]")
update_gland_hud()
addtimer(CALLBACK(src, .proc/clear_mind_control), mind_control_duration)
/obj/item/organ/heart/gland/proc/clear_mind_control()
if(!ownerCheck() || !active_mind_control)
return
to_chat(owner, "<span class='userdanger'>You feel the compulsion fade, and you completely forget about your previous orders.</span>")
active_mind_control = FALSE
/obj/item/organ/heart/gland/Remove(mob/living/carbon/M, special = 0)
active = 0
if(initial(uses) == 1)
uses = initial(uses)
var/datum/atom_hud/abductor/hud = GLOB.huds[DATA_HUD_ABDUCTOR]
hud.remove_from_hud(owner)
clear_mind_control()
..()
/obj/item/organ/heart/gland/Insert(var/mob/living/carbon/M, special = 0)
/obj/item/organ/heart/gland/Insert(mob/living/carbon/M, special = 0)
..()
if(special != 2 && uses) // Special 2 means abductor surgery
Start()
var/datum/atom_hud/abductor/hud = GLOB.huds[DATA_HUD_ABDUCTOR]
hud.add_to_hud(owner)
update_gland_hud()
/obj/item/organ/heart/gland/on_life()
if(!beating)
@@ -60,6 +99,8 @@
cooldown_high = 400
uses = -1
icon_state = "health"
mind_control_uses = 3
mind_control_duration = 3000
/obj/item/organ/heart/gland/heals/activate()
to_chat(owner, "<span class='notice'>You feel curiously revitalized.</span>")
@@ -72,6 +113,8 @@
cooldown_high = 1200
uses = -1
icon_state = "slime"
mind_control_uses = 1
mind_control_duration = 2400
/obj/item/organ/heart/gland/slime/activate()
to_chat(owner, "<span class='warning'>You feel nauseous!</span>")
@@ -83,11 +126,12 @@
Slime.Leader = owner
/obj/item/organ/heart/gland/mindshock
origin_tech = "materials=4;biotech=4;magnets=6;abductor=3"
cooldown_low = 300
cooldown_high = 300
uses = -1
icon_state = "mindshock"
mind_control_uses = 1
mind_control_duration = 6000
/obj/item/organ/heart/gland/mindshock/activate()
to_chat(owner, "<span class='notice'>You get a headache.</span>")
@@ -105,6 +149,8 @@
uses = -1
human_only = 1
icon_state = "species"
mind_control_uses = 5
mind_control_duration = 300
/obj/item/organ/heart/gland/pop/activate()
to_chat(owner, "<span class='notice'>You feel unlike yourself.</span>")
@@ -112,11 +158,12 @@
owner.set_species(species)
/obj/item/organ/heart/gland/ventcrawling
origin_tech = "materials=4;biotech=5;bluespace=4;abductor=3"
cooldown_low = 1800
cooldown_high = 2400
uses = 1
icon_state = "vent"
mind_control_uses = 4
mind_control_duration = 1800
/obj/item/organ/heart/gland/ventcrawling/activate()
to_chat(owner, "<span class='notice'>You feel very stretchy.</span>")
@@ -128,6 +175,8 @@
cooldown_high = 2400
uses = 1
icon_state = "viral"
mind_control_uses = 1
mind_control_duration = 1800
/obj/item/organ/heart/gland/viral/activate()
to_chat(owner, "<span class='warning'>You feel sick.</span>")
@@ -140,11 +189,12 @@
/obj/item/organ/heart/gland/emp //TODO : Replace with something more interesting
origin_tech = "materials=4;biotech=4;magnets=6;abductor=3"
cooldown_low = 900
cooldown_high = 1600
uses = 10
icon_state = "emp"
mind_control_uses = 1
mind_control_duration = 1800
/obj/item/organ/heart/gland/emp/activate()
to_chat(owner, "<span class='warning'>You feel a spike of pain in your head.</span>")
@@ -155,6 +205,8 @@
cooldown_high = 900
uses = 10
icon_state = "spider"
mind_control_uses = 2
mind_control_duration = 2400
/obj/item/organ/heart/gland/spiderman/activate()
to_chat(owner, "<span class='warning'>You feel something crawling in your skin.</span>")
@@ -168,6 +220,8 @@
icon_state = "egg"
lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi'
mind_control_uses = 2
mind_control_duration = 1800
/obj/item/organ/heart/gland/egg/activate()
to_chat(owner, "<span class='boldannounce'>You lay an egg!</span>")
@@ -179,6 +233,8 @@
cooldown_low = 200
cooldown_high = 400
uses = -1
mind_control_uses = 1
mind_control_duration = 450
/obj/item/organ/heart/gland/bloody/activate()
owner.blood_volume -= 20
@@ -196,6 +252,8 @@
cooldown_high = 600
human_only = 1
uses = 1
mind_control_uses = 1
mind_control_duration = 600
/obj/item/organ/heart/gland/bodysnatch/activate()
to_chat(owner, "<span class='warning'>You feel something moving around inside you...</span>")
@@ -229,15 +287,16 @@
STOP_PROCESSING(SSobj, src)
for(var/mob/M in contents)
src.visible_message("<span class='warning'>[src] hatches!</span>")
M.loc = src.loc
M.forceMove(drop_location())
qdel(src)
/obj/item/organ/heart/gland/plasma
cooldown_low = 1200
cooldown_high = 1800
origin_tech = "materials=4;biotech=4;plasmatech=6;abductor=3"
uses = -1
mind_control_uses = 1
mind_control_duration = 800
/obj/item/organ/heart/gland/plasma/activate()
to_chat(owner, "<span class='warning'>You feel bloated.</span>")
@@ -48,6 +48,7 @@
dat += "<a href='?src=[REF(src)];dispense=vest'>Agent Vest</A><br>"
dat += "<a href='?src=[REF(src)];dispense=silencer'>Radio Silencer</A><br>"
dat += "<a href='?src=[REF(src)];dispense=tool'>Science Tool</A><br>"
dat += "<a href='?src=[REF(src)];dispense=mind_device'>Mental Interface Device</A><br>"
else
dat += "<span class='bad'>NO EXPERIMENT MACHINE DETECTED</span> <br>"
@@ -109,6 +110,8 @@
Dispense(/obj/item/device/abductor/gizmo)
if("vest")
Dispense(/obj/item/clothing/suit/armor/abductor/vest)
if("mind_device")
Dispense(/obj/item/device/abductor/mind_device,cost=2)
updateUsrDialog()
/obj/machinery/abductor/console/proc/TeleporterRetrieve()
@@ -4,8 +4,7 @@
desc = "A shell of swarmer that was completely powered down. It can no longer activate itself."
icon = 'icons/mob/swarmer.dmi'
icon_state = "swarmer_unactivated"
origin_tech = "bluespace=4;materials=4;programming=7"
materials = list(MAT_METAL = 10000, MAT_GLASS = 4000)
materials = list(MAT_METAL=10000, MAT_GLASS=4000)
/obj/effect/mob_spawn/swarmer
name = "unactivated swarmer"
@@ -168,9 +167,13 @@
/turf/closed/indestructible/swarmer_act()
return FALSE
/obj/swarmer_act()
/obj/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
if(resistance_flags & INDESTRUCTIBLE)
return FALSE
for(var/mob/living/L in contents)
if(!issilicon(L) && !isbrain(L))
to_chat(S, "<span class='warning'>An organism has been detected inside this object. Aborting.</span>")
return FALSE
return ..()
/obj/item/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
@@ -375,7 +375,7 @@
return
var/key_of_revenant
message_admins("Revenant ectoplasm was left undestroyed for 1 minute and is reforming into a new revenant.")
loc = get_turf(src) //In case it's in a backpack or someone's hand
forceMove(drop_location()) //In case it's in a backpack or someone's hand
revenant.forceMove(loc)
if(client_to_revive)
for(var/mob/M in GLOB.dead_mob_list)
@@ -79,7 +79,6 @@
desc = "Still it beats furiously, emanating an aura of utter hate."
icon = 'icons/obj/surgery.dmi'
icon_state = "demon_heart-on"
origin_tech = "combat=5;biotech=7"
/obj/item/organ/heart/demon/update_icon()
return //always beating visually
+62 -233
View File
@@ -1,7 +1,3 @@
/datum/game_mode
var/list/datum/mind/syndicates = list()
var/nukeops_lastname = ""
/datum/game_mode/nuclear
name = "nuclear emergency"
config_tag = "nuclear"
@@ -18,12 +14,11 @@
<span class='notice'>Crew</span>: Defend the nuclear authentication disk and ensure that it leaves with you on the emergency shuttle."
var/const/agents_possible = 5 //If we ever need more syndicate agents.
var/nukes_left = 1 // Call 3714-PRAY right now and order more nukes! Limited offer!
var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station
var/syndies_didnt_escape = 0 //Used for tracking if the syndies got the shuttle off of the z-level
var/list/pre_nukeops = list()
var/datum/objective_team/nuclear/nuke_team
/datum/game_mode/nuclear/pre_setup()
var/n_agents = min(round(num_players() / 10), antag_candidates.len, agents_possible)
for(var/i = 0, i < n_agents, ++i)
@@ -33,120 +28,23 @@
new_op.special_role = "Nuclear Operative"
log_game("[new_op.key] (ckey) has been selected as a nuclear operative")
return TRUE
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
/datum/game_mode/proc/update_synd_icons_added(datum/mind/synd_mind)
var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS]
opshud.join_hud(synd_mind.current)
set_antag_hud(synd_mind.current, "synd")
/datum/game_mode/proc/update_synd_icons_removed(datum/mind/synd_mind)
var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS]
opshud.leave_hud(synd_mind.current)
set_antag_hud(synd_mind.current, null)
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
/datum/game_mode/nuclear/post_setup()
var/nuke_code = random_nukecode()
var/agent_number = 1
var/datum/mind/leader = pick(pre_nukeops)
syndicates += pre_nukeops
for(var/i = 1 to pre_nukeops.len)
var/datum/mind/op = pre_nukeops[i]
forge_syndicate_objectives(op)
greet_syndicate(op)
equip_syndicate(op.current)
if(nuke_code)
op.store_memory("<B>Syndicate Nuclear Bomb Code</B>: [nuke_code]", 0, 0)
to_chat(op.current, "The nuclear authorization code is: <B>[nuke_code]</B>")
if(op == leader)
op.current.forceMove(pick(GLOB.nukeop_leader_start))
prepare_syndicate_leader(op, nuke_code)
else
op.current.forceMove(GLOB.nukeop_start[((i - 1) % GLOB.nukeop_start.len) + 1])
op.current.real_name = "[syndicate_name()] Operative #[agent_number++]"
update_synd_icons_added(op)
op.current.playsound_local(get_turf(op.current), 'sound/ambience/antag/ops.ogg',100,0)
var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list
if(nuke)
nuke.r_code = nuke_code
//Assign leader
var/datum/mind/leader_mind = pre_nukeops[1]
var/datum/antagonist/nukeop/L = leader_mind.add_antag_datum(/datum/antagonist/nukeop/leader)
nuke_team = L.nuke_team
//Assign the remaining operatives
for(var/i = 2 to pre_nukeops.len)
var/datum/mind/nuke_mind = pre_nukeops[i]
nuke_mind.add_antag_datum(/datum/antagonist/nukeop,nuke_team)
return ..()
/datum/game_mode/proc/prepare_syndicate_leader(datum/mind/synd_mind, nuke_code)
var/leader_title = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord")
addtimer(CALLBACK(src, .proc/nuketeam_name_assign, synd_mind), 1)
synd_mind.current.real_name = "[syndicate_name()] [leader_title]"
to_chat(synd_mind.current, "<B>You are the Syndicate [leader_title] for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors.</B>")
to_chat(synd_mind.current, "<B>If you feel you are not up to this task, give your ID to another operative.</B>")
to_chat(synd_mind.current, "<B>In your hand you will find a special item capable of triggering a greater challenge for your team. Examine it carefully and consult with your fellow operatives before activating it.</B>")
var/obj/item/device/nuclear_challenge/challenge = new /obj/item/device/nuclear_challenge
synd_mind.current.put_in_hands(challenge, TRUE)
var/static/id_cache = typecacheof(/obj/item/card/id)
var/list/foundIDs = typecache_filter_list(synd_mind.current.GetAllContents(), id_cache)
if(foundIDs.len)
for(var/i in 1 to foundIDs.len)
var/obj/item/card/id/ID = foundIDs[i]
ID.name = "lead agent card"
ID.access += ACCESS_SYNDICATE_LEADER
else
message_admins("Warning: Nuke Ops spawned without access to leave their spawn area!")
var/obj/item/device/radio/headset/syndicate/alt/A = locate() in synd_mind.current
if(A)
A.command = TRUE
if(nuke_code)
var/obj/item/paper/P = new
P.info = "The nuclear authorization code is: <b>[nuke_code]</b>"
P.name = "nuclear bomb code"
var/mob/living/carbon/human/H = synd_mind.current
H.put_in_hands(P, TRUE)
H.update_icons()
else
nuke_code = "code will be provided later"
return
/datum/game_mode/proc/nuketeam_name_assign(datum/mind/synd_mind)
nukeops_lastname = nukelastname(synd_mind.current)
NukeNameAssign(nukeops_lastname, syndicates)
/datum/game_mode/proc/forge_syndicate_objectives(datum/mind/syndicate)
var/datum/objective/nuclear/syndobj = new
syndobj.owner = syndicate
syndicate.objectives += syndobj
/datum/game_mode/proc/greet_syndicate(datum/mind/syndicate, you_are=1)
if(you_are)
to_chat(syndicate.current, "<span class='notice'>You are a [syndicate_name()] agent!</span>")
syndicate.announce_objectives()
/datum/game_mode/proc/equip_syndicate(mob/living/carbon/human/synd_mob, telecrystals = TRUE)
synd_mob.set_species(/datum/species/human) //Plasamen burn up otherwise, and lizards are vulnerable to asimov AIs
if(telecrystals)
synd_mob.equipOutfit(/datum/outfit/syndicate)
else
synd_mob.equipOutfit(/datum/outfit/syndicate/no_crystals)
return TRUE
/datum/game_mode/nuclear/OnNukeExplosion(off_station)
..()
nukes_left--
var/obj/docking_port/mobile/Shuttle = SSshuttle.getShuttle("syndicate")
syndies_didnt_escape = (Shuttle && (Shuttle.z == ZLEVEL_CENTCOM || Shuttle.z == ZLEVEL_TRANSIT)) ? 0 : 1
nuke_off_station = off_station
/datum/game_mode/nuclear/check_win()
if (nukes_left == 0)
@@ -154,8 +52,8 @@
return ..()
/datum/game_mode/proc/are_operatives_dead()
for(var/datum/mind/operative_mind in syndicates)
if(ishuman(operative_mind.current) && (operative_mind.current.stat!=2))
for(var/datum/mind/operative_mind in get_antagonists(/datum/antagonist/nukeop))
if(ishuman(operative_mind.current) && (operative_mind.current.stat != DEAD))
return FALSE
return TRUE
@@ -164,7 +62,7 @@
return replacementmode.check_finished()
if((SSshuttle.emergency.mode == SHUTTLE_ENDGAME) || station_was_nuked)
return TRUE
if(are_operatives_dead())
if(nuke_team.operatives_dead())
var/obj/machinery/nuclearbomb/N
pass(N) //suppress unused warning
if(N.bomb_set) //snaaaaaaaaaake! It's not over yet!
@@ -172,85 +70,39 @@
..()
/datum/game_mode/nuclear/declare_completion()
var/disk_rescued = 1
for(var/obj/item/disk/nuclear/D in GLOB.poi_list)
if(!D.onCentCom())
disk_rescued = 0
break
var/crew_evacuated = (SSshuttle.emergency.mode == SHUTTLE_ENDGAME)
if(nuke_off_station == NUKE_SYNDICATE_BASE)
SSticker.mode_result = "loss - syndicate nuked - disk secured"
to_chat(world, "<FONT size = 3><B>Humiliating Syndicate Defeat</B></FONT>")
to_chat(world, "<B>The crew of [station_name()] gave [syndicate_name()] operatives back their bomb! The syndicate base was destroyed!</B> Next time, don't lose the nuke!")
SSticker.news_report = NUKE_SYNDICATE_BASE
else if(!disk_rescued && station_was_nuked && !syndies_didnt_escape)
SSticker.mode_result = "win - syndicate nuke"
to_chat(world, "<FONT size = 3><B>Syndicate Major Victory!</B></FONT>")
to_chat(world, "<B>[syndicate_name()] operatives have destroyed [station_name()]!</B>")
SSticker.news_report = STATION_NUKED
else if (!disk_rescued && station_was_nuked && syndies_didnt_escape)
SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time"
to_chat(world, "<FONT size = 3><B>Total Annihilation</B></FONT>")
to_chat(world, "<B>[syndicate_name()] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion.</B> Next time, don't lose the disk!")
SSticker.news_report = STATION_NUKED
else if (!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape)
SSticker.mode_result = "halfwin - blew wrong station"
to_chat(world, "<FONT size = 3><B>Crew Minor Victory</B></FONT>")
to_chat(world, "<B>[syndicate_name()] operatives secured the authentication disk but blew up something that wasn't [station_name()].</B> Next time, don't do that!")
SSticker.news_report = NUKE_MISS
else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape)
SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time"
to_chat(world, "<FONT size = 3><B>[syndicate_name()] operatives have earned Darwin Award!</B></FONT>")
to_chat(world, "<B>[syndicate_name()] operatives blew up something that wasn't [station_name()] and got caught in the explosion.</B> Next time, don't do that!")
SSticker.news_report = NUKE_MISS
else if ((disk_rescued || SSshuttle.emergency.mode != SHUTTLE_ENDGAME) && are_operatives_dead())
SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead"
to_chat(world, "<FONT size = 3><B>Crew Major Victory!</B></FONT>")
to_chat(world, "<B>The Research Staff has saved the disk and killed the [syndicate_name()] Operatives</B>")
SSticker.news_report = OPERATIVES_KILLED
else if (disk_rescued)
SSticker.mode_result = "loss - evacuation - disk secured"
to_chat(world, "<FONT size = 3><B>Crew Major Victory</B></FONT>")
to_chat(world, "<B>The Research Staff has saved the disk and stopped the [syndicate_name()] Operatives!</B>")
SSticker.news_report = OPERATIVES_KILLED
else if (!disk_rescued && are_operatives_dead())
SSticker.mode_result = "halfwin - evacuation - disk not secured"
to_chat(world, "<FONT size = 3><B>Neutral Victory!</B></FONT>")
to_chat(world, "<B>The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name()] Operatives!</B>")
SSticker.news_report = OPERATIVE_SKIRMISH
else if (!disk_rescued && crew_evacuated)
SSticker.mode_result = "halfwin - detonation averted"
to_chat(world, "<FONT size = 3><B>Syndicate Minor Victory!</B></FONT>")
to_chat(world, "<B>[syndicate_name()] operatives survived the assault but did not achieve the destruction of [station_name()].</B> Next time, don't lose the disk!")
SSticker.news_report = OPERATIVE_SKIRMISH
else if (!disk_rescued && !crew_evacuated)
SSticker.mode_result = "halfwin - interrupted"
to_chat(world, "<FONT size = 3><B>Neutral Victory</B></FONT>")
to_chat(world, "<B>Round was mysteriously interrupted!</B>")
SSticker.news_report = OPERATIVE_SKIRMISH
..()
return
var result = nuke_team.get_result()
switch(result)
if(NUKE_RESULT_FLUKE)
SSticker.mode_result = "loss - syndicate nuked - disk secured"
SSticker.news_report = NUKE_SYNDICATE_BASE
if(NUKE_RESULT_NUKE_WIN)
SSticker.mode_result = "win - syndicate nuke"
SSticker.news_report = STATION_NUKED
if(NUKE_RESULT_NOSURVIVORS)
SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time"
SSticker.news_report = STATION_NUKED
if(NUKE_RESULT_WRONG_STATION)
SSticker.mode_result = "halfwin - blew wrong station"
SSticker.news_report = NUKE_MISS
if(NUKE_RESULT_WRONG_STATION_DEAD)
SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time"
SSticker.news_report = NUKE_MISS
if(NUKE_RESULT_CREW_WIN_SYNDIES_DEAD)
SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead"
SSticker.news_report = OPERATIVES_KILLED
if(NUKE_RESULT_CREW_WIN)
SSticker.mode_result = "loss - evacuation - disk secured"
SSticker.news_report = OPERATIVES_KILLED
if(NUKE_RESULT_DISK_LOST)
SSticker.mode_result = "halfwin - evacuation - disk not secured"
SSticker.news_report = OPERATIVE_SKIRMISH
if(NUKE_RESULT_DISK_STOLEN)
SSticker.mode_result = "halfwin - detonation averted"
SSticker.news_report = OPERATIVE_SKIRMISH
else
SSticker.mode_result = "halfwin - interrupted"
SSticker.news_report = OPERATIVE_SKIRMISH
return ..()
/datum/game_mode/nuclear/generate_report()
return "One of Central Command's trading routes was recently disrupted by a raid carried out by the Gorlex Marauders. They seemed to only be after one ship - a highly-sensitive \
@@ -258,48 +110,16 @@
can activate this explosive is on your station. Ensure that it is protected at all times, and remain alert for possible intruders."
/datum/game_mode/proc/auto_declare_completion_nuclear()
if( syndicates.len || (SSticker && istype(SSticker.mode, /datum/game_mode/nuclear)) )
var/text = "<br><FONT size=3><B>The syndicate operatives were:</B></FONT>"
var/purchases = ""
var/TC_uses = 0
for(var/datum/mind/syndicate in syndicates)
text += printplayer(syndicate)
for(var/datum/component/uplink/H in GLOB.uplinks)
if(H.purchase_log)
purchases += H.purchase_log.generate_render()
else
stack_trace("WARNING: Uplink with no purchase_log in nuclear mode! Owner: [H.owner]")
text += "<br>"
text += "(Syndicates used [TC_uses] TC) [purchases]"
if(TC_uses == 0 && station_was_nuked && !are_operatives_dead())
text += "<BIG>[icon2html('icons/badass.dmi', world, "badass")]</BIG>"
to_chat(world, text)
var/list/nuke_teams = list()
for(var/datum/antagonist/nukeop/N in GLOB.antagonists) //collect all nuke teams
nuke_teams |= N.nuke_team
for(var/datum/objective_team/nuclear/nuke_team in nuke_teams)
nuke_team.roundend_display()
return TRUE
/proc/nukelastname(mob/M) //--All praise goes to NEO|Phyte, all blame goes to DH, and it was Cindi-Kate's idea. Also praise Urist for copypasta ho.
var/randomname = pick(GLOB.last_names)
var/newname = copytext(sanitize(input(M,"You are the nuke operative [pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord")]. Please choose a last name for your family.", "Name change",randomname)),1,MAX_NAME_LEN)
if (!newname)
newname = randomname
else
if (newname == "Unknown" || newname == "floor" || newname == "wall" || newname == "rwall" || newname == "_")
to_chat(M, "That name is reserved.")
return nukelastname(M)
return capitalize(newname)
/proc/NukeNameAssign(lastname,list/syndicates)
for(var/datum/mind/synd_mind in syndicates)
var/mob/living/carbon/human/H = synd_mind.current
synd_mind.name = H.dna.species.random_name(H.gender,0,lastname)
synd_mind.current.real_name = synd_mind.name
return
/proc/is_nuclear_operative(mob/M)
return M && istype(M) && M.mind && SSticker && SSticker.mode && M.mind in SSticker.mode.syndicates
return M && istype(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/nukeop)
/datum/outfit/syndicate
name = "Syndicate Operative - Basic"
@@ -315,15 +135,24 @@
backpack_contents = list(/obj/item/storage/box/syndie=1)
var/tc = 25
var/command_radio = FALSE
/datum/outfit/syndicate/leader
name = "Syndicate Leader - Basic"
id = /obj/item/card/id/syndicate/nuke_leader
r_hand = /obj/item/device/nuclear_challenge
command_radio = TRUE
/datum/outfit/syndicate/no_crystals
tc = 0
/datum/outfit/syndicate/post_equip(mob/living/carbon/human/H)
var/obj/item/device/radio/R = H.ears
R.set_frequency(GLOB.SYND_FREQ)
R.freqlock = 1
if(command_radio)
R.command = TRUE
if(tc)
var/obj/item/device/radio/uplink/nuclear/U = new(H, H.key, tc)
+4 -4
View File
@@ -77,16 +77,16 @@
icon = 'icons/obj/machines/nuke_terminal.dmi'
icon_state = "nuclearbomb_base"
anchored = TRUE //stops it being moved
use_tag = TRUE
/obj/machinery/nuclearbomb/syndicate
use_tag = TRUE
//ui_style = "syndicate" // actually the nuke op bomb is a stole nt bomb
/obj/machinery/nuclearbomb/syndicate/get_cinematic_type(off_station)
var/datum/game_mode/nuclear/NM = SSticker.mode
switch(off_station)
if(0)
if(istype(NM) && NM.syndies_didnt_escape)
if(istype(NM) && !NM.nuke_team.syndies_escaped())
return CINEMATIC_ANNIHILATION
else
return CINEMATIC_NUKE_WIN
@@ -353,7 +353,7 @@
var/N = text2num(user_input)
if(!N)
return
timer_set = Clamp(N,minimum_timer_set,maximum_timer_set)
timer_set = CLAMP(N,minimum_timer_set,maximum_timer_set)
. = TRUE
if("safety")
if(auth && yes_code)
@@ -572,4 +572,4 @@ This is here to make the tiles around the station mininuke change when it's arme
user.visible_message("<span class='suicide'>[user] is pretending to go delta! It looks like [user.p_theyre()] trying to commit suicide!</span>")
playsound(src, 'sound/machines/alarm.ogg', 30, -1, 1)
addtimer(CALLBACK(src, .proc/manual_suicide, user), 101)
return MANUAL_SUICIDE
return MANUAL_SUICIDE

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