Merge branch 'master' into loadout-loading
This commit is contained in:
+17
-16
@@ -79,21 +79,22 @@
|
||||
//DNA - Because fuck you and your magic numbers being all over the codebase.
|
||||
#define DNA_BLOCK_SIZE 3
|
||||
|
||||
#define DNA_UNI_IDENTITY_BLOCKS 14
|
||||
#define DNA_UNI_IDENTITY_BLOCKS 15
|
||||
#define DNA_HAIR_COLOR_BLOCK 1
|
||||
#define DNA_FACIAL_HAIR_COLOR_BLOCK 2
|
||||
#define DNA_SKIN_TONE_BLOCK 3
|
||||
#define DNA_EYE_COLOR_BLOCK 4
|
||||
#define DNA_GENDER_BLOCK 5
|
||||
#define DNA_FACIAL_HAIR_STYLE_BLOCK 6
|
||||
#define DNA_HAIR_STYLE_BLOCK 7
|
||||
#define DNA_COLOR_ONE_BLOCK 8
|
||||
#define DNA_COLOR_TWO_BLOCK 9
|
||||
#define DNA_COLOR_THREE_BLOCK 10
|
||||
#define DNA_MUTANTTAIL_BLOCK 11
|
||||
#define DNA_MUTANTEAR_BLOCK 12
|
||||
#define DNA_MUTANTMARKING_BLOCK 13
|
||||
#define DNA_TAUR_BLOCK 14
|
||||
#define DNA_LEFT_EYE_COLOR_BLOCK 4
|
||||
#define DNA_RIGHT_EYE_COLOR_BLOCK 5
|
||||
#define DNA_GENDER_BLOCK 6
|
||||
#define DNA_FACIAL_HAIR_STYLE_BLOCK 7
|
||||
#define DNA_HAIR_STYLE_BLOCK 8
|
||||
#define DNA_COLOR_ONE_BLOCK 9
|
||||
#define DNA_COLOR_TWO_BLOCK 10
|
||||
#define DNA_COLOR_THREE_BLOCK 11
|
||||
#define DNA_MUTANTTAIL_BLOCK 12
|
||||
#define DNA_MUTANTEAR_BLOCK 13
|
||||
#define DNA_MUTANTMARKING_BLOCK 14
|
||||
#define DNA_TAUR_BLOCK 15
|
||||
|
||||
#define DNA_SEQUENCE_LENGTH 4
|
||||
#define DNA_MUTATION_BLOCKS 8
|
||||
@@ -142,11 +143,11 @@
|
||||
#define CUSTOM_SKINTONE 24 //adds a "_g" suffix to bodypart overlays icon states if a custom skintone is used.
|
||||
#define HORNCOLOR 25
|
||||
#define WINGCOLOR 26
|
||||
#define CAN_SCAR 27 // If this species can be scarred (fleshy)
|
||||
|
||||
#define ROBOTIC_LIMBS 27 //has robotic limbs that render like organic ones
|
||||
#define CAN_SCAR 28 // If this species can be scarred (fleshy)
|
||||
/// Used for determining which wounds are applicable to this species.
|
||||
#define HAS_FLESH 28 /// if we have flesh (can suffer slash/piercing/burn wounds, requires they don't have NOBLOOD)
|
||||
#define HAS_BONE 29 /// if we have bones (can suffer bone wounds)
|
||||
#define HAS_FLESH 29 /// if we have flesh (can suffer slash/piercing/burn wounds, requires they don't have NOBLOOD)
|
||||
#define HAS_BONE 30 /// if we have bones (can suffer bone wounds)
|
||||
|
||||
//organ slots
|
||||
#define ORGAN_SLOT_BRAIN "brain"
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
#define EXTOOLS (world.system_type == MS_WINDOWS ? "byond-extools.dll" : "libbyond-extools.so")
|
||||
@@ -9,7 +9,12 @@
|
||||
#define DISABLE_BITFIELD(variable, flag) (variable &= ~(flag))
|
||||
#define CHECK_BITFIELD(variable, flag) (variable & (flag))
|
||||
#define TOGGLE_BITFIELD(variable, flag) (variable ^= (flag))
|
||||
|
||||
#define COPY_SPECIFIC_BITFIELDS(a,b,flags)\
|
||||
do{\
|
||||
var/_old = a & ~(flags);\
|
||||
var/_cleaned = b & (flags);\
|
||||
a = _old | _cleaned;\
|
||||
} while(0);
|
||||
#define CHECK_MULTIPLE_BITFIELDS(flagvar, flags) (((flagvar) & (flags)) == (flags))
|
||||
|
||||
GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Defines for managed input/keybinding system.
|
||||
/// Max length of a keypress command before it's considered to be a forged packet/bogus command
|
||||
#define MAX_KEYPRESS_COMMANDLENGTH 32
|
||||
#define MAX_KEYPRESS_COMMANDLENGTH 64
|
||||
/// Maximum keys that can be bound to one button
|
||||
#define MAX_COMMANDS_PER_KEY 5
|
||||
/// Maximum keys per keybind
|
||||
|
||||
@@ -281,8 +281,6 @@ GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0))
|
||||
#define CALCULATE_ADJACENT_TURFS(T) SSadjacent_air.queue[T] = 1
|
||||
#endif
|
||||
|
||||
#define EXTOOLS (world.system_type == MS_WINDOWS ? "byond-extools.dll" : "libbyond-extools.so")
|
||||
|
||||
GLOBAL_VAR(atmos_extools_initialized) // this must be an uninitialized (null) one or init_monstermos will be called twice because reasons
|
||||
#define ATMOS_EXTOOLS_CHECK if(!GLOB.atmos_extools_initialized){\
|
||||
GLOB.atmos_extools_initialized=TRUE;\
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
#define TRAY_NAME_UPDATE name = myseed ? "[initial(name)] ([myseed.plantname])" : initial(name)
|
||||
#define YIELD_WEED_MINIMUM 3
|
||||
#define YIELD_WEED_MAXIMUM 10
|
||||
#define STATIC_NUTRIENT_CAPACITY 10
|
||||
|
||||
//Both available scanning modes for the plant analyzer.
|
||||
#define PLANT_SCANMODE_STATS 0
|
||||
#define PLANT_SCANMODE_CHEMICALS 1
|
||||
|
||||
//Seed flags.
|
||||
#define MUTATE_EARLY (1<<0)
|
||||
@@ -47,7 +47,7 @@
|
||||
#define BALLS_SIZE_DEF 2
|
||||
#define BALLS_SIZE_MAX 3
|
||||
|
||||
#define CUM_RATE 2 // holy shit what a really shitty define name - relates to units per arbitrary measure of time?
|
||||
#define CUM_RATE 2 // units per 10 seconds
|
||||
#define CUM_RATE_MULT 1
|
||||
#define CUM_EFFICIENCY 1 //amount of nutrition required per life()
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
#define DEF_BREASTS_SHAPE "Pair"
|
||||
|
||||
#define MILK_RATE 5
|
||||
#define MILK_RATE 3
|
||||
#define MILK_RATE_MULT 1
|
||||
#define MILK_EFFICIENCY 1
|
||||
|
||||
@@ -99,8 +99,12 @@
|
||||
#define NO_ASS_SLAP (1<<10)
|
||||
#define BIMBOFICATION (1<<11)
|
||||
#define NO_AUTO_WAG (1<<12)
|
||||
|
||||
#define GENITAL_EXAMINE (1<<13)
|
||||
#define VORE_EXAMINE (1<<14)
|
||||
#define TOGGLES_CITADEL 0
|
||||
|
||||
//belly sound pref things
|
||||
#define NORMIE_HEARCHECK 4
|
||||
|
||||
//special species definitions
|
||||
#define MINIMUM_MUTANT_COLOR "#202020" //this is how dark players mutant parts and skin can be
|
||||
|
||||
@@ -2,19 +2,6 @@
|
||||
|
||||
#define COLOR_INPUT_DISABLED "#F0F0F0"
|
||||
#define COLOR_INPUT_ENABLED "#D3B5B5"
|
||||
|
||||
#define COLOR_DARKMODE_INFO_BUTTONS_BG "#40628A"
|
||||
#define COLOR_DARKMODE_ISSUE_BUTTON_BG "#A92C2C"
|
||||
#define COLOR_DARKMODE_BACKGROUND "#272727"
|
||||
#define COLOR_DARKMODE_DARKBACKGROUND "#242424"
|
||||
#define COLOR_DARKMODE_TEXT "#E0E0E0"
|
||||
|
||||
#define COLOR_WHITEMODE_INFO_BUTTONS_BG "#90B3DD"
|
||||
#define COLOR_WHITEMODE_ISSUE_BUTTON_BG "#EF7F7F"
|
||||
#define COLOR_WHITEMODE_BACKGROUND "#F0F0F0"
|
||||
#define COLOR_WHITEMODE_DARKBACKGROUND "#E6E6E6"
|
||||
#define COLOR_WHITEMODE_TEXT "#000000"
|
||||
|
||||
#define COLOR_FLOORTILE_GRAY "#8D8B8B"
|
||||
#define COLOR_ALMOST_BLACK "#333333"
|
||||
#define COLOR_BLACK "#000000"
|
||||
@@ -64,4 +51,4 @@
|
||||
#define COLOR_ASSEMBLY_LBLUE "#5D99BE"
|
||||
#define COLOR_ASSEMBLY_BLUE "#38559E"
|
||||
#define COLOR_ASSEMBLY_PURPLE "#6F6192"
|
||||
#define COLOR_ASSEMBLY_PINK "#ff4adc"
|
||||
#define COLOR_ASSEMBLY_PINK "#ff4adc"
|
||||
|
||||
@@ -230,9 +230,6 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
|
||||
#define EXPLODE_LIGHT 3
|
||||
#define EXPLODE_GIB_THRESHOLD 50
|
||||
|
||||
#define EMP_HEAVY 1
|
||||
#define EMP_LIGHT 2
|
||||
|
||||
#define GRENADE_CLUMSY_FUMBLE 1
|
||||
#define GRENADE_NONCLUMSY_FUMBLE 2
|
||||
#define GRENADE_NO_FUMBLE 3
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//config files
|
||||
#define CONFIG_GET(X) global.config.Get(/datum/config_entry/##X)
|
||||
#define CONFIG_SET(X, Y) global.config.Set(/datum/config_entry/##X, ##Y)
|
||||
/// Gets the datum of the object, for when editing a const define.
|
||||
#define CONFIG_GET_ENTRY(X) global.config.GetEntryDatum(/datum/config_entry/##X)
|
||||
|
||||
#define CONFIG_MAPS_FILE "maps.txt"
|
||||
@@ -17,3 +18,5 @@
|
||||
#define POLICYCONFIG_ON_DEFIB_INTACT "ON_DEFIB_INTACT"
|
||||
/// Displayed to defibbed/revival surgery'd patients after the memory loss time threshold
|
||||
#define POLICYCONFIG_ON_DEFIB_LATE "ON_DEFIB_LATE"
|
||||
/// Displayed to pyroclastic slimes on spawn
|
||||
#define POLICYCONFIG_ON_PYROCLASTIC_SENTIENT "PYROCLASTIC_SLIME"
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#define COMSIG_ELEMENT_DETACH "element_detach"
|
||||
|
||||
/// sent to the component itself when unregistered from a parent
|
||||
#define COMSIG_COMPONENT_UNREGISTER_PARENT "component_unregister_parent"
|
||||
#define COMSIG_COMPONENT_UNREGISTER_PARENT "component_unregister_parent"
|
||||
/// sent to the component itself when registered to a parent
|
||||
#define COMSIG_COMPONENT_REGISTER_PARENT "component_register_parent"
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
// /atom signals
|
||||
//from base of atom/proc/Initialize(): sent any time a new atom is created
|
||||
#define COMSIG_ATOM_CREATED "atom_created"
|
||||
//from SSatoms InitAtom - Only if the atom was not deleted or failed initialization
|
||||
#define COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE "atom_init_success"
|
||||
#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params)
|
||||
#define COMPONENT_NO_AFTERATTACK 1 //Return this in response if you don't want afterattack to be called
|
||||
#define COMSIG_ATOM_HULK_ATTACK "hulk_attack" //from base of atom/attack_hulk(): (/mob/living/carbon/human)
|
||||
@@ -184,6 +186,7 @@
|
||||
// #define HEARING_SOURCE 8
|
||||
#define COMSIG_MOVABLE_DISPOSING "movable_disposing" //called when the movable is added to a disposal holder object for disposal movement: (obj/structure/disposalholder/holder, obj/machinery/disposal/source)
|
||||
#define COMSIG_MOVABLE_TELEPORTED "movable_teleported" //from base of do_teleport(): (channel, turf/origin, turf/destination)
|
||||
#define COMSIG_MOVABLE_CHASM_DROP "movable_chasm_drop" //from base of /datum/component/chasm/drop() (/datum/component/chasm)
|
||||
|
||||
// /mind signals
|
||||
#define COMSIG_PRE_MIND_TRANSFER "pre_mind_transfer" //from base of mind/transfer_to() before it's done: (new_character, old_character)
|
||||
@@ -243,6 +246,8 @@
|
||||
#define COMPONENT_BLOCK_SWAP 1
|
||||
|
||||
#define COMSIG_PROCESS_BORGCHARGER_OCCUPANT "living_charge"
|
||||
///from base of mob/AltClickOn(): (atom/A)
|
||||
#define COMSIG_MOB_ALTCLICKON "mob_altclickon"
|
||||
|
||||
// /client signals
|
||||
#define COMSIG_MOB_CLIENT_LOGIN "mob_client_login" //sent when a mob/login() finishes: (client)
|
||||
@@ -287,6 +292,10 @@
|
||||
#define COMPONENT_INTERRUPT_LIFE_BIOLOGICAL 1 // interrupt biological processes
|
||||
#define COMPONENT_INTERRUPT_LIFE_PHYSICAL 2 // interrupt physical handling
|
||||
|
||||
#define COMSIG_LIVING_BIOLOGICAL_LIFE "biological_life" //from base of mob/living/BiologicalLife() (seconds, times_fired)
|
||||
|
||||
#define COMSIG_LIVING_PHYSICAL_LIFE "physical_life" //from base of mob/living/PhysicalLife() (seconds, times_fired)
|
||||
|
||||
// /mob/living/carbon physiology signals
|
||||
#define COMSIG_CARBON_GAIN_WOUND "carbon_gain_wound" //from /datum/wound/proc/apply_wound() (/mob/living/carbon/C, /datum/wound/W, /obj/item/bodypart/L)
|
||||
#define COMSIG_CARBON_LOSE_WOUND "carbon_lose_wound" //from /datum/wound/proc/remove_wound() (/mob/living/carbon/C, /datum/wound/W, /obj/item/bodypart/L)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#define DYE_REGISTRY_SNEAKERS "sneakers"
|
||||
#define DYE_REGISTRY_FANNYPACK "fannypack"
|
||||
#define DYE_REGISTRY_BEDSHEET "bedsheet"
|
||||
#define DYE_LAWYER_SPECIAL "lawyer_special"
|
||||
|
||||
#define DYE_RED "red"
|
||||
#define DYE_ORANGE "orange"
|
||||
@@ -16,6 +17,7 @@
|
||||
#define DYE_RAINBOW "rainbow"
|
||||
#define DYE_MIME "mime"
|
||||
#define DYE_COSMIC "cosmic"
|
||||
#define DYE_SYNDICATE "syndicate"
|
||||
#define DYE_QM "qm"
|
||||
#define DYE_LAW "law"
|
||||
#define DYE_CAPTAIN "captain"
|
||||
@@ -26,3 +28,5 @@
|
||||
#define DYE_CMO "cmo"
|
||||
#define DYE_REDCOAT "redcoat"
|
||||
#define DYE_CLOWN "clown"
|
||||
#define DYE_CHAP "chap"
|
||||
#define DYE_CENTCOM "centcom"
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#define TOXIC (1<<11)
|
||||
#define PINEAPPLE (1<<12)
|
||||
#define BREAKFAST (1<<13)
|
||||
#define ANTITOXIC (1<<14)
|
||||
|
||||
#define DRINK_NICE 1
|
||||
#define DRINK_GOOD 2
|
||||
|
||||
@@ -76,6 +76,7 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list(
|
||||
#define ismush(A) (is_species(A, /datum/species/mush))
|
||||
#define isshadow(A) (is_species(A, /datum/species/shadow))
|
||||
#define isskeleton(A) (is_species(A, /datum/species/skeleton))
|
||||
#define isrobotic(A) (is_species(A, /datum/species/ipc) || is_species(A, /datum/species/synthliz))
|
||||
#define isethereal(A) (is_species(A, /datum/species/ethereal))
|
||||
|
||||
// Citadel specific species
|
||||
|
||||
@@ -54,3 +54,16 @@
|
||||
|
||||
//donator items
|
||||
#define LOADOUT_CATEGORY_DONATOR "Donator"
|
||||
|
||||
//how many prosthetics can we have
|
||||
#define MAXIMUM_LOADOUT_PROSTHETICS 2
|
||||
|
||||
//what limbs can be amputated or be prosthetic
|
||||
#define LOADOUT_ALLOWED_LIMB_TARGETS list(BODY_ZONE_L_ARM,BODY_ZONE_R_ARM,BODY_ZONE_L_LEG,BODY_ZONE_R_LEG)
|
||||
|
||||
//options for modifiying limbs
|
||||
#define LOADOUT_LIMB_NORMAL "Normal"
|
||||
#define LOADOUT_LIMB_PROSTHETIC "Prosthetic"
|
||||
#define LOADOUT_LIMB_AMPUTATED "Amputated"
|
||||
|
||||
#define LOADOUT_LIMBS list(LOADOUT_LIMB_NORMAL,LOADOUT_LIMB_PROSTHETIC,LOADOUT_LIMB_AMPUTATED) //you can amputate your legs/arms though
|
||||
@@ -41,11 +41,13 @@
|
||||
#define MC_HDD "HDD"
|
||||
#define MC_SDD "SDD"
|
||||
#define MC_CARD "CARD"
|
||||
#define MC_CARD2 "CARD2"
|
||||
#define MC_NET "NET"
|
||||
#define MC_PRINT "PRINT"
|
||||
#define MC_CELL "CELL"
|
||||
#define MC_CHARGE "CHARGE"
|
||||
#define MC_AI "AI"
|
||||
#define MC_SENSORS "SENSORS"
|
||||
|
||||
//NTNet stuff, for modular computers
|
||||
// NTNet module-configuration values. Do not change these. If you need to add another use larger number (5..6..7 etc)
|
||||
|
||||
@@ -199,8 +199,8 @@
|
||||
|
||||
#define EXP_DISTRIBUTION(desired_mean) ( -(1/(1/desired_mean)) * log(rand(1, 1000) * 0.001) )
|
||||
|
||||
#define LORENTZ_DISTRIBUTION(x, s) ( s*tan(TODEGREES(PI*(rand()-0.5))) + x )
|
||||
#define LORENTZ_CUMULATIVE_DISTRIBUTION(x, y, s) ( (1/PI)*TORADIANS(arctan((x-y)/s)) + 1/2 )
|
||||
#define LORENTZ_DISTRIBUTION(x, s) ( s*tan((rand()-0.5)*180) + x )
|
||||
#define LORENTZ_CUMULATIVE_DISTRIBUTION(x, y, s) ( (1/180)*(arctan((x-y)/s)) + 1/2 )
|
||||
|
||||
#define RULE_OF_THREE(a, b, x) ((a*x)/b)
|
||||
// )
|
||||
|
||||
@@ -116,6 +116,7 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
|
||||
#define CRAYON_FONT "Comic Sans MS"
|
||||
#define PRINTER_FONT "Times New Roman"
|
||||
#define SIGNFONT "Times New Roman"
|
||||
#define CHARCOAL_FONT "Candara"
|
||||
|
||||
#define RESIZE_DEFAULT_SIZE 1
|
||||
|
||||
@@ -318,9 +319,9 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
|
||||
#define SHELTER_DEPLOY_ANCHORED_OBJECTS "anchored objects"
|
||||
|
||||
//debug printing macros
|
||||
#define debug_world(msg) if (GLOB.Debug2) to_chat(world, "DEBUG: [msg]")
|
||||
#define debug_usr(msg) if (GLOB.Debug2&&usr) to_chat(usr, "DEBUG: [msg]")
|
||||
#define debug_admins(msg) if (GLOB.Debug2) to_chat(GLOB.admins, "DEBUG: [msg]")
|
||||
#define debug_world(msg) if (GLOB.Debug2) to_chat(world, "<span class=\"filter_debuglog\">DEBUG: [msg]</span>")
|
||||
#define debug_usr(msg) if (GLOB.Debug2&&usr) to_chat(usr, "<span class=\"filter_debuglog\">DEBUG: [msg]</span>")
|
||||
#define debug_admins(msg) if (GLOB.Debug2) to_chat(GLOB.admins, "<span class=\"filter_debuglog\">DEBUG: [msg]</span>")
|
||||
#define debug_world_log(msg) if (GLOB.Debug2) log_world("DEBUG: [msg]")
|
||||
|
||||
#define INCREMENT_TALLY(L, stat) if(L[stat]){L[stat]++}else{L[stat] = 1}
|
||||
|
||||
@@ -64,7 +64,6 @@
|
||||
#define DEFAULT_BODYPART_ICON 'icons/mob/human_parts.dmi'
|
||||
#define DEFAULT_BODYPART_ICON_ORGANIC 'icons/mob/human_parts_greyscale.dmi'
|
||||
#define DEFAULT_BODYPART_ICON_ROBOTIC 'icons/mob/augmentation/augments.dmi'
|
||||
#define DEFAULT_BODYPART_ICON_CITADEL 'modular_citadel/icons/mob/mutant_bodyparts.dmi'
|
||||
|
||||
#define MONKEY_BODYPART "monkey"
|
||||
#define ALIEN_BODYPART "alien"
|
||||
@@ -313,7 +312,7 @@
|
||||
|
||||
#define HUMAN_FIRE_STACK_ICON_NUM 3
|
||||
|
||||
#define TYPING_INDICATOR_TIMEOUT 5 MINUTES
|
||||
#define TYPING_INDICATOR_TIMEOUT 20 MINUTES
|
||||
|
||||
#define GRAB_PIXEL_SHIFT_PASSIVE 6
|
||||
#define GRAB_PIXEL_SHIFT_AGGRESSIVE 12
|
||||
@@ -333,4 +332,4 @@
|
||||
/// If you examine the same atom twice in this timeframe, we call examine_more() instead of examine()
|
||||
#define EXAMINE_MORE_TIME 1 SECONDS
|
||||
|
||||
#define SILENCE_RANGED_MESSAGE (1<<0)
|
||||
#define SILENCE_RANGED_MESSAGE (1<<0)
|
||||
|
||||
@@ -22,3 +22,5 @@
|
||||
var/category as text
|
||||
/// Only clients/mobs with `see_invisibility` higher can use the verb.
|
||||
var/invisibility as num
|
||||
/// Whether or not the verb appears in statpanel and commandbar when you press space
|
||||
var/hidden as num
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// Anomaly core types
|
||||
/// Bluespace cores
|
||||
#define ANOMALY_CORE_BLUESPACE /obj/item/assembly/signaler/anomaly/bluespace
|
||||
/// Gravitational cores
|
||||
#define ANOMALY_CORE_GRAVITATIONAL /obj/item/assembly/signaler/anomaly/grav
|
||||
/// Flux
|
||||
#define ANOMALY_CORE_FLUX /obj/item/assembly/signaler/anomaly/flux
|
||||
/// Vortex
|
||||
#define ANOMALY_CORE_VORTEX /obj/item/assembly/signaler/anomaly/vortex
|
||||
/// Pyro
|
||||
#define ANOMALY_CORE_PYRO /obj/item/assembly/signaler/anomaly/pyro
|
||||
|
||||
// Max amounts of cores you can make
|
||||
#define MAX_CORES_BLUESPACE 8
|
||||
#define MAX_CORES_GRAVITATIONAL 8
|
||||
#define MAX_CORES_FLUX 8
|
||||
#define MAX_CORES_VORTEX 8
|
||||
#define MAX_CORES_PYRO 8
|
||||
|
||||
/// chance supermatter anomalies drop real cores
|
||||
#define SUPERMATTER_ANOMALY_DROP_CHANCE 20
|
||||
@@ -0,0 +1,7 @@
|
||||
#define ROCKPAPERSCISSORS_RANGE 3
|
||||
#define ROCKPAPERSCISSORS_TIME_LIMIT 20 SECONDS
|
||||
|
||||
#define ROCKPAPERSCISSORS_LOSE "lose"
|
||||
#define ROCKPAPERSCISSORS_WIN "win"
|
||||
#define ROCKPAPERSCISSORS_TIE "tie"
|
||||
#define ROCKPAPERSCISSORS_NOT_DECIDED "not_decided"
|
||||
@@ -30,6 +30,8 @@
|
||||
|
||||
#define STATUS_EFFECT_FLESHMEND /datum/status_effect/fleshmend //Very fast healing; suppressed by fire, and heals less fire damage
|
||||
|
||||
#define STATUS_EFFECT_PANACEA /datum/status_effect/panacea //Anatomic panacea that directly heals, rather than injecting a small chemical cocktail
|
||||
|
||||
#define STATUS_EFFECT_EXERCISED /datum/status_effect/exercised //Prevents heart disease
|
||||
|
||||
#define STATUS_EFFECT_HIPPOCRATIC_OATH /datum/status_effect/hippocraticOath //Gives you an aura of healing as well as regrowing the Rod of Asclepius if lost
|
||||
|
||||
@@ -24,7 +24,10 @@ GLOBAL_LIST_INIT(default_weight_class_to_volume, list(
|
||||
// Let's keep all of this in one place. given what we put above anyways..
|
||||
|
||||
// volume amount for items
|
||||
/// volume for a data disk
|
||||
#define ITEM_VOLUME_DISK 1
|
||||
/// volume for a shotgun stripper clip holding 4 shells
|
||||
#define ITEM_VOLUME_STRIPPER_CLIP (DEFAULT_VOLUME_NORMAL * 0.5)
|
||||
|
||||
// #define SAMPLE_VOLUME_AMOUNT 2
|
||||
|
||||
|
||||
@@ -51,7 +51,8 @@
|
||||
#define INIT_ORDER_FAIL2TOPIC 99
|
||||
#define INIT_ORDER_TITLE 98
|
||||
#define INIT_ORDER_GARBAGE 95
|
||||
#define INIT_ORDER_DBCORE 93
|
||||
#define INIT_ORDER_DBCORE 94
|
||||
#define INIT_ORDER_STATPANELS 93
|
||||
#define INIT_ORDER_BLACKBOX 92
|
||||
#define INIT_ORDER_SERVER_MAINT 91
|
||||
#define INIT_ORDER_INPUT 90
|
||||
@@ -86,6 +87,7 @@
|
||||
#define INIT_ORDER_MINOR_MAPPING -40
|
||||
#define INIT_ORDER_PATH -50
|
||||
#define INIT_ORDER_PERSISTENCE -95
|
||||
#define INIT_ORDER_DEMO -99 // o avoid a bunch of changes related to initialization being written, do this last
|
||||
#define INIT_ORDER_CHAT -100 //Should be last to ensure chat remains smooth during init.
|
||||
|
||||
|
||||
@@ -93,7 +95,6 @@
|
||||
// If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child)
|
||||
|
||||
#define FIRE_PRIORITY_VORE 5
|
||||
#define FIRE_PRIORITY_PING 10
|
||||
#define FIRE_PRIORITY_IDLE_NPC 10
|
||||
#define FIRE_PRIORITY_SERVER_MAINT 10
|
||||
#define FIRE_PRIORITY_RESEARCH 10
|
||||
@@ -121,6 +122,7 @@
|
||||
#define FIRE_PRIORITY_PROJECTILES 200
|
||||
#define FIRE_PRIORITY_TICKER 200
|
||||
#define FIRE_PRIORITY_ATMOS_ADJACENCY 300
|
||||
#define FIRE_PRIORITY_STATPANEL 390
|
||||
#define FIRE_PRIORITY_CHAT 400
|
||||
#define FIRE_PRIORITY_OVERLAYS 500
|
||||
#define FIRE_PRIORITY_INPUT 1000 // This must always always be the max highest priority. Player input must never be lost.
|
||||
|
||||
@@ -26,3 +26,10 @@
|
||||
#define TGUI_WINDOW_ID(index) "tgui-window-[index]"
|
||||
/// Get a pool index of the provided window id
|
||||
#define TGUI_WINDOW_INDEX(window_id) text2num(copytext(window_id, 13))
|
||||
|
||||
/// Creates a message packet for sending via output()
|
||||
#define TGUI_CREATE_MESSAGE(type, payload) ( \
|
||||
url_encode(json_encode(list( \
|
||||
"type" = type, \
|
||||
"payload" = payload, \
|
||||
))))
|
||||
@@ -205,6 +205,7 @@
|
||||
#define TRAIT_NO_ALCOHOL "alcohol_intolerance"
|
||||
#define TRAIT_MUTATION_STASIS "mutation_stasis" //Prevents processed genetics mutations from processing.
|
||||
#define TRAIT_FAST_PUMP "fast_pump"
|
||||
#define TRAIT_NO_PROCESS_FOOD "no-process-food" // You don't get benefits from nutriment, nor nutrition from reagent consumables
|
||||
#define TRAIT_NICE_SHOT "nice_shot" //hnnnnnnnggggg..... you're pretty good...
|
||||
|
||||
// mobility flag traits
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
#define WOUND_DAMAGE_EXPONENT 1.225
|
||||
#define WOUND_DAMAGE_EXPONENT 1.2
|
||||
|
||||
/// an attack must do this much damage after armor in order to roll for being a wound (incremental pressure damage need not apply)
|
||||
#define WOUND_MINIMUM_DAMAGE 5
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
var/matrix/mtrx=new()
|
||||
return mtrx.Scale(0.65)
|
||||
|
||||
proc/get_racelist(var/mob/user)//This proc returns a list of species that 'user' has available to them. It searches the list of ckeys attached to the 'whitelist' var for a species and also checks if they're an admin.
|
||||
/proc/get_racelist(mob/user)//This proc returns a list of species that 'user' has available to them. It searches the list of ckeys attached to the 'whitelist' var for a species and also checks if they're an admin.
|
||||
for(var/spath in subtypesof(/datum/species))
|
||||
var/datum/species/S = new spath()
|
||||
var/list/wlist = S.whitelist
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#define EXTOOLS_LOGGING // rust_g is used as a fallback if this is undefined
|
||||
|
||||
/proc/extools_log_write()
|
||||
|
||||
/proc/extools_finalize_logging()
|
||||
@@ -553,12 +553,6 @@
|
||||
if(D.vars[varname] == value)
|
||||
return D
|
||||
|
||||
//remove all nulls from a list
|
||||
/proc/removeNullsFromList(list/L)
|
||||
while(L.Remove(null))
|
||||
continue
|
||||
return L
|
||||
|
||||
//Copies a list, and all lists inside it recusively
|
||||
//Does not copy any other reference type
|
||||
/proc/deepCopyList(list/l)
|
||||
@@ -681,3 +675,11 @@
|
||||
continue
|
||||
if(istype(D, path))
|
||||
return TRUE
|
||||
|
||||
/proc/safe_json_encode(list/L, default = "")
|
||||
. = default
|
||||
return json_encode(L)
|
||||
|
||||
/proc/safe_json_decode(string, default = list())
|
||||
. = default
|
||||
return json_decode(string)
|
||||
|
||||
+38
-11
@@ -4,10 +4,15 @@
|
||||
#define SEND_SOUND(target, sound) DIRECT_OUTPUT(target, sound)
|
||||
#define SEND_TEXT(target, text) DIRECT_OUTPUT(target, text)
|
||||
#define WRITE_FILE(file, text) DIRECT_OUTPUT(file, text)
|
||||
#ifdef EXTOOLS_LOGGING
|
||||
// proc hooked, so we can just put in standard TRUE and FALSE
|
||||
#define WRITE_LOG(log, text) extools_log_write(log,text,TRUE)
|
||||
#define WRITE_LOG_NO_FORMAT(log, text) extools_log_write(log,text,FALSE)
|
||||
#else
|
||||
//This is an external call, "true" and "false" are how rust parses out booleans
|
||||
#define WRITE_LOG(log, text) rustg_log_write(log, text, "true")
|
||||
#define WRITE_LOG_NO_FORMAT(log, text) rustg_log_write(log, text, "false")
|
||||
|
||||
#endif
|
||||
//print a warning message to world.log
|
||||
#define WARNING(MSG) warning("[MSG] in [__FILE__] at line [__LINE__] src: [UNLINT(src)] usr: [usr].")
|
||||
/proc/warning(msg)
|
||||
@@ -200,23 +205,45 @@
|
||||
/proc/start_log(log)
|
||||
WRITE_LOG(log, "Starting up round ID [GLOB.round_id].\n-------------------------")
|
||||
|
||||
/* ui logging */
|
||||
/proc/log_tgui(user_or_client, text)
|
||||
/**
|
||||
* Appends a tgui-related log entry. All arguments are optional.
|
||||
*/
|
||||
/proc/log_tgui(user, message, context,
|
||||
datum/tgui_window/window,
|
||||
datum/src_object)
|
||||
var/entry = ""
|
||||
if(!user_or_client)
|
||||
entry += "no user"
|
||||
else if(istype(user_or_client, /mob))
|
||||
var/mob/user = user_or_client
|
||||
entry += "[user.ckey] (as [user])"
|
||||
else if(istype(user_or_client, /client))
|
||||
var/client/client = user_or_client
|
||||
// Insert user info
|
||||
if(!user)
|
||||
entry += "<nobody>"
|
||||
else if(istype(user, /mob))
|
||||
var/mob/mob = user
|
||||
entry += "[mob.ckey] (as [mob] at [mob.x],[mob.y],[mob.z])"
|
||||
else if(istype(user, /client))
|
||||
var/client/client = user
|
||||
entry += "[client.ckey]"
|
||||
entry += ":\n[text]"
|
||||
// Insert context
|
||||
if(context)
|
||||
entry += " in [context]"
|
||||
else if(window)
|
||||
entry += " in [window.id]"
|
||||
// Resolve src_object
|
||||
if(!src_object && window && window.locked_by)
|
||||
src_object = window.locked_by.src_object
|
||||
// Insert src_object info
|
||||
if(src_object)
|
||||
entry += "\nUsing: [src_object.type] [REF(src_object)]"
|
||||
// Insert message
|
||||
if(message)
|
||||
entry += "\n[message]"
|
||||
WRITE_LOG(GLOB.tgui_log, entry)
|
||||
|
||||
/* Close open log handles. This should be called as late as possible, and no logging should hapen after. */
|
||||
/proc/shutdown_logging()
|
||||
#ifdef EXTOOLS_LOGGING
|
||||
extools_finalize_logging()
|
||||
#else
|
||||
rustg_log_close_all()
|
||||
#endif
|
||||
|
||||
|
||||
/* Helper procs for building detailed log lines */
|
||||
|
||||
@@ -71,3 +71,18 @@
|
||||
|
||||
/proc/pathflatten(path)
|
||||
return replacetext(path, "/", "_")
|
||||
|
||||
/// Returns the md5 of a file at a given path.
|
||||
/proc/md5filepath(path)
|
||||
. = md5(file(path))
|
||||
|
||||
/// Save file as an external file then md5 it.
|
||||
/// Used because md5ing files stored in the rsc sometimes gives incorrect md5 results.
|
||||
/proc/md5asfile(file)
|
||||
var/static/notch = 0
|
||||
// its importaint this code can handle md5filepath sleeping instead of hard blocking, if it's converted to use rust_g.
|
||||
var/filename = "tmp/md5asfile.[world.realtime].[world.timeofday].[world.time].[world.tick_usage].[notch]"
|
||||
notch = WRAP(notch+1, 0, 2^15)
|
||||
fcopy(file, filename)
|
||||
. = md5filepath(filename)
|
||||
fdel(filename)
|
||||
|
||||
+41
-19
@@ -1103,24 +1103,36 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0
|
||||
alpha += 25
|
||||
obj_flags &= ~FROZEN
|
||||
|
||||
/// Save file used in icon2base64. Used for converting icons to base64.
|
||||
GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of icons for the browser output
|
||||
|
||||
//Converts an icon to base64. Operates by putting the icon in the iconCache savefile,
|
||||
// exporting it as text, and then parsing the base64 from that.
|
||||
// (This relies on byond automatically storing icons in savefiles as base64)
|
||||
/proc/icon2base64(icon/icon, iconKey = "misc")
|
||||
|
||||
/// Generate a filename for this asset
|
||||
/// The same asset will always lead to the same asset name
|
||||
/// (Generated names do not include file extention.)
|
||||
/proc/generate_asset_name(file)
|
||||
return "asset.[md5(fcopy_rsc(file))]"
|
||||
|
||||
/**
|
||||
* Converts an icon to base64. Operates by putting the icon in the iconCache savefile,
|
||||
* exporting it as text, and then parsing the base64 from that.
|
||||
* (This relies on byond automatically storing icons in savefiles as base64)
|
||||
*/
|
||||
/proc/icon2base64(icon/icon)
|
||||
if (!isicon(icon))
|
||||
return FALSE
|
||||
WRITE_FILE(GLOB.iconCache[iconKey], icon)
|
||||
var/iconData = GLOB.iconCache.ExportText(iconKey)
|
||||
WRITE_FILE(GLOB.dummySave["dummy"], icon)
|
||||
var/iconData = GLOB.dummySave.ExportText("dummy")
|
||||
var/list/partial = splittext(iconData, "{")
|
||||
return replacetext(copytext_char(partial[2], 3, -5), "\n", "")
|
||||
|
||||
/proc/icon2html(thing, target, icon_state, dir, frame = 1, moving = FALSE)
|
||||
/proc/icon2html(thing, target, icon_state, dir = SOUTH, frame = 1, moving = FALSE, sourceonly = FALSE)
|
||||
if (!thing)
|
||||
return
|
||||
|
||||
var/key
|
||||
var/icon/I = thing
|
||||
|
||||
if (!target)
|
||||
return
|
||||
if (target == world)
|
||||
@@ -1136,17 +1148,26 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0
|
||||
if (!isicon(I))
|
||||
if (isfile(thing)) //special snowflake
|
||||
var/name = sanitize_filename("[generate_asset_name(thing)].png")
|
||||
if(!SSassets.cache[name])
|
||||
register_asset(name, thing)
|
||||
if (!SSassets.cache[name])
|
||||
SSassets.transport.register_asset(name, thing)
|
||||
for (var/thing2 in targets)
|
||||
send_asset(thing2, key)
|
||||
return "<img class='icon icon-misc' src=\"[url_encode(name)]\">"
|
||||
SSassets.transport.send_assets(thing2, name)
|
||||
if(sourceonly)
|
||||
return SSassets.transport.get_asset_url(name)
|
||||
return "<img class='icon icon-misc' src='[SSassets.transport.get_asset_url(name)]'>"
|
||||
var/atom/A = thing
|
||||
if (isnull(dir))
|
||||
dir = A.dir
|
||||
|
||||
I = A.icon
|
||||
if (isnull(icon_state))
|
||||
icon_state = A.icon_state
|
||||
I = A.icon
|
||||
if (!(icon_state in icon_states(I, 1)))
|
||||
icon_state = initial(A.icon_state)
|
||||
if (isnull(dir))
|
||||
dir = initial(A.dir)
|
||||
|
||||
if (isnull(dir))
|
||||
dir = A.dir
|
||||
|
||||
if (ishuman(thing)) // Shitty workaround for a BYOND issue.
|
||||
var/icon/temp = I
|
||||
I = icon()
|
||||
@@ -1162,11 +1183,11 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0
|
||||
|
||||
key = "[generate_asset_name(I)].png"
|
||||
if(!SSassets.cache[key])
|
||||
register_asset(key, I)
|
||||
SSassets.transport.register_asset(key, I)
|
||||
for (var/thing2 in targets)
|
||||
send_asset(thing2, key)
|
||||
SSassets.transport.send_assets(thing2, key)
|
||||
|
||||
return "<img class='icon icon-[icon_state]' src=\"[url_encode(key)]\">"
|
||||
return "<img class='icon icon-[icon_state]' src='[SSassets.transport.get_asset_url(key)]'>"
|
||||
|
||||
/proc/icon2base64html(thing)
|
||||
if (!thing)
|
||||
@@ -1202,7 +1223,7 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0
|
||||
return "<img class='icon icon-[A.icon_state]' src='data:image/png;base64,[bicon_cache[key]]'>"
|
||||
|
||||
//Costlier version of icon2html() that uses getFlatIcon() to account for overlays, underlays, etc. Use with extreme moderation, ESPECIALLY on mobs.
|
||||
/proc/costly_icon2html(thing, target)
|
||||
/proc/costly_icon2html(thing, target, sourceonly = FALSE)
|
||||
if (!thing)
|
||||
return
|
||||
|
||||
@@ -1210,4 +1231,5 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0
|
||||
return icon2html(thing, target)
|
||||
|
||||
var/icon/I = getFlatIcon(thing)
|
||||
return icon2html(I, target)
|
||||
return icon2html(I, target, sourceonly = sourceonly)
|
||||
|
||||
|
||||
@@ -349,7 +349,7 @@
|
||||
if(!previous)
|
||||
var/list/report_parts = list(personal_report(C), GLOB.common_report)
|
||||
content = report_parts.Join()
|
||||
C.verbs -= /client/proc/show_previous_roundend_report
|
||||
remove_verb(C, /client/proc/show_previous_roundend_report)
|
||||
fdel(filename)
|
||||
text2file(content, filename)
|
||||
else
|
||||
@@ -358,7 +358,7 @@
|
||||
roundend_report.stylesheets = list()
|
||||
roundend_report.add_stylesheet("roundend", 'html/browser/roundend.css')
|
||||
roundend_report.add_stylesheet("font-awesome", 'html/font-awesome/css/all.min.css')
|
||||
roundend_report.open(0)
|
||||
roundend_report.open(FALSE)
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/personal_report(client/C, popcount)
|
||||
var/list/parts = list()
|
||||
@@ -402,7 +402,7 @@
|
||||
for (var/i in GLOB.ai_list)
|
||||
var/mob/living/silicon/ai/aiPlayer = i
|
||||
if(aiPlayer.mind)
|
||||
parts += "<b>[aiPlayer.name]</b> (Played by: <b>[aiPlayer.mind.key]</b>)'s laws [aiPlayer.stat != DEAD ? "at the end of the round" : "when it was <span class='redtext'>deactivated</span>"] were:"
|
||||
parts += "<b>[aiPlayer.name]</b>[aiPlayer.mind.hide_ckey ? "" : " (Played by: <b>[aiPlayer.mind.key]</b>)"]'s laws [aiPlayer.stat != DEAD ? "at the end of the round" : "when it was <span class='redtext'>deactivated</span>"] were:"
|
||||
parts += aiPlayer.laws.get_law_list(include_zeroth=TRUE)
|
||||
|
||||
parts += "<b>Total law changes: [aiPlayer.law_change_counter]</b>"
|
||||
@@ -413,14 +413,14 @@
|
||||
for(var/mob/living/silicon/robot/robo in aiPlayer.connected_robots)
|
||||
borg_num--
|
||||
if(robo.mind)
|
||||
robolist += "<b>[robo.name]</b> (Played by: <b>[robo.mind.key]</b>)[robo.stat == DEAD ? " <span class='redtext'>(Deactivated)</span>" : ""][borg_num ?", ":""]<br>"
|
||||
robolist += "<b>[robo.name]</b>[robo.mind.hide_ckey ? "" : " (Played by: <b>[robo.mind.key]</b>)"] [robo.stat == DEAD ? " <span class='redtext'>(Deactivated)</span>" : ""][borg_num ?", ":""]<br>"
|
||||
parts += "[robolist]"
|
||||
if(!borg_spacer)
|
||||
borg_spacer = TRUE
|
||||
|
||||
for (var/mob/living/silicon/robot/robo in GLOB.silicon_mobs)
|
||||
if (!robo.connected_ai && robo.mind)
|
||||
parts += "[borg_spacer?"<br>":""]<b>[robo.name]</b> (Played by: <b>[robo.mind.key]</b>) [(robo.stat != DEAD)? "<span class='greentext'>survived</span> as an AI-less borg!" : "was <span class='redtext'>unable to survive</span> the rigors of being a cyborg without an AI."] Its laws were:"
|
||||
parts += "[borg_spacer?"<br>":""]<b>[robo.name]</b>[robo.mind.hide_ckey ? "" : " (Played by: <b>[robo.mind.key]</b>)"] [(robo.stat != DEAD)? "<span class='greentext'>survived</span> as an AI-less borg!" : "was <span class='redtext'>unable to survive</span> the rigors of being a cyborg without an AI."] Its laws were:"
|
||||
|
||||
if(robo) //How the hell do we lose robo between here and the world messages directly above this?
|
||||
parts += robo.laws.get_law_list(include_zeroth=TRUE)
|
||||
@@ -529,7 +529,7 @@
|
||||
var/jobtext = ""
|
||||
if(ply.assigned_role)
|
||||
jobtext = " the <b>[ply.assigned_role]</b>"
|
||||
var/text = "<b>[ply.key]</b> was <b>[ply.name]</b>[jobtext] and"
|
||||
var/text = "<b>[ply.hide_ckey ? "<b>[ply.name]</b>[jobtext] " : "[ply.key]</b> was <b>[ply.name]</b>[jobtext] and "]"
|
||||
if(ply.current)
|
||||
if(ply.current.stat == DEAD)
|
||||
text += " <span class='redtext'>died</span>"
|
||||
|
||||
+14
-10
@@ -462,16 +462,14 @@
|
||||
else
|
||||
. = max(0, min(255, 138.5177312231 * log(temp - 10) - 305.0447927307))
|
||||
|
||||
/proc/fusionpower2text(power) //used when displaying fusion power on analyzers
|
||||
switch(power)
|
||||
if(0 to 5)
|
||||
return "low"
|
||||
if(5 to 20)
|
||||
return "mid"
|
||||
if(20 to 50)
|
||||
return "high"
|
||||
if(50 to INFINITY)
|
||||
return "super"
|
||||
/proc/instability2text(instability) //used when displaying fusion power on analyzers
|
||||
switch(instability)
|
||||
if(0 to 2)
|
||||
return "stable, meaning that its heat will always increase."
|
||||
if(2 to 3)
|
||||
return "metastable, meaning that its heat will trend upwards."
|
||||
if (3 to INFINITY)
|
||||
return "unstable, meaning that its heat will trend downwards."
|
||||
|
||||
/proc/color2hex(color) //web colors
|
||||
if(!color)
|
||||
@@ -620,6 +618,12 @@
|
||||
else //regex everything else (works for /proc too)
|
||||
return lowertext(replacetext("[the_type]", "[type2parent(the_type)]/", ""))
|
||||
|
||||
|
||||
/// Return html to load a url.
|
||||
/// for use inside of browse() calls to html assets that might be loaded on a cdn.
|
||||
/proc/url2htmlloader(url)
|
||||
return {"<html><head><meta http-equiv="refresh" content="0;URL='[url]'"/></head><body onLoad="parent.location='[url]'"></body></html>"}
|
||||
|
||||
/proc/strtohex(str)
|
||||
if(!istext(str)||!str)
|
||||
return
|
||||
|
||||
@@ -1254,6 +1254,10 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
var/obj/structure/window/W = O
|
||||
if(W.ini_dir == dir_to_check || W.ini_dir == FULLTILE_WINDOW_DIR || dir_to_check == FULLTILE_WINDOW_DIR)
|
||||
return FALSE
|
||||
if(istype(O, /obj/structure/railing))
|
||||
var/obj/structure/railing/rail = O
|
||||
if(rail.ini_dir == dir_to_check || rail.ini_dir == FULLTILE_WINDOW_DIR || dir_to_check == FULLTILE_WINDOW_DIR)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/proc/pass()
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* handles adding verbs and updating the stat panel browser
|
||||
*
|
||||
* pass the verb type path to this instead of adding it directly to verbs so the statpanel can update
|
||||
* Arguments:
|
||||
* * target - Who the verb is being added to, client or mob typepath
|
||||
* * verb - typepath to a verb, or a list of verbs, supports lists of lists
|
||||
*/
|
||||
/proc/add_verb(client/target, verb_or_list_to_add)
|
||||
if(!target)
|
||||
CRASH("add_verb called without a target")
|
||||
if(IsAdminAdvancedProcCall())
|
||||
return
|
||||
var/mob/mob_target = null
|
||||
|
||||
if(ismob(target))
|
||||
mob_target = target
|
||||
target = mob_target.client
|
||||
else if(!istype(target, /client))
|
||||
CRASH("add_verb called on a non-mob and non-client")
|
||||
var/list/verbs_list = list()
|
||||
if(!islist(verb_or_list_to_add))
|
||||
verbs_list += verb_or_list_to_add
|
||||
else
|
||||
var/list/verb_listref = verb_or_list_to_add
|
||||
var/list/elements_to_process = verb_listref.Copy()
|
||||
while(length(elements_to_process))
|
||||
var/element_or_list = elements_to_process[length(elements_to_process)] //Last element
|
||||
elements_to_process.len--
|
||||
if(islist(element_or_list))
|
||||
elements_to_process += element_or_list //list/a += list/b adds the contents of b into a, not the reference to the list itself
|
||||
else
|
||||
verbs_list += element_or_list
|
||||
|
||||
if(mob_target)
|
||||
mob_target.verbs += verbs_list
|
||||
if(!target)
|
||||
return //Our work is done.
|
||||
else
|
||||
target.verbs += verbs_list
|
||||
|
||||
var/list/output_list = list()
|
||||
for(var/thing in verbs_list)
|
||||
var/procpath/verb_to_add = thing
|
||||
output_list[++output_list.len] = list(verb_to_add.category, verb_to_add.name)
|
||||
output_list = url_encode(json_encode(output_list))
|
||||
|
||||
target << output("[output_list];", "statbrowser:add_verb_list")
|
||||
|
||||
/**
|
||||
* handles removing verb and sending it to browser to update, use this for removing verbs
|
||||
*
|
||||
* pass the verb type path to this instead of removing it from verbs so the statpanel can update
|
||||
* Arguments:
|
||||
* * target - Who the verb is being removed from, client or mob typepath
|
||||
* * verb - typepath to a verb, or a list of verbs, supports lists of lists
|
||||
*/
|
||||
/proc/remove_verb(client/target, verb_or_list_to_remove)
|
||||
if(IsAdminAdvancedProcCall())
|
||||
return
|
||||
|
||||
var/mob/mob_target = null
|
||||
if(ismob(target))
|
||||
mob_target = target
|
||||
target = mob_target.client
|
||||
else if(!istype(target, /client))
|
||||
CRASH("remove_verb called on a non-mob and non-client")
|
||||
|
||||
var/list/verbs_list = list()
|
||||
if(!islist(verb_or_list_to_remove))
|
||||
verbs_list += verb_or_list_to_remove
|
||||
else
|
||||
var/list/verb_listref = verb_or_list_to_remove
|
||||
var/list/elements_to_process = verb_listref.Copy()
|
||||
while(length(elements_to_process))
|
||||
var/element_or_list = elements_to_process[length(elements_to_process)] //Last element
|
||||
elements_to_process.len--
|
||||
if(islist(element_or_list))
|
||||
elements_to_process += element_or_list //list/a += list/b adds the contents of b into a, not the reference to the list itself
|
||||
else
|
||||
verbs_list += element_or_list
|
||||
|
||||
if(mob_target)
|
||||
mob_target.verbs -= verbs_list
|
||||
if(!target)
|
||||
return //Our work is done.
|
||||
else
|
||||
target.verbs -= verbs_list
|
||||
|
||||
var/list/output_list = list()
|
||||
for(var/thing in verbs_list)
|
||||
var/procpath/verb_to_remove = thing
|
||||
output_list[++output_list.len] = list(verb_to_remove.category, verb_to_remove.name)
|
||||
output_list = url_encode(json_encode(output_list))
|
||||
|
||||
target << output("[output_list];", "statbrowser:remove_verb_list")
|
||||
@@ -267,7 +267,7 @@ GLOBAL_LIST_INIT(redacted_strings, list("\[REDACTED\]", "\[CLASSIFIED\]", "\[ARC
|
||||
|
||||
GLOBAL_LIST_INIT(wisdoms, world.file2list("strings/wisdoms.txt"))
|
||||
|
||||
GLOBAL_LIST_INIT(speech_verbs, list("default","says","gibbers", "states", "chitters", "declares", "bellows", "buzzes" ,"beeps", "chirps" ,"hisses" ,"poofs" ,"rattles", "mewls" ,"barks", "blorbles", "squeaks", "squawks", "flutters"))
|
||||
GLOBAL_LIST_INIT(speech_verbs, list("default","says","gibbers", "states", "chitters", "chimpers", "declares", "bellows", "buzzes" ,"beeps", "chirps", "clicks", "hisses" ,"poofs" , "puffs", "rattles", "mewls" ,"barks", "blorbles", "squeaks", "squawks", "flutters", "warbles"))
|
||||
|
||||
GLOBAL_LIST_INIT(roundstart_tongues, list("default","human tongue" = /obj/item/organ/tongue, "lizard tongue" = /obj/item/organ/tongue/lizard, "skeleton tongue" = /obj/item/organ/tongue/bone, "fly tongue" = /obj/item/organ/tongue/fly, "ipc tongue" = /obj/item/organ/tongue/robot/ipc))
|
||||
|
||||
@@ -278,3 +278,12 @@ GLOBAL_LIST_INIT(all_mutant_parts, list("tail_lizard" = "Tail", "mam_tail" = "Ta
|
||||
GLOBAL_LIST_INIT(unlocked_mutant_parts, list("horns", "insect_fluff"))
|
||||
//parts in either of the above two lists that require a second option that allows them to be coloured
|
||||
GLOBAL_LIST_INIT(colored_mutant_parts, list("insect_wings" = "wings_color", "deco_wings" = "wings_color", "horns" = "horns_color"))
|
||||
|
||||
//body ids that have greyscale sprites
|
||||
GLOBAL_LIST_INIT(greyscale_limb_types, list("human","moth","lizard","pod","plant","jelly","slime","golem","lum","stargazer","mush","ethereal","snail","c_golem","b_golem","mammal","xeno","ipc","insect","synthliz","avian","aquatic"))
|
||||
|
||||
//body ids that have prosthetic sprites
|
||||
GLOBAL_LIST_INIT(prosthetic_limb_types, list("xion","bishop","cybersolutions","grayson","hephaestus","nanotrasen","talon"))
|
||||
|
||||
//body ids that have non-gendered bodyparts
|
||||
GLOBAL_LIST_INIT(nongendered_limb_types, list("fly", "zombie" ,"synth", "shadow", "cultgolem", "agent", "plasmaman", "clockgolem", "clothgolem"))
|
||||
|
||||
@@ -107,13 +107,8 @@ GLOBAL_LIST_INIT(maintenance_loot, list(
|
||||
/obj/item/toy/eightball = 1,
|
||||
/obj/item/reagent_containers/pill/floorpill = 1,
|
||||
/obj/item/reagent_containers/food/snacks/cannedpeaches/maint = 2,
|
||||
/obj/item/storage/daki = 3, //VERY IMPORTANT CIT CHANGE - adds bodypillows to maint
|
||||
/obj/item/storage/pill_bottle/penis_enlargement = 2,
|
||||
/obj/item/storage/pill_bottle/breast_enlargement = 2,
|
||||
/obj/item/clothing/shoes/wheelys = 1,
|
||||
/obj/item/clothing/shoes/kindleKicks = 1,
|
||||
/obj/item/autosurgeon/penis = 1,
|
||||
/obj/item/autosurgeon/testicles = 1,
|
||||
/obj/item/storage/box/marshmallow = 2,
|
||||
/obj/item/clothing/gloves/tackler/offbrand = 1,
|
||||
/obj/item/stack/sticky_tape = 1,
|
||||
|
||||
@@ -13,6 +13,7 @@ GLOBAL_LIST_EMPTY(deliverybeacontags) //list of all tags associated with d
|
||||
GLOBAL_LIST_EMPTY(nuke_list)
|
||||
GLOBAL_LIST_EMPTY(alarmdisplay) //list of all machines or programs that can display station alerts
|
||||
GLOBAL_LIST_EMPTY(singularities) //list of all singularities on the station (actually technically all engines)
|
||||
GLOBAL_LIST_EMPTY(grounding_rods) //list of all grounding rods on the station
|
||||
|
||||
GLOBAL_LIST(chemical_reactions_list) //list of all /datum/chemical_reaction datums. Used during chemical reactions
|
||||
GLOBAL_LIST(chemical_reagents_list) //list of all /datum/reagent datums indexed by reagent id. Used by chemistry stuff
|
||||
@@ -41,3 +42,6 @@ GLOBAL_LIST_EMPTY(ai_status_displays)
|
||||
|
||||
GLOBAL_LIST_EMPTY(mob_spawners) // All mob_spawn objects
|
||||
GLOBAL_LIST_EMPTY(alert_consoles) // Station alert consoles, /obj/machinery/computer/station_alert
|
||||
|
||||
//list of everyone playing rock paper scissors
|
||||
GLOBAL_LIST_EMPTY(rockpaperscissors_players)
|
||||
|
||||
+2
-2
@@ -112,8 +112,8 @@
|
||||
/mob/living/silicon/ai/CtrlClickOn(var/atom/A)
|
||||
A.AICtrlClick(src)
|
||||
/mob/living/silicon/ai/AltClickOn(var/atom/A)
|
||||
if(!A.AIAltClick(src))
|
||||
altclick_listed_turf(A)
|
||||
A.AIAltClick(src)
|
||||
|
||||
|
||||
/*
|
||||
The following criminally helpful code is just the previous code cleaned up;
|
||||
|
||||
+17
-13
@@ -319,20 +319,13 @@
|
||||
return ..()
|
||||
/*
|
||||
Alt click
|
||||
Unused except for AI
|
||||
Used as an alternate way to interact with things.
|
||||
*/
|
||||
/mob/proc/AltClickOn(atom/A)
|
||||
if(!A.AltClick(src))
|
||||
altclick_listed_turf(A)
|
||||
|
||||
/mob/proc/altclick_listed_turf(atom/A)
|
||||
var/turf/T = get_turf(A)
|
||||
if(T == A.loc || T == A)
|
||||
if(T == listed_turf)
|
||||
listed_turf = null
|
||||
else if(TurfAdjacent(T))
|
||||
listed_turf = T
|
||||
client.statpanel = T.name
|
||||
. = SEND_SIGNAL(src, COMSIG_MOB_ALTCLICKON, A)
|
||||
if(. & COMSIG_MOB_CANCEL_CLICKON)
|
||||
return
|
||||
A.AltClick(src)
|
||||
|
||||
/mob/living/carbon/AltClickOn(atom/A)
|
||||
if(!stat && mind && iscarbon(A) && A != src)
|
||||
@@ -344,7 +337,18 @@
|
||||
..()
|
||||
|
||||
/atom/proc/AltClick(mob/user)
|
||||
. = SEND_SIGNAL(src, COMSIG_CLICK_ALT, user)
|
||||
SEND_SIGNAL(src, COMSIG_CLICK_ALT, user)
|
||||
var/turf/T = get_turf(src)
|
||||
if(T && (isturf(loc) || isturf(src)) && user.TurfAdjacent(T))
|
||||
user.listed_turf = T
|
||||
user.client << output("[url_encode(json_encode(T.name))];", "statbrowser:create_listedturf")
|
||||
|
||||
/// Use this instead of [/mob/proc/AltClickOn] where you only want turf content listing without additional atom alt-click interaction
|
||||
/atom/proc/AltClickNoInteract(mob/user, atom/A)
|
||||
var/turf/T = get_turf(A)
|
||||
if(T && user.TurfAdjacent(T))
|
||||
user.listed_turf = T
|
||||
user.client << output("[url_encode(json_encode(T.name))];", "statbrowser:create_listedturf")
|
||||
|
||||
/mob/proc/TurfAdjacent(turf/T)
|
||||
return T.Adjacent(src)
|
||||
|
||||
@@ -98,8 +98,7 @@
|
||||
/mob/living/silicon/robot/CtrlClickOn(atom/A)
|
||||
A.BorgCtrlClick(src)
|
||||
/mob/living/silicon/robot/AltClickOn(atom/A)
|
||||
if(!A.BorgAltClick(src))
|
||||
altclick_listed_turf(A)
|
||||
A.BorgAltClick(src)
|
||||
|
||||
/atom/proc/BorgCtrlShiftClick(mob/living/silicon/robot/user) //forward to human click if not overridden
|
||||
CtrlShiftClick(user)
|
||||
|
||||
@@ -149,6 +149,27 @@
|
||||
name = "Choking (Plasma)"
|
||||
desc = "There's highly flammable, toxic plasma in the air and you're breathing it in. Find some fresh air. The box in your backpack has an oxygen tank and gas mask in it."
|
||||
icon_state = "too_much_tox"
|
||||
|
||||
/obj/screen/alert/not_enough_ch4
|
||||
name = "Choking (No CH4)"
|
||||
desc = "You're not getting enough methane. Find some good air before you pass out!"
|
||||
icon_state = "not_enough_ch4"
|
||||
|
||||
/obj/screen/alert/too_much_ch4
|
||||
name = "Choking (CH4)"
|
||||
desc = "There's too much methane in the air, and you're breathing it in! Find some good air before you pass out!"
|
||||
icon_state = "too_much_ch4"
|
||||
|
||||
/obj/screen/alert/not_enough_ch3br
|
||||
name = "Choking (No CH3Br)"
|
||||
desc = "You're not getting enough methyl bromide. Find some good air before you pass out!"
|
||||
icon_state = "not_enough_tox"
|
||||
|
||||
/obj/screen/alert/too_much_ch3br
|
||||
name = "Choking (CH3Br)"
|
||||
desc = "There's highly toxic methyl bromide in the air and you're breathing it in. Find some fresh air. The box in your backpack has an oxygen tank and gas mask in it."
|
||||
icon_state = "too_much_tox"
|
||||
|
||||
//End gas alerts
|
||||
|
||||
|
||||
@@ -184,14 +205,23 @@
|
||||
|
||||
/obj/screen/alert/hot
|
||||
name = "Too Hot"
|
||||
desc = "You're flaming hot! Get somewhere cooler and take off any insulating clothing like a fire suit."
|
||||
desc = "The air around you is pretty toasty! Consider putting on some insulating clothing, or moving to a cooler area."
|
||||
icon_state = "hot"
|
||||
|
||||
/obj/screen/alert/cold
|
||||
name = "Too Cold"
|
||||
desc = "You're freezing cold! Get somewhere warmer and take off any insulating clothing like a space suit."
|
||||
desc = "The air around you is pretty cold! Consider wearing a coat, or moving to a warmer area."
|
||||
icon_state = "cold"
|
||||
|
||||
/obj/screen/alert/sweat
|
||||
name = "Sweating"
|
||||
desc = "You're sweating! Get somewhere cooler and take off any insulating clothing like a fire suit."
|
||||
icon_state = "sweat"
|
||||
|
||||
/obj/screen/alert/shiver
|
||||
name = "Shivering"
|
||||
desc = "You're shivering! Get somewhere warmer and take off any insulating clothing like a space suit."
|
||||
|
||||
/obj/screen/alert/lowpressure
|
||||
name = "Low Pressure"
|
||||
desc = "The air around you is hazardously thin. A space suit would protect you."
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
var/icon/credits_icon = new(CREDITS_PATH)
|
||||
LAZYINITLIST(credits)
|
||||
var/list/_credits = credits
|
||||
verbs += /client/proc/ClearCredits
|
||||
add_verb(src, /client/proc/ClearCredits)
|
||||
var/static/list/credit_order_for_this_round
|
||||
if(isnull(credit_order_for_this_round))
|
||||
credit_order_for_this_round = list("Thanks for playing!") + (shuffle(icon_states(credits_icon)) - "Thanks for playing!")
|
||||
@@ -21,13 +21,13 @@
|
||||
_credits += new /obj/screen/credit(null, I, src, credits_icon)
|
||||
sleep(CREDIT_SPAWN_SPEED)
|
||||
sleep(CREDIT_ROLL_SPEED - CREDIT_SPAWN_SPEED)
|
||||
verbs -= /client/proc/ClearCredits
|
||||
remove_verb(src, /client/proc/ClearCredits)
|
||||
qdel(credits_icon)
|
||||
|
||||
/client/proc/ClearCredits()
|
||||
set name = "Hide Credits"
|
||||
set category = "OOC"
|
||||
verbs -= /client/proc/ClearCredits
|
||||
remove_verb(src, /client/proc/ClearCredits)
|
||||
QDEL_LIST(credits)
|
||||
credits = null
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
ShiftClickOn(A)
|
||||
return
|
||||
if(modifiers["alt"])
|
||||
altclick_listed_turf(A)
|
||||
AltClickNoInteract(src, A)
|
||||
return
|
||||
if(modifiers["ctrl"])
|
||||
CtrlClickOn(A)
|
||||
|
||||
@@ -32,4 +32,4 @@
|
||||
/mob/camera/blob/AltClickOn(atom/A) //Remove a blob
|
||||
var/turf/T = get_turf(A)
|
||||
if(T)
|
||||
remove_blob(T)
|
||||
remove_blob(T)
|
||||
|
||||
@@ -14,13 +14,15 @@
|
||||
var/list/modes // allowed modes
|
||||
var/list/gamemode_cache
|
||||
var/list/votable_modes // votable modes
|
||||
// var/list/ic_filter_regex
|
||||
var/list/storyteller_cache
|
||||
var/list/mode_names
|
||||
var/list/mode_reports
|
||||
var/list/mode_false_report_weight
|
||||
|
||||
var/motd
|
||||
// var/policy
|
||||
|
||||
// var/static/regex/ic_filter_regex
|
||||
|
||||
/datum/controller/configuration/proc/admin_reload()
|
||||
if(IsAdminAdvancedProcCall())
|
||||
@@ -50,6 +52,11 @@
|
||||
break
|
||||
loadmaplist(CONFIG_MAPS_FILE)
|
||||
LoadMOTD()
|
||||
// LoadPolicy()
|
||||
// LoadChatFilter()
|
||||
|
||||
if (Master)
|
||||
Master.OnConfigLoad()
|
||||
|
||||
/datum/controller/configuration/proc/full_wipe()
|
||||
if(IsAdminAdvancedProcCall())
|
||||
@@ -135,7 +142,7 @@
|
||||
|
||||
if(entry == "$include")
|
||||
if(!value)
|
||||
log_config("LINE [linenumber]: Invalid $include directive: [value]")
|
||||
log_config("LINE [linenumber]: Warning: Invalid $include directive: [value]")
|
||||
else
|
||||
LoadEntries(value, stack)
|
||||
++.
|
||||
@@ -143,7 +150,7 @@
|
||||
|
||||
var/datum/config_entry/E = _entries[entry]
|
||||
if(!E)
|
||||
log_config("LINE [linenumber]: Unknown setting: '[entry]'")
|
||||
log_config("LINE [linenumber]: Unknown setting in configuration: '[entry]'")
|
||||
continue
|
||||
|
||||
if(lockthis)
|
||||
@@ -153,9 +160,9 @@
|
||||
var/datum/config_entry/new_ver = entries_by_type[E.deprecated_by]
|
||||
var/new_value = E.DeprecationUpdate(value)
|
||||
var/good_update = istext(new_value)
|
||||
log_config("LINE [linenumber]: [entry] is deprecated and will be removed soon. Migrate to [new_ver.name]![good_update ? " Suggested new value is: [new_value]" : ""]")
|
||||
log_config("LINE [linenumber]: Entry [entry] is deprecated and will be removed soon. Migrate to [new_ver.name]![good_update ? " Suggested new value is: [new_value]" : ""]")
|
||||
if(!warned_deprecated_configs)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, /proc/message_admins, "This server is using deprecated configuration settings. Please check the logs and update accordingly."), 0)
|
||||
DelayedMessageAdmins("This server is using deprecated configuration settings. Please check the logs and update accordingly.")
|
||||
warned_deprecated_configs = TRUE
|
||||
if(good_update)
|
||||
value = new_value
|
||||
@@ -163,7 +170,7 @@
|
||||
else
|
||||
warning("[new_ver.type] is deprecated but gave no proper return for DeprecationUpdate()")
|
||||
|
||||
var/validated = E.ValidateAndSet(value, TRUE)
|
||||
var/validated = E.ValidateAndSet(value)
|
||||
if(!validated)
|
||||
log_config("LINE [linenumber]: Failed to validate setting \"[value]\" for [entry]")
|
||||
else
|
||||
@@ -190,18 +197,11 @@
|
||||
var/list/banned_edits = list(NAMEOF(src, entries_by_type), NAMEOF(src, entries), NAMEOF(src, directory))
|
||||
return !(var_name in banned_edits) && ..()
|
||||
|
||||
/datum/controller/configuration/stat_entry()
|
||||
if(!statclick)
|
||||
statclick = new/obj/effect/statclick/debug(null, "Edit", src)
|
||||
stat("[name]:", statclick)
|
||||
|
||||
/datum/controller/configuration/proc/Get(entry_type)
|
||||
var/datum/config_entry/E = GetEntryDatum(entry_type)
|
||||
if((E.protection & CONFIG_ENTRY_HIDDEN) && IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "[REF(src)]")
|
||||
log_admin_private("Config access of [entry_type] attempted by [key_name(usr)]")
|
||||
return
|
||||
return E.config_entry_value
|
||||
/datum/controller/configuration/stat_entry(msg)
|
||||
msg = "Edit"
|
||||
return msg
|
||||
|
||||
/// Your typical GET but returns a config.
|
||||
/datum/controller/configuration/proc/GetEntryDatum(entry_type)
|
||||
var/datum/config_entry/E = entry_type
|
||||
var/entry_is_abstract = initial(E.abstract_type) == entry_type
|
||||
@@ -210,8 +210,24 @@
|
||||
E = entries_by_type[entry_type]
|
||||
if(!E)
|
||||
CRASH("Missing config entry for [entry_type]!")
|
||||
if((E.protection & CONFIG_ENTRY_HIDDEN) && IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "[REF(src)]")
|
||||
log_admin_private("Config access of [entry_type] attempted by [key_name(usr)]")
|
||||
return
|
||||
return E
|
||||
|
||||
/datum/controller/configuration/proc/Get(entry_type)
|
||||
var/datum/config_entry/E = entry_type
|
||||
var/entry_is_abstract = initial(E.abstract_type) == entry_type
|
||||
if(entry_is_abstract)
|
||||
CRASH("Tried to retrieve an abstract config_entry: [entry_type]")
|
||||
E = entries_by_type[entry_type]
|
||||
if(!E)
|
||||
CRASH("Missing config entry for [entry_type]!")
|
||||
if((E.protection & CONFIG_ENTRY_HIDDEN) && IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "[REF(src)]")
|
||||
log_admin_private("Config access of [entry_type] attempted by [key_name(usr)]")
|
||||
return
|
||||
return E.config_entry_value
|
||||
|
||||
/datum/controller/configuration/proc/Set(entry_type, new_val)
|
||||
var/datum/config_entry/E = entry_type
|
||||
var/entry_is_abstract = initial(E.abstract_type) == entry_type
|
||||
@@ -236,7 +252,6 @@
|
||||
for(var/T in gamemode_cache)
|
||||
// I wish I didn't have to instance the game modes in order to look up
|
||||
// their information, but it is the only way (at least that I know of).
|
||||
// for future reference: just use initial() lol
|
||||
var/datum/game_mode/M = new T()
|
||||
|
||||
if(M.config_tag)
|
||||
@@ -258,7 +273,37 @@
|
||||
var/tm_info = GLOB.revdata.GetTestMergeInfo()
|
||||
if(motd || tm_info)
|
||||
motd = motd ? "[motd]<br>[tm_info]" : tm_info
|
||||
/*
|
||||
Policy file should be a json file with a single object.
|
||||
Value is raw html.
|
||||
|
||||
Possible keywords :
|
||||
Job titles / Assigned roles (ghost spawners for example) : Assistant , Captain , Ash Walker
|
||||
Mob types : /mob/living/simple_animal/hostile/carp
|
||||
Antagonist types : /datum/antagonist/highlander
|
||||
Species types : /datum/species/lizard
|
||||
special keywords defined in _DEFINES/admin.dm
|
||||
|
||||
Example config:
|
||||
{
|
||||
"Assistant" : "Don't kill everyone",
|
||||
"/datum/antagonist/highlander" : "<b>Kill everyone</b>",
|
||||
"Ash Walker" : "Kill all spacemans"
|
||||
}
|
||||
|
||||
*/
|
||||
/*
|
||||
/datum/controller/configuration/proc/LoadPolicy()
|
||||
policy = list()
|
||||
var/rawpolicy = file2text("[directory]/policy.json")
|
||||
if(rawpolicy)
|
||||
var/parsed = safe_json_decode(rawpolicy)
|
||||
if(!parsed)
|
||||
log_config("JSON parsing failure for policy.json")
|
||||
DelayedMessageAdmins("JSON parsing failure for policy.json")
|
||||
else
|
||||
policy = parsed
|
||||
*/
|
||||
/datum/controller/configuration/proc/loadmaplist(filename)
|
||||
log_config("Loading config file [filename]...")
|
||||
filename = "[directory]/[filename]"
|
||||
@@ -305,6 +350,8 @@
|
||||
currentmap.voteweight = text2num(data)
|
||||
if ("default","defaultmap")
|
||||
defaultmap = currentmap
|
||||
//if ("votable")
|
||||
// currentmap.votable = TRUE
|
||||
if ("endmap")
|
||||
LAZYINITLIST(maplist)
|
||||
maplist[currentmap.map_name] = currentmap
|
||||
@@ -326,6 +373,7 @@
|
||||
return new T
|
||||
return new /datum/game_mode/extended()
|
||||
|
||||
/// For dynamic.
|
||||
/datum/controller/configuration/proc/pick_storyteller(storyteller_name)
|
||||
for(var/T in storyteller_cache)
|
||||
var/datum/dynamic_storyteller/S = T
|
||||
@@ -334,6 +382,32 @@
|
||||
return T
|
||||
return /datum/dynamic_storyteller/classic
|
||||
|
||||
/// Same with this
|
||||
/datum/controller/configuration/proc/get_runnable_storytellers()
|
||||
var/list/datum/dynamic_storyteller/runnable_storytellers = new
|
||||
var/list/probabilities = Get(/datum/config_entry/keyed_list/storyteller_weight)
|
||||
var/list/repeated_mode_adjust = Get(/datum/config_entry/number_list/repeated_mode_adjust)
|
||||
var/list/min_player_counts = Get(/datum/config_entry/keyed_list/storyteller_min_players)
|
||||
for(var/T in storyteller_cache)
|
||||
var/datum/dynamic_storyteller/S = T
|
||||
var/config_tag = initial(S.config_tag)
|
||||
var/probability = (config_tag in probabilities) ? probabilities[config_tag] : initial(S.weight)
|
||||
var/min_players = (config_tag in min_player_counts) ? min_player_counts[config_tag] : initial(S.min_players)
|
||||
if(probability <= 0)
|
||||
continue
|
||||
if(length(GLOB.player_list) < min_players)
|
||||
continue
|
||||
if(SSpersistence.saved_storytellers.len == repeated_mode_adjust.len)
|
||||
var/name = initial(S.name)
|
||||
var/recent_round = min(SSpersistence.saved_storytellers.Find(name),3)
|
||||
var/adjustment = 0
|
||||
while(recent_round)
|
||||
adjustment += repeated_mode_adjust[recent_round]
|
||||
recent_round = SSpersistence.saved_modes.Find(name,recent_round+1,0)
|
||||
probability *= ((100-adjustment)/100)
|
||||
runnable_storytellers[S] = probability
|
||||
return runnable_storytellers
|
||||
|
||||
/datum/controller/configuration/proc/get_runnable_modes()
|
||||
var/list/datum/game_mode/runnable_modes = new
|
||||
var/list/probabilities = Get(/datum/config_entry/keyed_list/probability)
|
||||
@@ -367,32 +441,6 @@
|
||||
runnable_modes[M] = final_weight
|
||||
return runnable_modes
|
||||
|
||||
/datum/controller/configuration/proc/get_runnable_storytellers()
|
||||
var/list/datum/dynamic_storyteller/runnable_storytellers = new
|
||||
var/list/probabilities = Get(/datum/config_entry/keyed_list/storyteller_weight)
|
||||
var/list/repeated_mode_adjust = Get(/datum/config_entry/number_list/repeated_mode_adjust)
|
||||
var/list/min_player_counts = Get(/datum/config_entry/keyed_list/storyteller_min_players)
|
||||
for(var/T in storyteller_cache)
|
||||
var/datum/dynamic_storyteller/S = T
|
||||
var/config_tag = initial(S.config_tag)
|
||||
var/probability = (config_tag in probabilities) ? probabilities[config_tag] : initial(S.weight)
|
||||
var/min_players = (config_tag in min_player_counts) ? min_player_counts[config_tag] : initial(S.min_players)
|
||||
if(probability <= 0)
|
||||
continue
|
||||
if(length(GLOB.player_list) < min_players)
|
||||
continue
|
||||
if(SSpersistence.saved_storytellers.len == repeated_mode_adjust.len)
|
||||
var/name = initial(S.name)
|
||||
var/recent_round = min(SSpersistence.saved_storytellers.Find(name),3)
|
||||
var/adjustment = 0
|
||||
while(recent_round)
|
||||
adjustment += repeated_mode_adjust[recent_round]
|
||||
recent_round = SSpersistence.saved_modes.Find(name,recent_round+1,0)
|
||||
probability *= ((100-adjustment)/100)
|
||||
runnable_storytellers[S] = probability
|
||||
return runnable_storytellers
|
||||
|
||||
|
||||
/datum/controller/configuration/proc/get_runnable_midround_modes(crew)
|
||||
var/list/datum/game_mode/runnable_modes = new
|
||||
var/list/probabilities = Get(/datum/config_entry/keyed_list/probability)
|
||||
@@ -418,7 +466,6 @@
|
||||
/*
|
||||
/datum/controller/configuration/proc/LoadChatFilter()
|
||||
var/list/in_character_filter = list()
|
||||
|
||||
if(!fexists("[directory]/in_character_filter.txt"))
|
||||
return
|
||||
log_config("Loading config file in_character_filter.txt...")
|
||||
@@ -428,8 +475,8 @@
|
||||
if(findtextEx(line,"#",1,2))
|
||||
continue
|
||||
in_character_filter += REGEX_QUOTE(line)
|
||||
|
||||
ic_filter_regex = in_character_filter.len ? regex("\\b([jointext(in_character_filter, "|")])\\b", "i") : null
|
||||
|
||||
syncChatRegexes()
|
||||
*/
|
||||
//Message admins when you can.
|
||||
/datum/controller/configuration/proc/DelayedMessageAdmins(text)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, /proc/message_admins, text), 0)
|
||||
|
||||
@@ -535,3 +535,15 @@
|
||||
|
||||
/datum/config_entry/number/max_shuttle_size
|
||||
config_entry_value = 500
|
||||
|
||||
//wound config stuff (increases the max injury roll, making injuries more likely)
|
||||
/datum/config_entry/number/wound_exponent
|
||||
config_entry_value = WOUND_DAMAGE_EXPONENT
|
||||
min_val = 0
|
||||
integer = FALSE
|
||||
|
||||
//adds a set amount to any injury rolls on a limb using get_damage() multiplied by this number
|
||||
/datum/config_entry/number/wound_damage_multiplier
|
||||
config_entry_value = 0.333
|
||||
min_val = 0
|
||||
integer = FALSE
|
||||
|
||||
@@ -368,6 +368,10 @@
|
||||
|
||||
/datum/config_entry/flag/allow_map_voting
|
||||
|
||||
/datum/config_entry/number/client_warn_version
|
||||
config_entry_value = null
|
||||
min_val = 500
|
||||
|
||||
/datum/config_entry/number/client_warn_version
|
||||
config_entry_value = null
|
||||
min_val = 500
|
||||
@@ -384,6 +388,10 @@
|
||||
/datum/config_entry/string/client_error_message
|
||||
config_entry_value = "Your version of byond is too old, may have issues, and is blocked from accessing this server."
|
||||
|
||||
/datum/config_entry/number/client_error_build
|
||||
config_entry_value = null
|
||||
min_val = 0
|
||||
|
||||
/datum/config_entry/number/minute_topic_limit
|
||||
config_entry_value = null
|
||||
min_val = 0
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/datum/config_entry/keyed_list/external_rsc_urls
|
||||
key_mode = KEY_MODE_TEXT
|
||||
value_mode = VALUE_MODE_FLAG
|
||||
|
||||
/datum/config_entry/flag/asset_simple_preload
|
||||
|
||||
/datum/config_entry/string/asset_transport
|
||||
/datum/config_entry/string/asset_transport/ValidateAndSet(str_val)
|
||||
return (lowertext(str_val) in list("simple", "webroot")) && ..(lowertext(str_val))
|
||||
|
||||
/datum/config_entry/string/asset_cdn_webroot
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
/datum/config_entry/string/asset_cdn_webroot/ValidateAndSet(str_var)
|
||||
if (!str_var || trim(str_var) == "")
|
||||
return FALSE
|
||||
if (str_var && str_var[length(str_var)] != "/")
|
||||
str_var += "/"
|
||||
return ..(str_var)
|
||||
|
||||
/datum/config_entry/string/asset_cdn_url
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
default = null
|
||||
|
||||
/datum/config_entry/string/asset_cdn_url/ValidateAndSet(str_var)
|
||||
if (!str_var || trim(str_var) == "")
|
||||
return FALSE
|
||||
if (str_var && str_var[length(str_var)] != "/")
|
||||
str_var += "/"
|
||||
return ..(str_var)
|
||||
@@ -16,4 +16,4 @@
|
||||
|
||||
/datum/controller/proc/Recover()
|
||||
|
||||
/datum/controller/proc/stat_entry()
|
||||
/datum/controller/proc/stat_entry(msg)
|
||||
|
||||
@@ -95,8 +95,6 @@ GLOBAL_REAL(Failsafe, /datum/controller/failsafe)
|
||||
/datum/controller/failsafe/proc/defcon_pretty()
|
||||
return defcon
|
||||
|
||||
/datum/controller/failsafe/stat_entry()
|
||||
if(!statclick)
|
||||
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
|
||||
|
||||
stat("Failsafe Controller:", statclick.update("Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])"))
|
||||
/datum/controller/failsafe/stat_entry(msg)
|
||||
msg = "Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])"
|
||||
return msg
|
||||
|
||||
@@ -24,11 +24,9 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
|
||||
//fuck off kevinz
|
||||
return QDEL_HINT_IWILLGC
|
||||
|
||||
/datum/controller/global_vars/stat_entry()
|
||||
if(!statclick)
|
||||
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
|
||||
|
||||
stat("Globals:", statclick.update("Edit"))
|
||||
/datum/controller/global_vars/stat_entry(msg)
|
||||
msg = "Edit"
|
||||
return msg
|
||||
|
||||
/datum/controller/global_vars/vv_edit_var(var_name, var_value)
|
||||
if(gvars_datum_protected_varlist[var_name])
|
||||
|
||||
+16
-10
@@ -76,7 +76,11 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
// Highlander-style: there can only be one! Kill off the old and replace it with the new.
|
||||
|
||||
if(!random_seed)
|
||||
random_seed = (TEST_RUN_PARAMETER in world.params) ? 29051994 : rand(1, 1e9)
|
||||
#ifdef UNIT_TESTS
|
||||
random_seed = 29051994
|
||||
#else
|
||||
random_seed = rand(1, 1e9)
|
||||
#endif
|
||||
rand_seed(random_seed)
|
||||
|
||||
var/list/_subsystems = list()
|
||||
@@ -184,9 +188,6 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
if(delay)
|
||||
sleep(delay)
|
||||
|
||||
if(tgs_prime)
|
||||
world.TgsInitializationComplete()
|
||||
|
||||
if(init_sss)
|
||||
init_subtypes(/datum/controller/subsystem, subsystems)
|
||||
|
||||
@@ -219,6 +220,9 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
world.fps = CONFIG_GET(number/fps)
|
||||
var/initialized_tod = REALTIMEOFDAY
|
||||
|
||||
if(tgs_prime)
|
||||
world.TgsInitializationComplete()
|
||||
|
||||
if(sleep_offline_after_initializations)
|
||||
world.sleep_offline = TRUE
|
||||
sleep(1)
|
||||
@@ -611,13 +615,10 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
skip_ticks = 1
|
||||
|
||||
|
||||
/datum/controller/master/stat_entry()
|
||||
if(!statclick)
|
||||
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
|
||||
/datum/controller/master/stat_entry(msg)
|
||||
msg = "(TickRate:[Master.processing]) (Iteration:[Master.iteration]) (TickLimit: [round(Master.current_ticklimit, 0.1)])"
|
||||
return msg
|
||||
|
||||
stat("Byond:", "(FPS:[world.fps]) (TickCount:[world.time/world.tick_lag]) (TickDrift:[round(Master.tickdrift,1)]([round((Master.tickdrift/(world.time/world.tick_lag))*100,0.1)]%)) (Internal Tick Usage: [round(MAPTICK_LAST_INTERNAL_TICK_USAGE,0.1)]%)")
|
||||
stat("Master Controller:", statclick.update("(TickRate:[Master.processing]) (Iteration:[Master.iteration]) (TickLimit: [round(Master.current_ticklimit, 0.1)])"))
|
||||
stat("Misc Subsystems", misc_statclick)
|
||||
|
||||
/datum/controller/master/StartLoadingMap()
|
||||
//disallow more than one map to load at once, multithreading it will just cause race conditions
|
||||
@@ -643,3 +644,8 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
processing = CONFIG_GET(number/mc_tick_rate/base_mc_tick_rate)
|
||||
else if (client_count > CONFIG_GET(number/mc_tick_rate/high_pop_mc_mode_amount))
|
||||
processing = CONFIG_GET(number/mc_tick_rate/high_pop_mc_tick_rate)
|
||||
|
||||
/datum/controller/master/proc/OnConfigLoad()
|
||||
for (var/thing in subsystems)
|
||||
var/datum/controller/subsystem/SS = thing
|
||||
SS.OnConfigLoad()
|
||||
|
||||
@@ -1,39 +1,91 @@
|
||||
/**
|
||||
* # Subsystem base class
|
||||
*
|
||||
* Defines a subsystem to be managed by the [Master Controller][/datum/controller/master]
|
||||
*
|
||||
* Simply define a child of this subsystem, using the [SUBSYSTEM_DEF] macro, and the MC will handle registration.
|
||||
* Changing the name is required
|
||||
**/
|
||||
|
||||
/datum/controller/subsystem
|
||||
// Metadata; you should define these.
|
||||
name = "fire coderbus" //name of the subsystem
|
||||
var/init_order = INIT_ORDER_DEFAULT //order of initialization. Higher numbers are initialized first, lower numbers later. Use defines in __DEFINES/subsystems.dm for easy understanding of order.
|
||||
var/wait = 20 //time to wait (in deciseconds) between each call to fire(). Must be a positive integer.
|
||||
var/priority = FIRE_PRIORITY_DEFAULT //When mutiple subsystems need to run in the same tick, higher priority subsystems will run first and be given a higher share of the tick before MC_TICK_CHECK triggers a sleep
|
||||
|
||||
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)
|
||||
/// Name of the subsystem - you must change this
|
||||
name = "fire coderbus"
|
||||
|
||||
var/initialized = FALSE //set to TRUE after it has been initialized, will obviously never be set if the subsystem doesn't initialize
|
||||
/// Order of initialization. Higher numbers are initialized first, lower numbers later. Use or create defines such as [INIT_ORDER_DEFAULT] so we can see the order in one file.
|
||||
var/init_order = INIT_ORDER_DEFAULT
|
||||
|
||||
//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
|
||||
/// Time to wait (in deciseconds) between each call to fire(). Must be a positive integer.
|
||||
var/wait = 20
|
||||
|
||||
/// Priority Weight: When mutiple subsystems need to run in the same tick, higher priority subsystems will be given a higher share of the tick before MC_TICK_CHECK triggers a sleep, higher priority subsystems also run before lower priority subsystems
|
||||
var/priority = FIRE_PRIORITY_DEFAULT
|
||||
|
||||
/// [Subsystem Flags][SS_NO_INIT] to control binary behavior. Flags must be set at compile time or before preinit finishes to take full effect. (You can also restart the mc to force them to process again)
|
||||
var/flags = 0
|
||||
|
||||
/// This var is set to TRUE after the subsystem has been initialized.
|
||||
var/initialized = FALSE
|
||||
|
||||
/// 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 list that is checked every tick
|
||||
var/can_fire = TRUE
|
||||
|
||||
// Bookkeeping variables; probably shouldn't mess with these.
|
||||
var/last_fire = 0 //last world.time we called fire()
|
||||
var/next_fire = 0 //scheduled world.time for next fire()
|
||||
var/cost = 0 //average time to execute
|
||||
var/tick_usage = 0 //average tick usage
|
||||
var/tick_overrun = 0 //average tick overrun
|
||||
var/state = SS_IDLE //tracks the current state of the ss, running, paused, etc.
|
||||
var/paused_ticks = 0 //ticks this ss is taking to run right now.
|
||||
var/paused_tick_usage //total tick_usage of all of our runs while pausing this run
|
||||
var/ticks = 1 //how many ticks does this ss take to run on avg.
|
||||
var/times_fired = 0 //number of times we have called fire()
|
||||
var/queued_time = 0 //time we entered the queue, (for timing and priority reasons)
|
||||
var/queued_priority //we keep a running total to make the math easier, if priority changes mid-fire that would break our running total, so we store it here
|
||||
//linked list stuff for the queue
|
||||
var/datum/controller/subsystem/queue_next
|
||||
var/datum/controller/subsystem/queue_prev
|
||||
|
||||
///Bitmap of what game states can this subsystem fire at. See [RUNLEVELS_DEFAULT] for more details.
|
||||
var/runlevels = RUNLEVELS_DEFAULT //points of the game at which the SS can fire
|
||||
|
||||
var/static/list/failure_strikes //How many times we suspect a subsystem type has crashed the MC, 3 strikes and you're out!
|
||||
/*
|
||||
* The following variables are managed by the MC and should not be modified directly.
|
||||
*/
|
||||
|
||||
/// Last world.time the subsystem completed a run (as in wasn't paused by [MC_TICK_CHECK])
|
||||
var/last_fire = 0
|
||||
|
||||
/// Scheduled world.time for next fire()
|
||||
var/next_fire = 0
|
||||
|
||||
/// Running average of the amount of milliseconds it takes the subsystem to complete a run (including all resumes but not the time spent paused)
|
||||
var/cost = 0
|
||||
|
||||
/// Running average of the amount of tick usage in percents of a tick it takes the subsystem to complete a run
|
||||
var/tick_usage = 0
|
||||
|
||||
/// Running average of the amount of tick usage (in percents of a game tick) the subsystem has spent past its allocated time without pausing
|
||||
var/tick_overrun = 0
|
||||
|
||||
/// Tracks the current execution state of the subsystem. Used to handle subsystems that sleep in fire so the mc doesn't run them again while they are sleeping
|
||||
var/state = SS_IDLE
|
||||
|
||||
/// Tracks how many fires the subsystem has consecutively paused on in the current run
|
||||
var/paused_ticks = 0
|
||||
|
||||
/// Tracks how much of a tick the subsystem has consumed in the current run
|
||||
var/paused_tick_usage
|
||||
|
||||
/// Tracks how many fires the subsystem takes to complete a run on average.
|
||||
var/ticks = 1
|
||||
|
||||
/// Tracks the amount of completed runs for the subsystem
|
||||
var/times_fired = 0
|
||||
|
||||
/// Time the subsystem entered the queue, (for timing and priority reasons)
|
||||
var/queued_time = 0
|
||||
|
||||
/// Priority at the time the subsystem entered the queue. Needed to avoid changes in priority (by admins and the like) from breaking things.
|
||||
var/queued_priority
|
||||
|
||||
/// How many times we suspect a subsystem type has crashed the MC, 3 strikes and you're out!
|
||||
var/static/list/failure_strikes
|
||||
|
||||
/// Next subsystem in the queue of subsystems to run this tick
|
||||
var/datum/controller/subsystem/queue_next
|
||||
/// Previous subsystem in the queue of subsystems to run this tick
|
||||
var/datum/controller/subsystem/queue_prev
|
||||
|
||||
//Do not blindly add vars here to the bottom, put it where it goes above
|
||||
//If your var only has two values, put it in as a flag.
|
||||
|
||||
|
||||
//Do not override
|
||||
///datum/controller/subsystem/New()
|
||||
@@ -46,6 +98,7 @@
|
||||
|
||||
//This is used so the mc knows when the subsystem sleeps. do not override.
|
||||
/datum/controller/subsystem/proc/ignite(resumed = 0)
|
||||
SHOULD_NOT_OVERRIDE(TRUE)
|
||||
set waitfor = 0
|
||||
. = SS_SLEEPING
|
||||
fire(resumed)
|
||||
@@ -87,7 +140,7 @@
|
||||
queue_node_flags = queue_node.flags
|
||||
|
||||
if (queue_node_flags & SS_TICKER)
|
||||
if (!(SS_flags & SS_TICKER))
|
||||
if ((SS_flags & (SS_TICKER|SS_BACKGROUND)) != SS_TICKER)
|
||||
continue
|
||||
if (queue_node_priority < SS_priority)
|
||||
break
|
||||
@@ -155,6 +208,9 @@
|
||||
if(SS_SLEEPING)
|
||||
state = SS_PAUSING
|
||||
|
||||
/// Called after the config has been loaded or reloaded.
|
||||
/datum/controller/subsystem/proc/OnConfigLoad()
|
||||
|
||||
/datum/controller/subsystem/proc/subsystem_log(msg)
|
||||
return log_subsystem(name, msg)
|
||||
|
||||
@@ -167,23 +223,12 @@
|
||||
log_subsystem("INIT", msg)
|
||||
return time
|
||||
|
||||
//hook for printing stats to the "MC" statuspanel for admins to see performance and related stats etc.
|
||||
/datum/controller/subsystem/stat_entry(msg)
|
||||
if(!statclick)
|
||||
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
|
||||
|
||||
|
||||
|
||||
if(can_fire && !(SS_NO_FIRE & flags))
|
||||
msg = "[round(cost,1)]ms|[round(tick_usage,1)]%([round(tick_overrun,1)]%)|[round(ticks,0.1)]\t[msg]"
|
||||
else
|
||||
msg = "OFFLINE\t[msg]"
|
||||
|
||||
var/title = name
|
||||
if (can_fire)
|
||||
title = "\[[state_letter()]][title]"
|
||||
|
||||
stat(title, statclick.update(msg))
|
||||
return msg
|
||||
|
||||
/datum/controller/subsystem/proc/state_letter()
|
||||
switch (state)
|
||||
|
||||
@@ -7,8 +7,9 @@ SUBSYSTEM_DEF(acid)
|
||||
var/list/currentrun = list()
|
||||
var/list/processing = list()
|
||||
|
||||
/datum/controller/subsystem/acid/stat_entry()
|
||||
..("P:[processing.len]")
|
||||
/datum/controller/subsystem/acid/stat_entry(msg)
|
||||
msg = "P:[length(processing)]"
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/acid/fire(resumed = 0)
|
||||
|
||||
@@ -6,12 +6,13 @@ SUBSYSTEM_DEF(adjacent_air)
|
||||
priority = FIRE_PRIORITY_ATMOS_ADJACENCY
|
||||
var/list/queue = list()
|
||||
|
||||
/datum/controller/subsystem/adjacent_air/stat_entry()
|
||||
/datum/controller/subsystem/adjacent_air/stat_entry(msg)
|
||||
#ifdef TESTING
|
||||
..("P:[length(queue)], S:[GLOB.atmos_adjacent_savings[1]], T:[GLOB.atmos_adjacent_savings[2]]")
|
||||
msg = "P:[length(queue)], S:[GLOB.atmos_adjacent_savings[1]], T:[GLOB.atmos_adjacent_savings[2]]"
|
||||
#else
|
||||
..("P:[length(queue)]")
|
||||
msg = "P:[length(queue)]"
|
||||
#endif
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/adjacent_air/Initialize()
|
||||
while(length(queue))
|
||||
|
||||
@@ -16,7 +16,6 @@ SUBSYSTEM_DEF(air)
|
||||
var/cost_atmos_machinery = 0
|
||||
var/cost_equalize = 0
|
||||
|
||||
var/list/active_turfs = list()
|
||||
var/list/hotspots = list()
|
||||
var/list/networks = list()
|
||||
var/list/pipenets_needing_rebuilt = list()
|
||||
@@ -54,14 +53,17 @@ SUBSYSTEM_DEF(air)
|
||||
msg += "PN:[round(cost_pipenets,1)]|"
|
||||
msg += "AM:[round(cost_atmos_machinery,1)]"
|
||||
msg += "} "
|
||||
msg += "AT:[active_turfs.len]|"
|
||||
var/active_turfs_len = get_amt_active_turfs()
|
||||
msg += "AT:[active_turfs_len]|"
|
||||
msg += "EG:[get_amt_excited_groups()]|"
|
||||
msg += "HS:[hotspots.len]|"
|
||||
msg += "PN:[networks.len]|"
|
||||
msg += "HP:[high_pressure_delta.len]|"
|
||||
msg += "AS:[active_super_conductivity.len]|"
|
||||
msg += "AT/MS:[round((cost ? active_turfs.len/cost : 0),0.1)]"
|
||||
..(msg)
|
||||
msg += "GA:[get_amt_gas_mixes()]|"
|
||||
msg += "MG:[get_max_gas_mixes()]|"
|
||||
msg += "AT/MS:[round((cost ? active_turfs_len/cost : 0),0.1)]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/air/Initialize(timeofday)
|
||||
extools_update_ssair()
|
||||
@@ -70,9 +72,11 @@ SUBSYSTEM_DEF(air)
|
||||
setup_atmos_machinery()
|
||||
setup_pipenets()
|
||||
gas_reactions = init_gas_reactions()
|
||||
extools_update_reactions()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/air/proc/extools_update_ssair()
|
||||
/datum/controller/subsystem/air/proc/extools_update_reactions()
|
||||
|
||||
/datum/controller/subsystem/air/fire(resumed = 0)
|
||||
var/timer = TICK_USAGE_REAL
|
||||
@@ -237,6 +241,8 @@ SUBSYSTEM_DEF(air)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_turf_equalize(resumed = 0)
|
||||
return process_turf_equalize_extools(resumed, (Master.current_ticklimit - TICK_USAGE) * 0.01 * world.tick_lag)
|
||||
/*
|
||||
//cache for sanic speed
|
||||
var/fire_count = times_fired
|
||||
if (!resumed)
|
||||
@@ -251,8 +257,11 @@ SUBSYSTEM_DEF(air)
|
||||
//equalize_pressure_in_zone(T, fire_count)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
*/
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_active_turfs(resumed = 0)
|
||||
return process_active_turfs_extools(resumed, (Master.current_ticklimit - TICK_USAGE) * 0.01 * world.tick_lag)
|
||||
/*
|
||||
//cache for sanic speed
|
||||
var/fire_count = times_fired
|
||||
if (!resumed)
|
||||
@@ -266,10 +275,10 @@ SUBSYSTEM_DEF(air)
|
||||
T.process_cell(fire_count)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
*/
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_excited_groups(resumed = 0)
|
||||
if(process_excited_groups_extools(resumed, (Master.current_ticklimit - TICK_USAGE) * 0.01 * world.tick_lag))
|
||||
sleep()
|
||||
return process_excited_groups_extools(resumed, (Master.current_ticklimit - TICK_USAGE) * 0.01 * world.tick_lag)
|
||||
/*
|
||||
if (!resumed)
|
||||
src.currentrun = excited_groups.Copy()
|
||||
@@ -288,13 +297,20 @@ SUBSYSTEM_DEF(air)
|
||||
return
|
||||
*/
|
||||
|
||||
/datum/controller/subsystem/air/proc/process_active_turfs_extools()
|
||||
/datum/controller/subsystem/air/proc/process_turf_equalize_extools()
|
||||
/datum/controller/subsystem/air/proc/process_excited_groups_extools()
|
||||
/datum/controller/subsystem/air/proc/get_amt_excited_groups()
|
||||
/datum/controller/subsystem/air/proc/get_amt_active_turfs()
|
||||
/datum/controller/subsystem/air/proc/get_amt_gas_mixes()
|
||||
/datum/controller/subsystem/air/proc/get_max_gas_mixes()
|
||||
/datum/controller/subsystem/air/proc/add_to_active_extools()
|
||||
/datum/controller/subsystem/air/proc/remove_from_active_extools()
|
||||
/datum/controller/subsystem/air/proc/get_active_turfs()
|
||||
/datum/controller/subsystem/air/proc/clear_active_turfs()
|
||||
|
||||
/datum/controller/subsystem/air/proc/remove_from_active(turf/open/T)
|
||||
active_turfs -= T
|
||||
if(currentpart == SSAIR_ACTIVETURFS)
|
||||
currentrun -= T
|
||||
remove_from_active_extools(T)
|
||||
#ifdef VISUALIZE_ACTIVE_TURFS
|
||||
T.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#00ff00")
|
||||
#endif
|
||||
@@ -308,9 +324,7 @@ SUBSYSTEM_DEF(air)
|
||||
T.add_atom_colour("#00ff00", TEMPORARY_COLOUR_PRIORITY)
|
||||
#endif
|
||||
T.set_excited(TRUE)
|
||||
active_turfs |= T
|
||||
if(currentpart == SSAIR_ACTIVETURFS)
|
||||
currentrun |= T
|
||||
add_to_active_extools(T)
|
||||
if(blockchanges)
|
||||
T.eg_garbage_collect()
|
||||
else if(T.flags_1 & INITIALIZED_1)
|
||||
@@ -335,12 +349,11 @@ SUBSYSTEM_DEF(air)
|
||||
|
||||
/datum/controller/subsystem/air/proc/setup_allturfs()
|
||||
var/list/turfs_to_init = block(locate(1, 1, 1), locate(world.maxx, world.maxy, world.maxz))
|
||||
var/list/active_turfs = src.active_turfs
|
||||
var/times_fired = ++src.times_fired
|
||||
|
||||
// Clear active turfs - faster than removing every single turf in the world
|
||||
// one-by-one, and Initalize_Atmos only ever adds `src` back in.
|
||||
active_turfs.Cut()
|
||||
clear_active_turfs()
|
||||
|
||||
for(var/thing in turfs_to_init)
|
||||
var/turf/T = thing
|
||||
@@ -348,28 +361,27 @@ SUBSYSTEM_DEF(air)
|
||||
continue
|
||||
T.Initalize_Atmos(times_fired)
|
||||
CHECK_TICK
|
||||
|
||||
if(active_turfs.len)
|
||||
var/starting_ats = active_turfs.len
|
||||
var/starting_ats = get_amt_active_turfs()
|
||||
if(starting_ats)
|
||||
sleep(world.tick_lag)
|
||||
var/timer = world.timeofday
|
||||
log_mapping("There are [starting_ats] active turfs at roundstart caused by a difference of the air between the adjacent turfs. You can see its coordinates using \"Mapping -> Show roundstart AT list\" verb (debug verbs required).")
|
||||
for(var/turf/T in active_turfs)
|
||||
var/list/turfs_to_check = get_active_turfs()
|
||||
for(var/T in turfs_to_check)
|
||||
GLOB.active_turfs_startlist += T
|
||||
|
||||
//now lets clear out these active turfs
|
||||
var/list/turfs_to_check = active_turfs.Copy()
|
||||
do
|
||||
var/list/new_turfs_to_check = list()
|
||||
for(var/turf/open/T in turfs_to_check)
|
||||
new_turfs_to_check += T.resolve_active_graph()
|
||||
CHECK_TICK
|
||||
|
||||
active_turfs += new_turfs_to_check
|
||||
for(var/T in new_turfs_to_check)
|
||||
add_to_active_extools(T)
|
||||
turfs_to_check = new_turfs_to_check
|
||||
|
||||
while (turfs_to_check.len)
|
||||
var/ending_ats = active_turfs.len
|
||||
var/ending_ats = get_amt_active_turfs()
|
||||
/*for(var/thing in excited_groups)
|
||||
var/datum/excited_group/EG = thing
|
||||
//EG.self_breakdown(space_is_all_consuming = 1)
|
||||
@@ -445,6 +457,8 @@ SUBSYSTEM_DEF(air)
|
||||
|
||||
return pipe_init_dirs_cache[type]["[dir]"]
|
||||
|
||||
/proc/get_extools_benchmarks()
|
||||
|
||||
#undef SSAIR_PIPENETS
|
||||
#undef SSAIR_ATMOSMACHINERY
|
||||
#undef SSAIR_ACTIVETURFS
|
||||
|
||||
@@ -4,6 +4,23 @@ SUBSYSTEM_DEF(assets)
|
||||
flags = SS_NO_FIRE
|
||||
var/list/cache = list()
|
||||
var/list/preload = list()
|
||||
var/datum/asset_transport/transport = new()
|
||||
|
||||
/datum/controller/subsystem/assets/OnConfigLoad()
|
||||
var/newtransporttype = /datum/asset_transport
|
||||
switch (CONFIG_GET(string/asset_transport))
|
||||
if ("webroot")
|
||||
newtransporttype = /datum/asset_transport/webroot
|
||||
|
||||
if (newtransporttype == transport.type)
|
||||
return
|
||||
|
||||
var/datum/asset_transport/newtransport = new newtransporttype ()
|
||||
if (newtransport.validate_config())
|
||||
transport = newtransport
|
||||
transport.Load()
|
||||
|
||||
|
||||
|
||||
/datum/controller/subsystem/assets/Initialize(timeofday)
|
||||
for(var/type in typesof(/datum/asset))
|
||||
@@ -11,8 +28,6 @@ SUBSYSTEM_DEF(assets)
|
||||
if (type != initial(A._abstract))
|
||||
get_asset_datum(type)
|
||||
|
||||
preload = cache.Copy() //don't preload assets generated during the round
|
||||
transport.Initialize(cache)
|
||||
|
||||
for(var/client/C in GLOB.clients)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/getFilesSlow, C, preload, FALSE), 10)
|
||||
..()
|
||||
|
||||
@@ -90,6 +90,8 @@ SUBSYSTEM_DEF(atoms)
|
||||
qdeleted = TRUE
|
||||
else if(!(A.flags_1 & INITIALIZED_1))
|
||||
BadInitializeCalls[the_type] |= BAD_INIT_DIDNT_INIT
|
||||
else
|
||||
SEND_SIGNAL(A,COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE)
|
||||
|
||||
return qdeleted || QDELING(A)
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ SUBSYSTEM_DEF(augury)
|
||||
var/list/observers_given_action = list()
|
||||
|
||||
/datum/controller/subsystem/augury/stat_entry(msg)
|
||||
..("W:[watchers.len]|D:[doombringers.len]")
|
||||
msg = "W:[watchers.len]|D:[length(doombringers)]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/augury/proc/register_doom(atom/A, severity)
|
||||
doombringers[A] = severity
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Aleksej Komarov
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
SUBSYSTEM_DEF(chat)
|
||||
name = "Chat"
|
||||
flags = SS_TICKER
|
||||
@@ -5,91 +10,29 @@ SUBSYSTEM_DEF(chat)
|
||||
priority = FIRE_PRIORITY_CHAT
|
||||
init_order = INIT_ORDER_CHAT
|
||||
|
||||
var/list/payload = list()
|
||||
|
||||
var/list/payload_by_client = list()
|
||||
|
||||
/datum/controller/subsystem/chat/fire()
|
||||
for(var/i in payload)
|
||||
var/client/C = i
|
||||
C << output(payload[C], "browseroutput:output")
|
||||
payload -= C
|
||||
|
||||
for(var/key in payload_by_client)
|
||||
var/client/client = key
|
||||
var/payload = payload_by_client[key]
|
||||
payload_by_client -= key
|
||||
if(client)
|
||||
// Send to tgchat
|
||||
client.tgui_panel?.window.send_message("chat/message", payload)
|
||||
// Send to old chat
|
||||
for(var/message in payload)
|
||||
SEND_TEXT(client, message_to_html(message))
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
|
||||
/datum/controller/subsystem/chat/proc/queue(target, message, handle_whitespace = TRUE, trailing_newline = TRUE, confidential = TRUE)
|
||||
if(!target || !message)
|
||||
return
|
||||
|
||||
if(!istext(message))
|
||||
stack_trace("to_chat called with invalid input type")
|
||||
return
|
||||
|
||||
if(target == world)
|
||||
target = GLOB.clients
|
||||
|
||||
//Some macros remain in the string even after parsing and fuck up the eventual output
|
||||
var/original_message = message
|
||||
|
||||
//url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript.
|
||||
//Do the double-encoding here to save nanoseconds
|
||||
var/twiceEncoded
|
||||
|
||||
/datum/controller/subsystem/chat/proc/queue(target, message)
|
||||
if(islist(target))
|
||||
var/sanitized_message = FALSE
|
||||
for(var/I in target)
|
||||
var/client/C = CLIENT_FROM_VAR(I) //Grab us a client if possible
|
||||
|
||||
if(!C)
|
||||
continue
|
||||
|
||||
//Send it to the old style output window.
|
||||
SEND_TEXT(C, original_message)
|
||||
|
||||
if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
|
||||
continue
|
||||
|
||||
if(!sanitized_message)
|
||||
message = replacetext(message, "\improper", "")
|
||||
message = replacetext(message, "\proper", "")
|
||||
if(handle_whitespace)
|
||||
message = replacetext(message, "\n", "<br>")
|
||||
message = replacetext(message, "\t", "[FOURSPACES][FOURSPACES]")
|
||||
if (trailing_newline)
|
||||
message += "<br>"
|
||||
twiceEncoded = url_encode(url_encode(message))
|
||||
sanitized_message = TRUE
|
||||
|
||||
if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue
|
||||
C.chatOutput.messageQueue += message
|
||||
continue
|
||||
|
||||
payload[C] += twiceEncoded
|
||||
|
||||
else
|
||||
var/client/C = CLIENT_FROM_VAR(target) //Grab us a client if possible
|
||||
|
||||
if(!C)
|
||||
return
|
||||
|
||||
//Send it to the old style output window.
|
||||
SEND_TEXT(C, original_message)
|
||||
|
||||
if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
|
||||
return
|
||||
|
||||
message = replacetext(message, "\improper", "")
|
||||
message = replacetext(message, "\proper", "")
|
||||
if(handle_whitespace)
|
||||
message = replacetext(message, "\n", "<br>")
|
||||
message = replacetext(message, "\t", "[FOURSPACES][FOURSPACES]")
|
||||
if (trailing_newline)
|
||||
message += "<br>"
|
||||
twiceEncoded = url_encode(url_encode(message))
|
||||
|
||||
if(!C.chatOutput.loaded) //Client still loading, put their messages in a queue
|
||||
C.chatOutput.messageQueue += message
|
||||
return
|
||||
|
||||
payload[C] += twiceEncoded
|
||||
for(var/_target in target)
|
||||
var/client/client = CLIENT_FROM_VAR(_target)
|
||||
if(client)
|
||||
LAZYADD(payload_by_client[client], list(message))
|
||||
return
|
||||
var/client/client = CLIENT_FROM_VAR(target)
|
||||
if(client)
|
||||
LAZYADD(payload_by_client[client], list(message))
|
||||
|
||||
@@ -20,7 +20,8 @@ SUBSYSTEM_DEF(disease)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/disease/stat_entry(msg)
|
||||
..("P:[active_diseases.len]")
|
||||
msg = "P:[length(active_diseases)]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/disease/proc/get_disease_name(id)
|
||||
var/datum/disease/advance/A = archive_diseases[id]
|
||||
|
||||
@@ -7,8 +7,9 @@ SUBSYSTEM_DEF(fire_burning)
|
||||
var/list/currentrun = list()
|
||||
var/list/processing = list()
|
||||
|
||||
/datum/controller/subsystem/fire_burning/stat_entry()
|
||||
..("P:[processing.len]")
|
||||
/datum/controller/subsystem/fire_burning/stat_entry(msg)
|
||||
msg = "P:[length(processing)]"
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/fire_burning/fire(resumed = 0)
|
||||
@@ -34,4 +35,3 @@ SUBSYSTEM_DEF(fire_burning)
|
||||
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ SUBSYSTEM_DEF(garbage)
|
||||
msg += "TGR:[round((totalgcs/(totaldels+totalgcs))*100, 0.01)]%"
|
||||
msg += " P:[pass_counts.Join(",")]"
|
||||
msg += "|F:[fail_counts.Join(",")]"
|
||||
..(msg)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/garbage/Shutdown()
|
||||
//Adds the del() log to the qdel log file
|
||||
|
||||
@@ -8,10 +8,11 @@ SUBSYSTEM_DEF(idlenpcpool)
|
||||
var/list/currentrun = list()
|
||||
var/static/list/idle_mobs_by_zlevel[][]
|
||||
|
||||
/datum/controller/subsystem/idlenpcpool/stat_entry()
|
||||
/datum/controller/subsystem/idlenpcpool/stat_entry(msg)
|
||||
var/list/idlelist = GLOB.simple_animals[AI_IDLE]
|
||||
var/list/zlist = GLOB.simple_animals[AI_Z_OFF]
|
||||
..("IdleNPCS:[idlelist.len]|Z:[zlist.len]")
|
||||
msg = "IdleNPCS:[length(idlelist)]|Z:[length(zlist)]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/idlenpcpool/proc/MaxZChanged()
|
||||
if (!islist(idle_mobs_by_zlevel))
|
||||
|
||||
@@ -7,8 +7,9 @@ SUBSYSTEM_DEF(lighting)
|
||||
wait = 2
|
||||
init_order = INIT_ORDER_LIGHTING
|
||||
|
||||
/datum/controller/subsystem/lighting/stat_entry()
|
||||
..("L:[GLOB.lighting_update_lights.len]|C:[GLOB.lighting_update_corners.len]|O:[GLOB.lighting_update_objects.len]")
|
||||
/datum/controller/subsystem/lighting/stat_entry(msg)
|
||||
msg = "L:[length(GLOB.lighting_update_lights)]|C:[length(GLOB.lighting_update_corners)]|O:[length(GLOB.lighting_update_objects)]"
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/lighting/Initialize(timeofday)
|
||||
|
||||
@@ -22,8 +22,9 @@ SUBSYSTEM_DEF(machines)
|
||||
NewPN.add_cable(PC)
|
||||
propagate_network(PC,PC.powernet)
|
||||
|
||||
/datum/controller/subsystem/machines/stat_entry()
|
||||
..("M:[processing.len]|PN:[powernets.len]")
|
||||
/datum/controller/subsystem/machines/stat_entry(msg)
|
||||
msg = "M:[length(processing)]|PN:[length(powernets)]"
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/machines/fire(resumed = 0)
|
||||
|
||||
@@ -10,8 +10,9 @@ SUBSYSTEM_DEF(mobs)
|
||||
var/static/list/cubemonkeys = list()
|
||||
var/static/list/cheeserats = list()
|
||||
|
||||
/datum/controller/subsystem/mobs/stat_entry()
|
||||
..("P:[GLOB.mob_living_list.len]")
|
||||
/datum/controller/subsystem/mobs/stat_entry(msg)
|
||||
msg = "P:[length(GLOB.mob_living_list)]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/mobs/proc/MaxZChanged()
|
||||
if (!islist(clients_by_zlevel))
|
||||
|
||||
@@ -6,9 +6,10 @@ SUBSYSTEM_DEF(npcpool)
|
||||
|
||||
var/list/currentrun = list()
|
||||
|
||||
/datum/controller/subsystem/npcpool/stat_entry()
|
||||
/datum/controller/subsystem/npcpool/stat_entry(msg)
|
||||
var/list/activelist = GLOB.simple_animals[AI_ON]
|
||||
..("NPCS:[activelist.len]")
|
||||
msg = "NPCS:[length(activelist)]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/npcpool/fire(resumed = FALSE)
|
||||
|
||||
|
||||
@@ -22,8 +22,9 @@ SUBSYSTEM_DEF(overlays)
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/overlays/stat_entry()
|
||||
..("Ov:[length(queue)]")
|
||||
/datum/controller/subsystem/overlays/stat_entry(msg)
|
||||
msg = "Ov:[length(queue)]"
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/overlays/Shutdown()
|
||||
|
||||
@@ -48,25 +48,6 @@ SUBSYSTEM_DEF(persistence)
|
||||
/datum/controller/subsystem/persistence/proc/LoadSatchels()
|
||||
var/placed_satchel = 0
|
||||
var/path
|
||||
if(fexists("data/npc_saves/SecretSatchels.sav")) //legacy conversion. Will only ever run once.
|
||||
var/savefile/secret_satchels = new /savefile("data/npc_saves/SecretSatchels.sav")
|
||||
for(var/map in secret_satchels)
|
||||
var/json_file = file("data/npc_saves/SecretSatchels[map].json")
|
||||
var/list/legacy_secret_satchels = splittext(secret_satchels[map],"#")
|
||||
var/list/satchels = list()
|
||||
for(var/i=1,i<=legacy_secret_satchels.len,i++)
|
||||
var/satchel_string = legacy_secret_satchels[i]
|
||||
var/list/chosen_satchel = splittext(satchel_string,"|")
|
||||
if(chosen_satchel.len == 3)
|
||||
var/list/data = list()
|
||||
data["x"] = text2num(chosen_satchel[1])
|
||||
data["y"] = text2num(chosen_satchel[2])
|
||||
data["saved_obj"] = chosen_satchel[3]
|
||||
satchels += list(data)
|
||||
var/list/file_data = list()
|
||||
file_data["data"] = satchels
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
fdel("data/npc_saves/SecretSatchels.sav")
|
||||
|
||||
var/json_file = file("data/npc_saves/SecretSatchels[SSmapping.config.map_name].json")
|
||||
var/list/json = list()
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
SUBSYSTEM_DEF(ping)
|
||||
name = "Ping"
|
||||
priority = FIRE_PRIORITY_PING
|
||||
wait = 3 SECONDS
|
||||
flags = SS_NO_INIT
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
var/list/currentrun = list()
|
||||
|
||||
/datum/controller/subsystem/ping/stat_entry()
|
||||
..("P:[GLOB.clients.len]")
|
||||
|
||||
|
||||
/datum/controller/subsystem/ping/fire(resumed = 0)
|
||||
if (!resumed)
|
||||
src.currentrun = GLOB.clients.Copy()
|
||||
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
while (currentrun.len)
|
||||
var/client/C = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
|
||||
if (!C || !C.chatOutput || !C.chatOutput.loaded)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
|
||||
// softPang isn't handled anywhere but it'll always reset the opts.lastPang.
|
||||
C.chatOutput.ehjax_send(data = C.is_afk(29) ? "softPang" : "pang")
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
@@ -4,16 +4,26 @@ PROCESSING_SUBSYSTEM_DEF(instruments)
|
||||
init_order = INIT_ORDER_INSTRUMENTS
|
||||
flags = SS_KEEP_TIMING
|
||||
priority = FIRE_PRIORITY_INSTRUMENTS
|
||||
var/static/list/datum/instrument/instrument_data = list() //id = datum
|
||||
/// List of all instrument data, associative id = datum
|
||||
var/static/list/datum/instrument/instrument_data = list()
|
||||
/// List of all song datums.
|
||||
var/static/list/datum/song/songs = list()
|
||||
/// Max lines in songs
|
||||
var/static/musician_maxlines = 600
|
||||
/// Max characters per line in songs
|
||||
var/static/musician_maxlinechars = 300
|
||||
/// Deciseconds between hearchecks. Too high and instruments seem to lag when people are moving around in terms of who can hear it. Too low and the server lags from this.
|
||||
var/static/musician_hearcheck_mindelay = 5
|
||||
/// Maximum instrument channels total instruments are allowed to use. This is so you don't have instruments deadlocking all sound channels.
|
||||
var/static/max_instrument_channels = MAX_INSTRUMENT_CHANNELS
|
||||
/// Current number of channels allocated for instruments
|
||||
var/static/current_instrument_channels = 0
|
||||
/// Single cached list for synthesizer instrument ids, so you don't have to have a new list with every synthesizer.
|
||||
var/static/list/synthesizer_instrument_ids
|
||||
|
||||
/datum/controller/subsystem/processing/instruments/Initialize()
|
||||
initialize_instrument_data()
|
||||
synthesizer_instrument_ids = get_allowed_instrument_ids()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/processing/instruments/proc/on_song_new(datum/song/S)
|
||||
@@ -29,7 +39,10 @@ PROCESSING_SUBSYSTEM_DEF(instruments)
|
||||
continue
|
||||
I = new path
|
||||
I.Initialize()
|
||||
instrument_data[I.id || "[I.type]"] = I
|
||||
if(!I.id)
|
||||
qdel(I)
|
||||
continue
|
||||
instrument_data[I.id] = I
|
||||
CHECK_TICK
|
||||
|
||||
/datum/controller/subsystem/processing/instruments/proc/get_instrument(id_or_path)
|
||||
|
||||
@@ -10,8 +10,9 @@ SUBSYSTEM_DEF(processing)
|
||||
var/list/processing = list()
|
||||
var/list/currentrun = list()
|
||||
|
||||
/datum/controller/subsystem/processing/stat_entry()
|
||||
..("[stat_tag]:[processing.len]")
|
||||
/datum/controller/subsystem/processing/stat_entry(msg)
|
||||
msg = "[stat_tag]:[length(processing)]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/processing/fire(resumed = 0)
|
||||
if (!resumed)
|
||||
|
||||
@@ -12,7 +12,7 @@ SUBSYSTEM_DEF(profiler)
|
||||
/datum/controller/subsystem/profiler/stat_entry(msg)
|
||||
msg += "F:[round(fetch_cost,1)]ms"
|
||||
msg += "|W:[round(write_cost,1)]ms"
|
||||
..(msg)
|
||||
return msg
|
||||
|
||||
/datum/controller/subsystem/profiler/Initialize()
|
||||
if(CONFIG_GET(flag/auto_profile))
|
||||
|
||||
@@ -294,6 +294,17 @@ SUBSYSTEM_DEF(research)
|
||||
//[88nodes * 5000points/node] / [1.5hr * 90min/hr * 60s/min]
|
||||
//Around 450000 points max???
|
||||
|
||||
/// The global list of raw anomaly types that have been refined, for hard limits.
|
||||
var/list/created_anomaly_types = list()
|
||||
/// The hard limits of cores created for each anomaly type. For faster code lookup without switch statements.
|
||||
var/list/anomaly_hard_limit_by_type = list(
|
||||
ANOMALY_CORE_BLUESPACE = MAX_CORES_BLUESPACE,
|
||||
ANOMALY_CORE_PYRO = MAX_CORES_PYRO,
|
||||
ANOMALY_CORE_GRAVITATIONAL = MAX_CORES_GRAVITATIONAL,
|
||||
ANOMALY_CORE_VORTEX = MAX_CORES_VORTEX,
|
||||
ANOMALY_CORE_FLUX = MAX_CORES_FLUX
|
||||
)
|
||||
|
||||
/datum/controller/subsystem/research/Initialize()
|
||||
point_types = TECHWEB_POINT_TYPE_LIST_ASSOCIATIVE_NAMES
|
||||
initialize_all_techweb_designs()
|
||||
|
||||
@@ -76,9 +76,7 @@ SUBSYSTEM_DEF(server_maint)
|
||||
if(!thing)
|
||||
continue
|
||||
var/client/C = thing
|
||||
var/datum/chatOutput/co = C.chatOutput
|
||||
if(co)
|
||||
co.ehjax_send(data = "roundrestart")
|
||||
C?.tgui_panel?.send_roundrestart()
|
||||
if(server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
|
||||
C << link("byond://[server]")
|
||||
var/datum/tgs_version/tgsversion = world.TgsVersion()
|
||||
|
||||
@@ -8,8 +8,9 @@ SUBSYSTEM_DEF(spacedrift)
|
||||
var/list/currentrun = list()
|
||||
var/list/processing = list()
|
||||
|
||||
/datum/controller/subsystem/spacedrift/stat_entry()
|
||||
..("P:[processing.len]")
|
||||
/datum/controller/subsystem/spacedrift/stat_entry(msg)
|
||||
msg = "P:[length(processing)]"
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/spacedrift/fire(resumed = 0)
|
||||
@@ -56,4 +57,3 @@ SUBSYSTEM_DEF(spacedrift)
|
||||
AM.inertia_last_loc = AM.loc
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
SUBSYSTEM_DEF(statpanels)
|
||||
name = "Stat Panels"
|
||||
wait = 4
|
||||
init_order = INIT_ORDER_STATPANELS
|
||||
priority = FIRE_PRIORITY_STATPANEL
|
||||
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
|
||||
var/list/currentrun = list()
|
||||
var/encoded_global_data
|
||||
var/mc_data_encoded
|
||||
var/list/cached_images = list()
|
||||
|
||||
/datum/controller/subsystem/statpanels/fire(resumed = FALSE)
|
||||
if (!resumed)
|
||||
var/datum/map_config/cached = SSmapping.next_map_config
|
||||
var/round_time = world.time - SSticker.round_start_time
|
||||
var/list/global_data = list(
|
||||
"Map: [SSmapping.config?.map_name || "Loading..."]",
|
||||
cached ? "Next Map: [cached.map_name]" : null,
|
||||
"Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]",
|
||||
"Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]",
|
||||
"Round Time: [round_time > MIDNIGHT_ROLLOVER ? "[round(round_time/MIDNIGHT_ROLLOVER)]:[worldtime2text()]" : worldtime2text()]",
|
||||
"Station Time: [STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]",
|
||||
"Time Dilation: [round(SStime_track.time_dilation_current,1)]% AVG:([round(SStime_track.time_dilation_avg_fast,1)]%, [round(SStime_track.time_dilation_avg,1)]%, [round(SStime_track.time_dilation_avg_slow,1)]%)"
|
||||
)
|
||||
|
||||
if(SSshuttle.emergency)
|
||||
var/ETA = SSshuttle.emergency.getModeStr()
|
||||
if(ETA)
|
||||
global_data += "[ETA] [SSshuttle.emergency.getTimerStr()]"
|
||||
/* Please fix
|
||||
if(SSvote.mode)
|
||||
var/static/list/supported = list(PLURALITY_VOTING, APPROVAL_VOTING)
|
||||
global_data += "Vote active!, There is currently a vote running. Question: [SSvote.question]"
|
||||
if(!(SSvote.vote_system in supported))
|
||||
global_data += "<STATPANEL VOTING DISABLED>, The current vote system is not supported by statpanel rendering. Please vote manually by opening the vote popup using the action button or chat link."
|
||||
return
|
||||
global_data += "Time Left:, [round(SSvote.end_time - world.time)] seconds"
|
||||
|
||||
global_data += "Choices:"
|
||||
for(var/i in 1 to SSvote.choice_statclicks.len)
|
||||
var/choice = SSvote.choice_statclicks[i]
|
||||
var/ivotedforthis = FALSE
|
||||
if(usr.ckey)
|
||||
switch(SSvote.vote_system)
|
||||
if(APPROVAL_VOTING)
|
||||
ivotedforthis = SSvote.voted[usr.ckey] && (i in SSvote.voted[usr.ckey])
|
||||
if(PLURALITY_VOTING)
|
||||
ivotedforthis = SSvote.voted[usr.ckey] == i
|
||||
|
||||
global_data += (ivotedforthis? "\[X\]" : "\[ \]", SSvote.choice_statclicks[choice])
|
||||
*/
|
||||
|
||||
encoded_global_data = url_encode(json_encode(global_data))
|
||||
src.currentrun = GLOB.clients.Copy()
|
||||
mc_data_encoded = null
|
||||
var/list/currentrun = src.currentrun
|
||||
while(length(currentrun))
|
||||
var/client/target = currentrun[length(currentrun)]
|
||||
currentrun.len--
|
||||
if(!target.statbrowser_ready)
|
||||
continue
|
||||
if(target.stat_tab == "Status")
|
||||
var/ping_str = url_encode("Ping: [round(target.lastping, 1)]ms (Average: [round(target.avgping, 1)]ms)")
|
||||
var/other_str = url_encode(json_encode(target.mob.get_status_tab_items()))
|
||||
target << output("[encoded_global_data];[ping_str];[other_str]", "statbrowser:update")
|
||||
if(!target.holder)
|
||||
target << output("", "statbrowser:remove_admin_tabs")
|
||||
else
|
||||
if(!("MC" in target.panel_tabs) || !("Tickets" in target.panel_tabs))
|
||||
target << output("[url_encode(target.holder.href_token)]", "statbrowser:add_admin_tabs")
|
||||
if(target.stat_tab == "MC")
|
||||
var/turf/eye_turf = get_turf(target.eye)
|
||||
var/coord_entry = url_encode(COORD(eye_turf))
|
||||
if(!mc_data_encoded)
|
||||
generate_mc_data()
|
||||
target << output("[mc_data_encoded];[coord_entry]", "statbrowser:update_mc")
|
||||
if(target.stat_tab == "Tickets")
|
||||
var/list/ahelp_tickets = GLOB.ahelp_tickets.stat_entry()
|
||||
target << output("[url_encode(json_encode(ahelp_tickets))];", "statbrowser:update_tickets")
|
||||
if(!length(GLOB.sdql2_queries) && ("SDQL2" in target.panel_tabs))
|
||||
target << output("", "statbrowser:remove_sdql2")
|
||||
else if(length(GLOB.sdql2_queries) && (target.stat_tab == "SDQL2" || !("SDQL2" in target.panel_tabs)))
|
||||
var/list/sdql2A = list()
|
||||
sdql2A[++sdql2A.len] = list("", "Access Global SDQL2 List", REF(GLOB.sdql2_vv_statobj))
|
||||
var/list/sdql2B = list()
|
||||
for(var/i in GLOB.sdql2_queries)
|
||||
var/datum/SDQL2_query/Q = i
|
||||
sdql2B = Q.generate_stat()
|
||||
sdql2A += sdql2B
|
||||
target << output(url_encode(json_encode(sdql2A)), "statbrowser:update_sdql2")
|
||||
if(target.mob)
|
||||
var/mob/M = target.mob
|
||||
if((target.stat_tab in target.spell_tabs) || !length(target.spell_tabs) && (length(M.mob_spell_list) || length(M.mind?.spell_list)))
|
||||
var/list/proc_holders = M.get_proc_holders()
|
||||
target.spell_tabs.Cut()
|
||||
for(var/phl in proc_holders)
|
||||
var/list/proc_holder_list = phl
|
||||
target.spell_tabs |= proc_holder_list[1]
|
||||
var/proc_holders_encoded = ""
|
||||
if(length(proc_holders))
|
||||
proc_holders_encoded = url_encode(json_encode(proc_holders))
|
||||
target << output("[url_encode(json_encode(target.spell_tabs))];[proc_holders_encoded]", "statbrowser:update_spells")
|
||||
if(M?.listed_turf)
|
||||
var/mob/target_mob = M
|
||||
if(!target_mob.TurfAdjacent(target_mob.listed_turf))
|
||||
target << output("", "statbrowser:remove_listedturf")
|
||||
target_mob.listed_turf = null
|
||||
else if(target.stat_tab == M?.listed_turf.name || !(M?.listed_turf.name in target.panel_tabs))
|
||||
var/list/overrides = list()
|
||||
var/list/turfitems = list()
|
||||
for(var/img in target.images)
|
||||
var/image/target_image = img
|
||||
if(!target_image.loc || target_image.loc.loc != target_mob.listed_turf || !target_image.override)
|
||||
continue
|
||||
overrides += target_image.loc
|
||||
turfitems[++turfitems.len] = list("[target_mob.listed_turf]", REF(target_mob.listed_turf), icon2html(target_mob.listed_turf, target, sourceonly=TRUE))
|
||||
for(var/tc in target_mob.listed_turf)
|
||||
var/atom/movable/turf_content = tc
|
||||
if(turf_content.mouse_opacity == MOUSE_OPACITY_TRANSPARENT)
|
||||
continue
|
||||
if(turf_content.invisibility > target_mob.see_invisible)
|
||||
continue
|
||||
if(turf_content in overrides)
|
||||
continue
|
||||
if(turf_content.IsObscured())
|
||||
continue
|
||||
if(length(turfitems) < 30) // only create images for the first 30 items on the turf, for performance reasons
|
||||
if(!(REF(turf_content) in cached_images))
|
||||
cached_images += REF(turf_content)
|
||||
turf_content.RegisterSignal(turf_content, COMSIG_PARENT_QDELETING, /atom/.proc/remove_from_cache) // we reset cache if anything in it gets deleted
|
||||
if(ismob(turf_content) || length(turf_content.overlays) > 2)
|
||||
turfitems[++turfitems.len] = list("[turf_content.name]", REF(turf_content), costly_icon2html(turf_content, target, sourceonly=TRUE))
|
||||
else
|
||||
turfitems[++turfitems.len] = list("[turf_content.name]", REF(turf_content), icon2html(turf_content, target, sourceonly=TRUE))
|
||||
else
|
||||
turfitems[++turfitems.len] = list("[turf_content.name]", REF(turf_content))
|
||||
else
|
||||
turfitems[++turfitems.len] = list("[turf_content.name]", REF(turf_content))
|
||||
turfitems = url_encode(json_encode(turfitems))
|
||||
target << output("[turfitems];", "statbrowser:update_listedturf")
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
|
||||
/datum/controller/subsystem/statpanels/proc/generate_mc_data()
|
||||
var/list/mc_data = list(
|
||||
list("CPU:", world.cpu),
|
||||
list("Instances:", "[num2text(world.contents.len, 10)]"),
|
||||
list("World Time:", "[world.time]"),
|
||||
list("Globals:", GLOB.stat_entry(), "\ref[GLOB]"),
|
||||
list("[config]:", config.stat_entry(), "\ref[config]"),
|
||||
list("Byond:", "(FPS:[world.fps]) (TickCount:[world.time/world.tick_lag]) (TickDrift:[round(Master.tickdrift,1)]([round((Master.tickdrift/(world.time/world.tick_lag))*100,0.1)]%)) (Internal Tick Usage: [round(MAPTICK_LAST_INTERNAL_TICK_USAGE,0.1)]%)"),
|
||||
list("Master Controller:", Master.stat_entry(), "\ref[Master]"),
|
||||
list("Failsafe Controller:", Failsafe.stat_entry(), "\ref[Failsafe]"),
|
||||
list("","")
|
||||
)
|
||||
for(var/ss in Master.subsystems)
|
||||
var/datum/controller/subsystem/sub_system = ss
|
||||
mc_data[++mc_data.len] = list("\[[sub_system.state_letter()]][sub_system.name]", sub_system.stat_entry(), "\ref[sub_system]")
|
||||
mc_data[++mc_data.len] = list("Camera Net", "Cameras: [GLOB.cameranet.cameras.len] | Chunks: [GLOB.cameranet.chunks.len]", "\ref[GLOB.cameranet]")
|
||||
mc_data_encoded = url_encode(json_encode(mc_data))
|
||||
|
||||
/atom/proc/remove_from_cache()
|
||||
SSstatpanels.cached_images -= REF(src)
|
||||
|
||||
/// verbs that send information from the browser UI
|
||||
/client/verb/set_tab(tab as text|null)
|
||||
set name = "Set Tab"
|
||||
set hidden = TRUE
|
||||
|
||||
stat_tab = tab
|
||||
|
||||
/client/verb/send_tabs(tabs as text|null)
|
||||
set name = "Send Tabs"
|
||||
set hidden = TRUE
|
||||
|
||||
panel_tabs |= tabs
|
||||
|
||||
/client/verb/remove_tabs(tabs as text|null)
|
||||
set name = "Remove Tabs"
|
||||
set hidden = TRUE
|
||||
|
||||
panel_tabs -= tabs
|
||||
|
||||
/client/verb/reset_tabs()
|
||||
set name = "Reset Tabs"
|
||||
set hidden = TRUE
|
||||
|
||||
panel_tabs = list()
|
||||
|
||||
/client/verb/panel_ready()
|
||||
set name = "Panel Ready"
|
||||
set hidden = TRUE
|
||||
|
||||
statbrowser_ready = TRUE
|
||||
@@ -24,15 +24,16 @@ SUBSYSTEM_DEF(tgui)
|
||||
var/basehtml
|
||||
|
||||
/datum/controller/subsystem/tgui/PreInit()
|
||||
basehtml = file2text('tgui/packages/tgui/public/tgui.html')
|
||||
basehtml = file2text('tgui/public/tgui.html')
|
||||
|
||||
/datum/controller/subsystem/tgui/Shutdown()
|
||||
close_all_uis()
|
||||
|
||||
/datum/controller/subsystem/tgui/stat_entry()
|
||||
..("P:[open_uis.len]")
|
||||
/datum/controller/subsystem/tgui/stat_entry(msg)
|
||||
msg = "P:[length(open_uis)]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/tgui/fire(resumed = 0)
|
||||
/datum/controller/subsystem/tgui/fire(resumed = FALSE)
|
||||
if(!resumed)
|
||||
src.current_run = open_uis.Copy()
|
||||
// Cache for sanic speed (lists are references anyways)
|
||||
@@ -81,7 +82,8 @@ SUBSYSTEM_DEF(tgui)
|
||||
window_found = TRUE
|
||||
break
|
||||
if(!window_found)
|
||||
log_tgui(user, "Error: Pool exhausted")
|
||||
log_tgui(user, "Error: Pool exhausted",
|
||||
context = "SStgui/request_pooled_window")
|
||||
return null
|
||||
return window
|
||||
|
||||
@@ -93,7 +95,7 @@ SUBSYSTEM_DEF(tgui)
|
||||
* required user mob
|
||||
*/
|
||||
/datum/controller/subsystem/tgui/proc/force_close_all_windows(mob/user)
|
||||
log_tgui(user, "force_close_all_windows")
|
||||
log_tgui(user, context = "SStgui/force_close_all_windows")
|
||||
if(user.client)
|
||||
user.client.tgui_windows = list()
|
||||
for(var/i in 1 to TGUI_WINDOW_HARD_LIMIT)
|
||||
@@ -109,7 +111,7 @@ SUBSYSTEM_DEF(tgui)
|
||||
* required window_id string
|
||||
*/
|
||||
/datum/controller/subsystem/tgui/proc/force_close_window(mob/user, window_id)
|
||||
log_tgui(user, "force_close_window")
|
||||
log_tgui(user, context = "SStgui/force_close_window")
|
||||
// Close all tgui datums based on window_id.
|
||||
for(var/datum/tgui/ui in user.tgui_open_uis)
|
||||
if(ui.window && ui.window.id == window_id)
|
||||
|
||||
@@ -11,8 +11,9 @@ SUBSYSTEM_DEF(throwing)
|
||||
var/list/currentrun
|
||||
var/list/processing = list()
|
||||
|
||||
/datum/controller/subsystem/throwing/stat_entry()
|
||||
..("P:[processing.len]")
|
||||
/datum/controller/subsystem/throwing/stat_entry(msg)
|
||||
msg = "P:[length(processing)]"
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/controller/subsystem/throwing/fire(resumed = 0)
|
||||
|
||||
@@ -396,6 +396,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
SSjob.EquipRank(N, player.mind.assigned_role, 0)
|
||||
if(CONFIG_GET(flag/roundstart_traits) && ishuman(N.new_character))
|
||||
SSquirks.AssignQuirks(N.new_character, N.client, TRUE, TRUE, SSjob.GetJob(player.mind.assigned_role), FALSE, N)
|
||||
N.client.prefs.post_copy_to(player)
|
||||
CHECK_TICK
|
||||
if(captainless)
|
||||
for(var/mob/dead/new_player/N in GLOB.player_list)
|
||||
@@ -416,6 +417,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
living.client.prefs.chat_toggles ^= CHAT_OOC
|
||||
var/obj/screen/splash/S = new(living.client, TRUE)
|
||||
S.Fade(TRUE)
|
||||
living.client.init_verbs()
|
||||
livings += living
|
||||
if(livings.len)
|
||||
addtimer(CALLBACK(src, .proc/release_characters, livings), 30, TIMER_CLIENT_TIME)
|
||||
|
||||
@@ -34,7 +34,8 @@ SUBSYSTEM_DEF(timer)
|
||||
bucket_resolution = world.tick_lag
|
||||
|
||||
/datum/controller/subsystem/timer/stat_entry(msg)
|
||||
..("B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)]")
|
||||
msg = "B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/timer/fire(resumed = FALSE)
|
||||
var/lit = last_invoke_tick
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/datum/accent
|
||||
|
||||
/datum/accent/proc/modify_speech(list/speech_args, datum/source, mob/living/carbon/owner) //transforms the message in some way
|
||||
return speech_args
|
||||
|
||||
/datum/accent/lizard/modify_speech(list/speech_args)
|
||||
var/message = speech_args[SPEECH_MESSAGE]
|
||||
var/static/regex/lizard_hiss = new("s+", "g")
|
||||
var/static/regex/lizard_hiSS = new("S+", "g")
|
||||
if(message[1] != "*")
|
||||
message = lizard_hiss.Replace(message, "sss")
|
||||
message = lizard_hiSS.Replace(message, "SSS")
|
||||
speech_args[SPEECH_MESSAGE] = message
|
||||
return speech_args
|
||||
|
||||
/datum/accent/fly/modify_speech(list/speech_args)
|
||||
var/message = speech_args[SPEECH_MESSAGE]
|
||||
var/static/regex/fly_buzz = new("z+", "g")
|
||||
var/static/regex/fly_buZZ = new("Z+", "g")
|
||||
if(message[1] != "*")
|
||||
message = fly_buzz.Replace(message, "zzz")
|
||||
message = fly_buZZ.Replace(message, "ZZZ")
|
||||
speech_args[SPEECH_MESSAGE] = message
|
||||
return speech_args
|
||||
|
||||
/datum/accent/abductor/modify_speech(list/speech_args, datum/source)
|
||||
var/message = speech_args[SPEECH_MESSAGE]
|
||||
var/mob/living/carbon/human/user = source
|
||||
var/rendered = "<span class='abductor'><b>[user.name]:</b> [message]</span>"
|
||||
user.log_talk(message, LOG_SAY, tag="abductor")
|
||||
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
|
||||
var/obj/item/organ/tongue/T = H.getorganslot(ORGAN_SLOT_TONGUE)
|
||||
if(!T || T.type != type)
|
||||
continue
|
||||
if(H.dna && H.dna.species.id == "abductor" && user.dna && user.dna.species.id == "abductor")
|
||||
var/datum/antagonist/abductor/A = user.mind.has_antag_datum(/datum/antagonist/abductor)
|
||||
if(!A || !(H.mind in A.team.members))
|
||||
continue
|
||||
to_chat(H, rendered)
|
||||
for(var/mob/M in GLOB.dead_mob_list)
|
||||
var/link = FOLLOW_LINK(M, user)
|
||||
to_chat(M, "[link] [rendered]")
|
||||
speech_args[SPEECH_MESSAGE] = ""
|
||||
return speech_args
|
||||
|
||||
/datum/accent/zombie/modify_speech(list/speech_args)
|
||||
var/message = speech_args[SPEECH_MESSAGE]
|
||||
var/list/message_list = splittext(message, " ")
|
||||
var/maxchanges = max(round(message_list.len / 1.5), 2)
|
||||
|
||||
for(var/i = rand(maxchanges / 2, maxchanges), i > 0, i--)
|
||||
var/insertpos = rand(1, message_list.len - 1)
|
||||
var/inserttext = message_list[insertpos]
|
||||
|
||||
if(!(copytext(inserttext, -3) == "..."))//3 == length("...")
|
||||
message_list[insertpos] = inserttext + "..."
|
||||
|
||||
if(prob(20) && message_list.len > 3)
|
||||
message_list.Insert(insertpos, "[pick("BRAINS", "Brains", "Braaaiinnnsss", "BRAAAIIINNSSS")]...")
|
||||
|
||||
speech_args[SPEECH_MESSAGE] = jointext(message_list, " ")
|
||||
return speech_args
|
||||
|
||||
/datum/accent/alien/modify_speech(list/speech_args, datum/source)
|
||||
playsound(source, "hiss", 25, 1, 1)
|
||||
return speech_args
|
||||
|
||||
/datum/accent/fluffy/modify_speech(list/speech_args)
|
||||
var/message = speech_args[SPEECH_MESSAGE]
|
||||
if(message[1] != "*")
|
||||
message = replacetext(message, "ne", "nye")
|
||||
message = replacetext(message, "nu", "nyu")
|
||||
message = replacetext(message, "na", "nya")
|
||||
message = replacetext(message, "no", "nyo")
|
||||
message = replacetext(message, "ove", "uv")
|
||||
message = replacetext(message, "l", "w")
|
||||
message = replacetext(message, "r", "w")
|
||||
speech_args[SPEECH_MESSAGE] = lowertext(message)
|
||||
return speech_args
|
||||
|
||||
/datum/accent/span
|
||||
var/span_flag
|
||||
|
||||
/datum/accent/span/modify_speech(list/speech_args)
|
||||
speech_args[SPEECH_SPANS] |= span_flag
|
||||
return speech_args
|
||||
|
||||
//bone tongues either have the sans accent or the papyrus accent
|
||||
/datum/accent/span/sans
|
||||
span_flag = SPAN_SANS
|
||||
|
||||
/datum/accent/span/papyrus
|
||||
span_flag = SPAN_PAPYRUS
|
||||
|
||||
/datum/accent/span/robot
|
||||
span_flag = SPAN_ROBOT
|
||||
|
||||
/datum/accent/dullahan/modify_speech(list/speech_args, datum/source, mob/living/carbon/owner)
|
||||
if(owner)
|
||||
if(isdullahan(owner))
|
||||
var/datum/species/dullahan/D = owner.dna.species
|
||||
if(isobj(D.myhead.loc))
|
||||
var/obj/O = D.myhead.loc
|
||||
O.say(speech_args[SPEECH_MESSAGE])
|
||||
speech_args[SPEECH_MESSAGE] = ""
|
||||
return speech_args
|
||||
+17
-20
@@ -8,14 +8,14 @@
|
||||
var/window_options = "can_close=1;can_minimize=1;can_maximize=0;can_resize=1;titlebar=1;" // window option is set using window_id
|
||||
var/stylesheets[0]
|
||||
var/scripts[0]
|
||||
var/title_image
|
||||
var/head_elements
|
||||
var/body_elements
|
||||
var/head_content = ""
|
||||
var/content = ""
|
||||
var/static/datum/asset/simple/namespaced/common/common_asset = get_asset_datum(/datum/asset/simple/namespaced/common)
|
||||
|
||||
|
||||
/datum/browser/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null)
|
||||
/datum/browser/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, atom/nref = null)
|
||||
|
||||
user = nuser
|
||||
window_id = nwindow_id
|
||||
@@ -27,7 +27,6 @@
|
||||
height = nheight
|
||||
if (nref)
|
||||
ref = nref
|
||||
add_stylesheet("common", 'html/browser/common.css') // this CSS sheet is common to all UIs
|
||||
|
||||
/datum/browser/proc/add_head_content(nhead_content)
|
||||
head_content = nhead_content
|
||||
@@ -35,22 +34,21 @@
|
||||
/datum/browser/proc/set_window_options(nwindow_options)
|
||||
window_options = nwindow_options
|
||||
|
||||
/datum/browser/proc/set_title_image(ntitle_image)
|
||||
//title_image = ntitle_image
|
||||
|
||||
/datum/browser/proc/add_stylesheet(name, file)
|
||||
if(istype(name, /datum/asset/spritesheet))
|
||||
var/datum/asset/spritesheet/sheet = name
|
||||
stylesheets["spritesheet_[sheet.name].css"] = "data/spritesheets/[sheet.name]"
|
||||
else
|
||||
var/asset_name = "[name].css"
|
||||
|
||||
stylesheets[asset_name] = file
|
||||
if(!SSassets.cache[asset_name])
|
||||
register_asset(asset_name, file)
|
||||
|
||||
if (!SSassets.cache[asset_name])
|
||||
SSassets.transport.register_asset(asset_name, file)
|
||||
|
||||
/datum/browser/proc/add_script(name, file)
|
||||
scripts["[ckey(name)].js"] = file
|
||||
register_asset("[ckey(name)].js", file)
|
||||
SSassets.transport.register_asset("[ckey(name)].js", file)
|
||||
|
||||
/datum/browser/proc/set_content(ncontent)
|
||||
content = ncontent
|
||||
@@ -60,15 +58,13 @@
|
||||
|
||||
/datum/browser/proc/get_header()
|
||||
var/file
|
||||
head_content += "<link rel='stylesheet' type='text/css' href='[common_asset.get_url_mappings()["common.css"]]'>"
|
||||
for (file in stylesheets)
|
||||
head_content += "<link rel='stylesheet' type='text/css' href='[file]'>"
|
||||
head_content += "<link rel='stylesheet' type='text/css' href='[SSassets.transport.get_asset_url(file)]'>"
|
||||
|
||||
|
||||
for (file in scripts)
|
||||
head_content += "<script type='text/javascript' src='[file]'></script>"
|
||||
|
||||
var/title_attributes = "class='uiTitle'"
|
||||
if (title_image)
|
||||
title_attributes = "class='uiTitle icon' style='background-image: url([title_image]);'"
|
||||
head_content += "<script type='text/javascript' src='[SSassets.transport.get_asset_url(file)]'></script>"
|
||||
|
||||
return {"<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
@@ -79,7 +75,7 @@
|
||||
</head>
|
||||
<body scroll=auto>
|
||||
<div class='uiWrapper'>
|
||||
[title ? "<div class='uiTitleWrapper'><div [title_attributes]><tt>[title]</tt></div></div>" : ""]
|
||||
[title ? "<div class='uiTitleWrapper'><div class='uiTitle'><tt>[title]</tt></div></div>" : ""]
|
||||
<div class='uiContent'>
|
||||
"}
|
||||
//" This is here because else the rest of the file looks like a string in notepad++.
|
||||
@@ -105,10 +101,11 @@
|
||||
var/window_size = ""
|
||||
if(width && height)
|
||||
window_size = "size=[width]x[height];"
|
||||
common_asset.send(user)
|
||||
if(stylesheets.len)
|
||||
send_asset_list(user, stylesheets)
|
||||
SSassets.transport.send_assets(user, stylesheets)
|
||||
if(scripts.len)
|
||||
send_asset_list(user, scripts)
|
||||
SSassets.transport.send_assets(user, scripts)
|
||||
user << browse(get_content(), "window=[window_id];[window_size][window_options]")
|
||||
if(use_onclose)
|
||||
setup_onclose()
|
||||
@@ -169,7 +166,7 @@
|
||||
return Button3
|
||||
|
||||
//Same shit, but it returns the button number, could at some point support unlimited button amounts.
|
||||
/proc/askuser(var/mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1, Timeout = 6000)
|
||||
/proc/askuser(mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1, Timeout = 6000)
|
||||
if (!istype(User))
|
||||
if (istype(User, /client/))
|
||||
var/client/C = User
|
||||
@@ -188,7 +185,7 @@
|
||||
var/selectedbutton = 0
|
||||
var/stealfocus
|
||||
|
||||
/datum/browser/modal/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null, StealFocus = 1, Timeout = 6000)
|
||||
/datum/browser/modal/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, atom/nref = null, StealFocus = 1, Timeout = 6000)
|
||||
..()
|
||||
stealfocus = StealFocus
|
||||
if (!StealFocus)
|
||||
|
||||
@@ -76,19 +76,11 @@
|
||||
return FALSE
|
||||
if(M.is_flying())
|
||||
return FALSE
|
||||
if(ishuman(AM))
|
||||
var/mob/living/carbon/human/H = AM
|
||||
if(istype(H.belt, /obj/item/wormhole_jaunter))
|
||||
var/obj/item/wormhole_jaunter/J = H.belt
|
||||
//To freak out any bystanders
|
||||
H.visible_message("<span class='boldwarning'>[H] falls into [parent]!</span>")
|
||||
J.chasm_react(H)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/component/chasm/proc/drop(atom/movable/AM)
|
||||
//Make sure the item is still there after our sleep
|
||||
if(!AM || QDELETED(AM))
|
||||
if(!AM || QDELETED(AM) || SEND_SIGNAL(AM, COMSIG_MOVABLE_CHASM_DROP, src))
|
||||
return
|
||||
falling_atoms[AM] = (falling_atoms[AM] || 0) + 1
|
||||
var/turf/T = target_turf
|
||||
|
||||
@@ -273,6 +273,16 @@
|
||||
time = 30
|
||||
category = CAT_CLOTHING
|
||||
|
||||
/datum/crafting_recipe/twinsheath
|
||||
name = "Twin Sword Sheath"
|
||||
result = /obj/item/storage/belt/sabre/twin
|
||||
reqs = list(/obj/item/stack/sheet/mineral/wood = 3,
|
||||
/obj/item/stack/sheet/leather = 8)
|
||||
tools = list(TOOL_WIRECUTTER)
|
||||
time = 70
|
||||
category = CAT_CLOTHING
|
||||
|
||||
|
||||
/datum/crafting_recipe/durathread_reinforcement_kit
|
||||
name = "Durathread Reinforcement Kit"
|
||||
result = /obj/item/armorkit
|
||||
|
||||
@@ -120,6 +120,53 @@
|
||||
category = CAT_MISC
|
||||
always_availible = FALSE // Disabled til learned
|
||||
|
||||
/datum/crafting_recipe/furnace
|
||||
name = "Sandstone Furnace"
|
||||
result = /obj/structure/furnace
|
||||
time = 300
|
||||
reqs = list(/obj/item/stack/sheet/mineral/sandstone = 15,
|
||||
/obj/item/stack/sheet/metal = 4,
|
||||
/obj/item/stack/rods = 2)
|
||||
tools = list(TOOL_CROWBAR)
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/tableanvil
|
||||
name = "Table Anvil"
|
||||
result = /obj/structure/anvil/obtainable/table
|
||||
time = 300
|
||||
reqs = list(/obj/item/stack/sheet/metal = 4,
|
||||
/obj/item/stack/rods = 2)
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER)
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/sandvil
|
||||
name = "Sandstone Anvil"
|
||||
result = /obj/structure/anvil/obtainable/sandstone
|
||||
time = 300
|
||||
reqs = list(/obj/item/stack/sheet/mineral/sandstone = 24)
|
||||
tools = list(TOOL_CROWBAR)
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/basaltblock
|
||||
name = "Sintered Basalt Block"
|
||||
result = /obj/item/basaltblock
|
||||
time = 200
|
||||
reqs = list(/obj/item/stack/ore/glass/basalt = 50)
|
||||
tools = list(TOOL_WELDER)
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/basaltanvil
|
||||
name = "Basalt Anvil"
|
||||
result = /obj/structure/anvil/obtainable/basalt
|
||||
time = 200
|
||||
reqs = list(/obj/item/basaltblock = 5)
|
||||
tools = list(TOOL_CROWBAR)
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
///////////////////
|
||||
//Tools & Storage//
|
||||
///////////////////
|
||||
@@ -175,6 +222,17 @@
|
||||
subcategory = CAT_TOOL
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/toolboxhammer
|
||||
name = "Toolbox Hammer"
|
||||
result = /obj/item/melee/smith/hammer/toolbox
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER)
|
||||
reqs = list(/obj/item/storage/toolbox = 1,
|
||||
/obj/item/stack/sheet/metal = 4,
|
||||
/obj/item/stack/rods = 2)
|
||||
time = 40
|
||||
subcategory = CAT_TOOL
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/papersack
|
||||
name = "Paper Sack"
|
||||
result = /obj/item/storage/box/papersack
|
||||
@@ -358,6 +416,25 @@
|
||||
//Unsorted//
|
||||
////////////
|
||||
|
||||
|
||||
|
||||
/datum/crafting_recipe/stick
|
||||
name = "Stick"
|
||||
time = 30
|
||||
reqs = list(/obj/item/stack/sheet/mineral/wood = 1)
|
||||
result = /obj/item/stick
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
|
||||
/datum/crafting_recipe/swordhilt
|
||||
name = "Sword Hilt"
|
||||
time = 30
|
||||
reqs = list(/obj/item/stack/sheet/mineral/wood = 2)
|
||||
result = /obj/item/swordhandle
|
||||
subcategory = CAT_MISCELLANEOUS
|
||||
category = CAT_MISC
|
||||
|
||||
/datum/crafting_recipe/blackcarpet
|
||||
name = "Black Carpet"
|
||||
reqs = list(/obj/item/stack/tile/carpet = 50, /obj/item/toy/crayon/black = 1)
|
||||
|
||||
@@ -45,8 +45,9 @@
|
||||
|
||||
/datum/fantasy_affix/tactical/apply(datum/component/fantasy/comp, newName)
|
||||
var/obj/item/master = comp.parent
|
||||
master.AddElement(/datum/element/tactical)
|
||||
comp.appliedElements += list(/datum/element/tactical)
|
||||
var/list/dat = list(/datum/element/tactical)
|
||||
master._AddElement(dat)
|
||||
comp.appliedElements += list(dat)
|
||||
return "tactical [newName]"
|
||||
|
||||
/datum/fantasy_affix/pyromantic
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// This used to be in paper.dm, it was some snowflake code that was
|
||||
// used ONLY on april's fool. I moved it to a component so it could be
|
||||
// used in other places
|
||||
|
||||
/datum/component/honkspam
|
||||
dupe_mode = COMPONENT_DUPE_UNIQUE
|
||||
var/spam_flag = FALSE
|
||||
|
||||
/datum/component/honkspam/Initialize()
|
||||
if(!isitem(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/interact)
|
||||
|
||||
/datum/component/honkspam/proc/reset_spamflag()
|
||||
spam_flag = FALSE
|
||||
|
||||
/datum/component/honkspam/proc/interact(mob/user)
|
||||
if(!spam_flag)
|
||||
spam_flag = TRUE
|
||||
var/obj/item/parent_item = parent
|
||||
playsound(parent_item.loc, 'sound/items/bikehorn.ogg', 50, TRUE)
|
||||
addtimer(CALLBACK(src, .proc/reset_spamflag), 2 SECONDS)
|
||||
@@ -65,10 +65,14 @@
|
||||
detonate(user)
|
||||
|
||||
/datum/component/killerqueen/proc/bump_detonate(datum/source, atom/A)
|
||||
var/atom/us = parent
|
||||
if(!us.density) // lazy anti-item-throw-OHKO, we need something better at some point
|
||||
return
|
||||
detonate(A)
|
||||
|
||||
/datum/component/killerqueen/proc/touch_detonate(datum/source, mob/user)
|
||||
detonate(user)
|
||||
return COMPONENT_NO_ATTACK_HAND
|
||||
|
||||
/datum/component/killerqueen/proc/on_examine(datum/source, mob/examiner, list/examine_return)
|
||||
if(examine_message)
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
The label component.
|
||||
|
||||
This component is used to manage labels applied by the hand labeler.
|
||||
|
||||
Atoms can only have one instance of this component, and therefore only one label at a time.
|
||||
This is to avoid having names like "Backpack (label1) (label2) (label3)". This is annoying and abnoxious to read.
|
||||
|
||||
When a player clicks the atom with a hand labeler to apply a label, this component gets applied to it.
|
||||
If the labeler is off, the component will be removed from it, and the label will be removed from its name.
|
||||
*/
|
||||
/datum/component/label
|
||||
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
|
||||
/// The name of the label the player is applying to the parent.
|
||||
var/label_name
|
||||
|
||||
/datum/component/label/Initialize(_label_name)
|
||||
if(!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
label_name = _label_name
|
||||
apply_label()
|
||||
|
||||
/datum/component/label/RegisterWithParent()
|
||||
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/OnAttackby)
|
||||
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/Examine)
|
||||
|
||||
/datum/component/label/UnregisterFromParent()
|
||||
UnregisterSignal(parent, list(COMSIG_PARENT_ATTACKBY, COMSIG_PARENT_EXAMINE))
|
||||
|
||||
/**
|
||||
This proc will fire after the parent is hit by a hand labeler which is trying to apply another label.
|
||||
Since the parent already has a label, it will remove the old one from the parent's name, and apply the new one.
|
||||
*/
|
||||
/datum/component/label/InheritComponent(datum/component/label/new_comp , i_am_original, _label_name)
|
||||
remove_label()
|
||||
if(new_comp)
|
||||
label_name = new_comp.label_name
|
||||
else
|
||||
label_name = _label_name
|
||||
apply_label()
|
||||
|
||||
/**
|
||||
This proc will trigger when any object is used to attack the parent.
|
||||
|
||||
If the attacking object is not a hand labeler, it will return.
|
||||
If the attacking object is a hand labeler it will restore the name of the parent to what it was before this component was added to it, and the component will be deleted.
|
||||
|
||||
Arguments:
|
||||
* source: The parent.
|
||||
* attacker: The object that is hitting the parent.
|
||||
* user: The mob who is wielding the attacking object.
|
||||
*/
|
||||
/datum/component/label/proc/OnAttackby(datum/source, obj/item/attacker, mob/user)
|
||||
// If the attacking object is not a hand labeler or its mode is 1 (has a label ready to apply), return.
|
||||
// The hand labeler should be off (mode is 0), in order to remove a label.
|
||||
var/obj/item/hand_labeler/labeler = attacker
|
||||
if(!istype(labeler) || labeler.mode)
|
||||
return
|
||||
|
||||
remove_label()
|
||||
playsound(parent, 'sound/items/poster_ripped.ogg', 20, TRUE)
|
||||
to_chat(user, "<span class='warning'>You remove the label from [parent].</span>")
|
||||
qdel(src) // Remove the component from the object.
|
||||
|
||||
/**
|
||||
This proc will trigger when someone examines the parent.
|
||||
It will attach the text found in the body of the proc to the `examine_list` and display it to the player examining the parent.
|
||||
|
||||
Arguments:
|
||||
* source: The parent.
|
||||
* user: The mob exmaining the parent.
|
||||
* examine_list: The current list of text getting passed from the parent's normal examine() proc.
|
||||
*/
|
||||
/datum/component/label/proc/Examine(datum/source, mob/user, list/examine_list)
|
||||
examine_list += "<span class='notice'>It has a label with some words written on it. Use a hand labeler to remove it.</span>"
|
||||
|
||||
/// Applies a label to the name of the parent in the format of: "parent_name (label)"
|
||||
/datum/component/label/proc/apply_label()
|
||||
var/atom/owner = parent
|
||||
owner.name += " ([label_name])"
|
||||
|
||||
/// Removes the label from the parent's name
|
||||
/datum/component/label/proc/remove_label()
|
||||
var/atom/owner = parent
|
||||
owner.name = replacetext(owner.name, "([label_name])", "") // Remove the label text from the parent's name, wherever it's located.
|
||||
owner.name = trim(owner.name) // Shave off any white space from the beginning or end of the parent's name.
|
||||
@@ -1,4 +1,4 @@
|
||||
//Thing meant for allowing datums and objects to access a NTnet network datum.
|
||||
//Thing meant for allowing datums and objects to access an NTnet network datum.
|
||||
/datum/proc/ntnet_receive(datum/netdata/data)
|
||||
return
|
||||
|
||||
|
||||
@@ -99,7 +99,6 @@ Bonus
|
||||
*/
|
||||
|
||||
/datum/symptom/alkali
|
||||
|
||||
name = "Alkali perspiration"
|
||||
desc = "The virus attaches to sudoriparous glands, synthesizing a chemical that bursts into flames when reacting with water, leading to self-immolation."
|
||||
stealth = 2
|
||||
@@ -113,9 +112,9 @@ Bonus
|
||||
symptom_delay_max = 90
|
||||
var/chems = FALSE
|
||||
var/explosion_power = 1
|
||||
threshold_desc = "<b>Resistance 9:</b> Doubles the intensity of the effect, but reduces its frequency.<br>\
|
||||
<b>Stage Speed 8:</b> Increases explosion radius when the host is wet.<br>\
|
||||
<b>Transmission 8:</b> Additionally synthesizes chlorine trifluoride and napalm inside the host."
|
||||
threshold_desc = list("Resistance 9" = "Doubles the intensity of the effect, but reduces its frequency.",
|
||||
"Stage Speed 8" = "Increases explosion radius when the host is wet.",
|
||||
"Transmission 8" = "Additionally synthesizes chlorine trifluoride and napalm inside the host.")
|
||||
|
||||
/datum/symptom/alkali/Start(datum/disease/advance/A)
|
||||
if(!..())
|
||||
|
||||
@@ -32,7 +32,7 @@ Bonus
|
||||
"Stage Speed 10" = "Further increases cooling speed."
|
||||
)
|
||||
|
||||
/datum/symptom/fever/Start(datum/disease/advance/A)
|
||||
/datum/symptom/shivering/Start(datum/disease/advance/A)
|
||||
if(!..())
|
||||
return
|
||||
if(A.properties["stage_rate"] >= 5) //dangerous cold
|
||||
@@ -58,4 +58,4 @@ Bonus
|
||||
if(unsafe)
|
||||
limit = 0
|
||||
M.adjust_bodytemperature(-get_cold * A.stage, limit)
|
||||
return 1
|
||||
return 1
|
||||
|
||||
+8
-4
@@ -132,7 +132,8 @@
|
||||
L[DNA_FACIAL_HAIR_STYLE_BLOCK] = construct_block(GLOB.facial_hair_styles_list.Find(H.facial_hair_style), GLOB.facial_hair_styles_list.len)
|
||||
L[DNA_FACIAL_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.facial_hair_color)
|
||||
L[DNA_SKIN_TONE_BLOCK] = construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len)
|
||||
L[DNA_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.eye_color)
|
||||
L[DNA_LEFT_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.left_eye_color)
|
||||
L[DNA_RIGHT_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.right_eye_color)
|
||||
L[DNA_COLOR_ONE_BLOCK] = sanitize_hexcolor(features["mcolor"], 6)
|
||||
L[DNA_COLOR_TWO_BLOCK] = sanitize_hexcolor(features["mcolor2"], 6)
|
||||
L[DNA_COLOR_THREE_BLOCK] = sanitize_hexcolor(features["mcolor3"], 6)
|
||||
@@ -224,8 +225,10 @@
|
||||
setblock(uni_identity, blocknumber, sanitize_hexcolor(H.facial_hair_color))
|
||||
if(DNA_SKIN_TONE_BLOCK)
|
||||
setblock(uni_identity, blocknumber, construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len))
|
||||
if(DNA_EYE_COLOR_BLOCK)
|
||||
setblock(uni_identity, blocknumber, sanitize_hexcolor(H.eye_color))
|
||||
if(DNA_LEFT_EYE_COLOR_BLOCK)
|
||||
setblock(uni_identity, blocknumber, sanitize_hexcolor(H.left_eye_color))
|
||||
if(DNA_RIGHT_EYE_COLOR_BLOCK)
|
||||
setblock(uni_identity, blocknumber, sanitize_hexcolor(H.right_eye_color))
|
||||
if(DNA_GENDER_BLOCK)
|
||||
switch(H.gender)
|
||||
if(MALE)
|
||||
@@ -464,7 +467,8 @@
|
||||
hair_color = sanitize_hexcolor(getblock(structure, DNA_HAIR_COLOR_BLOCK))
|
||||
facial_hair_color = sanitize_hexcolor(getblock(structure, DNA_FACIAL_HAIR_COLOR_BLOCK))
|
||||
skin_tone = dna.skin_tone_override || GLOB.skin_tones[deconstruct_block(getblock(structure, DNA_SKIN_TONE_BLOCK), GLOB.skin_tones.len)]
|
||||
eye_color = sanitize_hexcolor(getblock(structure, DNA_EYE_COLOR_BLOCK))
|
||||
left_eye_color = sanitize_hexcolor(getblock(structure, DNA_LEFT_EYE_COLOR_BLOCK))
|
||||
right_eye_color = sanitize_hexcolor(getblock(structure, DNA_RIGHT_EYE_COLOR_BLOCK))
|
||||
facial_hair_style = GLOB.facial_hair_styles_list[deconstruct_block(getblock(structure, DNA_FACIAL_HAIR_STYLE_BLOCK), GLOB.facial_hair_styles_list.len)]
|
||||
hair_style = GLOB.hair_styles_list[deconstruct_block(getblock(structure, DNA_HAIR_STYLE_BLOCK), GLOB.hair_styles_list.len)]
|
||||
if(icon_update)
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
RegisterSignal(A, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react)
|
||||
if(description)
|
||||
RegisterSignal(A, COMSIG_PARENT_EXAMINE, .proc/examine)
|
||||
RegisterSignal(A, COMSIG_ATOM_UPDATE_OVERLAYS, .proc/apply_overlay, TRUE)
|
||||
|
||||
num_decals_per_atom[A]++
|
||||
apply(A)
|
||||
@@ -39,21 +40,28 @@
|
||||
/datum/element/decal/Detach(datum/target)
|
||||
var/atom/A = target
|
||||
num_decals_per_atom[A]--
|
||||
apply(A, TRUE)
|
||||
if(!num_decals_per_atom[A])
|
||||
UnregisterSignal(A, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_COMPONENT_CLEAN_ACT, COMSIG_PARENT_EXAMINE, COMSIG_ATOM_UPDATE_OVERLAYS))
|
||||
UnregisterSignal(A, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE,
|
||||
COMSIG_COMPONENT_CLEAN_ACT, COMSIG_PARENT_EXAMINE, COMSIG_ATOM_UPDATE_OVERLAYS))
|
||||
LAZYREMOVE(num_decals_per_atom, A)
|
||||
apply(A)
|
||||
return ..()
|
||||
|
||||
/datum/element/decal/proc/apply(atom/target, removing = FALSE)
|
||||
if(num_decals_per_atom[target] == 1 && !removing)
|
||||
RegisterSignal(target, COMSIG_ATOM_UPDATE_OVERLAYS, .proc/apply_overlay, TRUE)
|
||||
target.update_icon()
|
||||
/datum/element/decal/proc/apply(atom/target)
|
||||
if(target.flags_1 & INITIALIZED_1)
|
||||
target.update_icon() //could use some queuing here now maybe.
|
||||
else if(!QDELETED(target) && num_decals_per_atom[target] == 1)
|
||||
RegisterSignal(target, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE, .proc/late_update_icon)
|
||||
if(isitem(target))
|
||||
addtimer(CALLBACK(target, /obj/item/.proc/update_slot_icon), 0, TIMER_UNIQUE)
|
||||
|
||||
/datum/element/decal/proc/late_update_icon(atom/source)
|
||||
source.update_icon()
|
||||
UnregisterSignal(source,COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE)
|
||||
|
||||
/datum/element/decal/proc/apply_overlay(atom/source, list/overlay_list)
|
||||
pic.dir = first_dir == NORTH ? source.dir : turn(first_dir, dir2angle(source.dir))
|
||||
if(first_dir)
|
||||
pic.dir = first_dir == SOUTH ? source.dir : turn(first_dir, dir2angle(source.dir)-180) //Never turn a dir by 0.
|
||||
for(var/i in 1 to num_decals_per_atom[source])
|
||||
overlay_list += pic
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user