diff --git a/code/__DEFINES/__game.dm b/code/__DEFINES/__game.dm index 7cb7440ba8da..ead4c9665c7c 100644 --- a/code/__DEFINES/__game.dm +++ b/code/__DEFINES/__game.dm @@ -152,6 +152,7 @@ block( \ //toggles_admin /// Splits admin tabs in Statpanel #define SPLIT_ADMIN_TABS (1<<0) +#define ADMIN_STEALTHMODE (1<<1) //================================================= diff --git a/code/__DEFINES/_math.dm b/code/__DEFINES/_math.dm index 7f19c95b2bcf..138adeeda451 100644 --- a/code/__DEFINES/_math.dm +++ b/code/__DEFINES/_math.dm @@ -9,23 +9,6 @@ #define CARDINAL_DIRS list(1,2,4,8) #define CARDINAL_ALL_DIRS list(1,2,4,5,6,8,9,10) -//some colors -#define COLOR_RED "#FF0000" -#define COLOR_GREEN "#00FF00" -#define COLOR_BLUE "#0000FF" -#define COLOR_CYAN "#00FFFF" -#define COLOR_PINK "#FF00FF" -#define COLOR_YELLOW "#FFFF00" -#define COLOR_ORANGE "#FF9900" -#define COLOR_WHITE "#FFFFFF" -#define COLOR_BLACK "#000000" -#define COLOR_OIL "#030303" - -//Grass Colors -#define COLOR_G_ICE "#C7EDDE" //faded cyan -#define COLOR_G_DES "#FF7C1C" //bright orange -#define COLOR_G_JUNG "#64AA6E" //faded green - #define LEFT 1 #define RIGHT 2 @@ -49,3 +32,6 @@ /// Gets the sign of x, returns -1 if negative, 0 if 0, 1 if positive #define SIGN(x) ( ((x) > 0) - ((x) < 0) ) + +/// Performs a linear interpolation between a and b. Note that amount=0 returns a, amount=1 returns b, and amount=0.5 returns the mean of a and b. +#define LERP(a, b, amount) ( amount ? ((a) + ((b) - (a)) * (amount)) : a ) diff --git a/code/__DEFINES/chat.dm b/code/__DEFINES/chat.dm index 85966e4032e2..f2db3980e887 100644 --- a/code/__DEFINES/chat.dm +++ b/code/__DEFINES/chat.dm @@ -6,6 +6,7 @@ #define MESSAGE_TYPE_SYSTEM "system" #define MESSAGE_TYPE_LOCALCHAT "localchat" #define MESSAGE_TYPE_RADIO "radio" +#define MESSAGE_TYPE_HIVEMIND "hivemind" #define MESSAGE_TYPE_INFO "info" #define MESSAGE_TYPE_WARNING "warning" #define MESSAGE_TYPE_DEADCHAT "deadchat" diff --git a/code/__DEFINES/colours.dm b/code/__DEFINES/colours.dm index 5fa106715f39..e9a03a6382da 100644 --- a/code/__DEFINES/colours.dm +++ b/code/__DEFINES/colours.dm @@ -1,214 +1,152 @@ // tg port thing -//different types of atom colourations -/// Only used by rare effects like greentext colouring mobs and when admins varedit color -#define ADMIN_COLOUR_PRIORITY 1 +//different types of atom colorations +/// Only used by rare effects like greentext coloring mobs and when admins varedit color +#define ADMIN_COLOR_PRIORITY 1 /// e.g. purple effect of the revenant on a mob, black effect when mob electrocuted -#define TEMPORARY_COLOUR_PRIORITY 2 -/// Colour splashed onto an atom (e.g. paint on turf) -#define WASHABLE_COLOUR_PRIORITY 3 -/// Colour inherent to the atom (e.g. blob color) -#define FIXED_COLOUR_PRIORITY 4 +#define TEMPORARY_COLOR_PRIORITY 2 +/// Color splashed onto an atom (e.g. paint on turf) +#define WASHABLE_COLOR_PRIORITY 3 +/// Color inherent to the atom (e.g. blob color) +#define FIXED_COLOR_PRIORITY 4 ///how many color priority levels there are. -#define COLOUR_PRIORITY_AMOUNT 4 - -#define COLOUR_DARKMODE_BACKGROUND "#202020" -#define COLOUR_DARKMODE_DARKBACKGROUND "#171717" -#define COLOUR_DARKMODE_TEXT "#a4bad6" - -#define COLOUR_WHITE "#FFFFFF" -#define COLOUR_VERY_LIGHT_GRAY "#EEEEEE" -#define COLOUR_SILVER "#C0C0C0" -#define COLOUR_GRAY "#808080" -#define COLOUR_FLOORTILE_GRAY "#8D8B8B" -#define COLOUR_DARK "#454545" -#define COLOUR_ALMOST_BLACK "#333333" -#define COLOUR_BLACK "#000000" -#define COLOUR_HALF_TRANSPARENT_BLACK "#0000007A" - -#define COLOUR_RED "#FF0000" -#define COLOUR_MOSTLY_PURE_RED "#FF3300" -#define COLOUR_DARK_RED "#A50824" -#define COLOUR_RED_LIGHT "#FF3333" -#define COLOUR_MAROON "#800000" -#define COLOUR_VIVID_RED "#FF3232" -#define COLOUR_LIGHT_GRAYISH_RED "#E4C7C5" -#define COLOUR_SOFT_RED "#FA8282" -#define COLOUR_CULT_RED "#960000" -#define COLOUR_BUBBLEGUM_RED "#950A0A" - -#define COLOUR_YELLOW "#FFFF00" -#define COLOUR_VIVID_YELLOW "#FBFF23" -#define COLOUR_VERY_SOFT_YELLOW "#FAE48E" - -#define COLOUR_OLIVE "#808000" -#define COLOUR_VIBRANT_LIME "#00FF00" -#define COLOUR_LIME "#32CD32" -#define COLOUR_DARK_LIME "#00aa00" -#define COLOUR_VERY_PALE_LIME_GREEN "#DDFFD3" -#define COLOUR_VERY_DARK_LIME_GREEN "#003300" -#define COLOUR_GREEN "#008000" -#define COLOUR_DARK_MODERATE_LIME_GREEN "#44964A" - -#define COLOUR_CYAN "#00FFFF" -#define COLOUR_DARK_CYAN "#00A2FF" -#define COLOUR_TEAL "#008080" -#define COLOUR_BLUE "#0000FF" -#define COLOUR_STRONG_BLUE "#1919c8" -#define COLOUR_BRIGHT_BLUE "#2CB2E8" -#define COLOUR_MODERATE_BLUE "#555CC2" -#define COLOUR_AMETHYST "#822BFF" -#define COLOUR_BLUE_LIGHT "#33CCFF" -#define COLOUR_NAVY "#000080" -#define COLOUR_BLUE_GRAY "#75A2BB" - -#define COLOUR_PINK "#FFC0CB" -#define COLOUR_LIGHT_PINK "#ff3cc8" -#define COLOUR_MOSTLY_PURE_PINK "#E4005B" -#define COLOUR_BLUSH_PINK "#DE5D83" -#define COLOUR_MAGENTA "#FF00FF" -#define COLOUR_STRONG_MAGENTA "#B800B8" -#define COLOUR_PURPLE "#800080" -#define COLOUR_VIOLET "#B900F7" -#define COLOUR_STRONG_VIOLET "#6927c5" - -#define COLOUR_ORANGE "#FF9900" -#define COLOUR_MOSTLY_PURE_ORANGE "#ff8000" -#define COLOUR_TAN_ORANGE "#FF7B00" -#define COLOUR_BRIGHT_ORANGE "#E2853D" -#define COLOUR_LIGHT_ORANGE "#ffc44d" -#define COLOUR_PALE_ORANGE "#FFBE9D" -#define COLOUR_BEIGE "#CEB689" -#define COLOUR_DARK_ORANGE "#C3630C" -#define COLOUR_DARK_MODERATE_ORANGE "#8B633B" - -#define COLOUR_BROWN "#BA9F6D" -#define COLOUR_DARK_BROWN "#997C4F" -#define COLOUR_ORANGE_BROWN "#a9734f" - -//Colour defines used by the soapstone (based on readability against grey tiles) -#define COLOUR_SOAPSTONE_PLASTIC "#a19d94" -#define COLOUR_SOAPSTONE_IRON "#b2b2b2" -#define COLOUR_SOAPSTONE_BRONZE "#FE8001" -#define COLOUR_SOAPSTONE_SILVER "#FFFFFF" -#define COLOUR_SOAPSTONE_GOLD "#FFD900" -#define COLOUR_SOAPSTONE_DIAMOND "#00ffee" - -#define COLOUR_GREEN_GRAY "#99BB76" -#define COLOUR_RED_GRAY "#B4696A" -#define COLOUR_PALE_BLUE_GRAY "#98C5DF" -#define COLOUR_PALE_GREEN_GRAY "#B7D993" -#define COLOUR_PALE_RED_GRAY "#D59998" -#define COLOUR_PALE_PURPLE_GRAY "#CBB1CA" -#define COLOUR_PURPLE_GRAY "#AE8CA8" - -//Colour defines used by the assembly detailer. -#define COLOUR_ASSEMBLY_BLACK "#545454" -#define COLOUR_ASSEMBLY_BGRAY "#9497AB" -#define COLOUR_ASSEMBLY_WHITE "#E2E2E2" -#define COLOUR_ASSEMBLY_RED "#CC4242" -#define COLOUR_ASSEMBLY_ORANGE "#E39751" -#define COLOUR_ASSEMBLY_BEIGE "#AF9366" -#define COLOUR_ASSEMBLY_BROWN "#97670E" -#define COLOUR_ASSEMBLY_GOLD "#AA9100" -#define COLOUR_ASSEMBLY_YELLOW "#CECA2B" -#define COLOUR_ASSEMBLY_GURKHA "#999875" -#define COLOUR_ASSEMBLY_LGREEN "#789876" -#define COLOUR_ASSEMBLY_GREEN "#44843C" -#define COLOUR_ASSEMBLY_LBLUE "#5D99BE" -#define COLOUR_ASSEMBLY_BLUE "#38559E" -#define COLOUR_ASSEMBLY_PURPLE "#6F6192" - -///Colours for xenobiology vatgrowing -#define COLOUR_SAMPLE_YELLOW "#c0b823" -#define COLOUR_SAMPLE_PURPLE "#342941" -#define COLOUR_SAMPLE_GREEN "#98b944" -#define COLOUR_SAMPLE_BROWN "#91542d" -#define COLOUR_SAMPLE_GRAY "#5e5856" - -///Main colours for UI themes -#define COLOUR_THEME_MIDNIGHT "#6086A0" -#define COLOUR_THEME_PLASMAFIRE "#FFB200" -#define COLOUR_THEME_RETRO "#24CA00" -#define COLOUR_THEME_SLIMECORE "#4FB259" -#define COLOUR_THEME_OPERATIVE "#B8221F" -#define COLOUR_THEME_GLASS "#75A4C4" -#define COLOUR_THEME_CLOCKWORK "#CFBA47" - -///Colours for eigenstates -#define COLOUR_PERIWINKLEE "#9999FF" +#define COLOR_PRIORITY_AMOUNT 4 + +// BLACK AND WHITE COLOR DEFINE. + +/// White rgb(255, 255, 255) +#define COLOR_WHITE "#FFFFFF" +/// Black rgb(0, 0, 0) +#define COLOR_BLACK "#000000" + +// THE THREE PRIMARIES COLORS DEFINES. + +/// Red rgb(255, 0, 0) +#define COLOR_RED "#FF0000" +/// Green rgb(0, 255, 0) +#define COLOR_GREEN "#00FF00" +/// Blue rgb(0, 0, 255) +#define COLOR_BLUE "#0000FF" + +//mix of two full primary colors + +/// Cyan rgb(0, 255, 255) B + G +#define COLOR_CYAN "#00FFFF" +/// Magenta rgb(255, 0, 255) R+B +#define COLOR_MAGENTA "#FF00FF" +/// Yellow rgb(255, 255, 0) R+G +#define COLOR_YELLOW "#FFFF00" + +// colors define in use bellow + +/// Olive rgb(128, 128, 0) +#define COLOR_OLIVE "#808000" +/// Silver rgb(192, 192, 192) shade of grey +#define COLOR_SILVER "#C0C0C0" +/// Gray rgb(128, 128, 128) +#define COLOR_GRAY "#808080" + +#define COLOR_FLOORTILE_GRAY "#8D8B8B" + +#define COLOR_HALF_TRANSPARENT_BLACK "#0000007A" + +#define COLOR_DARK_RED "#A50824" + +/// Maroon rgb(128, 0, 0) shade of red +#define COLOR_MAROON "#800000" + +#define COLOR_VIVID_RED "#FF3232" +#define COLOR_LIGHT_GRAYISH_RED "#E4C7C5" +#define COLOR_SOFT_RED "#FA8282" + +#define COLOR_VERY_SOFT_YELLOW "#FAE48E" + +///light green rgb( 0, 128, 0) +#define COLOR_LIGHT_GREEN "#008000" +#define COLOR_DARK_MODERATE_LIME_GREEN "#44964A" + +#define COLOR_TEAL "#008080" + +#define COLOR_MODERATE_BLUE "#555CC2" +/// Purple rgb( 128, 0, 128) +#define COLOR_PURPLE "#800080" +#define COLOR_STRONG_VIOLET "#6927c5" + +#define LIGHT_BEIGE "#CEB689" +#define COLOR_DARK_MODERATE_ORANGE "#8B633B" + +#define COLOR_BROWN "#BA9F6D" +#define COLOR_DARK_BROWN "#997C4F" + /** - * Some defines to generalise colours used in lighting. + * Some defines to generalise Colors used in lighting. * - * Important note: colours can end up significantly different from the basic html picture, especially when saturated + * Important note: Colors can end up significantly different from the basic html picture, especially when saturated */ -/// Full white. rgb(255, 255, 255) -#define LIGHT_COLOR_WHITE "#FFFFFF" /// Bright but quickly dissipating neon green. rgb(100, 200, 100) -#define LIGHT_COLOUR_GREEN "#64C864" -/// Electric green. rgb(0, 255, 0) -#define LIGHT_COLOUR_ELECTRIC_GREEN "#00FF00" +#define LIGHT_COLOR_GREEN "#64C864" /// Cold, diluted blue. rgb(100, 150, 250) -#define LIGHT_COLOUR_BLUE "#6496FA" +#define LIGHT_COLOR_BLUE "#6496FA" /// Light blueish green. rgb(125, 225, 175) -#define LIGHT_COLOUR_BLUEGREEN "#7DE1AF" +#define LIGHT_COLOR_BLUEGREEN "#7DE1AF" /// Diluted cyan. rgb(125, 225, 225) -#define LIGHT_COLOUR_CYAN "#7DE1E1" -/// Electric cyan rgb(0, 255, 255) -#define LIGHT_COLOUR_ELECTRIC_CYAN "#00FFFF" +#define LIGHT_COLOR_CYAN "#7DE1E1" /// More-saturated cyan. rgb(64, 206, 255) -#define LIGHT_COLOUR_LIGHT_CYAN "#40CEFF" +#define LIGHT_COLOR_LIGHT_CYAN "#40CEFF" /// Saturated blue. rgb(51, 117, 248) -#define LIGHT_COLOUR_DARK_BLUE "#6496FA" +#define LIGHT_COLOR_DARK_BLUE "#3375F8" /// Diluted, mid-warmth pink. rgb(225, 125, 225) -#define LIGHT_COLOUR_PINK "#E17DE1" +#define LIGHT_COLOR_PINK "#E17DE1" /// Dimmed yellow, leaning kaki. rgb(225, 225, 125) -#define LIGHT_COLOUR_YELLOW "#E1E17D" +#define LIGHT_COLOR_YELLOW "#E1E17D" /// Clear brown, mostly dim. rgb(150, 100, 50) -#define LIGHT_COLOUR_BROWN "#966432" +#define LIGHT_COLOR_BROWN "#966432" /// Mostly pure orange. rgb(250, 150, 50) -#define LIGHT_COLOUR_ORANGE "#FA9632" +#define LIGHT_COLOR_ORANGE "#FA9632" /// Light Purple. rgb(149, 44, 244) -#define LIGHT_COLOUR_PURPLE "#952CF4" +#define LIGHT_COLOR_PURPLE "#952CF4" /// Less-saturated light purple. rgb(155, 81, 255) -#define LIGHT_COLOUR_LAVENDER "#9B51FF" +#define LIGHT_COLOR_LAVENDER "#9B51FF" ///slightly desaturated bright yellow. -#define LIGHT_COLOUR_HOLY_MAGIC "#FFF743" +#define LIGHT_COLOR_HOLY_MAGIC "#FFF743" /// deep crimson -#define LIGHT_COLOUR_BLOOD_MAGIC "#D00000" +#define LIGHT_COLOR_BLOOD_MAGIC "#D00000" /* These ones aren't a direct color like the ones above, because nothing would fit */ /// Warm orange color, leaning strongly towards yellow. rgb(250, 160, 25) -#define LIGHT_COLOUR_FIRE "#FAA019" +#define LIGHT_COLOR_FIRE "#FAA019" /// Very warm yellow, leaning slightly towards orange. rgb(196, 138, 24) -#define LIGHT_COLOUR_LAVA "#C48A18" +#define LIGHT_COLOR_LAVA "#C48A18" /// Bright, non-saturated red. Leaning slightly towards pink for visibility. rgb(250, 100, 75) -#define LIGHT_COLOUR_FLARE "#FA644B" +#define LIGHT_COLOR_FLARE "#FA644B" /// Weird color, between yellow and green, very slimy. rgb(175, 200, 75) -#define LIGHT_COLOUR_SLIME_LAMP "#AFC84B" +#define LIGHT_COLOR_SLIME_LAMP "#AFC84B" /// Extremely diluted yellow, close to skin color (for some reason). rgb(250, 225, 175) -#define LIGHT_COLOUR_TUNGSTEN "#FAE1AF" +#define LIGHT_COLOR_TUNGSTEN "#FAE1AF" /// Barely visible cyan-ish hue, as the doctor prescribed. rgb(240, 250, 250) -#define LIGHT_COLOUR_HALOGEN "#F0FAFA" - -//The GAGS greyscale_colours for each department's computer/machine circuits -#define CIRCUIT_COLOUR_GENERIC "#1A7A13" -#define CIRCUIT_COLOUR_COMMAND "#1B4594" -#define CIRCUIT_COLOUR_SECURITY "#9A151E" -#define CIRCUIT_COLOUR_SCIENCE "#BC4A9B" -#define CIRCUIT_COLOUR_SERVICE "#92DCBA" -#define CIRCUIT_COLOUR_MEDICAL "#00CCFF" -#define CIRCUIT_COLOUR_ENGINEERING "#F8D700" -#define CIRCUIT_COLOUR_SUPPLY "#C47749" +#define LIGHT_COLOR_HALOGEN "#F0FAFA" /// The default color for admin say, used as a fallback when the preference is not enabled -#define DEFAULT_ASAY_COLOUR COLOUR_MOSTLY_PURE_RED -#define DEFAULT_HEX_COLOUR_LEN 6 +#define COLOR_MOSTLY_PURE_RED "#FF3300" +#define DEFAULT_ASAY_COLOR COLOR_MOSTLY_PURE_RED + +#define DEFAULT_HEX_COLOR_LEN 6 -// Colour filters +// Color filters /// Icon filter that creates ambient occlusion #define AMBIENT_OCCLUSION filter(type="drop_shadow", x=0, y=-2, size=4, border=4, color="#04080FAA") /// Icon filter that creates gaussian blur #define GAUSSIAN_BLUR(filter_size) filter(type="blur", size=filter_size) + +//some colors coming from _math.dm + +#define COLOR_ORANGE "#FF9900" +#define COLOR_OIL "#030303" + +//Grass Colors coming from _math.dm + +#define COLOR_G_ICE "#C7EDDE" //faded cyan +#define COLOR_G_DES "#FF7C1C" //bright orange +#define COLOR_G_JUNG "#64AA6E" //faded green diff --git a/code/__DEFINES/equipment.dm b/code/__DEFINES/equipment.dm index f0688282572d..375dd0db540d 100644 --- a/code/__DEFINES/equipment.dm +++ b/code/__DEFINES/equipment.dm @@ -194,11 +194,11 @@ //=========================================================================================== //Marine armor only, use for flags_marine_armor. -#define ARMOR_SQUAD_OVERLAY 1 -#define ARMOR_LAMP_OVERLAY 2 -#define ARMOR_LAMP_ON 4 -#define ARMOR_IS_REINFORCED 8 -#define SYNTH_ALLOWED 16 +#define ARMOR_SQUAD_OVERLAY (1<<0) +#define ARMOR_LAMP_OVERLAY (1<<1) +#define ARMOR_LAMP_ON (1<<2) +#define ARMOR_IS_REINFORCED (1<<3) +#define SYNTH_ALLOWED (1<<4) //=========================================================================================== //=========================================================================================== diff --git a/code/__DEFINES/keybinding.dm b/code/__DEFINES/keybinding.dm index 764282d59765..f4503aeea5d5 100644 --- a/code/__DEFINES/keybinding.dm +++ b/code/__DEFINES/keybinding.dm @@ -170,8 +170,7 @@ #define COMSIG_KB_YAUTJA_BUTCHER "keybinding_yautja_butcher" #define COMSIG_KB_YAUTJA_PRED_BUY "keybinding_yautja_pred_buy" #define COMSIG_KB_YAUTJA_MARK_PANEL "keybinding_yautja_mark_panel" -#define COMSIG_KB_YAUTJA_MARK_FOR_HUNT "keybinding_yautja_mark_for_hunt" -#define COMSIG_KB_YAUTJA_REMOVE_FROM_HUNT "keybinding_yautja_remove_from_hunt" +#define COMSIG_KB_YAUTJA_TOGGLE_MARK_FOR_HUNT "keybinding_yautja_toggle_mark_for_hunt" // Yautja Bracer #define COMSIG_KB_YAUTJA_TOGGLE_NOTIFICATION_SOUND "keybinding_yautja_toggle_notification_sound" @@ -192,6 +191,7 @@ #define COMSIG_KB_YAUTJA_BRACERNAME "keybinding_yautja_bracername" #define COMSIG_KB_YAUTJA_IDCHIP "keybinding_yautja_idchip" #define COMSIG_KB_YAUTJA_LINK_BRACER "keybinding_yautja_link_bracer" +#define COMSIG_KB_YAUTJA_CONTROL_FALCON "keybinding_yautja_control_falcon" //mask #define COMSIG_KB_YAUTJA_MASK_TOGGLE_ZOOM "keybinding_yautja_mask_toggle_zoom" diff --git a/code/__DEFINES/minimap.dm b/code/__DEFINES/minimap.dm index 003d723600c4..57c5ffeba38a 100644 --- a/code/__DEFINES/minimap.dm +++ b/code/__DEFINES/minimap.dm @@ -71,7 +71,6 @@ GLOBAL_LIST_INIT(all_minimap_flags, bitfield2list(MINIMAP_FLAG_ALL)) #define MINIMAP_ICON_COLOR_COMMANDER "#c6fcfc" #define MINIMAP_ICON_COLOR_HEAD "#F0C542" -#define MINIMAP_ICON_COLOR_SILVER "#c0c0c0" #define MINIMAP_ICON_COLOR_BRONZE "#eb9545" #define MINIMAP_ICON_COLOR_DOCTOR "#b83737" diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index e50d9e72497c..9cd69e61c8b2 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -47,9 +47,7 @@ //disabilities #define NEARSIGHTED (1<<0) -#define EPILEPSY (1<<1) -#define COUGHING (1<<2) -#define TOURETTES (1<<3) + #define NERVOUS (1<<4) #define OPIATE_RECEPTOR_DEFICIENCY (1<<5) //================================================= @@ -197,22 +195,22 @@ //================================================= //Species flags. -#define NO_BLOOD (1<<0) -#define NO_BREATHE (1<<1) +#define NO_BLOOD (1<<0) +#define NO_BREATHE (1<<1) #define NO_CLONE_LOSS (1<<2) -#define NO_SLIP (1<<3) +#define NO_SLIP (1<<3) #define NO_POISON (1<<4) -#define NO_CHEM_METABOLIZATION (1<<5) //Prevents reagents from acting on_mob_life(). +#define NO_CHEM_METABOLIZATION (1<<5) //Prevents reagents from acting on_mob_life(). #define HAS_SKIN_TONE (1<<6) -#define HAS_SKIN_COLOR (1<<7) -#define HAS_LIPS (1<<8) +#define HAS_SKIN_COLOR (1<<7) +#define HAS_LIPS (1<<8) #define HAS_UNDERWEAR (1<<9) -#define IS_WHITELISTED (1<<10) -#define IS_SYNTHETIC (1<<11) -#define NO_NEURO (1<<12) +#define IS_WHITELISTED (1<<10) +#define IS_SYNTHETIC (1<<11) +#define NO_NEURO (1<<12) #define SPECIAL_BONEBREAK (1<<13) //species do not get their bonebreak chance modified by endurance -#define NO_SHRAPNEL (1<<14) -#define HAS_HARDCRIT (1<<15) +#define NO_SHRAPNEL (1<<14) +#define HAS_HARDCRIT (1<<15) //================================================= diff --git a/code/__DEFINES/text.dm b/code/__DEFINES/text.dm index 0ce7e508daac..26567be26255 100644 --- a/code/__DEFINES/text.dm +++ b/code/__DEFINES/text.dm @@ -23,4 +23,4 @@ #define MAX_EMOTE_LEN 256 #define MAX_PAPER_MESSAGE_LEN 3072 #define MAX_BOOK_MESSAGE_LEN 9216 -#define MAX_NAME_LEN 26 +#define MAX_NAME_LEN 28 diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm index b0e97e05e9b2..fdfec5e8ca08 100644 --- a/code/__DEFINES/tgs.dm +++ b/code/__DEFINES/tgs.dm @@ -1,6 +1,6 @@ // tgstation-server DMAPI -#define TGS_DMAPI_VERSION "6.7.0" +#define TGS_DMAPI_VERSION "7.0.2" // All functions and datums outside this document are subject to change with any version and should not be relied on. @@ -73,12 +73,12 @@ #define TGS_EVENT_REPO_MERGE_PULL_REQUEST 3 /// Before the repository makes a sychronize operation. Parameters: Absolute repostiory path. #define TGS_EVENT_REPO_PRE_SYNCHRONIZE 4 -/// Before a BYOND install operation begins. Parameters: [/datum/tgs_version] of the installing BYOND. -#define TGS_EVENT_BYOND_INSTALL_START 5 -/// When a BYOND install operation fails. Parameters: Error message -#define TGS_EVENT_BYOND_INSTALL_FAIL 6 -/// When the active BYOND version changes. Parameters: (Nullable) [/datum/tgs_version] of the current BYOND, [/datum/tgs_version] of the new BYOND. -#define TGS_EVENT_BYOND_ACTIVE_VERSION_CHANGE 7 +/// Before a engine install operation begins. Parameters: Version string of the installing engine. +#define TGS_EVENT_ENGINE_INSTALL_START 5 +/// When a engine install operation fails. Parameters: Error message +#define TGS_EVENT_ENGINE_INSTALL_FAIL 6 +/// When the active engine version changes. Parameters: (Nullable) Version string of the current engine, version string of the new engine. +#define TGS_EVENT_ENGINE_ACTIVE_VERSION_CHANGE 7 /// When the compiler starts running. Parameters: Game directory path, origin commit SHA. #define TGS_EVENT_COMPILE_START 8 /// When a compile is cancelled. No parameters. @@ -108,7 +108,7 @@ // #define TGS_EVENT_DREAM_DAEMON_LAUNCH 22 /// After a single submodule update is performed. Parameters: Updated submodule name. #define TGS_EVENT_REPO_SUBMODULE_UPDATE 23 -/// After CodeModifications are applied, before DreamMaker is run. Parameters: Game directory path, origin commit sha, byond version. +/// After CodeModifications are applied, before DreamMaker is run. Parameters: Game directory path, origin commit sha, version string of the used engine. #define TGS_EVENT_PRE_DREAM_MAKER 24 /// Whenever a deployment folder is deleted from disk. Parameters: Game directory path. #define TGS_EVENT_DEPLOYMENT_CLEANUP 25 @@ -122,6 +122,7 @@ /// The watchdog will restart on reboot. #define TGS_REBOOT_MODE_RESTART 2 +// Note that security levels are currently meaningless in OpenDream /// DreamDaemon Trusted security level. #define TGS_SECURITY_TRUSTED 0 /// DreamDaemon Safe security level. @@ -136,6 +137,11 @@ /// DreamDaemon invisible visibility level. #define TGS_VISIBILITY_INVISIBLE 2 +/// The Build Your Own Net Dream engine. +#define TGS_ENGINE_TYPE_BYOND 0 +/// The OpenDream engine. +#define TGS_ENGINE_TYPE_OPENDREAM 1 + //REQUIRED HOOKS /** @@ -420,6 +426,7 @@ /** * Send a message to connected chats. This function may sleep! + * If TGS is offline when called, the message may be placed in a queue to be sent and this function will return immediately. Your message will be sent when TGS reconnects to the game. * * message - The [/datum/tgs_message_content] to send. * admin_only: If [TRUE], message will be sent to admin connected chats. Vice-versa applies. @@ -429,6 +436,7 @@ /** * Send a private message to a specific user. This function may sleep! + * If TGS is offline when called, the message may be placed in a queue to be sent and this function will return immediately. Your message will be sent when TGS reconnects to the game. * * message - The [/datum/tgs_message_content] to send. * user: The [/datum/tgs_chat_user] to PM. @@ -438,6 +446,7 @@ /** * Send a message to connected chats that are flagged as game-related in TGS. This function may sleep! + * If TGS is offline when called, the message may be placed in a queue to be sent and this function will return immediately. Your message will be sent when TGS reconnects to the game. * * message - The [/datum/tgs_message_content] to send. * channels - Optional list of [/datum/tgs_chat_channel]s to restrict the message to. @@ -449,6 +458,10 @@ /world/proc/TgsVersion() return +/// Returns the running engine type +/world/proc/TgsEngine() + return + /// Returns the current [/datum/tgs_version] of the DMAPI being used if it was activated, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping! /world/proc/TgsApiVersion() return diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 8c93957c3ca0..c2abe21a26ad 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -155,6 +155,8 @@ #define TRAIT_FORCED_STANDING "forcedstanding" /// Stuns preventing movement and using objects but without further impairement #define TRAIT_INCAPACITATED "incapacitated" +/// Disoriented. Unable to talk properly, and unable to use some skills as Xeno +#define TRAIT_DAZED "dazed" /// Apply this to identify a mob as merged with weeds #define TRAIT_MERGED_WITH_WEEDS "merged_with_weeds" @@ -313,6 +315,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_IMMOBILIZED" = TRAIT_IMMOBILIZED, "TRAIT_INCAPACITATED" = TRAIT_INCAPACITATED, "TRAIT_FLOORED" = TRAIT_FLOORED, + "TRAIT_DAZED" = TRAIT_DAZED, "TRAIT_UNDENSE" = TRAIT_UNDENSE, "TRAIT_YAUTJA_TECH" = TRAIT_YAUTJA_TECH, "TRAIT_SUPER_STRONG" = TRAIT_SUPER_STRONG, @@ -339,6 +342,8 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_VULTURE_USER" = TRAIT_VULTURE_USER, "TRAIT_CLOAKED" = TRAIT_CLOAKED, ), +// /mob/living/carbon/human = list( +// ), /mob/living/carbon/xenomorph = list( "TRAIT_ABILITY_NO_PLASMA_TRANSFER" = TRAIT_ABILITY_NO_PLASMA_TRANSFER, "TRAIT_ABILITY_OVIPOSITOR" = TRAIT_ABILITY_OVIPOSITOR, @@ -416,6 +421,7 @@ GLOBAL_LIST(trait_name_map) #define TRAIT_SOURCE_ATTACHMENT(slot) "t_s_attachment_[slot]" ///Status trait coming from ability #define TRAIT_SOURCE_ABILITY(ability) "t_s_ability_[ability]" +#define TRAIT_SOURCE_LIMB(limb) "t_s_limb_[limb]" ///Status trait forced by the xeno action charge #define TRAIT_SOURCE_XENO_ACTION_CHARGE "t_s_xeno_action_charge" ///Status trait coming from a xeno nest diff --git a/code/__DEFINES/xeno.dm b/code/__DEFINES/xeno.dm index 590ee9b97d41..e3a35d0c4744 100644 --- a/code/__DEFINES/xeno.dm +++ b/code/__DEFINES/xeno.dm @@ -177,6 +177,20 @@ /// The time until you can re-corrupt a comms relay after the last pylon was destroyed #define XENO_PYLON_DESTRUCTION_DELAY (5 MINUTES) +/// Evolution boost during hijack +#define XENO_HIJACK_EVILUTION_BUFF 10 + +/// For how long the buff lasts +#define XENO_HIJACK_EVILUTION_TIME (3 MINUTES) + +/// If this is marine to xeno ratio during hijack, xenos see marines on tacmap +#define HIJACK_RATIO_FOR_TACMAP 0.8 + +/// Xenos need to have their number to marines ratio lower than this to get larvae from pylons +#define ENDGAME_LARVA_CAP_MULTIPLIER 0.5 + +/// What percent of their numbers xeno get from pylons +#define LARVA_ADDITION_MULTIPLIER 0.10 /// The time against away_timer when an AFK xeno larva can be replaced #define XENO_LEAVE_TIMER_LARVA 80 //80 seconds diff --git a/code/__HELPERS/#maths.dm b/code/__HELPERS/#maths.dm index 6ea534a79923..7eea79742148 100644 --- a/code/__HELPERS/#maths.dm +++ b/code/__HELPERS/#maths.dm @@ -9,11 +9,10 @@ GLOBAL_LIST_INIT(sqrtTable, list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, // MATH DEFINES #define Ceiling(x) (-round(-x)) -#define Clamp(val, min_val, max_val) (max(min_val, min(val, max_val))) #define CLAMP01(x) (clamp(x, 0, 1)) // cotangent -#define Cot(x) (1 / Tan(x)) +#define Cot(x) (1 / tan(x)) // cosecant #define Csc(x) (1 / sin(x)) @@ -21,19 +20,12 @@ GLOBAL_LIST_INIT(sqrtTable, list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, #define Default(a, b) (a ? a : b) #define Floor(x) (round(x)) -//Finds nearest integer to x, above or below -//something.5 or higher, round up, else round down -#define roundNearest(x) (((Ceiling(x) - x) <= (x - Floor(x))) ? Ceiling(x) : Floor(x)) - // Greatest Common Divisor - Euclid's algorithm #define Gcd(a, b) (b ? Gcd(b, a % b) : a) #define Inverse(x) (1 / x) #define IsEven(x) (x % 2 == 0) -// Returns true if val is from min to max, inclusive. -#define IsInRange(val, min, max) (min <= val && val <= max) - #define IsInteger(x) (Floor(x) == x) #define IsOdd(x) (!IsEven(x)) #define IsMultiple(x, y) (x % y == 0) @@ -47,9 +39,6 @@ GLOBAL_LIST_INIT(sqrtTable, list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, // secant #define Sec(x) (1 / cos(x)) -// tangent -#define Tan(x) (sin(x) / cos(x)) - // 57.2957795 = 180 / Pi #define ToDegrees(radians) (radians * 57.2957795) @@ -85,11 +74,6 @@ GLOBAL_LIST_INIT(sqrtTable, list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, return rotated_point -// Round up -/proc/n_ceil(num) - if(isnum(num)) - return round(num)+1 - ///Format a power value in W, kW, MW, or GW. /proc/display_power(powerused) if(powerused < 1000) //Less than a kW diff --git a/code/__HELPERS/_time.dm b/code/__HELPERS/_time.dm index 8386feff41c2..733ca659501b 100644 --- a/code/__HELPERS/_time.dm +++ b/code/__HELPERS/_time.dm @@ -48,7 +48,7 @@ GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0) return gameTimestamp("mm:ss", time) /proc/time_left_until(target_time, current_time, time_unit) - return CEILING(target_time - current_time, 1) / time_unit + return Ceiling(target_time - current_time) / time_unit /proc/text2duration(text = "00:00") // Attempts to convert time text back to time value var/split_text = splittext(text, ":") @@ -91,21 +91,21 @@ GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0) return "right now" if(second < 60) return "[second] second[(second != 1)? "s":""]" - var/minute = FLOOR(second / 60, 1) + var/minute = Floor(second / 60) second = FLOOR(MODULUS(second, 60), round_seconds_to) var/secondT if(second) secondT = " and [second] second[(second != 1)? "s":""]" if(minute < 60) return "[minute] minute[(minute != 1)? "s":""][secondT]" - var/hour = FLOOR(minute / 60, 1) + var/hour = Floor(minute / 60) minute = MODULUS(minute, 60) var/minuteT if(minute) minuteT = " and [minute] minute[(minute != 1)? "s":""]" if(hour < 24) return "[hour] hour[(hour != 1)? "s":""][minuteT][secondT]" - var/day = FLOOR(hour / 24, 1) + var/day = Floor(hour / 24) hour = MODULUS(hour, 24) var/hourT if(hour) diff --git a/code/__HELPERS/filters.dm b/code/__HELPERS/filters.dm index aa8d77c81d3a..29e3ec9efb1e 100644 --- a/code/__HELPERS/filters.dm +++ b/code/__HELPERS/filters.dm @@ -46,7 +46,7 @@ GLOBAL_LIST_INIT(master_filter_info, list( "y" = -1, "size" = 1, "offset" = 0, - "color" = COLOUR_HALF_TRANSPARENT_BLACK + "color" = COLOR_HALF_TRANSPARENT_BLACK ) ), "blur" = list( diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 97243002740d..29755683165c 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -548,9 +548,9 @@ world if (!value) return color var/list/RGB = ReadRGB(color) - RGB[1] = Clamp(RGB[1]+value,0,255) - RGB[2] = Clamp(RGB[2]+value,0,255) - RGB[3] = Clamp(RGB[3]+value,0,255) + RGB[1] = clamp(RGB[1]+value,0,255) + RGB[2] = clamp(RGB[2]+value,0,255) + RGB[3] = clamp(RGB[3]+value,0,255) return rgb(RGB[1],RGB[2],RGB[3]) /proc/sort_atoms_by_layer(list/atoms) diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm index 830e612712e2..30ef9428586d 100644 --- a/code/__HELPERS/lists.dm +++ b/code/__HELPERS/lists.dm @@ -391,6 +391,19 @@ original += result return original +/// Returns a list of atoms sorted by each entry's distance to `target`. +/proc/sort_list_dist(list/atom/list_to_sort, atom/target) + var/list/distances = list() + for(var/atom/A as anything in list_to_sort) + // Just in case this happens anyway. + if(!istype(A)) + stack_trace("sort_list_dist() was called with a list containing a non-atom object. ([A.type])") + return list_to_sort + + distances[A] = get_dist_sqrd(A, target) + + return sortTim(distances, GLOBAL_PROC_REF(cmp_numeric_asc), TRUE) + //Converts a bitfield to a list of numbers (or words if a wordlist is provided) /proc/bitfield2list(bitfield = 0, list/wordlist) var/list/r = list() diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 2c0fdfa42a8a..14d5217eacd9 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -40,11 +40,11 @@ #define skillcheckexplicit(user, skill, req_level) ((!user.skills || user.skills.is_skilled(skill, req_level, TRUE))) // Ensure the frequency is within bounds of what it should be sending/receiving at -// Sets f within bounds via `Clamp(round(f), 1441, 1489)` +// Sets f within bounds via `clamp(round(f), 1441, 1489)` // If f is even, adds 1 to its value to make it odd -#define sanitize_frequency(f) ((Clamp(round(f), 1441, 1489) % 2) == 0 ? \ - Clamp(round(f), 1441, 1489) + 1 : \ - Clamp(round(f), 1441, 1489) \ +#define sanitize_frequency(f) ((clamp(round(f), 1441, 1489) % 2) == 0 ? \ + clamp(round(f), 1441, 1489) + 1 : \ + clamp(round(f), 1441, 1489) \ ) //Turns 1479 into 147.9 @@ -893,86 +893,103 @@ GLOBAL_DATUM(action_purple_power_up, /image) if(!GLOB.busy_indicator_clock) GLOB.busy_indicator_clock = image('icons/mob/mob.dmi', null, "busy_generic", "pixel_y" = 22) GLOB.busy_indicator_clock.layer = FLY_LAYER + GLOB.busy_indicator_clock.plane = ABOVE_HUD_PLANE return GLOB.busy_indicator_clock else if(busy_type == BUSY_ICON_MEDICAL) if(!GLOB.busy_indicator_medical) GLOB.busy_indicator_medical = image('icons/mob/mob.dmi', null, "busy_medical", "pixel_y" = 0) //This shows directly on top of the mob, no offset! GLOB.busy_indicator_medical.layer = FLY_LAYER + GLOB.busy_indicator_medical.plane = ABOVE_HUD_PLANE return GLOB.busy_indicator_medical else if(busy_type == BUSY_ICON_BUILD) if(!GLOB.busy_indicator_build) GLOB.busy_indicator_build = image('icons/mob/mob.dmi', null, "busy_build", "pixel_y" = 22) GLOB.busy_indicator_build.layer = FLY_LAYER + GLOB.busy_indicator_build.plane = ABOVE_HUD_PLANE return GLOB.busy_indicator_build else if(busy_type == BUSY_ICON_FRIENDLY) if(!GLOB.busy_indicator_friendly) GLOB.busy_indicator_friendly = image('icons/mob/mob.dmi', null, "busy_friendly", "pixel_y" = 22) GLOB.busy_indicator_friendly.layer = FLY_LAYER + GLOB.busy_indicator_friendly.plane = ABOVE_HUD_PLANE return GLOB.busy_indicator_friendly else if(busy_type == BUSY_ICON_HOSTILE) if(!GLOB.busy_indicator_hostile) GLOB.busy_indicator_hostile = image('icons/mob/mob.dmi', null, "busy_hostile", "pixel_y" = 22) GLOB.busy_indicator_hostile.layer = FLY_LAYER + GLOB.busy_indicator_hostile.plane = ABOVE_HUD_PLANE return GLOB.busy_indicator_hostile else if(busy_type == EMOTE_ICON_HIGHFIVE) if(!GLOB.emote_indicator_highfive) GLOB.emote_indicator_highfive = image('icons/mob/mob.dmi', null, "emote_highfive", "pixel_y" = 22) GLOB.emote_indicator_highfive.layer = FLY_LAYER + GLOB.emote_indicator_highfive.plane = ABOVE_HUD_PLANE return GLOB.emote_indicator_highfive else if(busy_type == EMOTE_ICON_FISTBUMP) if(!GLOB.emote_indicator_fistbump) GLOB.emote_indicator_fistbump = image('icons/mob/mob.dmi', null, "emote_fistbump", "pixel_y" = 22) GLOB.emote_indicator_fistbump.layer = FLY_LAYER + GLOB.emote_indicator_fistbump.plane = ABOVE_HUD_PLANE return GLOB.emote_indicator_fistbump else if(busy_type == EMOTE_ICON_ROCK_PAPER_SCISSORS) if(!GLOB.emote_indicator_rock_paper_scissors) GLOB.emote_indicator_rock_paper_scissors = image('icons/mob/mob.dmi', null, "emote_rps", "pixel_y" = 22) GLOB.emote_indicator_rock_paper_scissors.layer = FLY_LAYER + GLOB.emote_indicator_rock_paper_scissors.plane = ABOVE_HUD_PLANE return GLOB.emote_indicator_rock_paper_scissors else if(busy_type == EMOTE_ICON_ROCK) if(!GLOB.emote_indicator_rock) GLOB.emote_indicator_rock = image('icons/mob/mob.dmi', null, "emote_rock", "pixel_y" = 22) GLOB.emote_indicator_rock.layer = FLY_LAYER + GLOB.emote_indicator_rock.plane = ABOVE_HUD_PLANE return GLOB.emote_indicator_rock else if(busy_type == EMOTE_ICON_PAPER) if(!GLOB.emote_indicator_paper) GLOB.emote_indicator_paper = image('icons/mob/mob.dmi', null, "emote_paper", "pixel_y" = 22) GLOB.emote_indicator_paper.layer = FLY_LAYER + GLOB.emote_indicator_paper.plane = ABOVE_HUD_PLANE return GLOB.emote_indicator_paper else if(busy_type == EMOTE_ICON_SCISSORS) if(!GLOB.emote_indicator_scissors) GLOB.emote_indicator_scissors = image('icons/mob/mob.dmi', null, "emote_scissors", "pixel_y" = 22) GLOB.emote_indicator_scissors.layer = FLY_LAYER + GLOB.emote_indicator_scissors.plane = ABOVE_HUD_PLANE return GLOB.emote_indicator_scissors else if(busy_type == EMOTE_ICON_HEADBUTT) if(!GLOB.emote_indicator_headbutt) GLOB.emote_indicator_headbutt = image('icons/mob/mob.dmi', null, "emote_headbutt", "pixel_y" = 22) GLOB.emote_indicator_headbutt.layer = FLY_LAYER + GLOB.emote_indicator_headbutt.plane = ABOVE_HUD_PLANE return GLOB.emote_indicator_headbutt else if(busy_type == EMOTE_ICON_TAILSWIPE) if(!GLOB.emote_indicator_tailswipe) GLOB.emote_indicator_tailswipe = image('icons/mob/mob.dmi', null, "emote_tailswipe", "pixel_y" = 22) GLOB.emote_indicator_tailswipe.layer = FLY_LAYER + GLOB.emote_indicator_tailswipe.plane = ABOVE_HUD_PLANE return GLOB.emote_indicator_tailswipe else if(busy_type == ACTION_RED_POWER_UP) if(!GLOB.action_red_power_up) GLOB.action_red_power_up = image('icons/effects/effects.dmi', null, "anger", "pixel_x" = 16) GLOB.action_red_power_up.layer = FLY_LAYER + GLOB.action_red_power_up.plane = ABOVE_HUD_PLANE return GLOB.action_red_power_up else if(busy_type == ACTION_GREEN_POWER_UP) if(!GLOB.action_green_power_up) GLOB.action_green_power_up = image('icons/effects/effects.dmi', null, "vitality", "pixel_x" = 16) GLOB.action_green_power_up.layer = FLY_LAYER + GLOB.action_green_power_up.plane = ABOVE_HUD_PLANE return GLOB.action_green_power_up else if(busy_type == ACTION_BLUE_POWER_UP) if(!GLOB.action_blue_power_up) GLOB.action_blue_power_up = image('icons/effects/effects.dmi', null, "shock", "pixel_x" = 16) GLOB.action_blue_power_up.layer = FLY_LAYER + GLOB.action_blue_power_up.plane = ABOVE_HUD_PLANE return GLOB.action_blue_power_up else if(busy_type == ACTION_PURPLE_POWER_UP) if(!GLOB.action_purple_power_up) GLOB.action_purple_power_up = image('icons/effects/effects.dmi', null, "pain", "pixel_x" = 16) GLOB.action_purple_power_up.layer = FLY_LAYER + GLOB.action_purple_power_up.plane = ABOVE_HUD_PLANE return GLOB.action_purple_power_up @@ -1085,7 +1102,7 @@ GLOBAL_DATUM(action_purple_power_up, /image) ) . = FALSE break - if(user_flags & INTERRUPT_DAZED && busy_user.dazed) + if(user_flags & INTERRUPT_DAZED && HAS_TRAIT(busy_user, TRAIT_DAZED)) . = FALSE break if(user_flags & INTERRUPT_EMOTE && !busy_user.flags_emote) @@ -1576,7 +1593,7 @@ GLOBAL_LIST_INIT(WALLITEMS, list( . = 0 var/i = DS2TICKS(initial_delay) do - . += CEILING(i*DELTA_CALC, 1) + . += Ceiling(i*DELTA_CALC) sleep(i*world.tick_lag*DELTA_CALC) i *= 2 while (TICK_USAGE > min(TICK_LIMIT_TO_RUN, Master.current_ticklimit)) diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index d302191c67eb..59d14f2e0fed 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -87,6 +87,7 @@ DEFINE_BITFIELD(flags_ammo_behaviour, list( "AMMO_IGNORE_RESIST" = AMMO_IGNORE_RESIST, "AMMO_BALLISTIC" = AMMO_BALLISTIC, "AMMO_IGNORE_COVER" = AMMO_IGNORE_COVER, + "AMMO_ANTIVEHICLE" = AMMO_ANTIVEHICLE, "AMMO_STOPPED_BY_COVER" = AMMO_STOPPED_BY_COVER, "AMMO_SPECIAL_EMBED" = AMMO_SPECIAL_EMBED, "AMMO_STRIKES_SURFACE" = AMMO_STRIKES_SURFACE, @@ -97,7 +98,6 @@ DEFINE_BITFIELD(flags_ammo_behaviour, list( "AMMO_FLAME" = AMMO_FLAME, )) - DEFINE_BITFIELD(projectile_flags, list( "PROJECTILE_SHRAPNEL" = PROJECTILE_SHRAPNEL, "PROJECTILE_BULLSEYE" = PROJECTILE_BULLSEYE, @@ -120,6 +120,7 @@ DEFINE_BITFIELD(flags_gun_features, list( "GUN_ANTIQUE" = GUN_ANTIQUE, "GUN_RECOIL_BUILDUP" = GUN_RECOIL_BUILDUP, "GUN_SUPPORT_PLATFORM" = GUN_SUPPORT_PLATFORM, + "GUN_NO_DESCRIPTION" = GUN_NO_DESCRIPTION, )) DEFINE_BITFIELD(flags_magazine, list( @@ -150,6 +151,7 @@ DEFINE_BITFIELD(flags_atom, list( "INITIALIZED" = INITIALIZED, "ATOM_DECORATED" = ATOM_DECORATED, "USES_HEARING" = USES_HEARING, + "HTML_USE_INITAL_ICON" = HTML_USE_INITAL_ICON, )) DEFINE_BITFIELD(flags_item, list( @@ -181,7 +183,7 @@ DEFINE_BITFIELD(flags_inv_hide, list( "HIDETOPHAIR" = HIDETOPHAIR, "HIDEALLHAIR" = HIDEALLHAIR, "HIDETAIL" = HIDETAIL, - "HIDEFACE" = HIDEFACE + "HIDEFACE" = HIDEFACE, )) DEFINE_BITFIELD(flags_inventory, list( @@ -327,9 +329,6 @@ DEFINE_BITFIELD(flags_area, list( DEFINE_BITFIELD(disabilities, list( "NEARSIGHTED" = NEARSIGHTED, - "EPILEPSY" = EPILEPSY, - "COUGHING" = COUGHING, - "TOURETTES" = TOURETTES, "NERVOUS" = NERVOUS, "OPIATE_RECEPTOR_DEFICIENCY" = OPIATE_RECEPTOR_DEFICIENCY, )) @@ -423,6 +422,7 @@ DEFINE_BITFIELD(toggleable_flags, list( "MODE_NO_COMBAT_CAS" = MODE_NO_COMBAT_CAS, "MODE_LZ_PROTECTION" = MODE_LZ_PROTECTION, "MODE_SHIPSIDE_SD" = MODE_SHIPSIDE_SD, + "MODE_HARDCORE_PERMA" = MODE_HARDCORE_PERMA, "MODE_DISPOSABLE_MOBS" = MODE_DISPOSABLE_MOBS, "MODE_BYPASS_JOE" = MODE_BYPASS_JOE, )) @@ -456,7 +456,9 @@ DEFINE_BITFIELD(fire_immunity, list( "FIRE_IMMUNITY_NO_DAMAGE" = FIRE_IMMUNITY_NO_DAMAGE, "FIRE_IMMUNITY_NO_IGNITE" = FIRE_IMMUNITY_NO_IGNITE, "FIRE_IMMUNITY_XENO_FRENZY" = FIRE_IMMUNITY_XENO_FRENZY, + "FIRE_VULNERABILITY" = FIRE_VULNERABILITY, )) + DEFINE_BITFIELD(vend_flags, list( "VEND_TO_HAND" = VEND_TO_HAND, "VEND_UNIFORM_RANKS" = VEND_UNIFORM_RANKS, @@ -478,3 +480,122 @@ DEFINE_BITFIELD(vehicle_flags, list( "VEHICLE_CLASS_HEAVY" = VEHICLE_CLASS_HEAVY, "VEHICLE_BYPASS_BLOCKERS" = VEHICLE_BYPASS_BLOCKERS, )) + +DEFINE_BITFIELD(flags_pass, list( + "PASS_THROUGH" = PASS_THROUGH, + "PASS_AROUND" = PASS_AROUND, + "PASS_OVER_THROW_ITEM" = PASS_OVER_THROW_ITEM, + "PASS_OVER_THROW_MOB" = PASS_OVER_THROW_MOB, + "PASS_OVER_FIRE" = PASS_OVER_FIRE, + "PASS_OVER_ACID_SPRAY" = PASS_OVER_ACID_SPRAY, + "PASS_UNDER" = PASS_UNDER, + "PASS_GLASS" = PASS_GLASS, + "PASS_MOB_IS_XENO" = PASS_MOB_IS_XENO, + "PASS_MOB_IS_HUMAN" = PASS_MOB_IS_HUMAN, + "PASS_MOB_IS_OTHER" = PASS_MOB_IS_OTHER, + "PASS_MOB_THRU_XENO" = PASS_MOB_THRU_XENO, + "PASS_MOB_THRU_HUMAN" = PASS_MOB_THRU_HUMAN, + "PASS_MOB_THRU_OTHER" = PASS_MOB_THRU_OTHER, + "PASS_TYPE_CRAWLER" = PASS_TYPE_CRAWLER, + "PASS_HIGH_OVER_ONLY" = PASS_HIGH_OVER_ONLY, + "PASS_BUILDING_ONLY" = PASS_BUILDING_ONLY, + "PASS_CRUSHER_CHARGE" = PASS_CRUSHER_CHARGE, +)) + +DEFINE_BITFIELD(flags_can_pass_all, list( + "PASS_THROUGH" = PASS_THROUGH, + "PASS_AROUND" = PASS_AROUND, + "PASS_OVER_THROW_ITEM" = PASS_OVER_THROW_ITEM, + "PASS_OVER_THROW_MOB" = PASS_OVER_THROW_MOB, + "PASS_OVER_FIRE" = PASS_OVER_FIRE, + "PASS_OVER_ACID_SPRAY" = PASS_OVER_ACID_SPRAY, + "PASS_UNDER" = PASS_UNDER, + "PASS_GLASS" = PASS_GLASS, + "PASS_MOB_IS_XENO" = PASS_MOB_IS_XENO, + "PASS_MOB_IS_HUMAN" = PASS_MOB_IS_HUMAN, + "PASS_MOB_IS_OTHER" = PASS_MOB_IS_OTHER, + "PASS_MOB_THRU_XENO" = PASS_MOB_THRU_XENO, + "PASS_MOB_THRU_HUMAN" = PASS_MOB_THRU_HUMAN, + "PASS_MOB_THRU_OTHER" = PASS_MOB_THRU_OTHER, + "PASS_TYPE_CRAWLER" = PASS_TYPE_CRAWLER, + "PASS_HIGH_OVER_ONLY" = PASS_HIGH_OVER_ONLY, + "PASS_BUILDING_ONLY" = PASS_BUILDING_ONLY, + "PASS_CRUSHER_CHARGE" = PASS_CRUSHER_CHARGE, +)) + +DEFINE_BITFIELD(flags_can_pass_front, list( + "PASS_THROUGH" = PASS_THROUGH, + "PASS_AROUND" = PASS_AROUND, + "PASS_OVER_THROW_ITEM" = PASS_OVER_THROW_ITEM, + "PASS_OVER_THROW_MOB" = PASS_OVER_THROW_MOB, + "PASS_OVER_FIRE" = PASS_OVER_FIRE, + "PASS_OVER_ACID_SPRAY" = PASS_OVER_ACID_SPRAY, + "PASS_UNDER" = PASS_UNDER, + "PASS_GLASS" = PASS_GLASS, + "PASS_MOB_IS_XENO" = PASS_MOB_IS_XENO, + "PASS_MOB_IS_HUMAN" = PASS_MOB_IS_HUMAN, + "PASS_MOB_IS_OTHER" = PASS_MOB_IS_OTHER, + "PASS_MOB_THRU_XENO" = PASS_MOB_THRU_XENO, + "PASS_MOB_THRU_HUMAN" = PASS_MOB_THRU_HUMAN, + "PASS_MOB_THRU_OTHER" = PASS_MOB_THRU_OTHER, + "PASS_TYPE_CRAWLER" = PASS_TYPE_CRAWLER, + "PASS_HIGH_OVER_ONLY" = PASS_HIGH_OVER_ONLY, + "PASS_BUILDING_ONLY" = PASS_BUILDING_ONLY, + "PASS_CRUSHER_CHARGE" = PASS_CRUSHER_CHARGE, +)) + +DEFINE_BITFIELD(flags_can_pass_behind, list( + "PASS_THROUGH" = PASS_THROUGH, + "PASS_AROUND" = PASS_AROUND, + "PASS_OVER_THROW_ITEM" = PASS_OVER_THROW_ITEM, + "PASS_OVER_THROW_MOB" = PASS_OVER_THROW_MOB, + "PASS_OVER_FIRE" = PASS_OVER_FIRE, + "PASS_OVER_ACID_SPRAY" = PASS_OVER_ACID_SPRAY, + "PASS_UNDER" = PASS_UNDER, + "PASS_GLASS" = PASS_GLASS, + "PASS_MOB_IS_XENO" = PASS_MOB_IS_XENO, + "PASS_MOB_IS_HUMAN" = PASS_MOB_IS_HUMAN, + "PASS_MOB_IS_OTHER" = PASS_MOB_IS_OTHER, + "PASS_MOB_THRU_XENO" = PASS_MOB_THRU_XENO, + "PASS_MOB_THRU_HUMAN" = PASS_MOB_THRU_HUMAN, + "PASS_MOB_THRU_OTHER" = PASS_MOB_THRU_OTHER, + "PASS_TYPE_CRAWLER" = PASS_TYPE_CRAWLER, + "PASS_HIGH_OVER_ONLY" = PASS_HIGH_OVER_ONLY, + "PASS_BUILDING_ONLY" = PASS_BUILDING_ONLY, + "PASS_CRUSHER_CHARGE" = PASS_CRUSHER_CHARGE, +)) + +DEFINE_BITFIELD(sight, list( + "BLIND" = BLIND, + "SEE_BLACKNESS" = SEE_BLACKNESS, + "SEE_INFRA" = SEE_INFRA, + "SEE_MOBS" = SEE_MOBS, + "SEE_OBJS" = SEE_OBJS, + "SEE_PIXELS" = SEE_PIXELS, + "SEE_SELF" = SEE_SELF, + "SEE_THRU" = SEE_THRU, + "SEE_TURFS" = SEE_TURFS, +)) + +DEFINE_BITFIELD(vision_flags, list( + "BLIND" = BLIND, + "SEE_BLACKNESS" = SEE_BLACKNESS, + "SEE_INFRA" = SEE_INFRA, + "SEE_MOBS" = SEE_MOBS, + "SEE_OBJS" = SEE_OBJS, + "SEE_PIXELS" = SEE_PIXELS, + "SEE_SELF" = SEE_SELF, + "SEE_THRU" = SEE_THRU, + "SEE_TURFS" = SEE_TURFS, +)) + +DEFINE_BITFIELD(vis_flags, list( + "VIS_HIDE" = VIS_HIDE, + "VIS_INHERIT_DIR" = VIS_INHERIT_DIR, + "VIS_INHERIT_ICON" = VIS_INHERIT_ICON, + "VIS_INHERIT_ICON_STATE" = VIS_INHERIT_ICON_STATE, + "VIS_INHERIT_ID" = VIS_INHERIT_ID, + "VIS_INHERIT_LAYER" = VIS_INHERIT_LAYER, + "VIS_INHERIT_PLANE" = VIS_INHERIT_PLANE, + "VIS_UNDERLAY" = VIS_UNDERLAY, +)) diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index b99d52086e36..72e298d32729 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -376,8 +376,8 @@ var/shiftX = C.pixel_x / world.icon_size var/shiftY = C.pixel_y / world.icon_size var/list/actual_view = getviewsize(C ? C.view : GLOB.world_view_size) - tX = Clamp(origin.x + text2num(tX) + shiftX - round(actual_view[1] / 2) - 1, 1, world.maxx) - tY = Clamp(origin.y + text2num(tY) + shiftY - round(actual_view[2] / 2) - 1, 1, world.maxy) + tX = clamp(origin.x + text2num(tX) + shiftX - round(actual_view[1] / 2) - 1, 1, world.maxx) + tY = clamp(origin.y + text2num(tY) + shiftY - round(actual_view[2] / 2) - 1, 1, world.maxy) return locate(tX, tY, tZ) diff --git a/code/_onclick/hud/map_popups.dm b/code/_onclick/hud/map_popups.dm index aed6b46a7905..26dc93bbff2b 100644 --- a/code/_onclick/hud/map_popups.dm +++ b/code/_onclick/hud/map_popups.dm @@ -118,10 +118,11 @@ * anyway. they're effectively qdel'd. */ /client/proc/clear_map(map_name) - if(!map_name || !(map_name in screen_maps)) + if(!map_name || !screen_maps[map_name]) return FALSE for(var/atom/movable/screen/screen_obj in screen_maps[map_name]) screen_maps[map_name] -= screen_obj + remove_from_screen(screen_obj) if(screen_obj.del_on_map_removal) qdel(screen_obj) screen_maps -= map_name diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 00598d9db014..e4e8ff64c19c 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -532,9 +532,10 @@ options["Xeno Leader [xeno_lead]"] = list(TRACKER_LEADER, xeno_leader_index) xeno_leader_index++ + var/list/sorted_tunnels = sort_list_dist(user.hive.tunnels, get_turf(user)) var/tunnel_index = 1 - for(var/obj/structure/tunnel/tracked_tunnel in user.hive.tunnels) - options["Tunnel [tracked_tunnel.tunnel_desc]"] = list(TRACKER_TUNNEL, tunnel_index) + for(var/obj/structure/tunnel/tunnel in sorted_tunnels) + options["Tunnel [tunnel.tunnel_desc]"] = list(TRACKER_TUNNEL, tunnel_index) tunnel_index++ var/selected = tgui_input_list(user, "Select what you want the locator to track.", "Locator Options", options) diff --git a/code/controllers/subsystem/minimap.dm b/code/controllers/subsystem/minimap.dm index a808e7e3fd85..3255c7db2fc5 100644 --- a/code/controllers/subsystem/minimap.dm +++ b/code/controllers/subsystem/minimap.dm @@ -88,8 +88,8 @@ SUBSYSTEM_DEF(minimaps) else if(yval < smallest_y) smallest_y = yval - minimaps_by_z["[level]"].x_offset = FLOOR((SCREEN_PIXEL_SIZE-largest_x-smallest_x) / MINIMAP_SCALE, 1) - minimaps_by_z["[level]"].y_offset = FLOOR((SCREEN_PIXEL_SIZE-largest_y-smallest_y) / MINIMAP_SCALE, 1) + minimaps_by_z["[level]"].x_offset = Floor((SCREEN_PIXEL_SIZE-largest_x-smallest_x) / MINIMAP_SCALE) + minimaps_by_z["[level]"].y_offset = Floor((SCREEN_PIXEL_SIZE-largest_y-smallest_y) / MINIMAP_SCALE) icon_gen.Shift(EAST, minimaps_by_z["[level]"].x_offset) icon_gen.Shift(NORTH, minimaps_by_z["[level]"].y_offset) @@ -691,6 +691,11 @@ SUBSYSTEM_DEF(minimaps) if(faction == FACTION_NEUTRAL && isobserver(user)) faction = allowed_flags == MINIMAP_FLAG_XENO ? XENO_HIVE_NORMAL : FACTION_MARINE + if(is_xeno && xeno.hive.see_humans_on_tacmap && targeted_ztrait != ZTRAIT_MARINE_MAIN_SHIP) + allowed_flags |= MINIMAP_FLAG_USCM|MINIMAP_FLAG_PMC|MINIMAP_FLAG_UPP|MINIMAP_FLAG_CLF + targeted_ztrait = ZTRAIT_MARINE_MAIN_SHIP + map_holder = null + new_current_map = get_unannounced_tacmap_data_png(faction) old_map = get_tacmap_data_png(faction) current_svg = get_tacmap_data_svg(faction) diff --git a/code/controllers/subsystem/timer.dm b/code/controllers/subsystem/timer.dm index e7e17876d9db..47403f3379fb 100644 --- a/code/controllers/subsystem/timer.dm +++ b/code/controllers/subsystem/timer.dm @@ -583,7 +583,7 @@ SUBSYSTEM_DEF(timer) be supported and may refuse to run or run with a 0 wait") if (flags & TIMER_CLIENT_TIME) // REALTIMEOFDAY has a resolution of 1 decisecond - wait = max(CEILING(wait, 1), 1) // so if we use tick_lag timers may be inserted in the "past" + wait = max(Ceiling(wait), 1) // so if we use tick_lag timers may be inserted in the "past" else wait = max(CEILING(wait, world.tick_lag), world.tick_lag) diff --git a/code/controllers/subsystem/x_evolution.dm b/code/controllers/subsystem/x_evolution.dm index be787b37de80..857af8117df2 100644 --- a/code/controllers/subsystem/x_evolution.dm +++ b/code/controllers/subsystem/x_evolution.dm @@ -11,6 +11,7 @@ SUBSYSTEM_DEF(xevolution) var/time_ratio_modifier = 0.4 var/list/boost_power = list() + var/list/overridden_power = list() var/force_boost_power = FALSE // Debugging only /datum/controller/subsystem/xevolution/Initialize(start_timeofday) @@ -18,6 +19,7 @@ SUBSYSTEM_DEF(xevolution) for(var/hivenumber in GLOB.hive_datum) HS = GLOB.hive_datum[hivenumber] boost_power[HS.hivenumber] = 1 + overridden_power[HS.hivenumber] = FALSE return SS_INIT_SUCCESS /datum/controller/subsystem/xevolution/fire(resumed = FALSE) @@ -27,6 +29,9 @@ SUBSYSTEM_DEF(xevolution) if(!HS) continue + if(overridden_power[HS.hivenumber]) + continue + if(!HS.dynamic_evolution) boost_power[HS.hivenumber] = HS.evolution_rate + HS.evolution_bonus HS.hive_ui.update_burrowed_larva() @@ -42,7 +47,7 @@ SUBSYSTEM_DEF(xevolution) //Add on any bonuses from thie hivecore after applying upgrade progress boost_power_new += (0.5 * HS.has_special_structure(XENO_STRUCTURE_CORE)) - boost_power_new = Clamp(boost_power_new, BOOST_POWER_MIN, BOOST_POWER_MAX) + boost_power_new = clamp(boost_power_new, BOOST_POWER_MIN, BOOST_POWER_MAX) boost_power_new += HS.evolution_bonus if(!force_boost_power) @@ -54,6 +59,12 @@ SUBSYSTEM_DEF(xevolution) /datum/controller/subsystem/xevolution/proc/get_evolution_boost_power(hivenumber) return boost_power[hivenumber] +/datum/controller/subsystem/xevolution/proc/override_power(hivenumber, power, override) + var/datum/hive_status/hive_status = GLOB.hive_datum[hivenumber] + boost_power[hivenumber] = power + overridden_power[hivenumber] = override + hive_status.hive_ui.update_burrowed_larva() + #undef EVOLUTION_INCREMENT_TIME #undef BOOST_POWER_MIN #undef BOOST_POWER_MAX diff --git a/code/datums/balloon_alerts/balloon_alerts.dm b/code/datums/balloon_alerts/balloon_alerts.dm index 8ef770fa9d7f..59f826fbe7d2 100644 --- a/code/datums/balloon_alerts/balloon_alerts.dm +++ b/code/datums/balloon_alerts/balloon_alerts.dm @@ -37,20 +37,15 @@ if (isnull(viewer_client)) return - var/bound_width = world.icon_size - if (ismovable(src)) - var/atom/movable/movable_source = src - bound_width = movable_source.bound_width - var/image/balloon_alert = image(loc = get_atom_on_turf(src), layer = ABOVE_MOB_LAYER) balloon_alert.plane = RUNECHAT_PLANE balloon_alert.alpha = 0 balloon_alert.color = text_color balloon_alert.appearance_flags = NO_CLIENT_COLOR|KEEP_APART|RESET_COLOR|RESET_TRANSFORM|RESET_ALPHA balloon_alert.maptext = MAPTEXT("[text]") - balloon_alert.maptext_x = (BALLOON_TEXT_WIDTH - bound_width) * -0.5 balloon_alert.maptext_height = WXH_TO_HEIGHT(viewer_client?.MeasureText(text, null, BALLOON_TEXT_WIDTH)) balloon_alert.maptext_width = BALLOON_TEXT_WIDTH + balloon_alert.maptext_x = get_maxptext_x_offset(balloon_alert) if(appearance_flags & PIXEL_SCALE) balloon_alert.appearance_flags |= PIXEL_SCALE //"[text]" diff --git a/code/datums/beam.dm b/code/datums/beam.dm index e51dcafa0218..08b5ea9f9a64 100644 --- a/code/datums/beam.dm +++ b/code/datums/beam.dm @@ -125,11 +125,11 @@ //Position the effect so the beam is one continous line var/a if(abs(Pixel_x)>world.icon_size) - a = Pixel_x > 0 ? round(Pixel_x/32) : CEILING(Pixel_x/world.icon_size, 1) + a = Pixel_x > 0 ? round(Pixel_x/32) : Ceiling(Pixel_x/world.icon_size) X.x += a Pixel_x %= world.icon_size if(abs(Pixel_y)>world.icon_size) - a = Pixel_y > 0 ? round(Pixel_y/32) : CEILING(Pixel_y/world.icon_size, 1) + a = Pixel_y > 0 ? round(Pixel_y/32) : Ceiling(Pixel_y/world.icon_size) X.y += a Pixel_y %= world.icon_size diff --git a/code/datums/components/overlay_lighting.dm b/code/datums/components/overlay_lighting.dm index 00a5e86b5d60..8288453f7b24 100644 --- a/code/datums/components/overlay_lighting.dm +++ b/code/datums/components/overlay_lighting.dm @@ -194,7 +194,7 @@ get_new_turfs() -///Adds the luminosity and source for the afected movable atoms to keep track of their visibility. +///Adds the luminosity and source for the affected movable atoms to keep track of their visibility. /datum/component/overlay_lighting/proc/add_dynamic_lumi() LAZYSET(current_holder.affected_movable_lights, src, lumcount_range + 1) current_holder.underlays += visible_mask @@ -202,7 +202,7 @@ if(directional) current_holder.underlays += cone -///Removes the luminosity and source for the afected movable atoms to keep track of their visibility. +///Removes the luminosity and source for the affected movable atoms to keep track of their visibility. /datum/component/overlay_lighting/proc/remove_dynamic_lumi() LAZYREMOVE(current_holder.affected_movable_lights, src) current_holder.underlays -= visible_mask @@ -262,6 +262,9 @@ ///Used to determine the new valid current_holder from the parent's loc. /datum/component/overlay_lighting/proc/check_holder() var/atom/movable/movable_parent = GET_PARENT + if(QDELETED(movable_parent)) + set_holder(null) + return if(isturf(movable_parent.loc)) set_holder(movable_parent) return @@ -270,13 +273,21 @@ set_holder(null) return if(isturf(inside.loc)) - set_holder(inside) + // storage items block light, also don't be moving into a qdeleted item + if(QDELETED(inside) || istype(inside, /obj/item/storage)) + set_holder(null) + else + set_holder(inside) return set_holder(null) ///Called when the current_holder is qdeleted, to remove the light effect. /datum/component/overlay_lighting/proc/on_holder_qdel(atom/movable/source, force) + SIGNAL_HANDLER + if(QDELETED(current_holder)) + set_holder(null) + return UnregisterSignal(current_holder, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED)) if(directional) UnregisterSignal(current_holder, COMSIG_ATOM_DIR_CHANGE) @@ -285,6 +296,7 @@ ///Called when current_holder changes loc. /datum/component/overlay_lighting/proc/on_holder_moved(atom/movable/source, OldLoc, Dir, Forced) + SIGNAL_HANDLER if(!(overlay_lighting_flags & LIGHTING_ON)) return make_luminosity_update() @@ -328,7 +340,7 @@ turn_off() range = clamp(CEILING(new_range, 0.5), 1, 7) var/pixel_bounds = ((range - 1) * 64) + 32 - lumcount_range = CEILING(range, 1) + lumcount_range = Ceiling(range) if(current_holder && overlay_lighting_flags & LIGHTING_ON) current_holder.underlays -= visible_mask visible_mask.icon = light_overlays["[pixel_bounds]"] @@ -443,8 +455,7 @@ . = lum_power lum_power = new_lum_power var/difference = . - lum_power - for(var/t in affected_turfs) - var/turf/lit_turf = t + for(var/turf/lit_turf as anything in affected_turfs) lit_turf.dynamic_lumcount -= difference ///Here we append the behavior associated to changing lum_power. diff --git a/code/datums/components/weed_food.dm b/code/datums/components/weed_food.dm index 2335a053412f..400c2f15cf9a 100644 --- a/code/datums/components/weed_food.dm +++ b/code/datums/components/weed_food.dm @@ -90,6 +90,7 @@ RegisterSignal(parent_mob, COMSIG_MOVABLE_MOVED, PROC_REF(on_move)) RegisterSignal(parent_mob, list(COMSIG_LIVING_REJUVENATED, COMSIG_HUMAN_REVIVED), PROC_REF(on_rejuv)) RegisterSignal(parent_mob, COMSIG_HUMAN_SET_UNDEFIBBABLE, PROC_REF(on_update)) + RegisterSignal(SSdcs, COMSIG_GLOB_GROUNDSIDE_FORSAKEN_HANDLING, PROC_REF(on_forsaken)) if(parent_turf) RegisterSignal(parent_turf, COMSIG_WEEDNODE_GROWTH, PROC_REF(on_update)) @@ -109,6 +110,7 @@ UnregisterSignal(parent_buckle, COSMIG_OBJ_AFTER_BUCKLE) if(parent_nest) UnregisterSignal(parent_nest, COMSIG_PARENT_QDELETING) + UnregisterSignal(SSdcs, COMSIG_GLOB_GROUNDSIDE_FORSAKEN_HANDLING) /// SIGNAL_HANDLER for COMSIG_MOVABLE_MOVED /datum/component/weed_food/proc/on_move() @@ -178,6 +180,20 @@ UnregisterSignal(parent_nest, COMSIG_PARENT_QDELETING) parent_nest = null +/// SIGNAL_HANDLER for COMSIG_GLOB_GROUNDSIDE_FORSAKEN_HANDLING +/datum/component/weed_food/proc/on_forsaken() + SIGNAL_HANDLER + + UnregisterSignal(SSdcs, COMSIG_GLOB_GROUNDSIDE_FORSAKEN_HANDLING) + + if(!merged) + return + if(!is_ground_level(parent_mob.z)) + return + + var/datum/hive_status/hive = GLOB.hive_datum[XENO_HIVE_FORSAKEN] + weed_appearance.color = hive.color + /** * Try to start the process to turn into weeds * Returns TRUE if started successfully diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm index d933b81eb620..8b84513169e6 100644 --- a/code/datums/diseases/advance/advance.dm +++ b/code/datums/diseases/advance/advance.dm @@ -204,9 +204,9 @@ GLOBAL_LIST_INIT(advance_cures, list( hidden = list( (properties["stealth"] > 2), (properties["stealth"] > 3) ) // The more symptoms we have, the less transmittable it is but some symptoms can make up for it. - SetSpread(Clamp(properties["transmittable"] - symptoms.len, BLOOD, AIRBORNE)) + SetSpread(clamp(properties["transmittable"] - symptoms.len, BLOOD, AIRBORNE)) permeability_mod = max(Ceiling(0.4 * properties["transmittable"]), 1) - cure_chance = 15 - Clamp(properties["resistance"], -5, 5) // can be between 10 and 20 + cure_chance = 15 - clamp(properties["resistance"], -5, 5) // can be between 10 and 20 stage_prob = max(properties["stage_rate"], 2) SetSeverity(properties["severity"]) GenerateCure(properties) @@ -254,7 +254,7 @@ GLOBAL_LIST_INIT(advance_cures, list( // Will generate a random cure, the less resistance the symptoms have, the harder the cure. /datum/disease/advance/proc/GenerateCure(list/properties = list()) if(properties && properties.len) - var/res = Clamp(properties["resistance"] - (symptoms.len / 2), 1, GLOB.advance_cures.len) + var/res = clamp(properties["resistance"] - (symptoms.len / 2), 1, GLOB.advance_cures.len) cure_id = GLOB.advance_cures[res] // Get the cure name from the cure_id diff --git a/code/datums/effects/neurotoxin.dm b/code/datums/effects/neurotoxin.dm index 1657d41d8a36..490ed213292b 100644 --- a/code/datums/effects/neurotoxin.dm +++ b/code/datums/effects/neurotoxin.dm @@ -150,7 +150,7 @@ victim.hallucination = 3 victim.druggy = 3 if(70 to 100) // sound based hallucination - playsound_client(victim.client,pick('sound/voice/alien_distantroar_3.ogg','sound/voice/xenos_roaring.ogg','sound/voice/alien_queen_breath1.ogg', 'sound/voice/4_xeno_roars.ogg','sound/misc/notice2.ogg',"bone_break","gun_pulse","metalbang","pry","shatter")) + playsound_client(client = victim.client, soundin = pick('sound/voice/alien_distantroar_3.ogg','sound/voice/xenos_roaring.ogg','sound/voice/alien_queen_breath1.ogg', 'sound/voice/4_xeno_roars.ogg','sound/misc/notice2.ogg',"bone_break","gun_pulse","metalbang","pry","shatter"),vol = 65) diff --git a/code/datums/keybinding/yautja.dm b/code/datums/keybinding/yautja.dm index 4729db004582..c79788df49a3 100644 --- a/code/datums/keybinding/yautja.dm +++ b/code/datums/keybinding/yautja.dm @@ -30,16 +30,7 @@ classic_keys = list("Unbound") name = "pred_buy" full_name = "Claim equipment" - keybind_signal = COMSIG_KB_YAUTJA_BUTCHER - -/datum/keybinding/yautja/pred_buy/down(client/user) - . = ..() - if(.) - return - var/mob/living/carbon/human/H = user.mob - if(!isyautja(H)) - return - H.pred_buy() + keybind_signal = COMSIG_KB_YAUTJA_PRED_BUY /datum/keybinding/yautja/mark_panel hotkey_keys = list("Unbound") @@ -48,46 +39,12 @@ full_name = "Mark panel" keybind_signal = COMSIG_KB_YAUTJA_MARK_PANEL -/datum/keybinding/yautja/mark_panel/down(client/user) - . = ..() - if(.) - return - var/mob/living/carbon/human/H = user.mob - if(!isyautja(H)) - return - H.mark_panel() - /datum/keybinding/yautja/mark_for_hunt hotkey_keys = list("Unbound") classic_keys = list("Unbound") name = "mark_for_hunt" - full_name = "Mark for hunt" - keybind_signal = COMSIG_KB_YAUTJA_MARK_FOR_HUNT - -/datum/keybinding/yautja/mark_for_hunt/down(client/user) - . = ..() - if(.) - return - var/mob/living/carbon/human/H = user.mob - if(!isyautja(H)) - return - H.mark_for_hunt() - -/datum/keybinding/yautja/remove_from_hunt - hotkey_keys = list("Unbound") - classic_keys = list("Unbound") - name = "remove_from_hunt" - full_name = "Remove from hunt" - keybind_signal = COMSIG_KB_YAUTJA_REMOVE_FROM_HUNT - -/datum/keybinding/yautja/remove_from_hunt/down(client/user) - . = ..() - if(.) - return - var/mob/living/carbon/human/H = user.mob - if(!isyautja(H)) - return - H.remove_from_hunt() + full_name = "Toggle mark for hunt" + keybind_signal = COMSIG_KB_YAUTJA_TOGGLE_MARK_FOR_HUNT // BRACER SPECIFIC \\ @@ -168,22 +125,6 @@ full_name = "Toggle wristblades" keybind_signal = COMSIG_KB_YAUTJA_WRISTBLADES -/datum/keybinding/yautja/bracer_hunter/wristblades/down(client/user) - . = ..() - if(.) - return - var/mob/living/carbon/human/H = user.mob - - var/obj/item/clothing/gloves/yautja/hunter/gloves = H.gloves - if(istype(gloves)) - gloves.wristblades() - return TRUE - - var/obj/item/clothing/gloves/yautja/hunter/held = H.get_held_item() - if(istype(held)) - held.wristblades() - return TRUE - /datum/keybinding/yautja/bracer_hunter/track_gear hotkey_keys = list("Unbound") classic_keys = list("Unbound") @@ -214,22 +155,6 @@ full_name = "Toggle cloak" keybind_signal = COMSIG_KB_YAUTJA_CLOAKER -/datum/keybinding/yautja/bracer_hunter/cloaker/down(client/user) - . = ..() - if(.) - return - var/mob/living/carbon/human/H = user.mob - - var/obj/item/clothing/gloves/yautja/hunter/gloves = H.gloves - if(istype(gloves)) - gloves.cloaker() - return TRUE - - var/obj/item/clothing/gloves/yautja/hunter/held = H.get_held_item() - if(istype(held)) - held.cloaker() - return TRUE - /datum/keybinding/yautja/bracer_hunter/caster hotkey_keys = list("Unbound") classic_keys = list("Unbound") @@ -237,22 +162,6 @@ full_name = "Toggle plasma caster" keybind_signal = COMSIG_KB_YAUTJA_CASTER -/datum/keybinding/yautja/bracer_hunter/caster/down(client/user) - . = ..() - if(.) - return - var/mob/living/carbon/human/H = user.mob - - var/obj/item/clothing/gloves/yautja/hunter/gloves = H.gloves - if(istype(gloves)) - gloves.caster() - return TRUE - - var/obj/item/clothing/gloves/yautja/hunter/held = H.get_held_item() - if(istype(held)) - held.caster() - return TRUE - /datum/keybinding/yautja/bracer_hunter/change_explosion_type hotkey_keys = list("Unbound") classic_keys = list("Unbound") @@ -283,22 +192,6 @@ full_name = "Self-destruct" keybind_signal = COMSIG_KB_YAUTJA_ACTIVATE_SUICIDE -/datum/keybinding/yautja/bracer_hunter/activate_suicide/down(client/user) - . = ..() - if(.) - return - var/mob/living/carbon/human/H = user.mob - - var/obj/item/clothing/gloves/yautja/hunter/gloves = H.gloves - if(istype(gloves)) - gloves.activate_suicide() - return TRUE - - var/obj/item/clothing/gloves/yautja/hunter/held = H.get_held_item() - if(istype(held)) - held.activate_suicide() - return TRUE - /datum/keybinding/yautja/bracer_hunter/injectors hotkey_keys = list("Unbound") classic_keys = list("Unbound") @@ -306,21 +199,6 @@ full_name = "Create Stabilising Crystal" keybind_signal = COMSIG_KB_YAUTJA_INJECTORS -/datum/keybinding/yautja/bracer_hunter/injectors/down(client/user) - . = ..() - if(.) - return - var/mob/living/carbon/human/H = user.mob - - var/obj/item/clothing/gloves/yautja/hunter/gloves = H.gloves - if(istype(gloves)) - gloves.injectors() - return TRUE - - var/obj/item/clothing/gloves/yautja/hunter/held = H.get_held_item() - if(istype(held)) - held.injectors() - return TRUE /datum/keybinding/yautja/bracer_hunter/healing_capsule hotkey_keys = list("Unbound") classic_keys = list("Unbound") @@ -328,22 +206,6 @@ full_name = "Create Healing Capsule" keybind_signal = COMSIG_KB_YAUTJA_CAPSULE -/datum/keybinding/yautja/bracer_hunter/healing_capsule/down(client/user) - . = ..() - if(.) - return - var/mob/living/carbon/human/H = user.mob - - var/obj/item/clothing/gloves/yautja/hunter/gloves = H.gloves - if(istype(gloves)) - gloves.healing_capsule() - return TRUE - - var/obj/item/clothing/gloves/yautja/hunter/held = H.get_held_item() - if(istype(held)) - held.healing_capsule() - return TRUE - /datum/keybinding/yautja/bracer_hunter/call_disc hotkey_keys = list("Unbound") classic_keys = list("Unbound") @@ -351,22 +213,6 @@ full_name = "Call smart-disc" keybind_signal = COMSIG_KB_YAUTJA_CALL_DISC -/datum/keybinding/yautja/bracer_hunter/call_disc/down(client/user) - . = ..() - if(.) - return - var/mob/living/carbon/human/H = user.mob - - var/obj/item/clothing/gloves/yautja/hunter/gloves = H.gloves - if(istype(gloves)) - gloves.call_disc() - return TRUE - - var/obj/item/clothing/gloves/yautja/hunter/held = H.get_held_item() - if(istype(held)) - held.call_disc() - return TRUE - /datum/keybinding/yautja/bracer_hunter/remove_tracked_item hotkey_keys = list("Unbound") classic_keys = list("Unbound") @@ -420,22 +266,6 @@ full_name = "Yank combi-stick" keybind_signal = COMSIG_KB_YAUTJA_CALL_COMBI -/datum/keybinding/yautja/bracer_hunter/call_combi/down(client/user) - . = ..() - if(.) - return - var/mob/living/carbon/human/H = user.mob - - var/obj/item/clothing/gloves/yautja/hunter/gloves = H.gloves - if(istype(gloves)) - gloves.call_combi() - return TRUE - - var/obj/item/clothing/gloves/yautja/hunter/held = H.get_held_item() - if(istype(held)) - held.call_combi() - return TRUE - /datum/keybinding/yautja/bracer_hunter/translate hotkey_keys = list("Unbound") classic_keys = list("Unbound") @@ -443,22 +273,6 @@ full_name = "Translator" keybind_signal = COMSIG_KB_YAUTJA_TRANSLATE -/datum/keybinding/yautja/bracer_hunter/translate/down(client/user) - . = ..() - if(.) - return - var/mob/living/carbon/human/H = user.mob - - var/obj/item/clothing/gloves/yautja/hunter/gloves = H.gloves - if(istype(gloves)) - gloves.translate() - return TRUE - - var/obj/item/clothing/gloves/yautja/hunter/held = H.get_held_item() - if(istype(held)) - held.translate() - return TRUE - /datum/keybinding/yautja/bracer_hunter/bracername hotkey_keys = list("Unbound") classic_keys = list("Unbound") @@ -528,6 +342,13 @@ held.link_bracer() return TRUE +/datum/keybinding/yautja/bracer_hunter/control_falcon_drone + hotkey_keys = list("Unbound") + classic_keys = list("Unbound") + name = "control_falcon" + full_name = "Control falcon drone" + keybind_signal = COMSIG_KB_YAUTJA_CONTROL_FALCON + // Misc stuff - mask, teleporter \\ // mask @@ -545,32 +366,14 @@ classic_keys = list("Unbound") name = "toggle_zoom" full_name = "Toggle mask zoom" - keybind_signal = COMSIG_KB_YAUTJA_LINK_BRACER - -/datum/keybinding/yautja/mask/toggle_zoom/down(client/user) - . = ..() - if(.) - return - var/mob/living/carbon/human/H = user.mob - var/obj/item/clothing/mask/gas/yautja/mask = H.wear_mask - mask.toggle_zoom() - return TRUE + keybind_signal = COMSIG_KB_YAUTJA_MASK_TOGGLE_ZOOM /datum/keybinding/yautja/mask/togglesight hotkey_keys = list("Unbound") classic_keys = list("Unbound") name = "togglesight" full_name = "Toggle mask visors" - keybind_signal = COMSIG_KB_YAUTJA_LINK_BRACER - -/datum/keybinding/yautja/mask/togglesight/down(client/user) - . = ..() - if(.) - return - var/mob/living/carbon/human/H = user.mob - var/obj/item/clothing/mask/gas/yautja/mask = H.wear_mask - mask.togglesight() - return TRUE + keybind_signal = COMSIG_KB_YAUTJA_MASK_TOGGLESIGHT // teleporter diff --git a/code/datums/langchat/langchat.dm b/code/datums/langchat/langchat.dm index 83b9be0ac053..b82b03b51774 100644 --- a/code/datums/langchat/langchat.dm +++ b/code/datums/langchat/langchat.dm @@ -47,12 +47,12 @@ M.client.images -= langchat_image langchat_listeners = null -/atom/proc/langchat_set_x_offset() - langchat_image.maptext_x = world.icon_size / 2 - langchat_image.maptext_width / 2 -/atom/movable/langchat_set_x_offset() - langchat_image.maptext_x = bound_width / 2 - langchat_image.maptext_width / 2 -/mob/langchat_set_x_offset() - langchat_image.maptext_x = icon_size / 2 - langchat_image.maptext_width / 2 +/atom/proc/get_maxptext_x_offset(image/maptext_image) + return (world.icon_size / 2) - (maptext_image.maptext_width / 2) +/atom/movable/get_maxptext_x_offset(image/maptext_image) + return (bound_width / 2) - (maptext_image.maptext_width / 2) +/mob/get_maxptext_x_offset(image/maptext_image) + return (icon_size / 2) - (maptext_image.maptext_width / 2) ///Creates the image if one does not exist, resets settings that are modified by speech procs. /atom/proc/langchat_make_image(override_color = null) @@ -64,7 +64,7 @@ langchat_image.maptext_y = langchat_height langchat_image.maptext_height = 64 langchat_image.maptext_y -= LANGCHAT_MESSAGE_POP_Y_SINK - langchat_set_x_offset() + langchat_image.maptext_x = get_maxptext_x_offset(langchat_image) langchat_image.pixel_y = 0 langchat_image.alpha = 0 @@ -109,7 +109,7 @@ langchat_image.maptext = text_to_display langchat_image.maptext_width = LANGCHAT_WIDTH - langchat_set_x_offset() + langchat_image.maptext_x = get_maxptext_x_offset(langchat_image) langchat_listeners = listeners for(var/mob/M in langchat_listeners) @@ -156,7 +156,7 @@ langchat_image.maptext = text_to_display langchat_image.maptext_width = LANGCHAT_WIDTH * 2 - langchat_set_x_offset() + langchat_image.maptext_x = get_maxptext_x_offset(langchat_image) langchat_listeners = listeners for(var/mob/M in langchat_listeners) diff --git a/code/datums/medal_awards.dm b/code/datums/medal_awards.dm index ba8847c03661..a3041c622bd6 100644 --- a/code/datums/medal_awards.dm +++ b/code/datums/medal_awards.dm @@ -11,6 +11,7 @@ GLOBAL_LIST_EMPTY(medal_awards) GLOBAL_LIST_EMPTY(jelly_awards) +GLOBAL_LIST_EMPTY(medal_recommendations) /datum/recipient_awards var/list/medal_names @@ -160,7 +161,99 @@ GLOBAL_LIST_INIT(human_medals, list(MARINE_CONDUCT_MEDAL, MARINE_BRONZE_HEART_ME return TRUE -/proc/print_medal(mob/living/carbon/human/user, obj/printer) +/proc/give_medal_award_prefilled(medal_location, mob/giving_mob, chosen_recipient, recipient_rank, recipient_ckey, reason, _medal_type) + var/list/recipient_ranks = list() + for(var/datum/data/record/record in GLOB.data_core.general) + var/recipient_name = record.fields["name"] + recipient_ranks[recipient_name] = record.fields["rank"] + + if(!chosen_recipient) + return FALSE + + // Pick a medal + var/medal_type = _medal_type + if(!medal_type) + return FALSE + + // Write a citation + var/citation = strip_html(reason) + if(!citation) + return FALSE + + // Get mob information + var/posthumous = TRUE + var/mob/recipient_mob + var/found_other = FALSE + + for(var/mob/mob in GLOB.mob_list) + if(mob.real_name == chosen_recipient) + // Recipient: Check if they are dead, and get some info + // We might not get this info if gibbed, so we'd need to refactor again and find another way if we want stats always correct + if(isliving(mob) && mob.stat != DEAD) + posthumous = FALSE + recipient_mob = mob + if(found_other) + break + found_other = TRUE + if(!recipient_mob) + for(var/mob/mob in GLOB.dead_mob_list) + if(mob.real_name == chosen_recipient) + // Recipient: Check if they are dead?, and get some info + // We might not get this info if gibbed, so we'd need to refactor again and find another way if we want stats always correct + if(isliving(mob) && mob.stat != DEAD) + posthumous = FALSE + recipient_mob = mob + break + + // Create the recipient_award + if(!GLOB.medal_awards[chosen_recipient]) + GLOB.medal_awards[chosen_recipient] = new /datum/recipient_awards() + var/datum/recipient_awards/recipient_award = GLOB.medal_awards[chosen_recipient] + recipient_award.recipient_rank = recipient_rank + recipient_award.recipient_ckey = recipient_ckey + recipient_award.recipient_mob = recipient_mob + recipient_award.giver_mob += giving_mob + recipient_award.medal_names += medal_type + recipient_award.medal_citations += citation + recipient_award.posthumous += posthumous + recipient_award.giver_ckey += giving_mob.ckey + + recipient_award.giver_rank += recipient_ranks[giving_mob.real_name] // Currently not used in marine award message + recipient_award.giver_name += giving_mob.real_name // Currently not used in marine award message + + // Create an actual medal item + if(medal_location) + var/obj/item/clothing/accessory/medal/medal + switch(medal_type) + if(MARINE_CONDUCT_MEDAL) + medal = new /obj/item/clothing/accessory/medal/bronze/conduct(medal_location) + if(MARINE_BRONZE_HEART_MEDAL) + medal = new /obj/item/clothing/accessory/medal/bronze/heart(medal_location) + if(MARINE_VALOR_MEDAL) + medal = new /obj/item/clothing/accessory/medal/silver/valor(medal_location) + if(MARINE_HEROISM_MEDAL) + medal = new /obj/item/clothing/accessory/medal/gold/heroism(medal_location) + else + return FALSE + medal.recipient_name = chosen_recipient + medal.medal_citation = citation + medal.recipient_rank = recipient_rank + recipient_award.medal_items += medal + else + recipient_award.medal_items += null + + // Recipient: Add the medal to the player's stats + if(recipient_ckey) + var/datum/entity/player_entity/recipient_player = setup_player_entity(recipient_ckey) + if(recipient_player) + recipient_player.track_medal_earned(medal_type, recipient_mob, recipient_rank, citation, giving_mob) + + // Inform staff of success + message_admins("[key_name_admin(giving_mob)] awarded a [medal_type] to [chosen_recipient] for: \'[citation]\'.") + + return TRUE + +/proc/open_medal_panel(mob/living/carbon/human/user, obj/printer) var/obj/item/card/id/card = user.wear_id if(!card) to_chat(user, SPAN_WARNING("You must have an authenticated ID Card to award medals.")) @@ -178,8 +271,9 @@ GLOBAL_LIST_INIT(human_medals, list(MARINE_CONDUCT_MEDAL, MARINE_BRONZE_HEART_ME user.visible_message("ERROR: ID card not registered for [user.real_name] in USCM registry. Potential medal fraud detected.") return - if(give_medal_award(get_turf(printer))) - user.visible_message(SPAN_NOTICE("[printer] prints a medal.")) + GLOB.ic_medals_panel.user_locs[WEAKREF(user)] = WEAKREF(printer) + GLOB.ic_medals_panel.tgui_interact(user) + GLOBAL_LIST_INIT(xeno_medals, list(XENO_SLAUGHTER_MEDAL, XENO_RESILIENCE_MEDAL, XENO_SABOTAGE_MEDAL, XENO_PROLIFERATION_MEDAL, XENO_REJUVENATION_MEDAL)) @@ -364,3 +458,200 @@ GLOBAL_LIST_INIT(xeno_medals, list(XENO_SLAUGHTER_MEDAL, XENO_RESILIENCE_MEDAL, message_admins("[key_name_admin(usr)] deleted [recipient_name]'s [medal_type] for: \'[citation]\'.") return TRUE + +/datum/medal_recommendation + var/recipient_rank + var/recipient_ckey + var/recipient_name + var/recommended_by_name + var/recommended_by_ckey + var/reason + var/recommended_by_rank + + +/proc/add_medal_recommendation(mob/recommendation_giver) + // Pick a marine + var/list/possible_recipients = list() + var/list/recipient_ranks = list() + for(var/datum/data/record/record in GLOB.data_core.general) + var/recipient_name = record.fields["name"] + if(recipient_name == recommendation_giver.real_name) + continue + recipient_ranks[recipient_name] = record.fields["rank"] + possible_recipients += recipient_name + var/chosen_recipient = tgui_input_list(recommendation_giver, "Who do you want to recommend a medal for?", "Medal Recommendation", possible_recipients) + if(!chosen_recipient) + return FALSE + + // Write a citation + var/reason = strip_html(tgui_input_text(recommendation_giver, "Why does this person deserve a medal?", "Medal Recommendation", null, MAX_PAPER_MESSAGE_LEN, TRUE), MAX_PAPER_MESSAGE_LEN) + if(!reason) + return FALSE + + // Get mob information + var/recipient_rank = recipient_ranks[chosen_recipient] + var/recipient_ckey + var/mob/recipient_mob + var/found_other = FALSE + + for(var/mob/mob in GLOB.mob_list) + if(mob.real_name == chosen_recipient) + // We might not get this info if gibbed, so we'd need to refactor again and find another way if we want stats always correct + recipient_ckey = mob.persistent_ckey + recipient_mob = mob + if(found_other) + break + found_other = TRUE + if(!recipient_mob) + for(var/mob/mob in GLOB.dead_mob_list) + if(mob.real_name == chosen_recipient) + // Recipient: Check if they are dead?, and get some info + // We might not get this info if gibbed, so we'd need to refactor again and find another way if we want stats always correct + recipient_ckey = mob.persistent_ckey + recipient_mob = mob + break + + // Create the recipient_award + var/datum/medal_recommendation/recommendation = new /datum/medal_recommendation() + GLOB.medal_recommendations += recommendation + + recommendation.recipient_rank = recipient_rank + recommendation.recipient_ckey = recipient_ckey + recommendation.recipient_name = recipient_mob.real_name + recommendation.recommended_by_name = recommendation_giver.real_name + recommendation.recommended_by_ckey = recommendation_giver.ckey + recommendation.recommended_by_rank = recipient_ranks[recommendation_giver.real_name] + + + recommendation.reason = reason + + return TRUE + + +GLOBAL_DATUM_INIT(ic_medals_panel, /datum/ic_medal_panel, new) + +/datum/ic_medal_panel + var/name = "Medals Panel" + var/list/datum/weakref/user_locs = list() + +/datum/ic_medal_panel/tgui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "IcMedalsPanel", "Medals Panel") + ui.open() + ui.set_autoupdate(FALSE) + +/datum/ic_medal_panel/ui_state(mob/user) + var/datum/weakref/user_reference = WEAKREF(user) + var/datum/weakref/loc_reference = user_locs[user_reference] + if(istype(loc_reference?.resolve(), /obj/item)) + return GLOB.not_incapacitated_and_inventory_state + else + return GLOB.not_incapacitated_and_adjacent_state + +/datum/ic_medal_panel/ui_host(mob/user) + . = ..() + var/datum/weakref/user_reference = WEAKREF(user) + var/datum/weakref/loc_reference = user_locs[user_reference] + . = loc_reference?.resolve() + +/datum/ic_medal_panel/ui_data(mob/user) + var/list/data = list() + data["recommendations"] = list() + + for(var/datum/medal_recommendation/recommendation in GLOB.medal_recommendations) + var/recommendation_list = list() + + recommendation_list["rank"] = recommendation.recipient_rank + recommendation_list["name"] = recommendation.recipient_name + recommendation_list["ref"] = REF(recommendation) + recommendation_list["recommender_name"] = recommendation.recommended_by_name + recommendation_list["reason"] = recommendation.reason + recommendation_list["recommender_rank"] = recommendation.recommended_by_rank + + data["recommendations"] += list(recommendation_list) + return data + +/datum/ic_medal_panel/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + var/mob/living/carbon/human/user = usr + var/obj/item/card/id/card = user.wear_id + if(!card) + to_chat(user, SPAN_WARNING("You must have an authenticated ID Card to award medals.")) + return + + if(!((card.paygrade in GLOB.co_paygrades) || (card.paygrade in GLOB.highcom_paygrades))) + to_chat(user, SPAN_WARNING("Only a Senior Officer can award medals!")) + return + + if(!card.registered_ref) + user.visible_message("ERROR: ID card not registered in USCM registry. Potential medal fraud detected.") + return + + var/real_owner_ref = card.registered_ref + + if(real_owner_ref != WEAKREF(user)) + user.visible_message("ERROR: ID card not registered for [user.real_name] in USCM registry. Potential medal fraud detected.") + return + + var/datum/weakref/user_ref = WEAKREF(user) + var/datum/weakref/loc_ref = user_locs[user_ref] + var/atom/actual_loc = loc_ref?.resolve() + if(!actual_loc) + return + + switch(action) + if("grant_new_medal") + if(give_medal_award(get_turf(actual_loc))) + actual_loc.visible_message(SPAN_NOTICE("[actual_loc] prints a medal.")) + . = TRUE + + if("approve_medal") + var/recommendation_ref = params["ref"] + var/medal_type = params["medal_type"] + if(!(medal_type in GLOB.human_medals)) + return + var/datum/medal_recommendation/recommendation = locate(recommendation_ref) in GLOB.medal_recommendations + if(!recommendation) + return + if(recommendation.recipient_name == user.real_name) + to_chat(user, SPAN_WARNING("You cannot give medals to yourself!")) + return + + var/choice = tgui_alert(user, "Would you like to change the medal text?", "Medal Citation", list("Yes", "No")) + var/medal_citation = recommendation.reason + if(choice == "Yes") + medal_citation = strip_html(tgui_input_text(user, "What should the medal citation read?", "Medal Citation", null, MAX_PAPER_MESSAGE_LEN, TRUE), MAX_PAPER_MESSAGE_LEN) + + var/confirm_choice = tgui_alert(user, "Are you sure you want to give a medal to [recommendation.recipient_name]?", "Medal Confirmation", list("Yes", "No")) + if(confirm_choice != "Yes") + return + + if(give_medal_award_prefilled(get_turf(actual_loc), user, recommendation.recipient_name, recommendation.recipient_rank, recommendation.recipient_ckey, medal_citation, medal_type, recommendation.recommended_by_ckey, recommendation.recommended_by_name)) + GLOB.medal_recommendations -= recommendation + qdel(recommendation) + user.visible_message(SPAN_NOTICE("[actual_loc] prints a medal.")) + . = TRUE + + if("deny_medal") + var/recommendation_ref = params["ref"] + var/datum/medal_recommendation/recommendation = locate(recommendation_ref) in GLOB.medal_recommendations + if(!recommendation) + return + var/confirm = tgui_alert(user, "Are you sure you want to deny this medal recommendation?", "Medal Confirmation", list("Yes", "No")) + if(confirm != "Yes") + return + GLOB.medal_recommendations -= recommendation + qdel(recommendation) + . = TRUE + +/datum/ic_medal_panel/ui_close(mob/user) + . = ..() + user_locs -= WEAKREF(user) + +/datum/ic_medal_panel/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/spritesheet/medal) + ) diff --git a/code/datums/stamina/_stamina.dm b/code/datums/stamina/_stamina.dm index e233aaa81676..80e7df74e86b 100644 --- a/code/datums/stamina/_stamina.dm +++ b/code/datums/stamina/_stamina.dm @@ -34,7 +34,7 @@ if(!has_stamina) return - current_stamina = Clamp(current_stamina - amount, 0, max_stamina) + current_stamina = clamp(current_stamina - amount, 0, max_stamina) if(current_stamina < max_stamina) START_PROCESSING(SSobj, src) diff --git a/code/datums/status_effects/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm index a36b7b91e4c6..0ecfead05615 100644 --- a/code/datums/status_effects/debuffs/debuffs.dm +++ b/code/datums/status_effects/debuffs/debuffs.dm @@ -102,3 +102,19 @@ name = "Unconscious" desc = "You've been knocked out." icon_state = ALERT_KNOCKEDOUT + +/// DAZED: +/// This prevents talking as human or using abilities as Xenos, mainly +/datum/status_effect/incapacitating/dazed + id = "dazed" + needs_update_stat = TRUE + +/datum/status_effect/incapacitating/dazed/on_apply() + . = ..() + if(!.) + return + ADD_TRAIT(owner, TRAIT_DAZED, TRAIT_STATUS_EFFECT(id)) + +/datum/status_effect/incapacitating/dazed/on_remove() + REMOVE_TRAIT(owner, TRAIT_DAZED, TRAIT_STATUS_EFFECT(id)) + return ..() diff --git a/code/datums/tutorial/marine/basic_marine.dm b/code/datums/tutorial/marine/basic_marine.dm index be49977f7a48..af9d2eaf18dd 100644 --- a/code/datums/tutorial/marine/basic_marine.dm +++ b/code/datums/tutorial/marine/basic_marine.dm @@ -143,7 +143,7 @@ update_objective("Shoot at the Xenomorph until it dies.") var/mob/living/carbon/xenomorph/drone/tutorial/xeno_dummy = new(loc_from_corner(4, 5)) add_to_tracking_atoms(xeno_dummy) - add_highlight(xeno_dummy, COLOUR_VIVID_RED) + add_highlight(xeno_dummy, COLOR_VIVID_RED) RegisterSignal(xeno_dummy, COMSIG_MOB_DEATH, PROC_REF(on_xeno_death)) RegisterSignal(tutorial_mob, COMSIG_MOB_GUN_EMPTY, PROC_REF(on_magazine_empty)) // I'd like to prevent unwilling softlocks as much as I can diff --git a/code/defines/procs/announcement.dm b/code/defines/procs/announcement.dm index 3dd918abbc6b..3eae6076f610 100644 --- a/code/defines/procs/announcement.dm +++ b/code/defines/procs/announcement.dm @@ -145,7 +145,7 @@ for(var/mob/T in targets) if(isobserver(T)) continue - if(!ishuman(T) || isyautja(T) || !is_mainship_level(T.z)) + if(!ishuman(T) || isyautja(T) || !is_mainship_level((get_turf(T))?.z)) targets.Remove(T) log_ares_announcement("[title] Shipwide Update", message) diff --git a/code/game/camera_manager/camera_manager.dm b/code/game/camera_manager/camera_manager.dm index 93d56aca443c..450c7c8beb64 100644 --- a/code/game/camera_manager/camera_manager.dm +++ b/code/game/camera_manager/camera_manager.dm @@ -25,13 +25,16 @@ . = ..() map_name = "camera_manager_[REF(src)]_map" cam_screen = new + cam_screen.icon = null cam_screen.name = "screen" cam_screen.assigned_map = map_name cam_screen.del_on_map_removal = FALSE cam_screen.screen_loc = "[map_name]:1,1" + cam_screen.appearance_flags |= TILE_BOUND cam_background = new cam_background.assigned_map = map_name cam_background.del_on_map_removal = FALSE + cam_background.appearance_flags |= TILE_BOUND cam_plane_masters = list() for(var/plane in subtypesof(/atom/movable/screen/plane_master) - /atom/movable/screen/plane_master/blackness) @@ -42,14 +45,17 @@ . = ..() range_turfs = null current_area = null - cam_plane_masters = null + QDEL_LIST_ASSOC_VAL(cam_plane_masters) QDEL_NULL(cam_background) QDEL_NULL(cam_screen) if(current) UnregisterSignal(current, COMSIG_PARENT_QDELETING) + current = null + last_camera_turf = null /datum/component/camera_manager/proc/add_plane(atom/movable/screen/plane_master/instance) instance.assigned_map = map_name + instance.appearance_flags |= TILE_BOUND instance.del_on_map_removal = FALSE if(instance.blend_mode_override) instance.blend_mode = instance.blend_mode_override @@ -61,8 +67,8 @@ var/client/user_client = user.client if(!user_client) return - user_client.register_map_obj(cam_background) user_client.register_map_obj(cam_screen) + user_client.register_map_obj(cam_background) for(var/plane_id in cam_plane_masters) user_client.register_map_obj(cam_plane_masters[plane_id]) @@ -71,14 +77,10 @@ var/client/user_client = user.client if(!user_client) return - user_client.clear_map(cam_background) - user_client.clear_map(cam_screen) - for(var/plane_id in cam_plane_masters) - user_client.clear_map(cam_plane_masters[plane_id]) + user_client.clear_map(map_name) /datum/component/camera_manager/RegisterWithParent() . = ..() - START_PROCESSING(SSdcs, src) SEND_SIGNAL(parent, COMSIG_CAMERA_MAPNAME_ASSIGNED, map_name) RegisterSignal(parent, COMSIG_CAMERA_REGISTER_UI, PROC_REF(register)) RegisterSignal(parent, COMSIG_CAMERA_UNREGISTER_UI, PROC_REF(unregister)) @@ -90,8 +92,6 @@ /datum/component/camera_manager/UnregisterFromParent() . = ..() - STOP_PROCESSING(SSdcs, src) - UnregisterSignal(parent, COMSIG_CAMERA_REGISTER_UI) UnregisterSignal(parent, COMSIG_CAMERA_UNREGISTER_UI) UnregisterSignal(parent, COMSIG_CAMERA_SET_NVG) @@ -134,6 +134,8 @@ target_x = x target_y = y target_z = z + target_width = w + target_height = h update_area_camera() /datum/component/camera_manager/proc/enable_nvg(source, power, matrixcol) @@ -152,10 +154,10 @@ /datum/component/camera_manager/proc/sync_lighting_plane_alpha(lighting_alpha) var/atom/movable/screen/plane_master/lighting/lighting = cam_plane_masters["[LIGHTING_PLANE]"] - if (lighting) + if(lighting) lighting.alpha = lighting_alpha var/atom/movable/screen/plane_master/lighting/exterior_lighting = cam_plane_masters["[EXTERIOR_LIGHTING_PLANE]"] - if (exterior_lighting) + if(exterior_lighting) exterior_lighting.alpha = min(GLOB.minimum_exterior_lighting_alpha, lighting_alpha) /** @@ -215,7 +217,7 @@ var/turf/target = locate(current_area.center_x, current_area.center_y, target_z) var/list/visible_things = isXRay ? range("[x_size]x[y_size]", target) : view("[x_size]x[y_size]", target) - src.render_objects(visible_things) + render_objects(visible_things) /datum/component/camera_manager/proc/render_objects(list/visible_things) var/list/visible_turfs = list() diff --git a/code/game/cas_manager/datums/cas_fire_envelope.dm b/code/game/cas_manager/datums/cas_fire_envelope.dm index 04cd688194dd..d9355cd005a9 100644 --- a/code/game/cas_manager/datums/cas_fire_envelope.dm +++ b/code/game/cas_manager/datums/cas_fire_envelope.dm @@ -19,7 +19,7 @@ var/datum/cas_signal/recorded_loc = null var/obj/effect/firemission_guidance/guidance - + var/atom/tracked_object /datum/cas_fire_envelope/New() ..() @@ -27,6 +27,7 @@ /datum/cas_fire_envelope/Destroy(force, ...) linked_console = null + untrack_object() return ..() /datum/cas_fire_envelope/ui_data(mob/user) @@ -151,7 +152,9 @@ recorded_loc = marker return TRUE -/datum/cas_fire_envelope/proc/change_current_loc(location) +/datum/cas_fire_envelope/proc/change_current_loc(location, atom/object) + if(object) + untrack_object() if(!location && guidance) for(var/mob/M in guidance.users) if(istype(M) && M.client) @@ -162,6 +165,21 @@ guidance = new /obj/effect/firemission_guidance() guidance.forceMove(location) guidance.updateCameras(linked_console) + if(object) + tracked_object = object + RegisterSignal(tracked_object, COMSIG_PARENT_QDELETING, PROC_REF(on_tracked_object_del)) + +/// Call to unregister the on_tracked_object_del behavior +/datum/cas_fire_envelope/proc/untrack_object() + if(tracked_object) + UnregisterSignal(tracked_object, COMSIG_PARENT_QDELETING) + tracked_object = null + +/// Signal handler for when we are viewing a object in cam is qdel'd (but camera actually is actually some other obj) +/datum/cas_fire_envelope/proc/on_tracked_object_del(atom/target) + SIGNAL_HANDLER + tracked_object = null + change_current_loc() /datum/cas_fire_envelope/proc/user_is_guided(user) return guidance && (user in guidance.users) diff --git a/code/game/jobs/job/civilians/other/survivors.dm b/code/game/jobs/job/civilians/other/survivors.dm index 23097e139eda..a85731aa781a 100644 --- a/code/game/jobs/job/civilians/other/survivors.dm +++ b/code/game/jobs/job/civilians/other/survivors.dm @@ -14,7 +14,7 @@ var/hostile = FALSE /datum/job/civilian/survivor/set_spawn_positions(count) - spawn_positions = Clamp((round(count * SURVIVOR_TO_TOTAL_SPAWN_RATIO)), 2, 8) + spawn_positions = clamp((round(count * SURVIVOR_TO_TOTAL_SPAWN_RATIO)), 2, 8) total_positions = spawn_positions /datum/job/civilian/survivor/equip_job(mob/living/survivor) diff --git a/code/game/jobs/role_authority.dm b/code/game/jobs/role_authority.dm index 37131451ca07..be2b75e0e7f6 100644 --- a/code/game/jobs/role_authority.dm +++ b/code/game/jobs/role_authority.dm @@ -268,6 +268,7 @@ I hope it's easier to tell what the heck this proc is even doing, unlike previou var/datum/job/PJ = temp_roles_for_mode[JOB_PREDATOR] if(istype(PJ)) PJ.set_spawn_positions(GLOB.players_preassigned) + REDIS_PUBLISH("byond.round", "type" = "predator-round", "map" = SSmapping.configs[GROUND_MAP].map_name) // Assign the roles, this time for real, respecting limits we have established. var/list/roles_left = assign_roles(temp_roles_for_mode, unassigned_players) diff --git a/code/game/jobs/slot_scaling.dm b/code/game/jobs/slot_scaling.dm index 2d444d06e5ab..8bd4af908c07 100644 --- a/code/game/jobs/slot_scaling.dm +++ b/code/game/jobs/slot_scaling.dm @@ -10,7 +10,7 @@ /proc/job_slot_formula(marine_count, factor, c, min, max) if(marine_count <= factor) return min - return round(Clamp((marine_count/factor)+c, min, max)) + return round(clamp((marine_count/factor)+c, min, max)) /proc/medic_slot_formula(playercount) return job_slot_formula(playercount,40,1,3,5) diff --git a/code/game/machinery/computer/almayer_control.dm b/code/game/machinery/computer/almayer_control.dm index e9b969e023b8..d38ccd725785 100644 --- a/code/game/machinery/computer/almayer_control.dm +++ b/code/game/machinery/computer/almayer_control.dm @@ -110,7 +110,7 @@ return switch(action) if("award") - print_medal(usr, src) + open_medal_panel(usr, src) . = TRUE // evac stuff start \\ diff --git a/code/game/machinery/computer/camera_console.dm b/code/game/machinery/computer/camera_console.dm index 0975320274c8..120a1f9ccc2e 100644 --- a/code/game/machinery/computer/camera_console.dm +++ b/code/game/machinery/computer/camera_console.dm @@ -58,9 +58,8 @@ SStgui.close_uis(src) QDEL_NULL(current) QDEL_NULL(cam_screen) - qdel(cam_screen) QDEL_NULL(cam_background) - qdel(cam_background) + QDEL_NULL_LIST(cam_plane_masters) last_camera_turf = null concurrent_users = null return ..() diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index bcc4c4ac3ec8..77c9bbacc293 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -130,7 +130,7 @@ cooldown_message = world.time if("award") - print_medal(usr, src) + open_medal_panel(usr, src) if("evacuation_start") if(state == STATE_EVACUATION) diff --git a/code/game/machinery/computer/dropship_weapons.dm b/code/game/machinery/computer/dropship_weapons.dm index db376c40029c..dce026f4ce33 100644 --- a/code/game/machinery/computer/dropship_weapons.dm +++ b/code/game/machinery/computer/dropship_weapons.dm @@ -33,6 +33,8 @@ var/camera_width = 11 var/camera_height = 11 var/camera_map_name + ///Tracks equipment with a camera that is deployed and we are viewing + var/obj/structure/dropship_equipment/camera_area_equipment = null var/registered = FALSE @@ -62,17 +64,20 @@ /obj/structure/machinery/computer/dropship_weapons/attack_hand(mob/user) if(..()) return - if(!allowed(user)) + if(!allowed(user)) + // TODO: Restore cas simulator + to_chat(user, SPAN_WARNING("Weapons modification access denied.")) + return TRUE // everyone can access the simulator, requested feature. - to_chat(user, SPAN_WARNING("Weapons modification access denied, attempting to launch simulation.")) + /*to_chat(user, SPAN_WARNING("Weapons modification access denied, attempting to launch simulation.")) if(!selected_firemission) to_chat(user, SPAN_WARNING("Firemission must be selected before attempting to run the simulation")) - return + return TRUE tgui_interact(user) - return 1 + return FALSE*/ user.set_interaction(src) ui_interact(user) @@ -100,7 +105,7 @@ /obj/structure/machinery/computer/dropship_weapons/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0) var/obj/docking_port/mobile/marine_dropship/dropship = SSshuttle.getShuttle(shuttle_tag) - if (!istype(dropship)) + if(!istype(dropship)) return var/screen_mode = 0 @@ -129,11 +134,6 @@ if(screen_mode != 3 || !selected_firemission || dropship.mode != SHUTTLE_CALL) update_location(user, null) - ui_data(user) - if(!tacmap.map_holder) - var/level = SSmapping.levels_by_trait(tacmap.targeted_ztrait) - tacmap.map_holder = SSminimaps.fetch_tacmap_datum(level[1], tacmap.allowed_flags) - user.client.register_map_obj(tacmap.map_holder.map) tgui_interact(user) /obj/structure/machinery/computer/dropship_weapons/tgui_interact(mob/user, datum/tgui/ui) @@ -141,10 +141,15 @@ var/obj/docking_port/mobile/marine_dropship/dropship = SSshuttle.getShuttle(shuttle_tag) RegisterSignal(dropship, COMSIG_DROPSHIP_ADD_EQUIPMENT, PROC_REF(equipment_update)) RegisterSignal(dropship, COMSIG_DROPSHIP_REMOVE_EQUIPMENT, PROC_REF(equipment_update)) - registered=TRUE + registered = TRUE + + if(!tacmap.map_holder) + var/level = SSmapping.levels_by_trait(tacmap.targeted_ztrait) + tacmap.map_holder = SSminimaps.fetch_tacmap_datum(level[1], tacmap.allowed_flags) ui = SStgui.try_update_ui(user, src, ui) - if (!ui) + if(!ui) + user.client.register_map_obj(tacmap.map_holder.map) SEND_SIGNAL(src, COMSIG_CAMERA_REGISTER_UI, user) ui = new(user, src, "DropshipWeaponsConsole", "Weapons Console") ui.open() @@ -255,7 +260,7 @@ switch(action) if("button_push") playsound(src, get_sfx("terminal_button"), 25, FALSE) - return TRUE + return FALSE if("select_equipment") var/base_tag = params["equipment_id"] @@ -303,12 +308,13 @@ var/mount_point = equipment.ship_base.attach_id if(mount_point != equipment_tag) continue - if (istype(equipment, /obj/structure/dropship_equipment/sentry_holder)) + if(istype(equipment, /obj/structure/dropship_equipment/sentry_holder)) var/obj/structure/dropship_equipment/sentry_holder/sentry = equipment var/obj/structure/machinery/defenses/sentry/defense = sentry.deployed_turret - if (defense.has_camera) + if(defense.has_camera) defense.set_range() var/datum/shape/rectangle/current_bb = defense.range_bounds + camera_area_equipment = sentry SEND_SIGNAL(src, COMSIG_CAMERA_SET_AREA, current_bb.center_x, current_bb.center_y, defense.loc.z, current_bb.width, current_bb.height) return TRUE @@ -329,6 +335,7 @@ if(medevac.linked_stretcher) SEND_SIGNAL(src, COMSIG_CAMERA_SET_TARGET, medevac.linked_stretcher, 5, 5) return TRUE + if("fulton-target") var/equipment_tag = params["equipment_id"] for(var/obj/structure/dropship_equipment/equipment as anything in shuttle.equipments) @@ -340,6 +347,7 @@ var/target_ref = params["ref"] fulton.automate_interact(user, target_ref) return TRUE + if("fire-weapon") var/weapon_tag = params["eqp_tag"] var/obj/structure/dropship_equipment/weapon/DEW = get_weapon(weapon_tag) @@ -347,19 +355,23 @@ return FALSE var/datum/cas_signal/sig = get_cas_signal(camera_target_id) - if(!sig) return FALSE selected_equipment = DEW - ui_open_fire(user, shuttle, camera_target_id) + if(ui_open_fire(user, shuttle, camera_target_id)) + if(firemission_envelope) + firemission_envelope.untrack_object() return TRUE + if("deploy-equipment") var/equipment_tag = params["equipment_id"] for(var/obj/structure/dropship_equipment/equipment as anything in shuttle.equipments) var/mount_point = equipment.ship_base.attach_id if(mount_point != equipment_tag) continue + if(camera_area_equipment == equipment) + set_camera_target(null) equipment.equipment_interact(user) return TRUE @@ -384,13 +396,8 @@ var/x_offset_value = params["x_offset_value"] var/y_offset_value = params["y_offset_value"] - var/datum/cas_iff_group/cas_group = GLOB.cas_groups[faction] - var/datum/cas_signal/cas_sig - for(var/X in cas_group.cas_signals) - var/datum/cas_signal/LT = X - if(LT.target_id == target_id && LT.valid_signal()) - cas_sig = LT - break + camera_target_id = target_id + var/datum/cas_signal/cas_sig = get_cas_signal(camera_target_id, valid_only = TRUE) // we don't want rapid offset changes to trigger admin warnings // and block the user from accessing TGUI // we change the minute_count @@ -408,12 +415,14 @@ current.y + dy, current.z) - firemission_envelope.change_current_loc(new_target) - + camera_area_equipment = null + firemission_envelope.change_current_loc(new_target, cas_sig) return TRUE + if("nvg-enable") SEND_SIGNAL(src, COMSIG_CAMERA_SET_NVG, 5, "#7aff7a") return TRUE + if("nvg-disable") SEND_SIGNAL(src, COMSIG_CAMERA_CLEAR_NVG) return TRUE @@ -447,24 +456,28 @@ /obj/structure/machinery/computer/dropship_weapons/proc/get_weapon(eqp_tag) var/obj/docking_port/mobile/marine_dropship/dropship = SSshuttle.getShuttle(shuttle_tag) - for(var/obj/structure/dropship_equipment/equipment in dropship.equipments) - if(istype(equipment, /obj/structure/dropship_equipment/weapon)) - //is weapon - if(selected_equipment == equipment) - return equipment + var/obj/structure/dropship_equipment/equipment = dropship.equipments[eqp_tag] + if(istype(equipment, /obj/structure/dropship_equipment/weapon)) + //is weapon + return equipment return -/obj/structure/machinery/computer/dropship_weapons/proc/get_cas_signal(target_ref) +/obj/structure/machinery/computer/dropship_weapons/proc/get_cas_signal(target_ref, valid_only = FALSE) if(!target_ref) return var/datum/cas_iff_group/cas_group = GLOB.cas_groups[faction] for(var/datum/cas_signal/sig in cas_group.cas_signals) if(sig.target_id == target_ref) + if(valid_only && !sig.valid_signal()) + continue return sig - /obj/structure/machinery/computer/dropship_weapons/proc/set_camera_target(target_ref) + camera_area_equipment = null + if(firemission_envelope) + firemission_envelope.untrack_object() + var/datum/cas_signal/target = get_cas_signal(target_ref) camera_target_id = target_ref if(!target) diff --git a/code/game/machinery/computer/groundside_operations.dm b/code/game/machinery/computer/groundside_operations.dm index 7b4c2d5df771..b5d1c112a3f8 100644 --- a/code/game/machinery/computer/groundside_operations.dm +++ b/code/game/machinery/computer/groundside_operations.dm @@ -235,7 +235,7 @@ log_announcement("[key_name(usr)] has announced the following: [input]") if("award") - print_medal(usr, src) + open_medal_panel(usr, src) if("selectlz") if(SSticker.mode.active_lz) diff --git a/code/game/machinery/computer/research.dm b/code/game/machinery/computer/research.dm index 1ba696eeee9c..d5158cb76451 100644 --- a/code/game/machinery/computer/research.dm +++ b/code/game/machinery/computer/research.dm @@ -179,7 +179,7 @@ if("purchase_document") if(!photocopier) return - var/purchase_tier = FLOOR(text2num(params["purchase_document"]), 1) + var/purchase_tier = Floor(text2num(params["purchase_document"])) if(purchase_tier <= 0 || purchase_tier > 5) return if(purchase_tier > GLOB.chemical_data.clearance_level) diff --git a/code/game/machinery/floodlight.dm b/code/game/machinery/floodlight.dm index 580fea644eec..b90f8adbbb3f 100644 --- a/code/game/machinery/floodlight.dm +++ b/code/game/machinery/floodlight.dm @@ -2,7 +2,7 @@ name = "emergency floodlight" desc = "A powerful light usually stationed near landing zones to provide better visibility." icon = 'icons/obj/structures/machinery/floodlight.dmi' - icon_state = "flood00" + icon_state = "flood_0" density = TRUE anchored = TRUE light_power = 2 @@ -11,13 +11,14 @@ idle_power_usage = 0 active_power_usage = 100 + ///How far the light will go when the floodlight is on var/on_light_range = 6 - ///Whether or not the floodlight can be toggled on or off var/toggleable = TRUE - ///Whether or not the floodlight is turned on, disconnected from whether it has power or is lit var/turned_on = FALSE + ///base state + var/base_icon_state = "flood" /obj/structure/machinery/floodlight/Initialize(mapload, ...) . = ..() @@ -60,7 +61,7 @@ /obj/structure/machinery/floodlight/update_icon() . = ..() - icon_state = "flood0[light_on]" + icon_state = "[base_icon_state]_[light_on]" /obj/structure/machinery/floodlight/power_change(area/master_area = null) . = ..() @@ -71,7 +72,7 @@ /obj/structure/machinery/floodlight/landing name = "landing light" desc = "A powerful light usually stationed near landing zones to provide better visibility. This one seems to have been bolted down and is unable to be moved." - icon_state = "flood01" + icon_state = "flood_1" use_power = USE_POWER_NONE needs_power = FALSE unslashable = TRUE @@ -81,5 +82,6 @@ turned_on = TRUE /obj/structure/machinery/floodlight/landing/floor - icon_state = "floor_flood01" + icon_state = "floor_flood_1" + base_icon_state = "floor_flood" density = FALSE diff --git a/code/game/machinery/telecomms/presets.dm b/code/game/machinery/telecomms/presets.dm index 89a7d591a691..c97a28932262 100644 --- a/code/game/machinery/telecomms/presets.dm +++ b/code/game/machinery/telecomms/presets.dm @@ -91,7 +91,7 @@ return // Leave the poor thing alone health -= damage - health = Clamp(health, 0, initial(health)) + health = clamp(health, 0, initial(health)) if(health <= 0) toggled = FALSE // requires flipping on again once repaired diff --git a/code/game/machinery/vending/vending_types.dm b/code/game/machinery/vending/vending_types.dm index 90947684bee1..0a7b85cae7e2 100644 --- a/code/game/machinery/vending/vending_types.dm +++ b/code/game/machinery/vending/vending_types.dm @@ -267,6 +267,7 @@ /obj/item/ammo_magazine/rifle/rubber = 40, /obj/item/ammo_magazine/rifle/m4ra/rubber = 40, /obj/item/clothing/head/helmet/marine/MP = 8, + /obj/item/explosive/plastic/breaching_charge/rubber = 6, ) /obj/structure/machinery/vending/sea diff --git a/code/game/machinery/vending/vendor_types/intelligence_officer.dm b/code/game/machinery/vending/vendor_types/intelligence_officer.dm index 4d9ced354e2b..6446d17e2db7 100644 --- a/code/game/machinery/vending/vendor_types/intelligence_officer.dm +++ b/code/game/machinery/vending/vendor_types/intelligence_officer.dm @@ -72,6 +72,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_intelligence_officer, list( list("BACKPACK (CHOOSE 1)", 0, null, null, null), list("Expedition Pack", 0, /obj/item/storage/backpack/marine/satchel/intel, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_RECOMMENDED), + list("Expedition Chestrig", 0, /obj/item/storage/backpack/marine/satchel/intel/chestrig, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_RECOMMENDED), list("Radio Telephone Pack", 0, /obj/item/storage/backpack/marine/satchel/rto/io, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_REGULAR), list("HELMET (CHOOSE 1)", 0, null, null, null), diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_prep.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_prep.dm index e021b6fe0879..296bce8a9d8d 100644 --- a/code/game/machinery/vending/vendor_types/squad_prep/squad_prep.dm +++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_prep.dm @@ -190,6 +190,11 @@ list("Falling Falcons Shoulder Patch", round(scale * 15), /obj/item/clothing/accessory/patch/falcon, VENDOR_ITEM_REGULAR), list("USCM Shoulder Patch", round(scale * 15), /obj/item/clothing/accessory/patch, VENDOR_ITEM_REGULAR), list("Bedroll", round(scale * 20), /obj/item/roller/bedroll, VENDOR_ITEM_REGULAR), + + list("OPTICS", -1, null, null, null), + list("Advanced Medical Optic (CORPSMAN ONLY)", round(scale * 4), /obj/item/device/helmet_visor/medical/advanced, VENDOR_ITEM_REGULAR), + list("Squad Optic", round(scale * 15), /obj/item/device/helmet_visor, VENDOR_ITEM_REGULAR), + ) //--------------SQUAD SPECIFIC VERSIONS-------------- diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_smartgunner.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_smartgunner.dm index 8a1b77103cad..04061370168d 100644 --- a/code/game/machinery/vending/vendor_types/squad_prep/squad_smartgunner.dm +++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_smartgunner.dm @@ -4,9 +4,6 @@ GLOBAL_LIST_INIT(cm_vending_gear_smartgun, list( list("SMARTGUN SET (MANDATORY)", 0, null, null, null), list("Essential Smartgunner Set", 0, /obj/item/storage/box/m56_system, MARINE_CAN_BUY_ESSENTIALS, VENDOR_ITEM_MANDATORY), - list("SMARTGUN AMMUNITION", 0, null, null, null), - list("M56 Smartgun Drum", 15, /obj/item/ammo_magazine/smartgun, null, VENDOR_ITEM_RECOMMENDED), - list("GUN ATTACHMENTS (CHOOSE 1)", 0, null, null, null), list("Laser Sight", 0, /obj/item/attachable/lasersight, MARINE_CAN_BUY_ATTACHMENT, VENDOR_ITEM_REGULAR), list("Red-Dot Sight", 0, /obj/item/attachable/reddot, MARINE_CAN_BUY_ATTACHMENT, VENDOR_ITEM_REGULAR), diff --git a/code/game/objects/effects/acid_hole.dm b/code/game/objects/effects/acid_hole.dm index a4db9ef5c0e0..db24c1c9c56a 100644 --- a/code/game/objects/effects/acid_hole.dm +++ b/code/game/objects/effects/acid_hole.dm @@ -40,7 +40,7 @@ /obj/effect/acid_hole/attack_alien(mob/living/carbon/xenomorph/user) - if (!holed_wall) + if(!holed_wall) qdel(src) //no wall?! then cease existence... return @@ -49,6 +49,9 @@ expand_hole(user) return XENO_NO_DELAY_ACTION +/obj/effect/acid_hole/attack_larva(mob/living/carbon/xenomorph/larva/M) + attack_alien(M) + /obj/effect/acid_hole/proc/expand_hole(mob/living/carbon/xenomorph/user) if(user.action_busy || user.is_mob_incapacitated()) return diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm index 41adfdd9581d..7fa61c474ea1 100644 --- a/code/game/objects/effects/aliens.dm +++ b/code/game/objects/effects/aliens.dm @@ -500,13 +500,13 @@ QDEL_IN(src, ttl) /obj/effect/xenomorph/xeno_telegraph/red - color = COLOUR_DARK_RED + color = COLOR_DARK_RED /obj/effect/xenomorph/xeno_telegraph/brown - color = COLOUR_BROWN + color = COLOR_BROWN /obj/effect/xenomorph/xeno_telegraph/green - color = COLOUR_GREEN + color = COLOR_LIGHT_GREEN /// This has a brown icon state and does not have a color overlay by default. /obj/effect/xenomorph/xeno_telegraph/abduct_hook diff --git a/code/game/objects/effects/decals/cleanable/blood/robots.dm b/code/game/objects/effects/decals/cleanable/blood/robots.dm index 1bbadb1461b6..3ee3c9e07f9a 100644 --- a/code/game/objects/effects/decals/cleanable/blood/robots.dm +++ b/code/game/objects/effects/decals/cleanable/blood/robots.dm @@ -3,11 +3,11 @@ desc = "It's a useless heap of junk... or is it?" icon = 'icons/mob/robots.dmi' icon_state = "gib1" - basecolor="#030303" + basecolor=COLOR_OIL random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7") /obj/effect/decal/cleanable/blood/gibs/robot/update_icon() - color = "#FFFFFF" + color = COLOR_WHITE /obj/effect/decal/cleanable/blood/gibs/robot/dry() //pieces of robots do not dry up like return @@ -39,7 +39,7 @@ /obj/effect/decal/cleanable/blood/oil name = "motor oil" desc = "It's black and greasy." - basecolor="#030303" + basecolor=COLOR_OIL /obj/effect/decal/cleanable/blood/oil/dry() return diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm index 9cf2aa3d8e09..a88b4ea5c5ea 100644 --- a/code/game/objects/effects/decals/cleanable/misc.dm +++ b/code/game/objects/effects/decals/cleanable/misc.dm @@ -36,7 +36,7 @@ acid_damage = 1 icon_state = "greenglow" light_range = 1 - light_color = COLOUR_GREEN + light_color = COLOR_LIGHT_GREEN /obj/effect/decal/cleanable/flour name = "flour" desc = "It's still good. Four second rule!" @@ -55,7 +55,7 @@ anchored = TRUE layer = TURF_LAYER light_range = 1 - light_color = COLOUR_GREEN + light_color = COLOR_LIGHT_GREEN icon = 'icons/effects/effects.dmi' icon_state = "greenglow" diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm index cfe5f27da9a7..35e354c121bb 100644 --- a/code/game/objects/effects/decals/crayon.dm +++ b/code/game/objects/effects/decals/crayon.dm @@ -5,7 +5,7 @@ layer = ABOVE_TURF_LAYER anchored = TRUE -/obj/effect/decal/cleanable/crayon/New(location, main = "#FFFFFF",shade = "#000000", type = "rune") +/obj/effect/decal/cleanable/crayon/New(location, main = COLOR_WHITE,shade = COLOR_BLACK, type = "rune") ..() forceMove(location) diff --git a/code/game/objects/effects/decals/posters.dm b/code/game/objects/effects/decals/posters.dm index 7a8054efce1a..23f7b8c5296a 100644 --- a/code/game/objects/effects/decals/posters.dm +++ b/code/game/objects/effects/decals/posters.dm @@ -160,14 +160,14 @@ icon_state = "poster3" /obj/structure/sign/poster/music/Initialize() - serial_number = pick(3,5,25,26,29,38,39) + serial_number = pick(3,5,25,26,38,39) .=..() /obj/structure/sign/poster/pinup icon_state = "poster12" /obj/structure/sign/poster/pinup/Initialize() - serial_number = pick(12,16,17) + serial_number = pick(12,16,17,29) .=..() /obj/structure/sign/poster/propaganda diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 7cb2781b253b..fcd431c33d26 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -275,7 +275,7 @@ cases. Override_icon_state should be a list.*/ size = "huge" if(SIZE_MASSIVE) size = "massive" - . += "This is a [blood_color ? blood_color != "#030303" ? "bloody " : "oil-stained " : ""][icon2html(src, user)][src.name]. It is a [size] item." + . += "This is a [blood_color ? blood_color != COLOR_OIL ? "bloody " : "oil-stained " : ""][icon2html(src, user)][src.name]. It is a [size] item." if(desc) . += desc if(desc_lore) diff --git a/code/game/objects/items/books/manuals.dm b/code/game/objects/items/books/manuals.dm index 0854d2ec1b06..3140d0e30ca9 100644 --- a/code/game/objects/items/books/manuals.dm +++ b/code/game/objects/items/books/manuals.dm @@ -8,6 +8,7 @@ /// 0 - Normal book, 1 - Should not be treated as normal book, unable to be copied, unable to be modified unique = 1 + /obj/item/book/manual/engineering_construction name = "Station Repairs and Construction" icon_state ="bookEngineering" @@ -28,161 +29,6 @@ "} -/obj/item/book/manual/engineering_particle_accelerator - name = "Particle Accelerator User's Guide" - icon_state ="bookParticleAccelerator" - author = "Engineering Encyclopedia" - title = "Particle Accelerator User's Guide" - - dat = {" -
- - - - -If you've gotten this far, congratulations! You have mastered the art of cloning. Now, the real problem is how to resurrect yourself after that traitor had his way with you for cloning his target. - - - - "} - - /obj/item/book/manual/ripley_build_and_repair name = "APLU \"Ripley\" Construction and Operation Manual" icon_state ="book" @@ -430,271 +132,17 @@ author = "Dr. L. Ight" title = "Research and Development 101" - dat = {" -
- - - - -