diff --git a/SQL/database_changelog.txt b/SQL/database_changelog.txt index 96165390988..58efbbb5435 100644 --- a/SQL/database_changelog.txt +++ b/SQL/database_changelog.txt @@ -2,22 +2,36 @@ Any time you make a change to the schema files, remember to increment the databa Make sure to also update `DB_MAJOR_VERSION` and `DB_MINOR_VERSION`, which can be found in `code/__DEFINES/subsystem.dm`. -The latest database version is 5.24 (5.22 for /tg/); The query to update the schema revision table is: +The latest database version is 5.25 (5.23 for /tg/); The query to update the schema revision table is: -INSERT INTO `schema_revision` (`major`, `minor`) VALUES (5, 24); +INSERT INTO `schema_revision` (`major`, `minor`) VALUES (5, 25); or -INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (5, 24); +INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (5, 25); In any query remember to add a prefix to the table names if you use one. +----------------------------------------------------- +Version 5.25, 28 December 2022, by Mothblocks +Added `tutorial_completions` to mark what ckeys have completed contextual tutorials. + +``` +CREATE TABLE `tutorial_completions` ( + `id` INT NOT NULL AUTO_INCREMENT, + `ckey` VARCHAR(32) NOT NULL, + `tutorial_key` VARCHAR(64) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE INDEX `ckey_tutorial_unique` (`ckey`, `tutorial_key`)); +``` + +----------------------------------------------------- Version 5.24, 22 December 2021, by Mothblocks Fixes a bug in `telemetry_connections` that limited the range of IPs. ``` ALTER TABLE `telemetry_connections` MODIFY COLUMN `address` INT(10) UNSIGNED NOT NULL; ``` ------------------------------------------------------ +----------------------------------------------------- Version 5.23, 15 December 2021, by Mothblocks Adds `telemetry_connections` table for tracking tgui telemetry. diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql index 52f999c4101..ed6ebb3c992 100644 --- a/SQL/tgstation_schema.sql +++ b/SQL/tgstation_schema.sql @@ -716,6 +716,14 @@ CREATE TABLE `telemetry_connections` ( UNIQUE INDEX `unique_constraints` (`ckey` , `telemetry_ckey` , `address` , `computer_id`) ); +DROP TABLE IF EXISTS `tutorial_completions`; +CREATE TABLE `tutorial_completions` ( + `id` INT NOT NULL AUTO_INCREMENT, + `ckey` VARCHAR(32) NOT NULL, + `tutorial_key` VARCHAR(64) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE INDEX `ckey_tutorial_unique` (`ckey`, `tutorial_key`)); + /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; diff --git a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql index 3a9773b9dc5..e69cd9ee046 100644 --- a/SQL/tgstation_schema_prefixed.sql +++ b/SQL/tgstation_schema_prefixed.sql @@ -700,6 +700,14 @@ CREATE TABLE `SS13_telemetry_connections` ( UNIQUE INDEX `unique_constraints` (`ckey` , `telemetry_ckey` , `address` , `computer_id`) ); +DROP TABLE IF EXISTS `SS13_tutorial_completions`; +CREATE TABLE `SS13_tutorial_completions` ( + `id` INT NOT NULL AUTO_INCREMENT, + `ckey` VARCHAR(32) NOT NULL, + `tutorial_key` VARCHAR(64) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE INDEX `ckey_tutorial_unique` (`ckey`, `tutorial_key`)); + /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; diff --git a/code/__DEFINES/achievements.dm b/code/__DEFINES/achievements.dm index a4b84f3ae80..3502a6f4fc4 100644 --- a/code/__DEFINES/achievements.dm +++ b/code/__DEFINES/achievements.dm @@ -35,7 +35,7 @@ #define MEDAL_VOID_ASCENSION "Void" #define MEDAL_BLADE_ASCENSION "Blade" #define MEDAL_TOOLBOX_SOUL "Toolsoul" -#define MEDAL_CHEM_TUT "Beginner Chemist" +#define MEDAL_CHEM_TUT "Beginner Chemist" #define MEDAL_HOT_DAMN "Hot Damn!" #define MEDAL_CAYENNE_DISK "Very Important Piscis" #define MEDAL_TRAM_SURFER "Tram Surfer" @@ -69,24 +69,23 @@ //Mafia medal hub IDs (misc stuff) #define MAFIA_MEDAL_HATED "Universally Hated" -#define MAFIA_MEDAL_CHARISMATIC "Charismatic" -#define MAFIA_MEDAL_VIP "VIP" //Boss medals // Medal hub IDs for boss medals (Pre-fixes) -#define BOSS_MEDAL_ANY "Boss Killer" -#define BOSS_MEDAL_MINER "Blood-drunk Miner Killer" +#define BOSS_MEDAL_ANY "Boss Killer" + +#define BOSS_MEDAL_MINER "Blood-drunk Miner Killer" #define BOSS_MEDAL_FROSTMINER "Demonic-frost Miner Killer" -#define BOSS_MEDAL_BUBBLEGUM "Bubblegum Killer" -#define BOSS_MEDAL_COLOSSUS "Colossus Killer" -#define BOSS_MEDAL_DRAKE "Drake Killer" +#define BOSS_MEDAL_BUBBLEGUM "Bubblegum Killer" +#define BOSS_MEDAL_COLOSSUS "Colossus Killer" +#define BOSS_MEDAL_DRAKE "Drake Killer" #define BOSS_MEDAL_HIEROPHANT "Hierophant Killer" -#define BOSS_MEDAL_LEGION "Legion Killer" -#define BOSS_MEDAL_TENDRIL "Tendril Exterminator" -#define BOSS_MEDAL_SWARMERS "Swarmer Beacon Killer" -#define BOSS_MEDAL_WENDIGO "Wendigo Killer" -#define BOSS_MEDAL_KINGGOAT "King Goat Killer" +#define BOSS_MEDAL_LEGION "Legion Killer" +#define BOSS_MEDAL_TENDRIL "Tendril Exterminator" +#define BOSS_MEDAL_SWARMERS "Swarmer Beacon Killer" +#define BOSS_MEDAL_WENDIGO "Wendigo Killer" +#define BOSS_MEDAL_KINGGOAT "King Goat Killer" #define BOSS_MEDAL_MINER_CRUSHER "Blood-drunk Miner Crusher" #define BOSS_MEDAL_FROSTMINER_CRUSHER "Demonic-frost Miner Crusher" @@ -100,18 +99,18 @@ #define BOSS_MEDAL_KINGGOAT_CRUSHER "King Goat Crusher" // Medal hub IDs for boss-kill scores -#define BOSS_SCORE "Bosses Killed" -#define MINER_SCORE "BDMs Killed" -#define FROST_MINER_SCORE "DFMs Killed" -#define BUBBLEGUM_SCORE "Bubblegum Killed" -#define COLOSSUS_SCORE "Colossus Killed" -#define DRAKE_SCORE "Drakes Killed" -#define HIEROPHANT_SCORE "Hierophants Killed" -#define LEGION_SCORE "Legion Killed" +#define BOSS_SCORE "Bosses Killed" +#define MINER_SCORE "BDMs Killed" +#define FROST_MINER_SCORE "DFMs Killed" +#define BUBBLEGUM_SCORE "Bubblegum Killed" +#define COLOSSUS_SCORE "Colossus Killed" +#define DRAKE_SCORE "Drakes Killed" +#define HIEROPHANT_SCORE "Hierophants Killed" +#define LEGION_SCORE "Legion Killed" #define SWARMER_BEACON_SCORE "Swarmer Beacs Killed" -#define WENDIGO_SCORE "Wendigos Killed" -#define KINGGOAT_SCORE "King Goat Killed" -#define TENDRIL_CLEAR_SCORE "Tendrils Killed" +#define WENDIGO_SCORE "Wendigos Killed" +#define KINGGOAT_SCORE "King Goat Killed" +#define TENDRIL_CLEAR_SCORE "Tendrils Killed" // DB ID for hardcore random mode #define HARDCORE_RANDOM_SCORE "Hardcore Random Score" diff --git a/code/__DEFINES/atom_hud.dm b/code/__DEFINES/atom_hud.dm index 656a51c7f4c..5fa0dc389ce 100644 --- a/code/__DEFINES/atom_hud.dm +++ b/code/__DEFINES/atom_hud.dm @@ -27,26 +27,24 @@ #define DIAG_MECH_HUD "11" /// Bot HUDs #define DIAG_BOT_HUD "12" -/// Circuit assembly health bar -#define DIAG_CIRCUIT_HUD "13" /// Mech/Silicon tracking beacon, Circutry long range icon -#define DIAG_TRACK_HUD "14" +#define DIAG_TRACK_HUD "13" /// Airlock shock overlay -#define DIAG_AIRLOCK_HUD "15" +#define DIAG_AIRLOCK_HUD "14" /// Bot path indicators -#define DIAG_PATH_HUD "16" +#define DIAG_PATH_HUD "15" /// Gland indicators for abductors -#define GLAND_HUD "17" -#define SENTIENT_DISEASE_HUD "18" -#define AI_DETECT_HUD "19" +#define GLAND_HUD "16" +#define SENTIENT_DISEASE_HUD "17" +#define AI_DETECT_HUD "18" /// Displays launchpads' targeting reticle -#define DIAG_LAUNCHPAD_HUD "22" +#define DIAG_LAUNCHPAD_HUD "19" //for antag huds. these are used at the /mob level -#define ANTAG_HUD "23" +#define ANTAG_HUD "20" // for fans to identify pins -#define FAN_HUD "24" +#define FAN_HUD "21" /// Mech camera HUD -#define DIAG_CAMERA_HUD "25" +#define DIAG_CAMERA_HUD "22" // SKYRAT EDIT ADDITION BEGIN - gun permits /// ammo of guns diff --git a/code/__DEFINES/blood.dm b/code/__DEFINES/blood.dm index 320c3ded51a..3bf4af65969 100644 --- a/code/__DEFINES/blood.dm +++ b/code/__DEFINES/blood.dm @@ -2,13 +2,13 @@ /// Minimum alpha of footprints #define BLOODY_FOOTPRINT_BASE_ALPHA 20 /// How much blood a regular blood splatter contains -#define BLOOD_AMOUNT_PER_DECAL 50 +#define BLOOD_AMOUNT_PER_DECAL 50 /// How much blood an item can have stuck on it -#define BLOOD_ITEM_MAX 200 +#define BLOOD_ITEM_MAX 200 /// How much blood a blood decal can contain -#define BLOOD_POOL_MAX 300 +#define BLOOD_POOL_MAX 300 /// How much blood a footprint need to at least contain -#define BLOOD_FOOTPRINTS_MIN 5 +#define BLOOD_FOOTPRINTS_MIN 5 //Bloody shoe blood states /// Red blood diff --git a/code/__DEFINES/colors.dm b/code/__DEFINES/colors.dm index 7792ea62894..9e1fe18270a 100644 --- a/code/__DEFINES/colors.dm +++ b/code/__DEFINES/colors.dm @@ -28,8 +28,9 @@ #define COLOR_ALMOST_BLACK "#333333" #define COLOR_FULL_TONER_BLACK "#101010" #define COLOR_PRISONER_BLACK "#292929" +#define COLOR_NEARLY_ALL_BLACK "#111111" #define COLOR_BLACK "#000000" -#define COLOR_HALF_TRANSPARENT_BLACK "#0000007A" +#define COLOR_HALF_TRANSPARENT_BLACK "#0000007A" #define COLOR_RED "#FF0000" #define COLOR_SYNDIE_RED "#F10303" @@ -120,30 +121,30 @@ #define COLOR_SOAPSTONE_GOLD "#FFD900" #define COLOR_SOAPSTONE_DIAMOND "#00ffee" -#define COLOR_GREEN_GRAY "#99BB76" -#define COLOR_RED_GRAY "#B4696A" -#define COLOR_PALE_BLUE_GRAY "#98C5DF" -#define COLOR_PALE_GREEN_GRAY "#B7D993" -#define COLOR_PALE_RED_GRAY "#D59998" +#define COLOR_GREEN_GRAY "#99BB76" +#define COLOR_RED_GRAY "#B4696A" +#define COLOR_PALE_BLUE_GRAY "#98C5DF" +#define COLOR_PALE_GREEN_GRAY "#B7D993" +#define COLOR_PALE_RED_GRAY "#D59998" #define COLOR_PALE_PURPLE_GRAY "#CBB1CA" -#define COLOR_PURPLE_GRAY "#AE8CA8" +#define COLOR_PURPLE_GRAY "#AE8CA8" //Color defines used by the assembly detailer. -#define COLOR_ASSEMBLY_BLACK "#545454" -#define COLOR_ASSEMBLY_BGRAY "#9497AB" -#define COLOR_ASSEMBLY_WHITE "#E2E2E2" -#define COLOR_ASSEMBLY_RED "#CC4242" -#define COLOR_ASSEMBLY_ORANGE "#E39751" -#define COLOR_ASSEMBLY_BEIGE "#AF9366" -#define COLOR_ASSEMBLY_BROWN "#97670E" -#define COLOR_ASSEMBLY_GOLD "#AA9100" -#define COLOR_ASSEMBLY_YELLOW "#CECA2B" -#define COLOR_ASSEMBLY_GURKHA "#999875" -#define COLOR_ASSEMBLY_LGREEN "#789876" -#define COLOR_ASSEMBLY_GREEN "#44843C" -#define COLOR_ASSEMBLY_LBLUE "#5D99BE" -#define COLOR_ASSEMBLY_BLUE "#38559E" -#define COLOR_ASSEMBLY_PURPLE "#6F6192" +#define COLOR_ASSEMBLY_BLACK "#545454" +#define COLOR_ASSEMBLY_BGRAY "#9497AB" +#define COLOR_ASSEMBLY_WHITE "#E2E2E2" +#define COLOR_ASSEMBLY_RED "#CC4242" +#define COLOR_ASSEMBLY_ORANGE "#E39751" +#define COLOR_ASSEMBLY_BEIGE "#AF9366" +#define COLOR_ASSEMBLY_BROWN "#97670E" +#define COLOR_ASSEMBLY_GOLD "#AA9100" +#define COLOR_ASSEMBLY_YELLOW "#CECA2B" +#define COLOR_ASSEMBLY_GURKHA "#999875" +#define COLOR_ASSEMBLY_LGREEN "#789876" +#define COLOR_ASSEMBLY_GREEN "#44843C" +#define COLOR_ASSEMBLY_LBLUE "#5D99BE" +#define COLOR_ASSEMBLY_BLUE "#38559E" +#define COLOR_ASSEMBLY_PURPLE "#6F6192" ///Colors for grayscale tools #define COLOR_TOOL_BLUE "#1861d5" @@ -303,4 +304,4 @@ GLOBAL_LIST_INIT(cable_colors, list( CABLE_COLOR_WHITE = CABLE_HEX_COLOR_WHITE, CABLE_COLOR_YELLOW = CABLE_HEX_COLOR_YELLOW, CABLE_COLOR_BROWN = CABLE_HEX_COLOR_BROWN - )) +)) diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 83518fb5b59..28bd44e2ff3 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -56,9 +56,9 @@ #define FIRELOSS (1<<1) #define TOXLOSS (1<<2) #define OXYLOSS (1<<3) -#define SHAME (1<<4) +#define SHAME (1<<4) #define MANUAL_SUICIDE (1<<5) //suicide_act will do the actual killing. -#define MANUAL_SUICIDE_NONLETHAL (1<<6) //when the suicide is conditionally lethal +#define MANUAL_SUICIDE_NONLETHAL (1<<6) //when the suicide is conditionally lethal #define EFFECT_STUN "stun" #define EFFECT_KNOCKDOWN "knockdown" diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_explosion.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_explosion.dm index d2328f5e500..7d7ba861398 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_explosion.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_explosion.dm @@ -11,3 +11,5 @@ /// When returned on a signal hooked to [COMSIG_ATOM_EXPLODE], [COMSIG_ATOM_INTERNAL_EXPLOSION], or [COMSIG_AREA_INTERNAL_EXPLOSION] it prevents the explosion from being propagated further. #define COMSIG_CANCEL_EXPLOSION (1<<0) +/// from [/atom/movable/proc/set_explosion_resistance] : (old_block, new_block) +#define COMSIG_MOVABLE_EXPLOSION_BLOCK_CHANGED "explosion_block_changed" diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm index b878fb21823..5e5864665be 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm @@ -133,5 +133,9 @@ /// From /mob/living/befriend() : (mob/living/new_friend) #define COMSIG_LIVING_BEFRIENDED "living_befriended" + +/// From /obj/item/proc/pickup(): (/obj/item/picked_up_item) +#define COMSIG_LIVING_PICKED_UP_ITEM "living_picked_up_item" + /// From /mob/living/unfriend() : (mob/living/old_friend) #define COMSIG_LIVING_UNFRIENDED "living_unfriended" diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm index 1cac348d152..005d6594257 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm @@ -116,9 +116,12 @@ #define MOB_DEADSAY_SIGNAL_INTERCEPT (1<<0) ///from /mob/living/emote(): () #define COMSIG_MOB_EMOTE "mob_emote" -///from base of mob/swap_hand(): (obj/item) -#define COMSIG_MOB_SWAP_HANDS "mob_swap_hands" +///from base of mob/swap_hand(): (obj/item/currently_held_item) +#define COMSIG_MOB_SWAPPING_HANDS "mob_swapping_hands" #define COMPONENT_BLOCK_SWAP (1<<0) +/// from base of mob/swap_hand(): () +/// Performed after the hands are swapped. +#define COMSIG_MOB_SWAP_HANDS "mob_swap_hands" ///from base of /mob/verb/pointed: (atom/A) #define COMSIG_MOB_POINTED "mob_pointed" ///Mob is trying to open the wires of a target [/atom], from /datum/wires/interactable(): (atom/target) @@ -171,5 +174,9 @@ ///from living/flash_act(), when a mob is successfully flashed. #define COMSIG_MOB_FLASHED "mob_flashed" + /// from mob/get_status_tab_items(): (list/items) #define COMSIG_MOB_GET_STATUS_TAB_ITEMS "mob_get_status_tab_items" + +/// from mob/proc/dropItemToGround() +#define COMSIG_MOB_DROPPING_ITEM "mob_dropping_item" diff --git a/code/__DEFINES/explosions.dm b/code/__DEFINES/explosions.dm index cd30f89f1b0..f867ee9b813 100644 --- a/code/__DEFINES/explosions.dm +++ b/code/__DEFINES/explosions.dm @@ -18,9 +18,6 @@ /// Gibtonite will now explode #define GIBTONITE_DETONATE 3 -/// For object explosion block calculation -#define EXPLOSION_BLOCK_PROC -1 - /// A wrapper for [/atom/proc/ex_act] to ensure that the explosion propagation and attendant signal are always handled. #define EX_ACT(target, args...)\ if(!(target.flags_1 & PREVENT_CONTENTS_EXPLOSION_1)) { \ diff --git a/code/__DEFINES/fonts.dm b/code/__DEFINES/fonts.dm index be1d483a1b7..3b2ec46b178 100644 --- a/code/__DEFINES/fonts.dm +++ b/code/__DEFINES/fonts.dm @@ -12,13 +12,5 @@ /// Font used when signing on paper. #define SIGNATURE_FONT "Segoe Script" -//pda fonts -#define MONO "Monospaced" -#define VT "VT323" -#define ORBITRON "Orbitron" -#define SHARE "Share Tech Mono" - -GLOBAL_LIST_INIT(pda_styles, sort_list(list(MONO, VT, ORBITRON, SHARE))) - /// Emoji icon set #define EMOJI_SET 'modular_skyrat/master_files/icons/emoji.dmi' // SKYRAT EDIT - ORIGINAL: 'icons/ui_icons/emoji/emoji.dmi' diff --git a/code/__DEFINES/food.dm b/code/__DEFINES/food.dm index 87e27413358..128c82c7c9a 100644 --- a/code/__DEFINES/food.dm +++ b/code/__DEFINES/food.dm @@ -117,7 +117,7 @@ DEFINE_BITFIELD(food_flags, list( ///Amount of reagents you start with on crafted food excluding the used parts #define CRAFTED_FOOD_BASE_REAGENT_MODIFIER 0.7 ///Modifier of reagents you get when crafting food from the parts used -#define CRAFTED_FOOD_INGREDIENT_REAGENT_MODIFIER 0.5 +#define CRAFTED_FOOD_INGREDIENT_REAGENT_MODIFIER 0.5 #define IS_EDIBLE(O) (O.GetComponent(/datum/component/edible)) diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index 16cc59a00f9..ba4f0f12ea4 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -135,8 +135,8 @@ #define ui_borg_lamp "CENTER-3:16, SOUTH:5" #define ui_borg_tablet "CENTER-4:16, SOUTH:5" #define ui_inv1 "CENTER-2:16,SOUTH:5" -#define ui_inv2 "CENTER-1 :16,SOUTH:5" -#define ui_inv3 "CENTER :16,SOUTH:5" +#define ui_inv2 "CENTER-1 :16,SOUTH:5" +#define ui_inv3 "CENTER :16,SOUTH:5" #define ui_borg_module "CENTER+1:16,SOUTH:5" #define ui_borg_store "CENTER+2:16,SOUTH:5" #define ui_borg_camera "CENTER+3:21,SOUTH:5" diff --git a/code/__DEFINES/icon_smoothing.dm b/code/__DEFINES/icon_smoothing.dm index 3336f96ad0d..b1b145a0eb4 100644 --- a/code/__DEFINES/icon_smoothing.dm +++ b/code/__DEFINES/icon_smoothing.dm @@ -146,8 +146,8 @@ DEFINE_BITFIELD(smoothing_flags, list( #define SMOOTH_GROUP_WINDOW_FULLTILE_PLASTITANIUM S_OBJ(24) ///turf/closed/indestructible/opsglass, /obj/structure/window/reinforced/plasma/plastitanium #define SMOOTH_GROUP_WINDOW_FULLTILE_SHUTTLE S_OBJ(25) ///obj/structure/window/reinforced/shuttle -#define SMOOTH_GROUP_LATTICE S_OBJ(31) ///obj/structure/lattice -#define SMOOTH_GROUP_CATWALK S_OBJ(32) ///obj/structure/lattice/catwalk +#define SMOOTH_GROUP_LATTICE S_OBJ(31) ///obj/structure/lattice +#define SMOOTH_GROUP_CATWALK S_OBJ(32) ///obj/structure/lattice/catwalk #define SMOOTH_GROUP_AIRLOCK S_OBJ(41) ///obj/machinery/door/airlock diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 04495484698..896d7f0a0a4 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -279,3 +279,4 @@ GLOBAL_LIST_INIT(book_types, typecacheof(list( #define is_unassigned_job(job_type) (istype(job_type, /datum/job/unassigned)) #define isprojectilespell(thing) (istype(thing, /datum/action/cooldown/spell/pointed/projectile)) +#define is_multi_tile_object(atom) (atom.bound_width > world.icon_size || atom.bound_height > world.icon_size) diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index a06085bbf04..2ecdda04738 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -240,6 +240,9 @@ ///Layer for screentips #define SCREENTIP_LAYER 4 +/// Layer for tutorial instructions +#define TUTORIAL_INSTRUCTIONS_LAYER 5 + #define LOBBY_BACKGROUND_LAYER 3 #define LOBBY_BUTTON_LAYER 4 diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm index 62734b909a0..7bda18b5cd5 100644 --- a/code/__DEFINES/lighting.dm +++ b/code/__DEFINES/lighting.dm @@ -12,18 +12,18 @@ //Bay lighting engine shit, not in /code/modules/lighting because BYOND is being shit about it /// frequency, in 1/10ths of a second, of the lighting process -#define LIGHTING_INTERVAL 5 +#define LIGHTING_INTERVAL 5 #define MINIMUM_USEFUL_LIGHT_RANGE 1.4 /// type of falloff to use for lighting; 1 for circular, 2 for square -#define LIGHTING_FALLOFF 1 +#define LIGHTING_FALLOFF 1 /// use lambertian shading for light sources -#define LIGHTING_LAMBERTIAN 0 +#define LIGHTING_LAMBERTIAN 0 /// height off the ground of light sources on the pseudo-z-axis, you should probably leave this alone -#define LIGHTING_HEIGHT 1 +#define LIGHTING_HEIGHT 1 /// Value used to round lumcounts, values smaller than 1/129 don't matter (if they do, thanks sinking points), greater values will make lighting less precise, but in turn increase performance, VERY SLIGHTLY. -#define LIGHTING_ROUND_VALUE (1 / 64) +#define LIGHTING_ROUND_VALUE (1 / 64) /// icon used for lighting shading effects #define LIGHTING_ICON 'icons/effects/lighting_object.dmi' @@ -32,17 +32,6 @@ /// Set to zero to disable soft lighting. Luminosity changes then work if it's lit at all. #define LIGHTING_SOFT_THRESHOLD 0 -/// If I were you I'd leave this alone. -#define LIGHTING_BASE_MATRIX \ - list \ - ( \ - 1, 1, 1, 0, \ - 1, 1, 1, 0, \ - 1, 1, 1, 0, \ - 1, 1, 1, 0, \ - 0, 0, 0, 1 \ - ) \ - ///How many tiles standard fires glow. #define LIGHT_RANGE_FIRE 3 diff --git a/code/__DEFINES/maths.dm b/code/__DEFINES/maths.dm index db411b6285d..7117d7b4645 100644 --- a/code/__DEFINES/maths.dm +++ b/code/__DEFINES/maths.dm @@ -237,5 +237,9 @@ #define GET_TRUE_DIST(a, b) (a == null || b == null) ? -1 : max(abs(a.x -b.x), abs(a.y-b.y), abs(a.z-b.z)) +//We used to use linear regression to approximate the answer, but Mloc realized this was actually faster. +//And lo and behold, it is, and it's more accurate to boot. +#define CHEAP_HYPOTENUSE(Ax, Ay, Bx, By) (sqrt(abs(Ax - Bx) ** 2 + abs(Ay - By) ** 2)) //A squared + B squared = C squared + /// The number of cells in a taxicab circle (rasterized diamond) of radius X. #define DIAMOND_AREA(X) (1 + 2*(X)*((X)+1)) diff --git a/code/__DEFINES/matrices.dm b/code/__DEFINES/matrices.dm index b7240751b63..1bb86f9ff47 100644 --- a/code/__DEFINES/matrices.dm +++ b/code/__DEFINES/matrices.dm @@ -1,2 +1,3 @@ -/// Helper macro for compile time translation +/// Helper macro for creating a matrix at the given offsets. +/// Works at compile time. #define TRANSLATE_MATRIX(offset_x, offset_y) matrix(1, 0, (offset_x), 0, 1, (offset_y)) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 459eae812cc..4dcd37bd165 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -8,7 +8,7 @@ //movement intent defines for the m_intent var #define MOVE_INTENT_WALK "walk" -#define MOVE_INTENT_RUN "run" +#define MOVE_INTENT_RUN "run" //Blood levels #define BLOOD_VOLUME_MAX_LETHAL 2150 @@ -35,8 +35,8 @@ #define MOB_SIZE_HUGE 4 // Use this for things you don't want bluespace body-bagged //Ventcrawling defines -#define VENTCRAWLER_NONE 0 -#define VENTCRAWLER_NUDE 1 +#define VENTCRAWLER_NONE 0 +#define VENTCRAWLER_NUDE 1 #define VENTCRAWLER_ALWAYS 2 //Mob bio-types flags @@ -183,12 +183,12 @@ #define BRAIN_TRAUMA_SPECIAL /datum/brain_trauma/special #define BRAIN_TRAUMA_MAGIC /datum/brain_trauma/magic -#define TRAUMA_RESILIENCE_BASIC 1 //Curable with chems -#define TRAUMA_RESILIENCE_SURGERY 2 //Curable with brain surgery -#define TRAUMA_RESILIENCE_LOBOTOMY 3 //Curable with lobotomy -#define TRAUMA_RESILIENCE_WOUND 4 //Curable by healing the head wound -#define TRAUMA_RESILIENCE_MAGIC 5 //Curable only with magic -#define TRAUMA_RESILIENCE_ABSOLUTE 6 //This is here to stay +#define TRAUMA_RESILIENCE_BASIC 1 //Curable with chems +#define TRAUMA_RESILIENCE_SURGERY 2 //Curable with brain surgery +#define TRAUMA_RESILIENCE_LOBOTOMY 3 //Curable with lobotomy +#define TRAUMA_RESILIENCE_WOUND 4 //Curable by healing the head wound +#define TRAUMA_RESILIENCE_MAGIC 5 //Curable only with magic +#define TRAUMA_RESILIENCE_ABSOLUTE 6 //This is here to stay //Limit of traumas for each resilience tier #define TRAUMA_LIMIT_BASIC 3 @@ -349,7 +349,7 @@ //determines if a mob can smash through it #define ENVIRONMENT_SMASH_NONE 0 #define ENVIRONMENT_SMASH_STRUCTURES 1 //crates, lockers, ect -#define ENVIRONMENT_SMASH_WALLS 2 //walls +#define ENVIRONMENT_SMASH_WALLS 2 //walls #define ENVIRONMENT_SMASH_RWALLS 3 //rwalls #define NO_SLIP_WHEN_WALKING (1<<0) @@ -420,12 +420,12 @@ //#define AGE_MIN 17 //youngest a character can be //ORIGINAL #define AGE_MIN 18 //youngest a character can be //SKYRAT EDIT CHANGE - age #define AGE_MAX 85 //oldest a character can be -#define AGE_MINOR 20 //legal age of space drinking and smoking +#define AGE_MINOR 20 //legal age of space drinking and smoking #define WIZARD_AGE_MIN 30 //youngest a wizard can be #define APPRENTICE_AGE_MIN 29 //youngest an apprentice can be #define SHOES_SLOWDOWN 0 //How much shoes slow you down by default. Negative values speed you up -#define SHOES_SPEED_SLIGHT SHOES_SLOWDOWN - 1 // slightest speed boost to movement +#define SHOES_SPEED_SLIGHT SHOES_SLOWDOWN - 1 // slightest speed boost to movement #define POCKET_STRIP_DELAY (4 SECONDS) //time taken to search somebody's pockets #define DOOR_CRUSH_DAMAGE 15 //the amount of damage that airlocks deal when they crush you diff --git a/code/__DEFINES/modular_computer.dm b/code/__DEFINES/modular_computer.dm index f0f0877d47e..e7c6fd797df 100644 --- a/code/__DEFINES/modular_computer.dm +++ b/code/__DEFINES/modular_computer.dm @@ -25,7 +25,7 @@ #define PROGRAM_CATEGORY_CREW "Crew" #define PROGRAM_CATEGORY_ENGI "Engineering" #define PROGRAM_CATEGORY_SUPL "Supply" -#define PROGRAM_CATEGORY_SCI "Science" +#define PROGRAM_CATEGORY_SCI "Science" #define PROGRAM_CATEGORY_MISC "Other" #define DETOMATIX_RESIST_MINOR 1 diff --git a/code/__DEFINES/monkeys.dm b/code/__DEFINES/monkeys.dm index 50b712ade4b..f487f805d50 100644 --- a/code/__DEFINES/monkeys.dm +++ b/code/__DEFINES/monkeys.dm @@ -14,7 +14,7 @@ #define MONKEY_SYRINGE_RETALIATION_PROB 20 // Probability per Life tick that the monkey will: -/// probability that monkey aggro against the mob pulling it +/// probability that monkey aggro against the mob pulling it #define MONKEY_PULL_AGGRO_PROB 5 /// probability that monkey will get into mischief, i.e. finding/stealing items #define MONKEY_SHENANIGAN_PROB 20 diff --git a/code/__DEFINES/networks.dm b/code/__DEFINES/networks.dm index 8fc6b530e7f..ebd85c86c1e 100644 --- a/code/__DEFINES/networks.dm +++ b/code/__DEFINES/networks.dm @@ -78,7 +78,7 @@ #define NETWORK_PORT_UPDATE(LIST) if(LIST) { LIST["_updated"] = TRUE } #define NETWORK_PORT_CLEAR_UPDATE(LIST) if(LIST) { LIST["_updated"] = FALSE } #define NETWORK_PORT_SET_UPDATE(LIST) if(LIST) { LIST["_updated"] = TRUE } -#define NETWORK_PORT_DISCONNECT(LIST) if(LIST) { LIST["_disconnected"] = TRUE } +#define NETWORK_PORT_DISCONNECT(LIST) if(LIST) { LIST["_disconnected"] = TRUE } /// Error codes #define NETWORK_ERROR_OK null diff --git a/code/__DEFINES/power.dm b/code/__DEFINES/power.dm index 36cb2cdbb0f..b07ba5e9b58 100644 --- a/code/__DEFINES/power.dm +++ b/code/__DEFINES/power.dm @@ -4,9 +4,9 @@ #define MACHINERY_LAYER_1 1 -#define SOLAR_TRACK_OFF 0 -#define SOLAR_TRACK_TIMED 1 -#define SOLAR_TRACK_AUTO 2 +#define SOLAR_TRACK_OFF 0 +#define SOLAR_TRACK_TIMED 1 +#define SOLAR_TRACK_AUTO 2 ///conversion ratio from joules to watts #define WATTS / 0.002 diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index 8294c35d0fa..24e14b06fa7 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -31,7 +31,7 @@ #define CHAT_GHOSTWHISPER (1<<7) #define CHAT_GHOSTPDA (1<<8) #define CHAT_GHOSTRADIO (1<<9) -#define CHAT_BANKCARD (1<<10) +#define CHAT_BANKCARD (1<<10) #define CHAT_GHOSTLAWS (1<<11) #define CHAT_LOGIN_LOGOUT (1<<12) diff --git a/code/__DEFINES/radiation.dm b/code/__DEFINES/radiation.dm index ed6a4b547f7..bb345312ce5 100644 --- a/code/__DEFINES/radiation.dm +++ b/code/__DEFINES/radiation.dm @@ -29,7 +29,7 @@ Ask Mothblocks if they're around #define RAD_NO_INSULATION 1.0 // For things that shouldn't become irradiated for whatever reason #define RAD_VERY_LIGHT_INSULATION 0.9 // What girders have #define RAD_LIGHT_INSULATION 0.8 -#define RAD_MEDIUM_INSULATION 0.7 // What common walls have +#define RAD_MEDIUM_INSULATION 0.7 // What common walls have #define RAD_HEAVY_INSULATION 0.6 // What reinforced walls have #define RAD_EXTREME_INSULATION 0.5 // What rad collectors have #define RAD_FULL_INSULATION 0 // Completely stops radiation from coming through diff --git a/code/__DEFINES/radio.dm b/code/__DEFINES/radio.dm index 105c2cf7f06..324b5d68f16 100644 --- a/code/__DEFINES/radio.dm +++ b/code/__DEFINES/radio.dm @@ -60,19 +60,19 @@ // Frequencies are always odd numbers and range from 1201 to 1599. #define FREQ_UPLINK 1211 // Dummy loopback frequency, used for radio uplink. Not seen in game. -#define FREQ_SYNDICATE 1213 // Nuke op comms frequency, dark brown -#define FREQ_CTF_RED 1215 // CTF red team comms frequency, red -#define FREQ_CTF_BLUE 1217 // CTF blue team comms frequency, blue -#define FREQ_CTF_GREEN 1219 // CTF green team comms frequency, green -#define FREQ_CTF_YELLOW 1221 // CTF yellow team comms frequency, yellow -#define FREQ_CENTCOM 1337 // CentCom comms frequency, gray -#define FREQ_SUPPLY 1347 // Supply comms frequency, light brown -#define FREQ_SERVICE 1349 // Service comms frequency, green -#define FREQ_SCIENCE 1351 // Science comms frequency, plum -#define FREQ_COMMAND 1353 // Command comms frequency, gold -#define FREQ_MEDICAL 1355 // Medical comms frequency, soft blue -#define FREQ_ENGINEERING 1357 // Engineering comms frequency, orange -#define FREQ_SECURITY 1359 // Security comms frequency, red +#define FREQ_SYNDICATE 1213 // Nuke op comms frequency, dark brown +#define FREQ_CTF_RED 1215 // CTF red team comms frequency, red +#define FREQ_CTF_BLUE 1217 // CTF blue team comms frequency, blue +#define FREQ_CTF_GREEN 1219 // CTF green team comms frequency, green +#define FREQ_CTF_YELLOW 1221 // CTF yellow team comms frequency, yellow +#define FREQ_CENTCOM 1337 // CentCom comms frequency, gray +#define FREQ_SUPPLY 1347 // Supply comms frequency, light brown +#define FREQ_SERVICE 1349 // Service comms frequency, green +#define FREQ_SCIENCE 1351 // Science comms frequency, plum +#define FREQ_COMMAND 1353 // Command comms frequency, gold +#define FREQ_MEDICAL 1355 // Medical comms frequency, soft blue +#define FREQ_ENGINEERING 1357 // Engineering comms frequency, orange +#define FREQ_SECURITY 1359 // Security comms frequency, red #define FREQ_HOLOGRID_SOLUTION 1433 #define FREQ_STATUS_DISPLAYS 1435 @@ -82,23 +82,23 @@ // This represents 1/8th of the available spectrum. #define FREQ_NAV_BEACON 1445 -#define FREQ_AI_PRIVATE 1447 // AI private comms frequency, magenta +#define FREQ_AI_PRIVATE 1447 // AI private comms frequency, magenta #define FREQ_PRESSURE_PLATE 1447 #define FREQ_ELECTROPACK 1449 #define FREQ_MAGNETS 1449 #define FREQ_LOCATOR_IMPLANT 1451 -#define FREQ_SIGNALER 1457 // the default for new signalers -#define FREQ_COMMON 1459 // Common comms frequency, dark green +#define FREQ_SIGNALER 1457 // the default for new signalers +#define FREQ_COMMON 1459 // Common comms frequency, dark green #define MAX_FREQ 1489 // ------------------------------------------------------ #define MAX_FREE_FREQ 1599 // ------------------------------------------------- // Transmission types. -#define TRANSMISSION_WIRE 0 // some sort of wired connection, not used -#define TRANSMISSION_RADIO 1 // electromagnetic radiation (default) -#define TRANSMISSION_SUBSPACE 2 // subspace transmission (headsets only) -#define TRANSMISSION_SUPERSPACE 3 // reaches independent (CentCom) radios only +#define TRANSMISSION_WIRE 0 // some sort of wired connection, not used +#define TRANSMISSION_RADIO 1 // electromagnetic radiation (default) +#define TRANSMISSION_SUBSPACE 2 // subspace transmission (headsets only) +#define TRANSMISSION_SUPERSPACE 3 // reaches independent (CentCom) radios only // Filter types, used as an optimization to avoid unnecessary proc calls. #define RADIO_SIGNALER "signaler" diff --git a/code/__DEFINES/resonator.dm b/code/__DEFINES/resonator.dm index b6a4b897d26..1801fc0da46 100644 --- a/code/__DEFINES/resonator.dm +++ b/code/__DEFINES/resonator.dm @@ -1,3 +1,3 @@ -#define RESONATOR_MODE_AUTO 1 +#define RESONATOR_MODE_AUTO 1 #define RESONATOR_MODE_MANUAL 2 #define RESONATOR_MODE_MATRIX 3 diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 3e6e3d385c8..68d7bfc6c4a 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -20,7 +20,7 @@ * * make sure you add an update to the schema_version stable in the db changelog */ -#define DB_MINOR_VERSION 24 +#define DB_MINOR_VERSION 25 //! ## Timing subsystem diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 7e1c8a7d862..f6c6c6198ca 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -510,6 +510,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_PARALYSIS "paralysis" /// Used for limbs. #define TRAIT_DISABLED_BY_WOUND "disabled-by-wound" +/// This movable atom has the explosive block element +#define TRAIT_BLOCKING_EXPLOSIVES "blocking_explosives" /// Mobs with this trait can't send the mining shuttle console when used outside the station itself #define TRAIT_FORBID_MINING_SHUTTLE_CONSOLE_OUTSIDE_STATION "forbid_mining_shuttle_console_outside_station" diff --git a/code/__DEFINES/turfs.dm b/code/__DEFINES/turfs.dm index 6ff862413bf..a4fcb170dec 100644 --- a/code/__DEFINES/turfs.dm +++ b/code/__DEFINES/turfs.dm @@ -15,7 +15,7 @@ #define RECT_TURFS(H_RADIUS, V_RADIUS, CENTER) \ block( \ - locate(max(CENTER.x-(H_RADIUS),1), max(CENTER.y-(V_RADIUS),1), CENTER.z), \ + locate(max(CENTER.x-(H_RADIUS),1), max(CENTER.y-(V_RADIUS),1), CENTER.z), \ locate(min(CENTER.x+(H_RADIUS),world.maxx), min(CENTER.y+(V_RADIUS),world.maxy), CENTER.z) \ ) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 0c23609c726..bc549e583a4 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -11,12 +11,6 @@ return null return format_text ? format_text(checked_area.name) : checked_area.name -//We used to use linear regression to approximate the answer, but Mloc realized this was actually faster. -//And lo and behold, it is, and it's more accurate to boot. -///Calculate the hypotenuse cheaply (this should be in maths.dm) -/proc/cheap_hypotenuse(Ax, Ay, Bx, By) - return sqrt(abs(Ax - Bx) ** 2 + abs(Ay - By) ** 2) //A squared + B squared = C squared - /** toggle_organ_decay * inputs: first_object (object to start with) * outputs: diff --git a/code/__HELPERS/screen_objs.dm b/code/__HELPERS/screen_objs.dm index aa86b6d5795..7debecf816f 100644 --- a/code/__HELPERS/screen_objs.dm +++ b/code/__HELPERS/screen_objs.dm @@ -18,14 +18,26 @@ y += view_size[2] if(findtext(screen_loc, "SOUTH")) y += world.icon_size - // Cut out everything we just parsed - screen_loc = cut_relative_direction(screen_loc) var/list/x_and_y = splittext(screen_loc, ",") + var/list/x_pack = splittext(x_and_y[1], ":") var/list/y_pack = splittext(x_and_y[2], ":") - x += text2num(x_pack[1]) * world.icon_size - y += text2num(y_pack[1]) * world.icon_size + + var/x_coord = x_pack[1] + var/y_coord = y_pack[1] + + if (findtext(x_coord, "CENTER")) + x += view_size[1] / 2 + + if (findtext(y_coord, "CENTER")) + y += view_size[2] / 2 + + x_coord = text2num(cut_relative_direction(x_coord)) + y_coord = text2num(cut_relative_direction(y_coord)) + + x += x_coord * world.icon_size + y += y_coord * world.icon_size if(length(x_pack) > 1) x += text2num(x_pack[2]) diff --git a/code/_onclick/hud/ghost.dm b/code/_onclick/hud/ghost.dm index eeb8dccb933..b620d19cbb8 100644 --- a/code/_onclick/hud/ghost.dm +++ b/code/_onclick/hud/ghost.dm @@ -48,7 +48,7 @@ /atom/movable/screen/ghost/minigames_menu name ="Minigames" icon_state = "minigames" - + /atom/movable/screen/ghost/minigames_menu/Click() var/mob/dead/observer/observer = usr observer.open_minigames_menu() @@ -88,7 +88,7 @@ static_inventory += using using = new /atom/movable/screen/language_menu - using.screen_loc = ui_ghost_language_menu + using.screen_loc = ui_ghost_language_menu using.icon = ui_style using.hud = src static_inventory += using diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 0399d7146d5..be5c39ba9e9 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -59,7 +59,15 @@ if (after_attack_secondary_result == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN || after_attack_secondary_result == SECONDARY_ATTACK_CONTINUE_CHAIN) return TRUE - return afterattack(target, user, TRUE, params) == TRUE + var/afterattack_result = afterattack(target, user, TRUE, params) + + if (!(afterattack_result & AFTERATTACK_PROCESSED_ITEM) && isitem(target)) + if (isnull(user.get_inactive_held_item())) + SStutorials.suggest_tutorial(user, /datum/tutorial/switch_hands, params2list(params)) + else + SStutorials.suggest_tutorial(user, /datum/tutorial/drop, params2list(params)) + + return afterattack_result & TRUE //this is really stupid but its needed because afterattack can return TRUE | FLAGS. /// Called when the item is in the active hand, and clicked; alternately, there is an 'activate held object' verb or you can hit pagedown. /obj/item/proc/attack_self(mob/user, modifiers) diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index e822a4d88e3..032ff23afee 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -414,3 +414,4 @@ /datum/config_entry/flag/disallow_circuit_sounds +/datum/config_entry/flag/give_tutorials_without_db diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm index 263201b6846..7bfbe268b6d 100644 --- a/code/controllers/configuration/entries/general.dm +++ b/code/controllers/configuration/entries/general.dm @@ -649,3 +649,5 @@ default = 50 /datum/config_entry/string/morgue_cadaver_override_species + +/datum/config_entry/flag/toast_notification_on_init diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 99060e9ae96..5000aa07e30 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -267,6 +267,9 @@ GLOBAL_REAL(Master, /datum/controller/master) = new log_world(msg) + if(world.system_type == MS_WINDOWS && CONFIG_GET(flag/toast_notification_on_init) && !length(GLOB.clients)) + world.shelleo("start /min powershell -ExecutionPolicy Bypass -File tools/initToast/initToast.ps1 -name \"[world.name]\" -icon %CD%\\icons\\ui_icons\\common\\tg_16.png -port [world.port]") + // Set world options. world.change_fps(CONFIG_GET(number/fps)) var/initialized_tod = REALTIMEOFDAY diff --git a/code/controllers/subsystem/explosions.dm b/code/controllers/subsystem/explosions.dm index ff92af88fbd..5cdf16fa92e 100644 --- a/code/controllers/subsystem/explosions.dm +++ b/code/controllers/subsystem/explosions.dm @@ -119,30 +119,31 @@ SUBSYSTEM_DEF(explosions) var/x0 = epicenter.x var/y0 = epicenter.y var/list/wipe_colours = list() - for(var/turf/T in spiral_range_turfs(max_range, epicenter)) - wipe_colours += T - var/dist = cheap_hypotenuse(T.x, T.y, x0, y0) + var/list/cached_exp_block = list() + for(var/turf/explode in prepare_explosion_turfs(max_range, epicenter)) + wipe_colours += explode + var/our_x = explode.x + var/our_y = explode.y + var/dist = CHEAP_HYPOTENUSE(our_x, our_y, x0, y0) if(newmode == "Yes") - var/turf/TT = T - while(TT != epicenter) - TT = get_step_towards(TT,epicenter) - if(TT.density) - dist += TT.explosion_block - - for(var/obj/O in T) - var/the_block = O.explosion_block - dist += the_block == EXPLOSION_BLOCK_PROC ? O.GetExplosionBlock() : the_block + if(explode != epicenter) + var/our_block = cached_exp_block[get_step_towards(explode, epicenter)] + dist += our_block + cached_exp_block[explode] = our_block + explode.explosive_resistance + else + cached_exp_block[explode] = explode.explosive_resistance + dist = round(dist, 0.01) if(dist < dev) - T.color = "red" - T.maptext = MAPTEXT("Dev") + explode.color = "red" + explode.maptext = MAPTEXT("[dist]") else if (dist < heavy) - T.color = "yellow" - T.maptext = MAPTEXT("Heavy") + explode.color = "yellow" + explode.maptext = MAPTEXT("[dist]") else if (dist < light) - T.color = "blue" - T.maptext = MAPTEXT("Light") + explode.color = "blue" + explode.maptext = MAPTEXT("[dist]") else continue @@ -398,84 +399,82 @@ SUBSYSTEM_DEF(explosions) for(var/mob/living/L in viewers(flash_range, epicenter)) L.flash_act() - var/list/affected_turfs = GatherSpiralTurfs(max_range, epicenter) + var/list/affected_turfs = prepare_explosion_turfs(max_range, epicenter) var/reactionary = CONFIG_GET(flag/reactionary_explosions) - var/list/cached_exp_block - - if(reactionary) - cached_exp_block = CaculateExplosionBlock(affected_turfs) + // this list is setup in the form position -> block for that position + // we assert that turfs will be processed closed to farthest, so we can build this as we go along + // This is gonna be an array, index'd by turfs + var/list/cached_exp_block = list() //lists are guaranteed to contain at least 1 turf at this point + //we presuppose that we'll be iterating away from the epicenter + for(var/turf/explode as anything in affected_turfs) + var/our_x = explode.x + var/our_y = explode.y + var/dist = CHEAP_HYPOTENUSE(our_x, our_y, x0, y0) - for(var/TI in affected_turfs) - var/turf/T = TI - var/init_dist = cheap_hypotenuse(T.x, T.y, x0, y0) - var/dist = init_dist - + // Using this pattern, block will flow out from blocking turfs, essentially caching the recursion + // This is safe because if get_step_towards is ever anything but caridnally off, it'll do a diagonal move + // So we always sample from a "loop" closer + // It's kind of behaviorly unimpressive that that's a problem for the future if(reactionary) - var/turf/Trajectory = T - while(Trajectory != epicenter) - Trajectory = get_step_towards(Trajectory, epicenter) - dist += cached_exp_block[Trajectory] + if(explode == epicenter) + cached_exp_block[explode] = explode.explosive_resistance + else + var/our_block = cached_exp_block[get_step_towards(explode, epicenter)] + dist += our_block + cached_exp_block[explode] = our_block + explode.explosive_resistance - var/flame_dist = dist < flame_range - var/throw_dist = dist + var/severity = EXPLODE_NONE if(dist < devastation_range) - dist = EXPLODE_DEVASTATE + severity = EXPLODE_DEVASTATE else if(dist < heavy_impact_range) - dist = EXPLODE_HEAVY + severity = EXPLODE_HEAVY else if(dist < light_impact_range) - dist = EXPLODE_LIGHT - else - dist = EXPLODE_NONE + severity = EXPLODE_LIGHT - if(T == epicenter) // Ensures explosives detonating from bags trigger other explosives in that bag + if(explode == epicenter) // Ensures explosives detonating from bags trigger other explosives in that bag var/list/items = list() - for(var/I in T) - var/atom/A = I - if (length(A.contents) && !(A.flags_1 & PREVENT_CONTENTS_EXPLOSION_1)) //The atom/contents_explosion() proc returns null if the contents ex_acting has been handled by the atom, and TRUE if it hasn't. - items += A.get_all_contents(ignore_flag_1 = PREVENT_CONTENTS_EXPLOSION_1) - if(isliving(A)) - items -= A //Stops mobs from taking double damage from explosions originating from them/their turf, such as from projectiles - for(var/thing in items) - var/atom/movable/movable_thing = thing - if(QDELETED(movable_thing)) - continue - switch(dist) - if(EXPLODE_DEVASTATE) - SSexplosions.high_mov_atom += movable_thing - if(EXPLODE_HEAVY) - SSexplosions.med_mov_atom += movable_thing - if(EXPLODE_LIGHT) - SSexplosions.low_mov_atom += movable_thing - switch(dist) + for(var/atom/holder as anything in explode) + if (length(holder.contents) && !(holder.flags_1 & PREVENT_CONTENTS_EXPLOSION_1)) //The atom/contents_explosion() proc returns null if the contents ex_acting has been handled by the atom, and TRUE if it hasn't. + items += holder.get_all_contents(ignore_flag_1 = PREVENT_CONTENTS_EXPLOSION_1) + if(isliving(holder)) + items -= holder //Stops mobs from taking double damage from explosions originating from them/their turf, such as from projectiles + switch(severity) + if(EXPLODE_DEVASTATE) + SSexplosions.high_mov_atom += items + if(EXPLODE_HEAVY) + SSexplosions.med_mov_atom += items + if(EXPLODE_LIGHT) + SSexplosions.low_mov_atom += items + switch(severity) if(EXPLODE_DEVASTATE) - SSexplosions.highturf += T + SSexplosions.highturf += explode if(EXPLODE_HEAVY) - SSexplosions.medturf += T + SSexplosions.medturf += explode if(EXPLODE_LIGHT) - SSexplosions.lowturf += T + SSexplosions.lowturf += explode + //SKYRAT EDIT ADDITION - for(var/obj/machinery/light/iterating_light in T) + for(var/obj/machinery/light/iterating_light in explode) iterating_light.start_flickering() //SKYRAT EDIT END - if(flame_dist && prob(40) && !isspaceturf(T) && !T.density) - flameturf += T + + if(prob(40) && dist < flame_range && !isspaceturf(explode) && !explode.density) + flameturf += explode //--- THROW ITEMS AROUND --- - var/throw_dir = get_dir(epicenter,T) - var/throw_range = max_range-throw_dist - var/list/throwingturf = T.explosion_throw_details - if (throwingturf) - if (throwingturf[1] < throw_range) - throwingturf[1] = throw_range - throwingturf[2] = throw_dir + if (explode.explosion_throw_details) + var/list/throwingturf = explode.explosion_throw_details + if (throwingturf[1] < max_range - dist) + throwingturf[1] = max_range - dist + throwingturf[2] = get_dir(epicenter, explode) throwingturf[3] = max_range else - T.explosion_throw_details = list(throw_range, throw_dir, max_range) - throwturf += T + explode.explosion_throw_details = list(max_range - dist, get_dir(epicenter, explode), max_range) + throwturf += explode var/took = (REALTIMEOFDAY - started_at) / 10 @@ -593,68 +592,40 @@ SUBSYSTEM_DEF(explosions) #undef FREQ_UPPER #undef FREQ_LOWER -/datum/controller/subsystem/explosions/proc/GatherSpiralTurfs(range, turf/epicenter) +/// Returns a list of turfs in X range from the epicenter +/// Returns in a unique order, spiraling outwards +/// This is done to ensure our progressive cache of blast resistance is always valid +/// This is quite fast +/proc/prepare_explosion_turfs(range, turf/epicenter) var/list/outlist = list() - var/center = epicenter - var/dist = range - if(!dist) - outlist += center - return outlist + // Add in the center + outlist += epicenter - var/turf/t_center = get_turf(center) - if(!t_center) - return outlist + var/our_x = epicenter.x + var/our_y = epicenter.y + var/our_z = epicenter.z - var/list/L = outlist - var/turf/T - var/y - var/x - var/c_dist = 1 - L += t_center + var/max_x = world.maxx + var/max_y = world.maxy + for(var/i in 1 to range) + var/lowest_x = our_x - i + var/lowest_y = our_y - i + var/highest_x = our_x + i + var/highest_y = our_y + i + // top left to one before top right + if(highest_y <= max_y) + outlist += block(locate(max(lowest_x, 1), highest_y, our_z), locate(min(highest_x - 1, max_x), highest_y, our_z)) + // top right to one before bottom right + if(highest_x <= max_x) + outlist += block(locate(highest_x, min(highest_y, max_y), our_z), locate(highest_x, max(lowest_y + 1, 1), our_z)) + // bottom right to one before bottom left + if(lowest_y >= 1) + outlist += block(locate(min(highest_x, max_x), lowest_y, our_z), locate(max(lowest_x + 1, 1), lowest_y, our_z)) + // bottom left to one before top left + if(lowest_x >= 1) + outlist += block(locate(lowest_x, max(lowest_y, 1), our_z), locate(lowest_x, min(highest_y - 1, max_y), our_z)) - while( c_dist <= dist ) - y = t_center.y + c_dist - x = t_center.x - c_dist + 1 - for(x in x to t_center.x+c_dist) - T = locate(x,y,t_center.z) - if(T) - L += T - - y = t_center.y + c_dist - 1 - x = t_center.x + c_dist - for(y in t_center.y-c_dist to y) - T = locate(x,y,t_center.z) - if(T) - L += T - - y = t_center.y - c_dist - x = t_center.x + c_dist - 1 - for(x in t_center.x-c_dist to x) - T = locate(x,y,t_center.z) - if(T) - L += T - - y = t_center.y - c_dist + 1 - x = t_center.x - c_dist - for(y in y to t_center.y+c_dist) - T = locate(x,y,t_center.z) - if(T) - L += T - c_dist++ - . = L - -/datum/controller/subsystem/explosions/proc/CaculateExplosionBlock(list/affected_turfs) - . = list() - var/I - for(I in 1 to affected_turfs.len) // we cache the explosion block rating of every turf in the explosion area - var/turf/T = affected_turfs[I] - var/current_exp_block = T.density ? T.explosion_block : 0 - - for(var/obj/O in T) - var/the_block = O.explosion_block - current_exp_block += the_block == EXPLOSION_BLOCK_PROC ? O.GetExplosionBlock() : the_block - - .[T] = current_exp_block + return outlist /datum/controller/subsystem/explosions/fire(resumed = 0) if (!is_exploding()) @@ -743,15 +714,15 @@ SUBSYSTEM_DEF(explosions) for (var/thing in throw_turf) if (!thing) continue - var/turf/T = thing - var/list/L = T.explosion_throw_details - T.explosion_throw_details = null - if (length(L) != 3) + var/turf/explode = thing + var/list/details = explode.explosion_throw_details + explode.explosion_throw_details = null + if (length(details) != 3) continue - var/throw_range = L[1] - var/throw_dir = L[2] - var/max_range = L[3] - for(var/atom/movable/A in T) + var/throw_range = details[1] + var/throw_dir = details[2] + var/max_range = details[3] + for(var/atom/movable/A in explode) if(QDELETED(A)) continue if(!A.anchored && A.move_resist != INFINITY) diff --git a/code/controllers/subsystem/tutorials.dm b/code/controllers/subsystem/tutorials.dm new file mode 100644 index 00000000000..3df3df116cb --- /dev/null +++ b/code/controllers/subsystem/tutorials.dm @@ -0,0 +1,111 @@ +/// Namespace for housing code relating to giving contextual tutorials to users. +SUBSYSTEM_DEF(tutorials) + name = "Tutorials" + flags = SS_NO_FIRE + + /// A mapping of /datum/tutorial type to their manager singleton. + /// You probably shouldn't be indexing this directly. + var/list/datum/tutorial_manager/tutorial_managers = list() + + VAR_PRIVATE/list/datum/tutorial_manager/tutorial_managers_by_key = list() + +/datum/controller/subsystem/tutorials/Initialize() + init_tutorial_managers() + load_initial_tutorial_completions() + RegisterSignal(SSdcs, COMSIG_GLOB_CLIENT_CONNECT, PROC_REF(on_client_connect)) + + return SS_INIT_SUCCESS + +/// Will suggest the passed tutorial type to the user. +/// Will check that they should actually see it, e.g. hasn't completed it yet, etc. +/// Then, calls `/datum/tutorial/subtype/perform` with the extra arguments passed in. +/datum/controller/subsystem/tutorials/proc/suggest_tutorial(mob/user, datum/tutorial/tutorial_type, ...) + var/datum/tutorial_manager/tutorial_manager = tutorial_managers[tutorial_type] + if (isnull(tutorial_manager)) + CRASH("[tutorial_type] is not a valid tutorial type") + + if (!tutorial_manager.should_run(user)) + return + + INVOKE_ASYNC(tutorial_manager, TYPE_PROC_REF(/datum/tutorial_manager, try_perform), user, args.Copy(3)) + +/datum/controller/subsystem/tutorials/proc/init_tutorial_managers() + PRIVATE_PROC(TRUE) + + for (var/datum/tutorial/tutorial_type as anything in subtypesof(/datum/tutorial)) + var/datum/tutorial_manager/tutorial_manager = new /datum/tutorial_manager(tutorial_type) + tutorial_managers[tutorial_type] = tutorial_manager + tutorial_managers_by_key[tutorial_manager.get_key()] = tutorial_manager + +/datum/controller/subsystem/tutorials/proc/load_initial_tutorial_completions() + PRIVATE_PROC(TRUE) + set waitfor = FALSE // There's no reason to halt init for this + + var/list/ckey_options = list() + var/list/ckeys = list() + + for (var/client/client as anything in GLOB.clients) + var/ckey = client?.ckey + if (!ckey) + continue // client shenanigans, never trust + + var/index = ckeys.len + 1 + ckey_options += ":ckey[index]" + ckeys["ckey[index]"] = ckey + + if (ckey_options.len == 0) + return + + var/datum/db_query/select_all_query = SSdbcore.NewQuery( + "SELECT ckey, tutorial_key FROM [format_table_name("tutorial_completions")] WHERE ckey in ([ckey_options.Join(", ")])", + ckeys, + ) + + if (!select_all_query.Execute()) + qdel(select_all_query) + return + + while (select_all_query.NextRow()) + var/ckey = select_all_query.item[1] + var/tutorial_key = select_all_query.item[2] + + mark_ckey_completed_tutorial(ckey, tutorial_key) + + qdel(select_all_query) + +/datum/controller/subsystem/tutorials/proc/on_client_connect(datum/source, client/client) + SIGNAL_HANDLER + + var/ckey = client.ckey + if (!ckey) + return + + INVOKE_ASYNC(src, PROC_REF(check_completed_tutorials_for_ckey), ckey) + +/datum/controller/subsystem/tutorials/proc/check_completed_tutorials_for_ckey(ckey) + if (!SSdbcore.IsConnected()) + return + + var/datum/db_query/select_tutorials_for_ckey = SSdbcore.NewQuery( + "SELECT tutorial_key FROM [format_table_name("tutorial_completions")] WHERE ckey = :ckey", + list("ckey" = ckey) + ) + + if (!select_tutorials_for_ckey.Execute()) + return + + while (select_tutorials_for_ckey.NextRow()) + var/tutorial_key = select_tutorials_for_ckey.item[1] + + mark_ckey_completed_tutorial(ckey, tutorial_key) + + qdel(select_tutorials_for_ckey) + +/datum/controller/subsystem/tutorials/proc/mark_ckey_completed_tutorial(ckey, tutorial_key) + var/datum/tutorial_manager/tutorial_manager = tutorial_managers_by_key[tutorial_key] + if (isnull(tutorial_manager)) + // Not necessarily a bug. + // Could be an outdated server or a removed tutorial. + return + + tutorial_manager.mark_as_completed(ckey) diff --git a/code/datums/components/drift.dm b/code/datums/components/drift.dm index 58bcff8acdf..3a2d98dda9b 100644 --- a/code/datums/components/drift.dm +++ b/code/datums/components/drift.dm @@ -127,6 +127,7 @@ /datum/component/drift/proc/loop_death(datum/source) SIGNAL_HANDLER drifting_loop = null + UnregisterSignal(parent, COMSIG_MOVABLE_NEWTONIAN_MOVE) // We won't block a component from replacing us anymore /datum/component/drift/proc/handle_move(datum/source, old_loc) SIGNAL_HANDLER diff --git a/code/datums/components/twohanded.dm b/code/datums/components/twohanded.dm index 2c0de250a2a..3c438b8c085 100644 --- a/code/datums/components/twohanded.dm +++ b/code/datums/components/twohanded.dm @@ -173,7 +173,7 @@ return // blocked wield from item wielded = TRUE ADD_TRAIT(parent, TRAIT_WIELDED, REF(src)) - RegisterSignal(user, COMSIG_MOB_SWAP_HANDS, PROC_REF(on_swap_hands)) + RegisterSignal(user, COMSIG_MOB_SWAPPING_HANDS, PROC_REF(on_swapping_hands)) wield_callback?.Invoke(parent, user) // update item stats and name @@ -307,7 +307,7 @@ /** * on_swap_hands Triggers on swapping hands, blocks swap if the other hand is busy */ -/datum/component/two_handed/proc/on_swap_hands(mob/user, obj/item/held_item) +/datum/component/two_handed/proc/on_swapping_hands(mob/user, obj/item/held_item) SIGNAL_HANDLER if(!held_item) diff --git a/code/datums/elements/blocks_explosives.dm b/code/datums/elements/blocks_explosives.dm new file mode 100644 index 00000000000..1e867a81c1e --- /dev/null +++ b/code/datums/elements/blocks_explosives.dm @@ -0,0 +1,56 @@ +/// Apply this element to a movable atom when you want it to block explosions +/// It will mirror the blocking down to that movable's turf, keeping explosion work cheap +/datum/element/blocks_explosives + +/datum/element/blocks_explosives/Attach(datum/target) + if(!ismovable(target)) + return + . = ..() + ADD_TRAIT(target, TRAIT_BLOCKING_EXPLOSIVES, TRAIT_GENERIC) + var/atom/movable/moving_target = target + RegisterSignal(moving_target, COMSIG_MOVABLE_MOVED, PROC_REF(blocker_moved)) + RegisterSignal(moving_target, COMSIG_MOVABLE_EXPLOSION_BLOCK_CHANGED, PROC_REF(blocking_changed)) + moving_target.explosive_resistance = moving_target.explosion_block + + if(length(moving_target.locs) > 1) + for(var/atom/location as anything in moving_target.locs) + block_loc(location, moving_target.explosion_block) + else if(moving_target.loc) + block_loc(moving_target.loc, moving_target.explosion_block) + +/datum/element/blocks_explosives/Detach(datum/source) + . = ..() + REMOVE_TRAIT(source, TRAIT_BLOCKING_EXPLOSIVES, TRAIT_GENERIC) + +/// Call this when our blocking well, changes. we'll update our turf(s) with the details +/datum/element/blocks_explosives/proc/blocking_changed(atom/movable/target, old_block, new_block) + if(length(target.locs) > 1) + for(var/atom/location as anything in target.locs) + unblock_loc(location, old_block) + block_loc(location, new_block) + else if(target.loc) + unblock_loc(target.loc, old_block) + block_loc(target.loc, new_block) + +/// Applies a block amount to a turf. proc for convenince +/datum/element/blocks_explosives/proc/block_loc(atom/location, block_amount) + location.explosive_resistance += block_amount + +/// Removes a block amount from a turf. proc for convenince +/datum/element/blocks_explosives/proc/unblock_loc(atom/location, block_amount) + location.explosive_resistance -= block_amount + +/// Essentially just blocking_changed except we remove from the old loc, and add to the new one +/datum/element/blocks_explosives/proc/blocker_moved(atom/movable/target, atom/old_loc, dir, forced, list/old_locs) + if(length(old_locs) > 1) + for(var/atom/location as anything in old_locs) + unblock_loc(location, target.explosion_block) + else if(old_loc) + unblock_loc(old_loc, target.explosion_block) + + if(length(target.locs) > 1) + for(var/atom/location as anything in target.locs) + block_loc(location, target.explosion_block) + else if(target.loc) + block_loc(target.loc, target.explosion_block) + diff --git a/code/datums/storage/subtypes/rped.dm b/code/datums/storage/subtypes/rped.dm index 390cd17f976..5bbe29b59be 100644 --- a/code/datums/storage/subtypes/rped.dm +++ b/code/datums/storage/subtypes/rped.dm @@ -76,6 +76,9 @@ if(available - the_stack.amount < 0) return FALSE + else if(istype(to_insert, /obj/item/circuitboard/machine) || istype(to_insert, /obj/item/circuitboard/computer)) + return TRUE + //check normal insertion of other stock parts else if(!to_insert.get_part_rating()) return FALSE diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 6dfa790ddcf..56a03eafba1 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -39,8 +39,8 @@ ///HUD images that this atom can provide. var/list/hud_possible - ///Value used to increment ex_act() if reactionary_explosions is on - var/explosion_block = 0 + ///How much this atom resists explosions by, in the end + var/explosive_resistance = 0 /** * used to store the different colors on an atom @@ -1879,6 +1879,10 @@ pixel_y = pixel_y + base_pixel_y - . +// Not a valid operation, turfs and movables handle block differently +/atom/proc/set_explosion_block(explosion_block) + return + /** * Returns true if this atom has gravity for the passed in turf * diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 079150da73e..2cc2534336c 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -96,6 +96,10 @@ /// Whether a user will face atoms on entering them with a mouse. Despite being a mob variable, it is here for performances //SKYRAT EDIT ADDITION var/face_mouse = FALSE //SKYRAT EDIT ADDITION + /// Value used to increment ex_act() if reactionary_explosions is on + /// How much we as a source block explosions by + /// Will not automatically apply to the turf below you, you need to apply /datum/element/block_explosives in conjunction with this + var/explosion_block = 0 /mutable_appearance/emissive_blocker @@ -107,6 +111,11 @@ /atom/movable/Initialize(mapload) . = ..() +#ifdef UNIT_TESTS + if(explosion_block && !HAS_TRAIT(src, TRAIT_BLOCKING_EXPLOSIVES)) + stack_trace("[type] blocks explosives, but does not have the managing element applied") +#endif + switch(blocks_emissive) if(EMISSIVE_BLOCK_GENERIC) var/static/mutable_appearance/emissive_blocker/blocker = new() @@ -518,7 +527,7 @@ if(set_dir_on_move && dir != direction && !face_mouse) // SKYRAT EDIT CHANGE setDir(direction) - var/is_multi_tile_object = bound_width > 32 || bound_height > 32 + var/is_multi_tile_object = is_multi_tile_object(src) var/list/old_locs if(is_multi_tile_object && isturf(loc)) @@ -1135,6 +1144,13 @@ return TRUE +/atom/movable/set_explosion_block(explosion_block) + var/old_block = src.explosion_block + explosive_resistance -= old_block + src.explosion_block = explosion_block + explosive_resistance += explosion_block + SEND_SIGNAL(src, COMSIG_MOVABLE_EXPLOSION_BLOCK_CHANGED, old_block, explosion_block) + /atom/movable/proc/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) set waitfor = FALSE var/hitpush = TRUE diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index 1c6ecf7ba9c..27cd5175cfe 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -55,10 +55,10 @@ /datum/atom_hud/data/diagnostic /datum/atom_hud/data/diagnostic/basic - hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_CIRCUIT_HUD, DIAG_TRACK_HUD, DIAG_CAMERA_HUD, DIAG_AIRLOCK_HUD, DIAG_LAUNCHPAD_HUD) + hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, DIAG_CAMERA_HUD, DIAG_AIRLOCK_HUD, DIAG_LAUNCHPAD_HUD) /datum/atom_hud/data/diagnostic/advanced - hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_CIRCUIT_HUD, DIAG_TRACK_HUD, DIAG_CAMERA_HUD, DIAG_AIRLOCK_HUD, DIAG_LAUNCHPAD_HUD, DIAG_PATH_HUD) + hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, DIAG_CAMERA_HUD, DIAG_AIRLOCK_HUD, DIAG_LAUNCHPAD_HUD, DIAG_PATH_HUD) /datum/atom_hud/data/bot_path // This hud exists so the bot can see itself, that's all diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index d85c925096e..9a7da3b0026 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -101,6 +101,37 @@ amt += req_components[path] return amt +/** + * install the circuitboard in this frame + * * board - the machine circuitboard to install + * * user - the player + * * by_hand - is the player installing the board by hand or from the RPED. Used to decide how to transfer the board into the frame + */ +/obj/structure/frame/machine/proc/install_board(obj/item/circuitboard/machine/board, mob/user, by_hand) + if(!board.build_path) + to_chat(user, span_warning("This circuitboard seems to be broken.")) + return + if(!anchored && board.needs_anchored) + to_chat(user, span_warning("The frame needs to be secured first!")) + return + if(by_hand && !user.transferItemToLoc(board, src)) + return + else if(!board.forceMove(src)) + return + + playsound(src.loc, 'sound/items/deconstruct.ogg', 50, TRUE) + to_chat(user, span_notice("You add the circuit board to the frame.")) + circuit = board + icon_state = "box_2" + state = 3 + components = list() + //add circuit board as the first component to the list of components + //required for part_replacer to locate it while exchanging parts so it does not early return in /obj/machinery/proc/exchange_parts + components += circuit + req_components = board.req_components.Copy() + update_namelist(board.specific_parts) + return TRUE + /obj/structure/frame/machine/attackby(obj/item/P, mob/living/user, params) switch(state) if(1) @@ -152,27 +183,35 @@ set_anchored(!anchored) return + if(istype(P, /obj/item/storage/part_replacer) && P.contents.len) + var/obj/item/storage/part_replacer/replacer = P + // map of circuitboard names to the board + var/list/circuit_boards = list() + for(var/obj/item/circuitboard/machine/board in replacer.contents) + circuit_boards[board.name] = board + if(!length(circuit_boards)) + return + //if there is only one board directly install it else pick from list + var/obj/item/circuitboard/machine/target_board + if(circuit_boards.len == 1) + for(var/board_name in circuit_boards) + target_board = circuit_boards[board_name] + else + var/option = tgui_input_list(user, "Select Circuitboard To Install"," Available Boards", circuit_boards) + target_board = circuit_boards[option] + if(!target_board) + return + //install board + if(install_board(target_board, user, FALSE)) + user.Beam(src, icon_state = "rped_upgrade", time = 5) + replacer.play_rped_sound() + //attack this frame again with the rped so it can install stock parts since its now in state 3 + attackby(replacer, user, params) + return + if(istype(P, /obj/item/circuitboard/machine)) - var/obj/item/circuitboard/machine/board = P - if(!board.build_path) - to_chat(user, span_warning("This circuitboard seems to be broken.")) - return - if(!anchored && board.needs_anchored) - to_chat(user, span_warning("The frame needs to be secured first!")) - return - if(!user.transferItemToLoc(board, src)) - return - playsound(src.loc, 'sound/items/deconstruct.ogg', 50, TRUE) - to_chat(user, span_notice("You add the circuit board to the frame.")) - circuit = board - icon_state = "box_2" - state = 3 - components = list() - //add circuit board as the first component to the list of components - //required for part_replacer to locate it while exchanging parts so it does not early return in /obj/machinery/proc/exchange_parts - components += circuit - req_components = board.req_components.Copy() - update_namelist(board.specific_parts) + var/obj/item/circuitboard/machine/machine_board = P + install_board(machine_board, user, TRUE) return else if(istype(P, /obj/item/circuitboard)) @@ -251,7 +290,14 @@ qdel(src) return - if(istype(P, /obj/item/storage/part_replacer) && P.contents.len && get_req_components_amt()) + if(istype(P, /obj/item/storage/part_replacer)) + /** + * more efficient return so no if conditions after this are executed. + * Required when the rped is re attacking the frame after installing circuitboard so it returns quickly + */ + if(!P.contents.len || !get_req_components_amt()) + return + var/obj/item/storage/part_replacer/replacer = P var/list/added_components = list() var/list/part_list = replacer.get_sorted_parts() //parts sorted in order of tier diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 4388f48a303..7f1a0ab079d 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -55,6 +55,7 @@ acid = 70 /obj/machinery/door/Initialize(mapload) + AddElement(/datum/element/blocks_explosives) . = ..() set_init_door_layer() update_freelook_sight() @@ -70,7 +71,7 @@ //doors only block while dense though so we have to use the proc real_explosion_block = explosion_block - explosion_block = EXPLOSION_BLOCK_PROC + update_explosive_block() RegisterSignal(SSsecurity_level, COMSIG_SECURITY_LEVEL_CHANGED, PROC_REF(check_security_level)) var/static/list/loc_connections = list( @@ -501,9 +502,6 @@ //if it blows up a wall it should blow up a door return ..(severity ? min(EXPLODE_DEVASTATE, severity + 1) : EXPLODE_NONE, target) -/obj/machinery/door/GetExplosionBlock() - return density ? real_explosion_block : 0 - /obj/machinery/door/power_change() . = ..() if(. && !(machine_stat & NOPOWER)) @@ -519,4 +517,19 @@ INVOKE_ASYNC(src, PROC_REF(open)) +/obj/machinery/door/set_density(new_value) + . = ..() + update_explosive_block() + +/obj/machinery/door/proc/update_explosive_block() + set_explosion_block(real_explosion_block) + +// Kinda roundabout, essentially if we're dense, we respect real_explosion_block +// Otherwise, we block nothing +/obj/machinery/door/set_explosion_block(explosion_block) + real_explosion_block = explosion_block + if(density) + return ..() + return ..(0) + #undef DOOR_CLOSE_WAIT diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index b6747a6dcde..61368081a7b 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -678,6 +678,7 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e /obj/item/proc/pickup(mob/user) SHOULD_CALL_PARENT(TRUE) SEND_SIGNAL(src, COMSIG_ITEM_PICKUP, user) + SEND_SIGNAL(user, COMSIG_LIVING_PICKED_UP_ITEM, src) item_flags |= IN_INVENTORY /// called when "found" in pockets and storage items. Returns 1 if the search should end. diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index e7edfbf10f4..c32e46c5365 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -1054,7 +1054,7 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) if(istype(O)) var/x0 = O.x var/y0 = O.y - var/contender = cheap_hypotenuse(start.x, start.y, x0, y0) + var/contender = CHEAP_HYPOTENUSE(start.x, start.y, x0, y0) if(!winner) winner = O winning_dist = contender diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index 9ab500517fe..2ca038bceba 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -45,8 +45,8 @@ name = "retro identification card" desc = "A card used to provide ID and determine access across the station." icon_state = "card_grey" - worn_icon_state = "card_retro" inhand_icon_state = "card-id" + worn_icon_state = "nothing" lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi' slot_flags = ITEM_SLOT_ID @@ -897,7 +897,6 @@ name = "identification card" desc = "A card used to provide ID and determine access across the station. Has an integrated digital display and advanced microchips." icon_state = "card_grey" - worn_icon_state = "card_grey" wildcard_slots = WILDCARD_LIMIT_GREY flags_1 = UNPAINTABLE_1 @@ -1059,13 +1058,11 @@ name = "rainbow identification card" desc = "A rainbow card, promoting fun in a 'business proper' sense!" icon_state = "card_rainbow" - worn_icon_state = "card_rainbow" /obj/item/card/id/advanced/silver name = "silver identification card" desc = "A silver card which shows honour and dedication." icon_state = "card_silver" - worn_icon_state = "card_silver" inhand_icon_state = "silver_id" assigned_icon_state = "assigned_silver" wildcard_slots = WILDCARD_LIMIT_SILVER @@ -1084,7 +1081,6 @@ name = "gold identification card" desc = "A golden card which shows power and might." icon_state = "card_gold" - worn_icon_state = "card_gold" inhand_icon_state = "gold_id" assigned_icon_state = "assigned_gold" wildcard_slots = WILDCARD_LIMIT_GOLD @@ -1119,7 +1115,6 @@ name = "\improper CentCom ID" desc = "An ID straight from Central Command." icon_state = "card_centcom" - worn_icon_state = "card_centcom" assigned_icon_state = "assigned_centcom" registered_name = JOB_CENTCOM registered_age = null @@ -1165,7 +1160,6 @@ name = "black identification card" desc = "This card is telling you one thing and one thing alone. The person holding this card is an utter badass." icon_state = "card_black" - worn_icon_state = "card_black" assigned_icon_state = "assigned_syndicate" wildcard_slots = WILDCARD_LIMIT_GOLD @@ -1219,7 +1213,6 @@ name = "\improper Debug ID" desc = "A debug ID card. Has ALL the all access, you really shouldn't have this." icon_state = "card_centcom" - worn_icon_state = "card_centcom" assigned_icon_state = "assigned_centcom" trim = /datum/id_trim/admin wildcard_slots = WILDCARD_LIMIT_ADMIN @@ -1236,7 +1229,6 @@ name = "prisoner ID card" desc = "You are a number, you are not a free man." icon_state = "card_prisoner" - worn_icon_state = "card_prisoner" inhand_icon_state = "orange-id" lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi' @@ -1353,7 +1345,6 @@ registered_name = "Highlander" desc = "There can be only one!" icon_state = "card_black" - worn_icon_state = "card_black" assigned_icon_state = "assigned_syndicate" trim = /datum/id_trim/highlander wildcard_slots = WILDCARD_LIMIT_ADMIN @@ -1664,7 +1655,6 @@ /// A special variant of the classic chameleon ID card which accepts all access. /obj/item/card/id/advanced/chameleon/black icon_state = "card_black" - worn_icon_state = "card_black" assigned_icon_state = "assigned_syndicate" wildcard_slots = WILDCARD_LIMIT_GOLD diff --git a/code/game/objects/items/devices/scanners/gas_analyzer.dm b/code/game/objects/items/devices/scanners/gas_analyzer.dm index b0f013bedcf..8c46d31d2e3 100644 --- a/code/game/objects/items/devices/scanners/gas_analyzer.dm +++ b/code/game/objects/items/devices/scanners/gas_analyzer.dm @@ -204,6 +204,7 @@ desc = "A hand-held long-range environmental scanner which reports current gas levels." name = "long-range gas analyzer" icon_state = "analyzerranged" + worn_icon_state = "analyzer" w_class = WEIGHT_CLASS_NORMAL custom_materials = list(/datum/material/iron = 100, /datum/material/glass = 20, /datum/material/gold = 300, /datum/material/bluespace=200) grind_results = list(/datum/reagent/mercury = 5, /datum/reagent/iron = 5, /datum/reagent/silicon = 5) diff --git a/code/game/objects/items/emags.dm b/code/game/objects/items/emags.dm index 11a3952340b..9900eb17d73 100644 --- a/code/game/objects/items/emags.dm +++ b/code/game/objects/items/emags.dm @@ -145,7 +145,7 @@ desc = "An ominous card that contains the location of the station, and when applied to a communications console, \ the ability to long-distance contact the Syndicate fleet." icon_state = "battlecruisercaller" - worn_icon_state = "battlecruisercaller" + worn_icon_state = "emag" ///whether we have called the battlecruiser var/used = FALSE /// The battlecruiser team that the battlecruiser will get added to diff --git a/code/game/objects/items/puzzle_pieces.dm b/code/game/objects/items/puzzle_pieces.dm index c47d8cae8b8..c3e06b64d94 100644 --- a/code/game/objects/items/puzzle_pieces.dm +++ b/code/game/objects/items/puzzle_pieces.dm @@ -240,6 +240,7 @@ acid = 100 /obj/structure/light_puzzle/Initialize(mapload) + AddElement(/datum/element/blocks_explosives) . = ..() var/generated_board = -1 while(generated_board in banned_combinations) diff --git a/code/game/objects/items/religion.dm b/code/game/objects/items/religion.dm index 8d744fd0706..883f4734373 100644 --- a/code/game/objects/items/religion.dm +++ b/code/game/objects/items/religion.dm @@ -272,6 +272,7 @@ name = "Crusader's Hood" desc = "A brownish hood." icon = 'icons/obj/clothing/head/chaplain.dmi' + worn_icon = 'icons/mob/clothing/head/chaplain.dmi' icon_state = "crusader" inhand_icon_state = null w_class = WEIGHT_CLASS_NORMAL @@ -300,6 +301,7 @@ name = "Prophet's Hat" desc = "A religious-looking hat." icon_state = null + worn_icon = 'icons/mob/clothing/head/helmet.dmi' inhand_icon_state = null flags_1 = 0 armor_type = /datum/armor/crusader_prophet diff --git a/code/game/objects/items/storage/secure.dm b/code/game/objects/items/storage/secure.dm index 35c11a3685c..217d4f32571 100644 --- a/code/game/objects/items/storage/secure.dm +++ b/code/game/objects/items/storage/secure.dm @@ -208,7 +208,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/item/storage/secure/safe, 32) name = "captain's spare ID safe" desc = "In case of emergency, do not break glass. All Captains and Acting Captains are provided with codes to access this safe. \ It is made out of the same material as the station's Black Box and is designed to resist all conventional weaponry. \ -There appears to be a small amount of surface corrosion. It doesn't look like it could withstand much of an explosion." +There appears to be a small amount of surface corrosion. It doesn't look like it could withstand much of an explosion.\ +It remains quite flush against the wall, and there only seems to be enough room to fit something as slim as an ID card." can_hack_open = FALSE armor_type = /datum/armor/safe_caps_spare max_integrity = 300 @@ -227,6 +228,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/item/storage/secure/safe/caps_spare, 32) /obj/item/storage/secure/safe/caps_spare/Initialize(mapload) . = ..() + atom_storage.set_holdable(can_hold_list = list(/obj/item/card/id)) lock_code = SSid_access.spare_id_safe_code lock_set = TRUE atom_storage.locked = TRUE diff --git a/code/game/objects/items/storage/wallets.dm b/code/game/objects/items/storage/wallets.dm index fa16b4eadab..88e0d0c841d 100644 --- a/code/game/objects/items/storage/wallets.dm +++ b/code/game/objects/items/storage/wallets.dm @@ -154,6 +154,7 @@ /obj/item/storage/wallet/random icon_state = "random_wallet" // for mapping purposes + worn_icon_state = "wallet" /obj/item/storage/wallet/random/Initialize(mapload) . = ..() diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index ffca9ab56ee..a2a7da0c7fd 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -335,6 +335,7 @@ LINEN BINS name = "random bedsheet" desc = "If you're reading this description ingame, something has gone wrong! Honk!" bedsheet_type = BEDSHEET_ABSTRACT + item_flags = ABSTRACT var/static/list/bedsheet_list var/spawn_type = BEDSHEET_SINGLE @@ -360,6 +361,7 @@ LINEN BINS name = "random dorms bedsheet" desc = "If you're reading this description ingame, something has gone wrong! Honk!" bedsheet_type = BEDSHEET_DOUBLE + item_flags = ABSTRACT slot_flags = null /obj/item/bedsheet/dorms/Initialize(mapload) @@ -541,6 +543,7 @@ LINEN BINS /obj/item/bedsheet/dorms_double icon_state = "random_bedsheet" + item_flags = ABSTRACT bedsheet_type = BEDSHEET_ABSTRACT /obj/item/bedsheet/dorms_double/Initialize(mapload) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 5a9bc4cd1cf..99d55960787 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -40,6 +40,7 @@ acid = 100 /obj/structure/window/Initialize(mapload, direct) + AddElement(/datum/element/blocks_explosives) . = ..() if(direct) setDir(direct) @@ -55,9 +56,9 @@ setDir() AddElement(/datum/element/can_barricade) - //windows only block while reinforced and fulltile, so we'll use the proc - real_explosion_block = explosion_block - explosion_block = EXPLOSION_BLOCK_PROC + //windows only block while reinforced and fulltile + if(!reinf || !fulltile) + set_explosion_block(0) flags_1 |= ALLOW_DARK_PAINTS_1 RegisterSignal(src, COMSIG_OBJ_PAINTED, PROC_REF(on_painted)) @@ -424,9 +425,6 @@ return TRUE -/obj/structure/window/GetExplosionBlock() - return reinf && fulltile ? real_explosion_block : 0 - /obj/structure/window/spawner/east dir = EAST diff --git a/code/game/turfs/change_turf.dm b/code/game/turfs/change_turf.dm index cfc8902a717..30a651b7e05 100644 --- a/code/game/turfs/change_turf.dm +++ b/code/game/turfs/change_turf.dm @@ -83,6 +83,9 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( //SKYRAT EDIT END var/old_rcd_memory = rcd_memory var/old_always_lit = always_lit + var/old_explosion_throw_details = explosion_throw_details + // We get just the bits of explosive_resistance that aren't the turf + var/old_explosive_resistance = explosive_resistance - get_explosive_block() var/old_lattice_underneath = lattice_underneath var/old_bp = blueprint_data @@ -122,6 +125,8 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( new_turf.blueprint_data = old_bp new_turf.rcd_memory = old_rcd_memory + new_turf.explosion_throw_details = old_explosion_throw_details + new_turf.explosive_resistance += old_explosive_resistance lighting_corner_NE = old_lighting_corner_NE lighting_corner_SE = old_lighting_corner_SE diff --git a/code/game/turfs/closed/_closed.dm b/code/game/turfs/closed/_closed.dm index f70a3723f06..adbc6c7e8de 100644 --- a/code/game/turfs/closed/_closed.dm +++ b/code/game/turfs/closed/_closed.dm @@ -20,7 +20,7 @@ name = "wall" desc = "Effectively impervious to conventional methods of destruction." icon = 'icons/turf/walls.dmi' - explosion_block = 50 + explosive_resistance = 50 /turf/closed/indestructible/rust_heretic_act() return @@ -279,7 +279,7 @@ INITIALIZE_IMMEDIATE(/turf/closed/indestructible/splashscreen) desc = "A seemingly impenetrable wall." icon = 'icons/turf/walls.dmi' icon_state = "necro" - explosion_block = 50 + explosive_resistance = 50 baseturfs = /turf/closed/indestructible/necropolis /turf/closed/indestructible/necropolis/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) @@ -307,7 +307,7 @@ INITIALIZE_IMMEDIATE(/turf/closed/indestructible/splashscreen) smoothing_flags = SMOOTH_BITMASK smoothing_groups = SMOOTH_GROUP_CLOSED_TURFS + SMOOTH_GROUP_BOSS_WALLS canSmoothWith = SMOOTH_GROUP_BOSS_WALLS - explosion_block = 50 + explosive_resistance = 50 baseturfs = /turf/closed/indestructible/riveted/boss /turf/closed/indestructible/riveted/boss/see_through diff --git a/code/game/turfs/closed/wall/mineral_walls.dm b/code/game/turfs/closed/wall/mineral_walls.dm index 9bcd1b4061f..6e88d4640a3 100644 --- a/code/game/turfs/closed/wall/mineral_walls.dm +++ b/code/game/turfs/closed/wall/mineral_walls.dm @@ -15,7 +15,7 @@ base_icon_state = "gold_wall" sheet_type = /obj/item/stack/sheet/mineral/gold hardness = 65 //gold is soft - explosion_block = 0 //gold is a soft metal you dingus. + explosive_resistance = 0 //gold is a soft metal you dingus. smoothing_groups = SMOOTH_GROUP_GOLD_WALLS + SMOOTH_GROUP_WALLS + SMOOTH_GROUP_CLOSED_TURFS canSmoothWith = SMOOTH_GROUP_GOLD_WALLS custom_materials = list(/datum/material/gold = 4000) @@ -42,7 +42,7 @@ sheet_type = /obj/item/stack/sheet/mineral/diamond hardness = 5 //diamond is very hard slicing_duration = 200 //diamond wall takes twice as much time to slice - explosion_block = 3 + explosive_resistance = 3 smoothing_flags = SMOOTH_BITMASK smoothing_groups = SMOOTH_GROUP_DIAMOND_WALLS + SMOOTH_GROUP_WALLS + SMOOTH_GROUP_CLOSED_TURFS canSmoothWith = SMOOTH_GROUP_DIAMOND_WALLS @@ -72,7 +72,7 @@ base_icon_state = "sandstone_wall" sheet_type = /obj/item/stack/sheet/mineral/sandstone hardness = 50 //moh says this is apparently 6-7 on it's scale - explosion_block = 0 + explosive_resistance = 0 smoothing_flags = SMOOTH_BITMASK smoothing_groups = SMOOTH_GROUP_SANDSTONE_WALLS + SMOOTH_GROUP_WALLS + SMOOTH_GROUP_CLOSED_TURFS canSmoothWith = SMOOTH_GROUP_SANDSTONE_WALLS @@ -158,7 +158,7 @@ sheet_type = /obj/item/stack/sheet/mineral/wood hardness = 80 turf_flags = IS_SOLID - explosion_block = 0 + explosive_resistance = 0 smoothing_flags = SMOOTH_BITMASK smoothing_groups = SMOOTH_GROUP_WOOD_WALLS + SMOOTH_GROUP_WALLS + SMOOTH_GROUP_CLOSED_TURFS canSmoothWith = SMOOTH_GROUP_WOOD_WALLS @@ -215,7 +215,7 @@ base_icon_state = "snow_wall" smoothing_flags = SMOOTH_BITMASK hardness = 80 - explosion_block = 0 + explosive_resistance = 0 slicing_duration = 30 sheet_type = /obj/item/stack/sheet/mineral/snow canSmoothWith = null @@ -236,7 +236,7 @@ sheet_type = /obj/item/stack/sheet/mineral/abductor hardness = 10 slicing_duration = 200 //alien wall takes twice as much time to slice - explosion_block = 3 + explosive_resistance = 3 smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIAGONAL_CORNERS smoothing_groups = SMOOTH_GROUP_ABDUCTOR_WALLS + SMOOTH_GROUP_WALLS + SMOOTH_GROUP_CLOSED_TURFS canSmoothWith = SMOOTH_GROUP_ABDUCTOR_WALLS @@ -250,7 +250,7 @@ icon = 'icons/turf/walls/shuttle_wall.dmi' icon_state = "shuttle_wall-0" base_icon_state = "shuttle_wall" - explosion_block = 3 + explosive_resistance = 3 flags_1 = CAN_BE_DIRTY_1 flags_ricochet = RICOCHET_SHINY | RICOCHET_HARD sheet_type = /obj/item/stack/sheet/mineral/titanium @@ -314,7 +314,7 @@ icon = 'icons/turf/walls/plastitanium_wall.dmi' icon_state = "plastitanium_wall-0" base_icon_state = "plastitanium_wall" - explosion_block = 4 + explosive_resistance = 4 sheet_type = /obj/item/stack/sheet/mineral/plastitanium hardness = 25 //upgrade on titanium smoothing_flags = SMOOTH_BITMASK | SMOOTH_DIAGONAL_CORNERS diff --git a/code/game/turfs/closed/wall/reinf_walls.dm b/code/game/turfs/closed/wall/reinf_walls.dm index ead075e4a23..5168f337483 100644 --- a/code/game/turfs/closed/wall/reinf_walls.dm +++ b/code/game/turfs/closed/wall/reinf_walls.dm @@ -12,7 +12,7 @@ sheet_type = /obj/item/stack/sheet/plasteel sheet_amount = 1 girder_type = /obj/structure/girder/reinforced - explosion_block = 2 + explosive_resistance = 2 rad_insulation = RAD_HEAVY_INSULATION heat_capacity = 312500 //a little over 5 cm thick , 312500 for 1 m by 2.5 m by 0.25 m plasteel wall. also indicates the temperature at wich the wall will melt (currently only able to melt with H/E pipes) ///Dismantled state, related to deconstruction. @@ -233,7 +233,7 @@ icon = 'icons/turf/walls/plastitanium_wall.dmi' icon_state = "plastitanium_wall-0" base_icon_state = "plastitanium_wall" - explosion_block = 20 + explosive_resistance = 20 sheet_type = /obj/item/stack/sheet/mineral/plastitanium hardness = 25 //plastitanium turf_flags = IS_SOLID diff --git a/code/game/turfs/closed/walls.dm b/code/game/turfs/closed/walls.dm index bc33473d4d3..d251db6c357 100644 --- a/code/game/turfs/closed/walls.dm +++ b/code/game/turfs/closed/walls.dm @@ -6,7 +6,7 @@ icon = 'icons/turf/walls/wall.dmi' icon_state = "wall-0" base_icon_state = "wall" - explosion_block = 1 + explosive_resistance = 1 thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT heat_capacity = 62500 //a little over 5 cm thick , 62500 for 1 m by 2.5 m by 0.25 m iron wall. also indicates the temperature at wich the wall will melt (currently only able to melt with H/E pipes) @@ -266,7 +266,7 @@ return null /turf/closed/wall/acid_act(acidpwr, acid_volume) - if(explosion_block >= 2) + if(get_explosive_block() >= 2) acidpwr = min(acidpwr, 50) //we reduce the power so strong walls never get melted. return ..() diff --git a/code/game/turfs/open/space/transit.dm b/code/game/turfs/open/space/transit.dm index bf79168cec2..77d6ad3f1ea 100644 --- a/code/game/turfs/open/space/transit.dm +++ b/code/game/turfs/open/space/transit.dm @@ -5,7 +5,7 @@ dir = SOUTH baseturfs = /turf/open/space/transit flags_1 = NOJAUNT //This line goes out to every wizard that ever managed to escape the den. I'm sorry. - explosion_block = INFINITY + explosive_resistance = INFINITY /turf/open/space/transit/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) . = ..() diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 17f8adc4626..b541f33c146 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -92,6 +92,12 @@ GLOBAL_LIST_EMPTY(station_turfs) /// Sorry for the mess var/area/in_contents_of #endif + /// How much explosive resistance this turf is providing to itself + /// Defaults to -1, interpreted as initial(explosive_resistance) + /// This is an optimization to prevent turfs from needing to set these on init + /// This would either be expensive, or impossible to manage. Let's just avoid it yes? + /// Never directly access this, use get_explosive_block() instead + var/inherent_explosive_resistance = -1 /turf/vv_edit_var(var_name, new_value) var/static/list/banned_edits = list(NAMEOF_STATIC(src, x), NAMEOF_STATIC(src, y), NAMEOF_STATIC(src, z)) @@ -681,6 +687,26 @@ GLOBAL_LIST_EMPTY(station_turfs) continue movable_content.wash(clean_types) +/turf/set_density(new_value) + var/old_density = density + . = ..() + if(old_density == density) + return + + if(old_density) + explosive_resistance -= get_explosive_block() + if(density) + explosive_resistance += get_explosive_block() + +/// Wrapper around inherent_explosive_resistance +/// We assume this proc is cold, so we can move the "what is our block" into it +/turf/proc/get_explosive_block() + if(inherent_explosive_resistance != -1) + return inherent_explosive_resistance + if(explosive_resistance) + return initial(explosive_resistance) + return 0 + /** * Returns adjacent turfs to this turf that are reachable, in all cardinal directions * @@ -710,3 +736,9 @@ GLOBAL_LIST_EMPTY(station_turfs) /turf/proc/TakeTemperature(temp) temperature += temp + +// I'm sorry, this is the only way that both makes sense and is cheap +/turf/set_explosion_block(explosion_block) + explosive_resistance -= get_explosive_block() + inherent_explosive_resistance = explosion_block + explosive_resistance += get_explosive_block() diff --git a/code/modules/antagonists/blob/structures/core.dm b/code/modules/antagonists/blob/structures/core.dm index dd92eb6ff8b..e6f27779fbf 100644 --- a/code/modules/antagonists/blob/structures/core.dm +++ b/code/modules/antagonists/blob/structures/core.dm @@ -32,6 +32,7 @@ overmind.blobstrain.on_gain() update_appearance() AddComponent(/datum/component/stationloving, FALSE, TRUE) + AddElement(/datum/element/blocks_explosives) return ..() /obj/structure/blob/special/core/Destroy() diff --git a/code/modules/antagonists/blob/structures/shield.dm b/code/modules/antagonists/blob/structures/shield.dm index a274bb373cd..2d33d02ab91 100644 --- a/code/modules/antagonists/blob/structures/shield.dm +++ b/code/modules/antagonists/blob/structures/shield.dm @@ -16,6 +16,10 @@ fire = 90 acid = 90 +/obj/structure/blob/shield/Initialize(mapload, owner_overmind) + AddElement(/datum/element/blocks_explosives) + return ..() + /obj/structure/blob/shield/scannerreport() if(atmosblock) return "Will prevent the spread of atmospheric changes." diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm index fa0e58eb09f..375714eb6cf 100644 --- a/code/modules/antagonists/changeling/powers/mutations.dm +++ b/code/modules/antagonists/changeling/powers/mutations.dm @@ -476,6 +476,7 @@ name = "flesh mass" icon_state = "lingspacesuit_t" icon = 'icons/obj/clothing/suits/costume.dmi' + worn_icon = 'icons/mob/clothing/suits/costume.dmi' desc = "A huge, bulky mass of pressure and temperature-resistant organic tissue, evolved to facilitate space travel." item_flags = DROPDEL clothing_flags = STOPSPRESSUREDAMAGE //Not THICKMATERIAL because it's organic tissue, so if somebody tries to inject something into it, it still ends up in your blood. (also balance but muh fluff) diff --git a/code/modules/awaymissions/cordon.dm b/code/modules/awaymissions/cordon.dm index 9062aa05123..eaebbaca5a9 100644 --- a/code/modules/awaymissions/cordon.dm +++ b/code/modules/awaymissions/cordon.dm @@ -5,7 +5,7 @@ icon_state = "cordon" invisibility = INVISIBILITY_ABSTRACT mouse_opacity = MOUSE_OPACITY_TRANSPARENT - explosion_block = INFINITY + explosive_resistance = INFINITY rad_insulation = RAD_FULL_INSULATION opacity = TRUE density = TRUE diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index 3bdaac0aa5d..26a96193364 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -165,7 +165,6 @@ resistance_flags = NONE species_exception = list(/datum/species/golem) -// Lemom todo: and here /obj/item/clothing/suit/hazardvest/worn_overlays(mutable_appearance/standing, isinhands, icon_file) . = ..() if(!isinhands) diff --git a/code/modules/hydroponics/grown/rainbow_bunch.dm b/code/modules/hydroponics/grown/rainbow_bunch.dm index 91c6aae2cfa..14d0648b666 100644 --- a/code/modules/hydroponics/grown/rainbow_bunch.dm +++ b/code/modules/hydroponics/grown/rainbow_bunch.dm @@ -33,12 +33,13 @@ throw_range = 3 attack_verb_continuous = list("pompfs") attack_verb_simple = list("pompf") + greyscale_colors = "#000000" //only here for unit testing. overriden in initialize() greyscale_config = /datum/greyscale_config/flower_simple greyscale_config_worn = /datum/greyscale_config/flower_simple_worn /obj/item/food/grown/rainbow_flower/Initialize(mapload) . = ..() - if(greyscale_colors) + if(greyscale_colors != initial(greyscale_colors)) return var/flower_color = rand(1,8) diff --git a/code/modules/industrial_lift/tram_walls.dm b/code/modules/industrial_lift/tram_walls.dm index 85213b3364b..87188955533 100644 --- a/code/modules/industrial_lift/tram_walls.dm +++ b/code/modules/industrial_lift/tram_walls.dm @@ -26,6 +26,7 @@ var/slicing_duration = 100 /obj/structure/tramwall/Initialize(mapload) + AddElement(/datum/element/blocks_explosives) . = ..() var/obj/item/stack/initialized_mineral = new mineral set_custom_materials(initialized_mineral.mats_per_unit, mineral_amount) diff --git a/code/modules/instruments/piano_synth.dm b/code/modules/instruments/piano_synth.dm index 630bf8819dd..416d164cac0 100644 --- a/code/modules/instruments/piano_synth.dm +++ b/code/modules/instruments/piano_synth.dm @@ -56,6 +56,7 @@ name = "\improper Nanotrasen space pods" desc = "Flex your money, AND ignore what everyone else says, all at once!" icon_state = "spacepods" + worn_icon = 'icons/mob/clothing/ears.dmi' inhand_icon_state = null slot_flags = ITEM_SLOT_EARS strip_delay = 100 //air pods don't fall out diff --git a/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm b/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm index c834b7479cb..be2201eaf19 100644 --- a/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm +++ b/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm @@ -251,7 +251,7 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999)) icon_state = "hotelwall" smoothing_groups = SMOOTH_GROUP_CLOSED_TURFS + SMOOTH_GROUP_HOTEL_WALLS canSmoothWith = SMOOTH_GROUP_HOTEL_WALLS - explosion_block = INFINITY + explosive_resistance = INFINITY /turf/open/indestructible/hotelwood desc = "Stylish dark wood with extra reinforcement. Secured firmly to the floor to prevent tampering." @@ -271,7 +271,7 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999)) base_icon_state = "bluespace" baseturfs = /turf/open/space/bluespace flags_1 = NOJAUNT - explosion_block = INFINITY + explosive_resistance = INFINITY var/obj/item/hilbertshotel/parentSphere /turf/open/space/bluespace/Initialize(mapload) @@ -290,7 +290,7 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999)) /turf/closed/indestructible/hoteldoor name = "Hotel Door" icon_state = "hoteldoor" - explosion_block = INFINITY + explosive_resistance = INFINITY var/obj/item/hilbertshotel/parentSphere /turf/closed/indestructible/hoteldoor/proc/promptExit(mob/living/user) diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index c493ed5f35e..1549ae2acb0 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -280,9 +280,15 @@ * If the item can be dropped, it will be forceMove()'d to the ground and the turf's Entered() will be called. */ /mob/proc/dropItemToGround(obj/item/I, force = FALSE, silent = FALSE, invdrop = TRUE) + if (isnull(I)) + return TRUE + + SEND_SIGNAL(src, COMSIG_MOB_DROPPING_ITEM) . = doUnEquip(I, force, drop_location(), FALSE, invdrop = invdrop, silent = silent) + if(!. || !I) //ensure the item exists and that it was dropped properly. return + if(!(I.item_flags & NO_PIXEL_RANDOM_DROP)) I.pixel_x = I.base_pixel_x + rand(-6, 6) I.pixel_y = I.base_pixel_y + rand(-6, 6) diff --git a/code/modules/mob/living/basic/vermin/mouse.dm b/code/modules/mob/living/basic/vermin/mouse.dm index a1f4f3a38c5..93f2a31542c 100644 --- a/code/modules/mob/living/basic/vermin/mouse.dm +++ b/code/modules/mob/living/basic/vermin/mouse.dm @@ -86,7 +86,7 @@ /// Kills the rat and changes its icon state to be splatted (bloody). /mob/living/basic/mouse/proc/splat() icon_dead = "mouse_[body_color]_splat" - adjust_health(-maxHealth) + adjust_health(maxHealth) // On revival, re-add the mouse to the ratcap, or block it if we're at it /mob/living/basic/mouse/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 6b23ef61ccd..e022be2d07f 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -30,7 +30,7 @@ QDEL_NULL(dna) GLOB.carbon_list -= src -/mob/living/carbon/swap_hand(held_index) +/mob/living/carbon/perform_hand_swap(held_index) . = ..() if(!.) return diff --git a/code/modules/mob/living/carbon/human/human_update_icons.dm b/code/modules/mob/living/carbon/human/human_update_icons.dm index 70eef5c23cc..12de610c6e3 100644 --- a/code/modules/mob/living/carbon/human/human_update_icons.dm +++ b/code/modules/mob/living/carbon/human/human_update_icons.dm @@ -155,7 +155,7 @@ There are several things that need to be remembered: var/icon_file if(!icon_exists(icon_file, RESOLVE_ICON_STATE(worn_item))) - icon_file = 'icons/mob/simple/mob.dmi' + icon_file = 'icons/mob/clothing/id.dmi' id_overlay = wear_id.build_worn_icon(default_layer = ID_LAYER, default_icon_file = icon_file) diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm index f972cb0d885..e86ca257f12 100644 --- a/code/modules/mob/living/silicon/robot/inventory.dm +++ b/code/modules/mob/living/silicon/robot/inventory.dm @@ -397,7 +397,7 @@ if(slot_num > 4) // not >3 otherwise cycling with just one item on module 3 wouldn't work slot_num = 1 //Wrap around. -/mob/living/silicon/robot/swap_hand() +/mob/living/silicon/robot/perform_hand_swap() cycle_modules() /mob/living/silicon/robot/can_hold_items(obj/item/I) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 3f206619222..eb1cf2c78a6 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -616,7 +616,7 @@ else mode() -/mob/living/simple_animal/swap_hand(hand_index) +/mob/living/simple_animal/perform_hand_swap(hand_index) . = ..() if(!.) return diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 1c39a8f1f14..24f2caa7b63 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -885,11 +885,23 @@ return data -/mob/proc/swap_hand() +/mob/proc/swap_hand(held_index) + SHOULD_NOT_OVERRIDE(TRUE) // Override perform_hand_swap instead + var/obj/item/held_item = get_active_held_item() - if(SEND_SIGNAL(src, COMSIG_MOB_SWAP_HANDS, held_item) & COMPONENT_BLOCK_SWAP) + if(SEND_SIGNAL(src, COMSIG_MOB_SWAPPING_HANDS, held_item) & COMPONENT_BLOCK_SWAP) to_chat(src, span_warning("Your other hand is too busy holding [held_item].")) return FALSE + + var/result = perform_hand_swap(held_index) + if (result) + SEND_SIGNAL(src, COMSIG_MOB_SWAP_HANDS) + + return result + +/// Performs the actual ritual of swapping hands, such as setting the held index variables +/mob/proc/perform_hand_swap(held_index) + PROTECTED_PROC(TRUE) return TRUE /mob/proc/activate_hand(selhand) diff --git a/code/modules/mob_spawn/corpses/mining_corpses.dm b/code/modules/mob_spawn/corpses/mining_corpses.dm index 23a3117186d..c6e7525a92c 100644 --- a/code/modules/mob_spawn/corpses/mining_corpses.dm +++ b/code/modules/mob_spawn/corpses/mining_corpses.dm @@ -31,13 +31,13 @@ var/corpse_theme = pick_weight(list( "Miner" = 66, "Ashwalker" = 10, - "Golem" = 10, "Clown" = 10, + "Golem" = 10, pick(list( - "Shadow", + "Cultist", "Dame", "Operative", - "Cultist", + "Shadow", )) = 4, )) switch(corpse_theme) @@ -47,16 +47,16 @@ outfit = /datum/outfit/consumed_ashwalker if("Clown") outfit = /datum/outfit/consumed_clown - if("Golem") - outfit = /datum/outfit/consumed_golem + if("Cultist") + outfit = /datum/outfit/consumed_cultist if("Dame") outfit = /datum/outfit/consumed_dame + if("Golem") + outfit = /datum/outfit/consumed_golem if("Operative") outfit = /datum/outfit/syndicatecommandocorpse if("Shadow") outfit = /datum/outfit/consumed_shadowperson - if("Cultist") - outfit = /datum/outfit/consumed_cultist . = ..() /datum/outfit/consumed_miner @@ -70,31 +70,56 @@ if(visualsOnly) regular_uniform = TRUE //assume human else - var/new_species_type = pick_weight(list(/datum/species/human = 70, /datum/species/lizard = 26, /datum/species/fly = 2, /datum/species/plasmaman = 2)) + var/new_species_type = pick_weight(list( + /datum/species/human = 70, + /datum/species/lizard = 26, + /datum/species/fly = 2, + /datum/species/plasmaman = 2, + )) miner.set_species(new_species_type) if(new_species_type != /datum/species/plasmaman) regular_uniform = TRUE else uniform = /obj/item/clothing/under/plasmaman - head = /obj/item/clothing/head/helmet/space/plasmaman belt = /obj/item/tank/internals/plasmaman/belt + head = /obj/item/clothing/head/helmet/space/plasmaman if(new_species_type == /datum/species/lizard) shoes = null //digitigrade says no if(regular_uniform) uniform = /obj/item/clothing/under/rank/cargo/miner/lavaland if(prob(4)) - belt = pick_weight(list(/obj/item/storage/belt/mining = 2, /obj/item/storage/belt/mining/alt = 2)) + belt = pick_weight(list( + /obj/item/storage/belt/mining = 2, + /obj/item/storage/belt/mining/alt = 2, + )) else if(prob(10)) - belt = pick_weight(list(/obj/item/pickaxe = 8, /obj/item/pickaxe/mini = 4, /obj/item/pickaxe/silver = 2, /obj/item/pickaxe/diamond = 1)) + belt = pick_weight(list( + /obj/item/pickaxe = 8, + /obj/item/pickaxe/mini = 4, + /obj/item/pickaxe/silver = 2, + /obj/item/pickaxe/diamond = 1, + )) else belt = /obj/item/tank/internals/emergency_oxygen/engi if(prob(20)) - suit = pick_weight(list(/obj/item/clothing/suit/hooded/explorer = 18, /obj/item/clothing/suit/hooded/cloak/goliath = 2)) + suit = pick_weight(list( + /obj/item/clothing/suit/hooded/explorer = 18, + /obj/item/clothing/suit/hooded/cloak/goliath = 2, + )) if(prob(30)) - r_pocket = pick_weight(list(/obj/item/stack/marker_beacon = 20, /obj/item/stack/spacecash/c1000 = 7, /obj/item/reagent_containers/hypospray/medipen/survival = 2, /obj/item/borg/upgrade/modkit/damage = 1 )) + r_pocket = pick_weight(list( + /obj/item/stack/marker_beacon = 20, + /obj/item/stack/spacecash/c1000 = 7, + /obj/item/reagent_containers/hypospray/medipen/survival = 2, + /obj/item/borg/upgrade/modkit/damage = 1, + )) if(prob(10)) - l_pocket = pick_weight(list(/obj/item/stack/spacecash/c1000 = 7, /obj/item/reagent_containers/hypospray/medipen/survival = 2, /obj/item/borg/upgrade/modkit/cooldown = 1 )) + l_pocket = pick_weight(list( + /obj/item/stack/spacecash/c1000 = 7, + /obj/item/reagent_containers/hypospray/medipen/survival = 2, + /obj/item/borg/upgrade/modkit/cooldown = 1, + )) /datum/outfit/consumed_ashwalker name = "Legion-Consumed Ashwalker" @@ -106,17 +131,20 @@ if(prob(95)) head = /obj/item/clothing/head/helmet/gladiator else - head = /obj/item/clothing/head/helmet/skull suit = /obj/item/clothing/suit/armor/bone gloves = /obj/item/clothing/gloves/bracer + head = /obj/item/clothing/head/helmet/skull if(prob(5)) - back = pick_weight(list(/obj/item/spear/bonespear = 3, /obj/item/fireaxe/boneaxe = 2)) + back = pick_weight(list( + /obj/item/spear/bonespear = 3, + /obj/item/fireaxe/boneaxe = 2, + )) if(prob(10)) belt = /obj/item/storage/belt/mining/primitive - if(prob(30)) - r_pocket = /obj/item/knife/combat/bone if(prob(30)) l_pocket = /obj/item/knife/combat/bone + if(prob(30)) + r_pocket = /obj/item/knife/combat/bone //takes a lot from the clown job, notably NO PDA and different backpack loot + pocket goodies /datum/outfit/consumed_clown @@ -140,7 +168,14 @@ if(!visualsOnly) clown.fully_replace_character_name(clown.name, pick(GLOB.clown_names)) if(prob(70)) - var/backpack_loot = pick(list(/obj/item/stamp/clown = 1, /obj/item/reagent_containers/spray/waterflower = 1, /obj/item/food/grown/banana = 1, /obj/item/megaphone/clown = 1, /obj/item/reagent_containers/cup/soda_cans/canned_laughter = 1, /obj/item/pneumatic_cannon/pie)) + var/backpack_loot = pick(list( + /obj/item/food/grown/banana = 1, + /obj/item/megaphone/clown = 1, + /obj/item/pneumatic_cannon/pie, + /obj/item/reagent_containers/cup/soda_cans/canned_laughter = 1, + /obj/item/reagent_containers/spray/waterflower = 1, + /obj/item/stamp/clown = 1, + )) if(backpack_loot == /obj/item/pneumatic_cannon/pie) drop_a_pie_cannon = TRUE else @@ -148,7 +183,10 @@ if(prob(30)) backpack_contents += list(/obj/item/stack/sheet/mineral/bananium = pick_weight(list( 1 = 3, 2 = 2, 3 = 1))) if(prob(10)) - l_pocket = pick_weight(list(/obj/item/bikehorn/golden = 3, /obj/item/bikehorn/airhorn = 1)) + l_pocket = pick_weight(list( + /obj/item/bikehorn/golden = 3, + /obj/item/bikehorn/airhorn = 1, + )) if(prob(10)) r_pocket = /obj/item/implanter/sad_trombone @@ -163,26 +201,46 @@ /datum/outfit/consumed_golem/pre_equip(mob/living/carbon/human/golem, visualsOnly = FALSE) if(!visualsOnly) - golem.set_species(pick(/datum/species/golem/adamantine, /datum/species/golem/plasma, /datum/species/golem/diamond, /datum/species/golem/gold, /datum/species/golem/silver, /datum/species/golem/plasteel, /datum/species/golem/titanium, /datum/species/golem/plastitanium)) + golem.set_species(pick( + /datum/species/golem/adamantine, + /datum/species/golem/diamond, + /datum/species/golem/gold, + /datum/species/golem/plasma, + /datum/species/golem/plasteel, + /datum/species/golem/plastitanium, + /datum/species/golem/silver, + /datum/species/golem/titanium, + )) if(prob(30)) - glasses = pick_weight(list(/obj/item/clothing/glasses/meson = 2, /obj/item/clothing/glasses/hud/health = 2, /obj/item/clothing/glasses/hud/diagnostic =2, /obj/item/clothing/glasses/science = 2, /obj/item/clothing/glasses/welding = 2, /obj/item/clothing/glasses/night = 1)) + glasses = pick_weight(list( + /obj/item/clothing/glasses/hud/diagnostic = 2, + /obj/item/clothing/glasses/hud/health = 2, + /obj/item/clothing/glasses/meson = 2, + /obj/item/clothing/glasses/science = 2, + /obj/item/clothing/glasses/welding = 2, + /obj/item/clothing/glasses/night = 1, + )) if(prob(10) && !visualsOnly) //visualsonly = not a golem = can't put things in the belt slot without a jumpsuit - belt = pick(list(/obj/item/storage/belt/mining/vendor, /obj/item/storage/belt/utility/full)) + belt = pick(list( + /obj/item/crowbar/power, + /obj/item/screwdriver/power, + /obj/item/storage/belt/mining/vendor, + /obj/item/storage/belt/utility/full, + /obj/item/weldingtool/experimental, + )) if(prob(50)) neck = /obj/item/bedsheet/rd/royal_cape - if(prob(10) && !visualsOnly) //visualsonly = not a golem = can't put things in the pockets without a jumpsuit - l_pocket = pick(list(/obj/item/crowbar/power, /obj/item/screwdriver/power, /obj/item/weldingtool/electric)) // SKYRAT EDIT CHANGE FROM /obj/item/weldingtool/experimental //this is so pointlessly gendered but whatever bro i'm here to refactor not judge /datum/outfit/consumed_dame name = "Legion-Consumed Dame" uniform = /obj/item/clothing/under/costume/maid - gloves = /obj/item/clothing/gloves/color/white - shoes = /obj/item/clothing/shoes/laceup - head = /obj/item/clothing/head/helmet/knight suit = /obj/item/clothing/suit/armor/riot/knight - r_pocket = /obj/item/tank/internals/emergency_oxygen + gloves = /obj/item/clothing/gloves/color/white + head = /obj/item/clothing/head/helmet/knight mask = /obj/item/clothing/mask/breath + shoes = /obj/item/clothing/shoes/laceup + r_pocket = /obj/item/tank/internals/emergency_oxygen /datum/outfit/consumed_dame/pre_equip(mob/living/carbon/human/dame, visualsOnly = FALSE) if(!visualsOnly) @@ -197,14 +255,15 @@ /datum/outfit/consumed_shadowperson name = "Legion-Consumed Shadowperson" - r_pocket = /obj/item/reagent_containers/pill/shadowtoxin - accessory = /obj/item/clothing/accessory/medal/plasma/nobel_science uniform = /obj/item/clothing/under/color/black - shoes = /obj/item/clothing/shoes/sneakers/black suit = /obj/item/clothing/suit/toggle/labcoat - glasses = /obj/item/clothing/glasses/blindfold back = /obj/item/tank/internals/oxygen + glasses = /obj/item/clothing/glasses/blindfold mask = /obj/item/clothing/mask/breath + shoes = /obj/item/clothing/shoes/sneakers/black + r_pocket = /obj/item/reagent_containers/pill/shadowtoxin + + accessory = /obj/item/clothing/accessory/medal/plasma/nobel_science /datum/outfit/consumed_shadowperson/pre_equip(mob/living/carbon/human/shadowperson, visualsOnly = FALSE) if(visualsOnly) @@ -217,5 +276,10 @@ suit = /obj/item/clothing/suit/hooded/cultrobes suit_store = /obj/item/tome back = /obj/item/storage/backpack/cultpack + backpack_contents = list( + /obj/item/cult_shift = 1, + /obj/item/flashlight/flare/culttorch = 1, + /obj/item/reagent_containers/cup/beaker/unholywater = 1, + /obj/item/stack/sheet/runed_metal = 15, + ) r_pocket = /obj/item/clothing/glasses/hud/health/night/cultblind - backpack_contents = list(/obj/item/reagent_containers/cup/beaker/unholywater = 1, /obj/item/cult_shift = 1, /obj/item/flashlight/flare/culttorch = 1, /obj/item/stack/sheet/runed_metal = 15) diff --git a/code/modules/projectiles/guns/special/blastcannon.dm b/code/modules/projectiles/guns/special/blastcannon.dm index a255a2dfabf..6fda91369a4 100644 --- a/code/modules/projectiles/guns/special/blastcannon.dm +++ b/code/modules/projectiles/guns/special/blastcannon.dm @@ -322,13 +322,7 @@ var/decrement = 1 var/atom/location = loc if (reactionary) - if(location.density || !isturf(location)) - decrement += location.explosion_block - for(var/obj/thing in location) - if (thing == src) - continue - var/the_block = thing.explosion_block - decrement += the_block == EXPLOSION_BLOCK_PROC ? thing.GetExplosionBlock() : the_block + decrement += location.explosive_resistance range = max(range - decrement + 1, 0) // Already decremented by 1 in the parent. Exists so that if we pass through something with negative block it extends the range. heavy_ex_range = max(heavy_ex_range - decrement, 0) diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index 92cbb1226b7..061ff925ab4 100644 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -260,7 +260,7 @@ desc = "Used to set the destination of properly wrapped packages." icon = 'icons/obj/device.dmi' icon_state = "cargo tagger" - worn_icon_state = "cargo tagger" + worn_icon_state = "cargotagger" var/currTag = 0 //Destinations are stored in code\globalvars\lists\flavor_misc.dm var/locked_destination = FALSE //if true, users can't open the destination tag window to prevent changing the tagger's current destination w_class = WEIGHT_CLASS_TINY diff --git a/code/modules/research/stock_parts.dm b/code/modules/research/stock_parts.dm index 69b46b413a6..3867675ee8a 100644 --- a/code/modules/research/stock_parts.dm +++ b/code/modules/research/stock_parts.dm @@ -18,6 +18,12 @@ If you create T5+ please take a pass at mech_fabricator.dm. The parts being good . = ..() create_storage(type = /datum/storage/rped) +// check to see if this rped have atleast one circuitboard +/obj/item/storage/part_replacer/proc/has_an_circuitboard() + for(var/obj/item/circuitboard/machine/board in contents) + return TRUE + return FALSE + /obj/item/storage/part_replacer/pre_attack(obj/attacked_object, mob/living/user, params) if(!ismachinery(attacked_object) && !istype(attacked_object, /obj/structure/frame/machine)) return ..() @@ -37,13 +43,12 @@ If you create T5+ please take a pass at mech_fabricator.dm. The parts being good return TRUE var/obj/structure/frame/machine/attacked_frame = attacked_object - - if(!attacked_frame.components) - return ..() - + // no point attacking the frame with the rped if the frame doesn't have wiring or it doesn't have components & rped has no circuitboard to offer as an component. + if(attacked_frame.state == 1 || (!attacked_frame.components && !has_an_circuitboard())) + return TRUE + attacked_frame.attackby(src, user) if(works_from_distance) user.Beam(attacked_frame, icon_state = "rped_upgrade", time = 5) - attacked_frame.attackby(src, user) return TRUE /obj/item/storage/part_replacer/afterattack(obj/attacked_object, mob/living/user, adjacent, params) @@ -65,13 +70,12 @@ If you create T5+ please take a pass at mech_fabricator.dm. The parts being good return var/obj/structure/frame/machine/attacked_frame = attacked_object - - if(!attacked_frame.components) - return ..() - + // no point attacking the frame with the rped if the frame doesn't have wiring or it doesn't have components & rped has no circuitboard to offer as an component. + if(attacked_frame.state == 1 || (!attacked_frame.components && !has_an_circuitboard())) + return + attacked_frame.attackby(src, user) if(works_from_distance) user.Beam(attacked_frame, icon_state = "rped_upgrade", time = 5) - attacked_frame.attackby(src, user) /obj/item/storage/part_replacer/proc/play_rped_sound() //Plays the sound for RPED exhanging or installing parts. @@ -220,6 +224,9 @@ If you create T5+ please take a pass at mech_fabricator.dm. The parts being good var/list/part_list = list() //Assemble a list of current parts, then sort them by their rating! for(var/obj/item/component_part in contents) + //No need to put circuit boards in this list + if(istype(component_part, /obj/item/circuitboard)) + continue part_list += component_part //Sort the parts. This ensures that higher tier items are applied first. part_list = sortTim(part_list, GLOBAL_PROC_REF(cmp_rped_sort)) diff --git a/code/modules/tutorials/_tutorial.dm b/code/modules/tutorials/_tutorial.dm new file mode 100644 index 00000000000..69f63738955 --- /dev/null +++ b/code/modules/tutorials/_tutorial.dm @@ -0,0 +1,257 @@ +/// The base for a contextual tutorial. +/// In order to give a tutorial to someone, use `SStutorials.suggest_tutorial(user, /datum/tutorial/subtype)` +/datum/tutorial + /// If set, any account who started playing before this date will not be given this tutorial. + /// Date is in YYYY-MM-DD format. + var/grandfather_date + + /// The mob we are giving the tutorial to + VAR_PROTECTED/mob/user + + VAR_PRIVATE/atom/movable/screen/tutorial_instruction/instruction_screen + +/datum/tutorial/New(mob/user) + src.user = user + + RegisterSignal(user, COMSIG_PARENT_QDELETING, PROC_REF(destroy_self)) + RegisterSignal(user.client, COMSIG_PARENT_QDELETING, PROC_REF(destroy_self)) + +/datum/tutorial/Destroy(force, ...) + user.client?.screen -= instruction_screen + QDEL_NULL(instruction_screen) + + user = null + + return ..() + +/// Gets the [`/datum/tutorial_manager`] that owns this tutorial. +/datum/tutorial/proc/manager() + RETURN_TYPE(/datum/tutorial_manager) + return SStutorials.tutorial_managers[type] + +/// The actual steps of the tutorial. Is given any excess arguments of suggest_tutorial. +/// Must be overridden. +/datum/tutorial/proc/perform() + SHOULD_CALL_PARENT(FALSE) + CRASH("[type] does not override perform()") + +/// Returns TRUE/FALSE if this tutorial should be given. +/// If FALSE, does not mean it won't come back later. +/datum/tutorial/proc/should_perform() + SHOULD_CALL_PARENT(FALSE) + return TRUE + +/// Called by the tutorial when the user has successfully completed it. +/// Will mark it as completed in the datbaase and kick off destruction of the tutorial. +/datum/tutorial/proc/complete() + SIGNAL_HANDLER + PROTECTED_PROC(TRUE) + SHOULD_NOT_OVERRIDE(TRUE) + + manager().complete(user) + perform_base_completion_effects() + +/// As opposed to `complete()`, this merely hides the tutorial. +/// This should be used when the user doesn't need the tutorial anymore, but didn't +/// actually properly finish it. +/datum/tutorial/proc/dismiss() + SIGNAL_HANDLER + PROTECTED_PROC(TRUE) + SHOULD_NOT_OVERRIDE(TRUE) + + manager().dismiss(user) + perform_base_completion_effects() + +#define INSTRUCTION_SCREEN_DELAY (1 SECONDS) + +/datum/tutorial/proc/perform_base_completion_effects() + SHOULD_NOT_OVERRIDE(TRUE) + + var/delay = perform_completion_effects_with_delay() + + if (!isnull(instruction_screen)) + animate(instruction_screen, time = INSTRUCTION_SCREEN_DELAY, alpha = 0, easing = SINE_EASING) + delay += INSTRUCTION_SCREEN_DELAY + + QDEL_IN(src, delay) + +/// Called when the tutorial is being hidden, but before it is deleted. +/// You should unregister signals and fade out any of your creations in here. +/// Returns how long extra to delay the deletion. +/datum/tutorial/proc/perform_completion_effects_with_delay() + SHOULD_CALL_PARENT(FALSE) + PROTECTED_PROC(TRUE) + + return 0 + +#undef INSTRUCTION_SCREEN_DELAY + +/datum/tutorial/proc/destroy_self() + SIGNAL_HANDLER + PRIVATE_PROC(TRUE) + SHOULD_NOT_OVERRIDE(TRUE) + + manager().dismiss(user) + qdel(src) + +/// Shows a large piece of text on the user's screen with the given message. +/// If a message already exists, will fade it out and replace it. +/datum/tutorial/proc/show_instruction(message) + PROTECTED_PROC(TRUE) + + if (isnull(instruction_screen)) + instruction_screen = new(null, message, user.client) + user.client?.screen += instruction_screen + else + instruction_screen.change_message(message) + +/// Given a keybind and a message, will replace %KEY% in `message` with the first keybind they have. +/// As a fallback, will return the third parameter, `message_without_keybinds`, if none are set. +/datum/tutorial/proc/keybinding_message(datum/keybinding/keybinding_type, message, message_without_keybinds) + PROTECTED_PROC(TRUE) + + var/list/keybinds = user.client?.prefs.key_bindings[initial(keybinding_type.name)] + return keybinds?.len > 0 ? replacetext(message, "%KEY%", "[keybinds[1]]") : message_without_keybinds + +/// Creates a UI element with the given `icon_state`, starts it at `initial_screen_loc`, and animates it to `target_screen_loc`. +/// Waits `animate_start_time` before moving. +/datum/tutorial/proc/animate_ui_element(icon_state, initial_screen_loc, target_screen_loc, animate_start_time) + PROTECTED_PROC(TRUE) + + var/atom/movable/screen/preview = new + preview.icon = ui_style2icon(user.client?.prefs.read_preference(/datum/preference/choiced/ui_style) || GLOB.available_ui_styles[1]) + preview.icon_state = icon_state + preview.mouse_opacity = MOUSE_OPACITY_TRANSPARENT + preview.screen_loc = "1,1" + + var/view = user.client?.view + + var/list/origin_offsets = screen_loc_to_offset(initial_screen_loc, view) + + // A little offset to the right + var/matrix/origin_transform = TRANSLATE_MATRIX(origin_offsets[1] - world.icon_size * 0.5, origin_offsets[2] - world.icon_size * 1.5) + + var/list/target_offsets = screen_loc_to_offset(target_screen_loc, view) + // `- world.icon_Size * 0.5` to patch over a likely bug in screen_loc_to_offset with CENTER, needs more looking at + var/matrix/animate_to_transform = TRANSLATE_MATRIX(target_offsets[1] - world.icon_size * 1.5, target_offsets[2] - world.icon_size) + + preview.transform = origin_transform + + preview.alpha = 0 + animate(preview, time = animate_start_time, alpha = 255, easing = CUBIC_EASING) + animate(1.4 SECONDS) + animate(transform = animate_to_transform, time = 2 SECONDS, easing = SINE_EASING | EASE_IN) + animate(alpha = 0, time = 2.4 SECONDS, easing = CUBIC_EASING | EASE_IN, flags = ANIMATION_PARALLEL) + + user.client?.screen += preview + + return preview + +/// A singleton that manages when to create tutorials of a specific tutorial type. +/datum/tutorial_manager + VAR_PRIVATE/datum/tutorial/tutorial_type + + /// ckeys that we know have finished the tutorial + VAR_PRIVATE/list/finished_ckeys = list() + + /// ckeys that have performed the tutorial, but have not completed it. + /// Doesn't mean that they can still see the tutorial, might have meant the tutorial was dismissed + /// without being completed, such as during a log out. + VAR_PRIVATE/list/performing_ckeys = list() + +/datum/tutorial_manager/New(tutorial_type) + ASSERT(ispath(tutorial_type, /datum/tutorial)) + src.tutorial_type = tutorial_type + +/datum/tutorial_manager/Destroy(force, ...) + if (!force) + stack_trace("Something is trying to destroy [type], which is a singleton") + return QDEL_HINT_LETMELIVE + return ..() + +/// Checks if we should perform the tutorial for the given user, and performs if so. +/// Use `SStutorials.suggest_tutorial` instead of calling this directly. +/datum/tutorial_manager/proc/try_perform(mob/user, list/arguments) + var/datum/tutorial/tutorial = new tutorial_type(user) + if (!tutorial.should_perform(user)) + qdel(tutorial) + return + + performing_ckeys[user.ckey] = TRUE + + tutorial.perform(arglist(arguments)) + +/// Checks if the user should be given this tutorial +/datum/tutorial_manager/proc/should_run(mob/user) + var/ckey = user.ckey + + if (isnull(ckey)) + return FALSE + + if (ckey in finished_ckeys) + return FALSE + + if (ckey in performing_ckeys) + return FALSE + + if (!SSdbcore.IsConnected()) + return CONFIG_GET(flag/give_tutorials_without_db) + + var/player_join_date = user.client?.player_join_date + if (isnull(player_join_date)) + return FALSE + + // This works because ISO-8601 is cool + var/grandfather_date = initial(tutorial_type.grandfather_date) + if (!isnull(grandfather_date) && player_join_date < grandfather_date) + return FALSE + + return TRUE + +/// Marks the tutorial as completed. +/// Call `/datum/tutorial/proc/complete()` instead. +/datum/tutorial_manager/proc/complete(mob/user) + set waitfor = FALSE + + ASSERT(!isnull(user.ckey)) + + finished_ckeys[user.ckey] = TRUE + performing_ckeys -= user.ckey + + SSblackbox.record_feedback("tally", "tutorial_completed", 1, "[tutorial_type]") + log_game("[key_name(user)] completed the [tutorial_type] tutorial.") + + if (SSdbcore.IsConnected()) + INVOKE_ASYNC(src, PROC_REF(log_completion_to_database), user.ckey) + +/datum/tutorial_manager/proc/log_completion_to_database(ckey) + PRIVATE_PROC(TRUE) + + var/datum/db_query/insert_tutorial_query = SSdbcore.NewQuery( + "INSERT INTO [format_table_name("tutorial_completions")] (ckey, tutorial_key) VALUES (:ckey, :tutorial_key) ON DUPLICATE KEY UPDATE tutorial_key = tutorial_key", + list( + "ckey" = ckey, + "tutorial_key" = get_key(), + ) + ) + + insert_tutorial_query.warn_execute() + + qdel(insert_tutorial_query) + +/// Dismisses the tutorial, not marking it as completed in the database. +/// Call `/datum/tutorial/proc/dismiss()` instead. +/datum/tutorial_manager/proc/dismiss(mob/user) + performing_ckeys -= user.ckey + +/// Given a ckey, will mark them as being completed without affecting the database. +/// Call `/datum/tutorial/proc/complete()` instead. +/datum/tutorial_manager/proc/mark_as_completed(ckey) + finished_ckeys[ckey] = TRUE + performing_ckeys -= ckey + +/// Gives the key that will be saved in the database. +/// Must be 64 characters or less. +/datum/tutorial_manager/proc/get_key() + SHOULD_BE_PURE(TRUE) + return copytext("[tutorial_type]", length("[/datum/tutorial]") + 2) diff --git a/code/modules/tutorials/tutorial_instruction.dm b/code/modules/tutorials/tutorial_instruction.dm new file mode 100644 index 00000000000..488b3558eef --- /dev/null +++ b/code/modules/tutorials/tutorial_instruction.dm @@ -0,0 +1,53 @@ +/atom/movable/screen/tutorial_instruction + icon = 'icons/effects/alphacolors.dmi' + icon_state = "white" + color = COLOR_NEARLY_ALL_BLACK + alpha = 0 + screen_loc = "TOP-2,CENTER" + layer = TUTORIAL_INSTRUCTIONS_LAYER + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + + var/client/client + var/atom/movable/screen/tutorial_instruction_text/instruction_text + +/atom/movable/screen/tutorial_instruction/Initialize(mapload, message, client/client) + . = ..() + + transform = transform.Scale(36, 2.5) + + src.client = client + animate(src, alpha = 245, time = 0.8 SECONDS, easing = SINE_EASING) + + instruction_text = new(src, message, client) + vis_contents += instruction_text + +/atom/movable/screen/tutorial_instruction/Destroy() + client = null + QDEL_NULL(instruction_text) + + return ..() + +/atom/movable/screen/tutorial_instruction/proc/change_message(message) + instruction_text.change_message(message) + +/atom/movable/screen/tutorial_instruction_text + maptext_height = 480 + maptext_y = -2 + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + layer = TUTORIAL_INSTRUCTIONS_LAYER + +/atom/movable/screen/tutorial_instruction_text/Initialize(mapload, message, client/client) + . = ..() + + var/view = client?.view_size.getView() + maptext_width = view ? view_to_pixels(view)[1] : 480 + pixel_x = (maptext_width - world.icon_size) * -0.5 + + change_message(message) + +/atom/movable/screen/tutorial_instruction_text/proc/change_message(message) + // We don't use MAPTEXT macro here because it doesn't handle big text + message = "[message]" + + animate(src, alpha = 0, time = (maptext ? 0.5 SECONDS : 0), easing = SINE_EASING) + animate(alpha = 255, time = 0.5 SECONDS, maptext = message) diff --git a/code/modules/tutorials/tutorials/drop.dm b/code/modules/tutorials/tutorials/drop.dm new file mode 100644 index 00000000000..de692edab43 --- /dev/null +++ b/code/modules/tutorials/tutorials/drop.dm @@ -0,0 +1,109 @@ +#define TIME_TO_START_MOVING_DROP_ICON (0.5 SECONDS) + +#define STAGE_DROP_ITEM "STAGE_DROP_ITEM" +#define STAGE_PICK_SOMETHING_UP "STAGE_PICK_SOMETHING_UP" + +/// Tutorial for showing how to drop items. +/// Fired when clicking on an item with another item with a filled inactive hand. +/datum/tutorial/drop + grandfather_date = "2023-01-07" + + var/stage = STAGE_DROP_ITEM + var/atom/movable/screen/drop_preview + var/obj/last_held_item + +/datum/tutorial/drop/Destroy(force, ...) + last_held_item = null + user.client?.screen -= drop_preview + QDEL_NULL(drop_preview) + return ..() + +/datum/tutorial/drop/perform(list/params) + create_drop_preview(params[SCREEN_LOC]) + addtimer(CALLBACK(src, PROC_REF(show_instructions)), TIME_TO_START_MOVING_DROP_ICON) + + RegisterSignal(user, COMSIG_MOB_DROPPING_ITEM, PROC_REF(on_dropped_item)) + RegisterSignal(user, COMSIG_MOB_SWAP_HANDS, PROC_REF(on_swap_hands)) + RegisterSignal(user, COMSIG_LIVING_PICKED_UP_ITEM, PROC_REF(on_pick_up_item)) + + update_held_item() + +/datum/tutorial/drop/perform_completion_effects_with_delay() + UnregisterSignal(user, list(COMSIG_MOB_DROPPING_ITEM, COMSIG_MOB_SWAP_HANDS, COMSIG_LIVING_PICKED_UP_ITEM)) + if (!isnull(last_held_item)) + UnregisterSignal(last_held_item, COMSIG_MOVABLE_MOVED) + + return 0 + +/datum/tutorial/drop/proc/create_drop_preview(initial_screen_loc) + drop_preview = animate_ui_element( + "act_drop", + initial_screen_loc, + ui_drop_throw, + TIME_TO_START_MOVING_DROP_ICON, + ) + +/datum/tutorial/drop/proc/show_instructions() + if (QDELETED(src)) + return + + switch (stage) + if (STAGE_DROP_ITEM) + show_instruction(keybinding_message( + /datum/keybinding/mob/drop_item, + "Press '%KEY%' to drop your current item", + "Click 'DROP' to drop your current item", + )) + if (STAGE_PICK_SOMETHING_UP) + show_instruction("Pick something up!") + +/datum/tutorial/drop/proc/on_swap_hands() + SIGNAL_HANDLER + + if (isnull(user.get_active_held_item())) + if (stage != STAGE_PICK_SOMETHING_UP) + stage = STAGE_PICK_SOMETHING_UP + show_instructions() + else if (stage == STAGE_PICK_SOMETHING_UP) + stage = STAGE_DROP_ITEM + show_instructions() + + update_held_item() + +/datum/tutorial/drop/proc/on_dropped_item() + SIGNAL_HANDLER + + stage = STAGE_PICK_SOMETHING_UP + show_instructions() + +/datum/tutorial/drop/proc/on_pick_up_item() + SIGNAL_HANDLER + + if (stage != STAGE_PICK_SOMETHING_UP) + dismiss() + return + + complete() + +// Exists so that if we, say, place the item on a table, we don't count that as completion +/datum/tutorial/drop/proc/update_held_item() + if (!isnull(last_held_item)) + UnregisterSignal(last_held_item, COMSIG_MOVABLE_MOVED) + + last_held_item = user.get_active_held_item() + if (isnull(last_held_item)) + return + + RegisterSignal(last_held_item, COMSIG_MOVABLE_MOVED, PROC_REF(on_held_item_moved)) + +/datum/tutorial/drop/proc/on_held_item_moved() + SIGNAL_HANDLER + + if (stage == STAGE_PICK_SOMETHING_UP) + return + + dismiss() + +#undef STAGE_DROP_ITEM +#undef STAGE_PICK_SOMETHING_UP +#undef TIME_TO_START_MOVING_DROP_ICON diff --git a/code/modules/tutorials/tutorials/switch_hands.dm b/code/modules/tutorials/tutorials/switch_hands.dm new file mode 100644 index 00000000000..bf27a9e9d83 --- /dev/null +++ b/code/modules/tutorials/tutorials/switch_hands.dm @@ -0,0 +1,86 @@ +#define TIME_TO_START_MOVING_HAND_ICON (0.5 SECONDS) + +#define STAGE_SHOULD_SWAP_HAND "STAGE_SHOULD_SWAP_HAND" +#define STAGE_PICK_UP_ITEM "STAGE_PICK_UP_ITEM" + +/// Tutorial for showing how to switch hands. +/// Fired when clicking on an item with another item with an empty inactive hand. +/datum/tutorial/switch_hands + grandfather_date = "2023-01-07" + + var/stage = STAGE_SHOULD_SWAP_HAND + var/atom/movable/screen/hand_preview + + // So that they don't just drop the item + var/hand_to_watch + +/datum/tutorial/switch_hands/New(mob/user) + . = ..() + + hand_to_watch = (user.active_hand_index % user.held_items.len) + 1 + +/datum/tutorial/switch_hands/Destroy(force, ...) + user.client?.screen -= hand_preview + QDEL_NULL(hand_preview) + + return ..() + +/datum/tutorial/switch_hands/perform(list/params) + create_hand_preview(params[SCREEN_LOC]) + addtimer(CALLBACK(src, PROC_REF(show_instructions)), TIME_TO_START_MOVING_HAND_ICON) + + RegisterSignal(user, COMSIG_MOB_SWAP_HANDS, PROC_REF(on_swap_hands)) + RegisterSignal(user, COMSIG_LIVING_PICKED_UP_ITEM, PROC_REF(on_pick_up_item)) + +/datum/tutorial/switch_hands/perform_completion_effects_with_delay() + UnregisterSignal(user, list(COMSIG_MOB_SWAP_HANDS, COMSIG_LIVING_PICKED_UP_ITEM)) + return 0 + +/datum/tutorial/switch_hands/proc/create_hand_preview(initial_screen_loc) + hand_preview = animate_ui_element( + "hand_[hand_to_watch % 2 == 0 ? "r" : "l"]", + initial_screen_loc, + ui_hand_position(hand_to_watch), + TIME_TO_START_MOVING_HAND_ICON, + ) + +/datum/tutorial/switch_hands/proc/show_instructions() + if (QDELETED(src)) + return + + switch (stage) + if (STAGE_SHOULD_SWAP_HAND) + var/hand_name = hand_to_watch % 2 == 0 ? "right" : "left" + show_instruction(keybinding_message( + /datum/keybinding/mob/swap_hands, + "Press '%KEY%' to use your [hand_name] hand", + "Click 'SWAP' to use your [hand_name] hand", + )) + if (STAGE_PICK_UP_ITEM) + show_instruction("Pick something up!") + +/datum/tutorial/switch_hands/proc/on_swap_hands() + SIGNAL_HANDLER + + if (isnull(user.get_active_held_item())) + stage = STAGE_PICK_UP_ITEM + show_instructions() + else if (isnull(user.get_inactive_held_item())) + stage = STAGE_SHOULD_SWAP_HAND + show_instructions() + else + // You somehow got an item in both hands during the tutorial without switching hands. + // Good job I guess? + complete() + +/datum/tutorial/switch_hands/proc/on_pick_up_item() + SIGNAL_HANDLER + + if (user.active_hand_index != hand_to_watch) + return + + complete() + +#undef STAGE_PICK_UP_ITEM +#undef STAGE_SHOULD_SWAP_HAND +#undef TIME_TO_START_MOVING_HAND_ICON diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index 33b0b0b2bdb..5760a886e4a 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -208,10 +208,12 @@ #include "tgui_create_message.dm" #include "timer_sanity.dm" #include "traitor.dm" +#include "tutorial_sanity.dm" #include "unit_test.dm" #include "verify_config_tags.dm" #include "verify_emoji_names.dm" #include "wizard_loadout.dm" +#include "worn_icons.dm" #ifdef REFERENCE_TRACKING_DEBUG //Don't try and parse this file if ref tracking isn't turned on. IE: don't parse ref tracking please mr linter #include "find_reference_sanity.dm" #endif diff --git a/code/modules/unit_tests/tutorial_sanity.dm b/code/modules/unit_tests/tutorial_sanity.dm new file mode 100644 index 00000000000..3c4ae37c9c0 --- /dev/null +++ b/code/modules/unit_tests/tutorial_sanity.dm @@ -0,0 +1,19 @@ +/// Verifies that every tutorial has properly set variables +/datum/unit_test/tutorial_sanity + +/datum/unit_test/tutorial_sanity/Run() + var/regex/regex_valid_date = regex(@"\d{4}-\d{2}-\d{2}") + var/list/keys = list() + + for (var/datum/tutorial/tutorial_type as anything in SStutorials.tutorial_managers) + var/datum/tutorial_manager/tutorial_manager = SStutorials.tutorial_managers[tutorial_type] + + var/grandfather_date = initial(tutorial_type.grandfather_date) + if (!isnull(grandfather_date)) + TEST_ASSERT(regex_valid_date.Find(grandfather_date), "[tutorial_type] has an invalid grandfather_date ([grandfather_date])") + + var/key = tutorial_manager.get_key() + TEST_ASSERT(!(key in keys), "[key] shows up twice") + TEST_ASSERT(length(key) < 64, "[key] is more than 64 characters, it won't fit in the SQL table.") + + TEST_ASSERT_EQUAL(SStutorials.tutorial_managers.len, length(subtypesof(/datum/tutorial)), "Expected tutorial_managers to have one of every tutorial") diff --git a/code/modules/unit_tests/worn_icons.dm b/code/modules/unit_tests/worn_icons.dm new file mode 100644 index 00000000000..32c0b2e8fe6 --- /dev/null +++ b/code/modules/unit_tests/worn_icons.dm @@ -0,0 +1,117 @@ +/// Makes sure suit slot items aren't using CS:S fallbacks. +/datum/unit_test/worn_icons + var/static/list/possible_icon_states = list() + /// additional_icon_location is for downstream modularity support for finding missing sprites in additonal DMI file locations. + /// Make sure this location is also present in tools/deploy.sh + /// If you need additional paths ontop of this second one, you can add another generate_possible_icon_states_list("your/folder/path/") below the if(additional_icon_location) block in Run(), and make sure to add that path to tools/deploy.sh as well. + var/additional_icon_location = null + +/datum/unit_test/worn_icons/proc/generate_possible_icon_states_list(directory_path) + if(!directory_path) + directory_path = "icons/mob/clothing/" + for(var/file_path in flist(directory_path)) + if(findtext(file_path, ".dmi")) + for(var/sprite_icon in icon_states("[directory_path][file_path]", 1)) //2nd arg = 1 enables 64x64+ icon support, otherwise you'll end up with "sword0_1" instead of "sword" + possible_icon_states[sprite_icon] += list("[directory_path][file_path]") + else + possible_icon_states += generate_possible_icon_states_list("[directory_path][file_path]") + +/datum/unit_test/worn_icons/Run() + generate_possible_icon_states_list() + if(additional_icon_location) + generate_possible_icon_states_list(additional_icon_location) + + var/list/already_warned_icons = list() + + for(var/obj/item/item_path as anything in (subtypesof(/obj/item) - typesof(/obj/item/mod))) + var/cached_slot_flags = initial(item_path.slot_flags) + if(!cached_slot_flags || (cached_slot_flags & ITEM_SLOT_LPOCKET) || (cached_slot_flags & ITEM_SLOT_RPOCKET) || initial(item_path.item_flags) & ABSTRACT) + continue + + + if(initial(item_path.greyscale_colors) && initial(item_path.greyscale_config_worn)) //GAGS has its own unit test. + continue + + var/worn_icon = initial(item_path.worn_icon) //override icon file. where our sprite is contained if set. (ie modularity stuff) + var/worn_icon_state = initial(item_path.worn_icon_state) //overrides icon_state. + var/icon_state = worn_icon_state || initial(item_path.icon_state) //icon_state. what sprite name we are looking for. + + + if(isnull(icon_state)) + continue //no sprite for the item. + if(icon_state in already_warned_icons) + continue + + var/match_message + if(icon_state in possible_icon_states) + for(var/file_place in possible_icon_states[icon_state]) + match_message += (match_message ? " & '[file_place]'" : " - Matching sprite found in: '[file_place]'") + + if(worn_icon) //easiest to check since we override everything. this automatically includes downstream support. + if(!(icon_state in icon_states(worn_icon, 1))) + TEST_FAIL("[item_path] using invalid [worn_icon_state ? "worn_icon_state" : "icon_state"], \"[icon_state]\" in worn_icon override file, '[worn_icon]'[match_message]") + continue + + var/icon_file //checks against all the default icon locations if one isn't defined. + var/fail_reasons + var/spacer + if(cached_slot_flags & ITEM_SLOT_BACK) + icon_file = 'icons/mob/clothing/back.dmi' + + if(!(icon_state in icon_states(icon_file, 1))) + already_warned_icons += icon_state + fail_reasons += "[item_path] using invalid [worn_icon_state ? "worn_icon_state" : "icon_state"], \"[icon_state]\" in '[icon_file]'[match_message]" + spacer = "\n\t" + + if(cached_slot_flags & ITEM_SLOT_ID) + icon_file = 'icons/mob/clothing/id.dmi' + if(!(icon_state in icon_states(icon_file, 1))) + already_warned_icons += icon_state + fail_reasons += "[spacer][item_path] using invalid [worn_icon_state ? "worn_icon_state" : "icon_state"], \"[icon_state]\" in '[icon_file]'[match_message]" + spacer = "\n\t" + + if(cached_slot_flags & ITEM_SLOT_GLOVES) + icon_file = 'icons/mob/clothing/hands.dmi' + if(!(icon_state in icon_states(icon_file, 1))) + already_warned_icons += icon_state + fail_reasons += "[spacer][item_path] using invalid [worn_icon_state ? "worn_icon_state" : "icon_state"], \"[icon_state]\" in '[icon_file]'[match_message]" + spacer = "\n\t" + + if(cached_slot_flags & ITEM_SLOT_EYES) + icon_file = 'icons/mob/clothing/eyes.dmi' + if(!(icon_state in icon_states(icon_file, 1))) + already_warned_icons += icon_state + fail_reasons += "[spacer][item_path] using invalid [worn_icon_state ? "worn_icon_state" : "icon_state"], \"[icon_state]\" in '[icon_file]'[match_message]" + spacer = "\n\t" + + if(cached_slot_flags & ITEM_SLOT_EARS) + icon_file = 'icons/mob/clothing/ears.dmi' + if(!(icon_state in icon_states(icon_file, 1))) + already_warned_icons += icon_state + fail_reasons += "[spacer][item_path] using invalid [worn_icon_state ? "worn_icon_state" : "icon_state"], \"[icon_state]\" in '[icon_file]'[match_message]" + spacer = "\n\t" + + if(cached_slot_flags & ITEM_SLOT_NECK) + icon_file = 'icons/mob/clothing/neck.dmi' + if(!(icon_state in icon_states(icon_file, 1))) + already_warned_icons += icon_state + fail_reasons += "[spacer][item_path] using invalid [worn_icon_state ? "worn_icon_state" : "icon_state"], \"[icon_state]\" in '[icon_file]'[match_message]" + spacer = "\n\t" + + if(cached_slot_flags & ITEM_SLOT_MASK) + icon_file = 'icons/mob/clothing/mask.dmi' + if(!(icon_state in icon_states(icon_file, 1))) + already_warned_icons += icon_state + fail_reasons += "[spacer][item_path] using invalid [worn_icon_state ? "worn_icon_state" : "icon_state"], \"[icon_state]\" in '[icon_file]'[match_message]" + spacer = "\n\t" + + if(cached_slot_flags & ITEM_SLOT_BELT) + icon_file = 'icons/mob/clothing/belt.dmi' + if(!(icon_state in icon_states(icon_file, 1))) + already_warned_icons += icon_state + fail_reasons += "[spacer][item_path] using invalid [worn_icon_state ? "worn_icon_state" : "icon_state"], \"[icon_state]\" in '[icon_file]'[match_message]" + spacer = "\n\t" + + if(fail_reasons) + TEST_FAIL(fail_reasons) + diff --git a/config/config.txt b/config/config.txt index 2f57ba97810..3ac807188ae 100644 --- a/config/config.txt +++ b/config/config.txt @@ -648,3 +648,7 @@ PR_ANNOUNCEMENTS_PER_ROUND 5 ## Uncomment to block granting profiling privileges to users with R_DEBUG, for performance purposes #FORBID_ADMIN_PROFILING + +## Comment to disable sending a toast notification on the host server when initializations complete. +## Even if this is enabled, a notification will only be sent if there are no clients connected. +TOAST_NOTIFICATION_ON_INIT diff --git a/config/game_options.txt b/config/game_options.txt index fa59a2100b0..3cf2af6c919 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -556,3 +556,8 @@ MAXFINE 2000 ## Comment if you wish to enable title music playing at the lobby screen. This flag is disabled by default to facilitate better code testing on local machines. ## Do keep in mind that this flag will not affect individual player's preferences: if they opt-out on your server, it will never play for them. DISALLOW_TITLE_MUSIC + +## If enabled, then when the database is disabled, all players will get tutorials. +## This is primarily useful for developing tutorials. If you have a proper DB setup, you +## don't need (or want) this. +#GIVE_TUTORIALS_WITHOUT_DB diff --git a/html/changelogs/AutoChangeLog-pr-18152.yml b/html/changelogs/AutoChangeLog-pr-18152.yml deleted file mode 100644 index 5e4e5a66d2e..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18152.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - rscadd: "you can flip eyepatches" - - bugfix: "blindfolds now take into consideration both eye colors for their color" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18257.yml b/html/changelogs/AutoChangeLog-pr-18257.yml deleted file mode 100644 index 586ee2d53e4..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18257.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Big chungus wholesome 100" -delete-after: True -changes: - - bugfix: "Amputated and reattached limbs now get wounded based on their own biology, not the current owner's biology." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18307.yml b/html/changelogs/AutoChangeLog-pr-18307.yml deleted file mode 100644 index 2b1eef1f8bd..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18307.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Jolly" -delete-after: True -changes: - - code_imp: "The lists in admin_verbs.dm was organized to be made better. This shouldn't affect the panels admins use at all, since they're already alphabetized." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18311.yml b/html/changelogs/AutoChangeLog-pr-18311.yml deleted file mode 100644 index 050ad7a4f6e..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18311.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "Melbert" -delete-after: True -changes: - - qol: "The preview dummy in the preferences menu now shows some visual quirks, like Heterochromia or nearsighted." - - bugfix: "Fixed some quirks which read a preference roundstart not applying the preference." - - refactor: "Refactored some bits of quirk datums and the quirk application process." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18344.yml b/html/changelogs/AutoChangeLog-pr-18344.yml deleted file mode 100644 index 13a6fa08b2a..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18344.yml +++ /dev/null @@ -1,10 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - rscadd: "Carp will now run away if their health gets low, meaning they may have a chance to regenerate." - - rscadd: "Lia will now fight back if attacked instead of letting herself get killed, watch out!" - - balance: "Magicarp will now aim their spells more intelligently." - - rscadd: "Tame Magicarp can be ordered to use their spells on things." - - refactor: "Carp are now \"Basic Mobs\" instead of \"Simple Mobs\"" - - bugfix: "Dehydrated carp no longer give you a bad feeling when they're your friend and a good feeling when they're going to attack you." - - balance: "Tamed carp are now friendly only to their tamer rather than their whole faction, which should make dehydrated carp more active. Order them to stay or follow you if you want them to behave around your friends." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18345.yml b/html/changelogs/AutoChangeLog-pr-18345.yml deleted file mode 100644 index 17cd04623f5..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18345.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "guardian spirits check for death before they add themselves to you" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18348.yml b/html/changelogs/AutoChangeLog-pr-18348.yml deleted file mode 100644 index 6a976cdb78d..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18348.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Melbert" -delete-after: True -changes: - - refactor: "Drowsiness and Blurred Eyes are now tracked via status effect." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18356.yml b/html/changelogs/AutoChangeLog-pr-18356.yml deleted file mode 100644 index ea3b7a15dea..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18356.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Melbert" -delete-after: True -changes: - - bugfix: "Wedding dresses no longer render their shoes over the dress" - - bugfix: "Things which have inv flags set should more consistently actually hide the things they mean to hide" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18365.yml b/html/changelogs/AutoChangeLog-pr-18365.yml deleted file mode 100644 index c483906dcea..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18365.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "Space Carp can now breathe in space" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18367.yml b/html/changelogs/AutoChangeLog-pr-18367.yml deleted file mode 100644 index 3b790e55d48..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18367.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - balance: "standard holoparasites and assassin holoparasites in stealth mode can deal wounds" - - balance: "you can now ride charger holoparasites" - - balance: "charger holoparasites have a bit less armor and speed" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18368.yml b/html/changelogs/AutoChangeLog-pr-18368.yml deleted file mode 100644 index c8dcda74019..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18368.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "fixes moonicorns not applying pax" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18393.yml b/html/changelogs/AutoChangeLog-pr-18393.yml deleted file mode 100644 index a6410cec235..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18393.yml +++ /dev/null @@ -1,9 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - rscadd: "Ian has learned some new tricks, tell him what a good boy he is!" - - rscadd: "Ian will come on a walk with you, if you are his friend." - - refactor: "Ian's tricks work the same way as some other mobs' tricks and should be extendable to future mobs." - - bugfix: "Dogs no longer run at the maximum possible speed for a mob at all times." - - rscadd: "When Ian gets old, he also slows down. Poor little guy." - - rscadd: "Dogs will no longer dislike the presence of Felinids who have taken the time to befriend them." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18398.yml b/html/changelogs/AutoChangeLog-pr-18398.yml deleted file mode 100644 index 53448da9c69..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18398.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "Starlight will actually show now, instead of just being replaced by fullbright most of the time" - - bugfix: "Emissive lighting will once again work. Sorry lads" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18438.yml b/html/changelogs/AutoChangeLog-pr-18438.yml deleted file mode 100644 index 371ddc124d9..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18438.yml +++ /dev/null @@ -1,17 +0,0 @@ -author: "Fikou" -delete-after: True -changes: - - admin: "admins can now give someone a holoparasite through a new menu in vv dropdown" - - qol: "alt click holopara abilities were moved to right click" - - qol: "support holoparas heal with right click" - - admin: "holoparas have less hardcoded stuff so admins can edit them easier" - - qol: "holoparasites now get their light color from their guardian color" - - bugfix: "holoparasites no longer have the hostile faction, things will attack them" - - bugfix: "holoparasites fly over chasms and stuff properly again" - - qol: "holoparasites update their health every time the summoner gets damaged, rather than every 2 seconds. they also instantly react to the summoner's death, deletion and have a screen overlay of how damaged the summoner is" - - qol: "holoparasite creation now uses a radial menu with tooltips for each subtype, as such, the guide papers no longer exist. it also shows ghosts which type you picked" - - bugfix: "holoparasites can no longer be fugu'd" - - bugfix: "fixes overlay lighting runtiming if deleted during a signal queue" - - bugfix: "fixes negative gravity being weird, and gravitokinetic holoparasite's turf slams not working" - - bugfix: "fixes invisible info tooltips for radial menus" - - admin: "you can now make holoparas not controlled by anyone" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18468.yml b/html/changelogs/AutoChangeLog-pr-18468.yml deleted file mode 100644 index 53bb72995f0..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18468.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - admin: "Added config for disabling station traits" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18549.yml b/html/changelogs/AutoChangeLog-pr-18549.yml deleted file mode 100644 index 4a8d9cf8458..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18549.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - balance: "While Ian still enjoys being petted, his heart will now most closely belong to anyone who gives him an expensive luxury dog bone." - - code_imp: "Using an item which _can_ deal damage on a mob tracking hostile actions (such as a dog) won't automatically be considered to be a hostile action if you aren't actually hitting it with the item." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18550.yml b/html/changelogs/AutoChangeLog-pr-18550.yml deleted file mode 100644 index c849814a182..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18550.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - code_imp: "Ghosts are now basic mobs! You might not notice any difference, but..." - - code_imp: "Ghost mobs now spawn with hair and sometimes facial hair." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18581.yml b/html/changelogs/AutoChangeLog-pr-18581.yml deleted file mode 100644 index 4110b8abd8a..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18581.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - rscadd: "Space Carp seem to have begun associating the station with food and attempting to enter from the outside, rather than simply congregating around solar panels. Employees are advised that these are wild animals, and should not be fed." - - rscadd: "Space Carp can intermittently teleport short distances, leaving a short lived rift which other nearby carp will be attracted to follow them through." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18590.yml b/html/changelogs/AutoChangeLog-pr-18590.yml deleted file mode 100644 index e944b52e65a..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18590.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "LT3" -delete-after: True -changes: - - bugfix: "Disposal pipes and cable wires now co-exist with the tram bridge" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18591.yml b/html/changelogs/AutoChangeLog-pr-18591.yml deleted file mode 100644 index a054299953f..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18591.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "burn chambers will not get stuck on depressurizing while cycling to exterior airlocks" - - bugfix: "using an airlock sensor will properly cycle the air inside the chamber" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18593.yml b/html/changelogs/AutoChangeLog-pr-18593.yml deleted file mode 100644 index 2456ee9dce3..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18593.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Gofawful5" -delete-after: True -changes: - - rscadd: "Added a plushie based on a strange white-haired cat-thing." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18596.yml b/html/changelogs/AutoChangeLog-pr-18596.yml deleted file mode 100644 index 5c810970d7a..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18596.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "GoldenAlpharex" -delete-after: True -changes: - - bugfix: "Changing species will now by default update the visuals of the affected mob. This should hopefully provide more consistent behavior all around." - - bugfix: "Xenobiological Slime Hybrids no longer have grown a third eye overnight." - - bugfix: "Fixed bad armor values on some clothes available on Interdyne." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18597.yml b/html/changelogs/AutoChangeLog-pr-18597.yml deleted file mode 100644 index 33ff750cac3..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18597.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - rscadd: "Added new fishnet style socks, in a choice of three lengths" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18598.yml b/html/changelogs/AutoChangeLog-pr-18598.yml deleted file mode 100644 index 71dbfe2ad42..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18598.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - imageadd: "New look and animations for the Heretic's transmutation rune" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18599.yml b/html/changelogs/AutoChangeLog-pr-18599.yml deleted file mode 100644 index c94fa827d69..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18599.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "New players connecting via an active Panic Bunker Interview System can now close out the window once they have their interview approved by an admin." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18603.yml b/html/changelogs/AutoChangeLog-pr-18603.yml deleted file mode 100644 index 3bcefdc52e8..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18603.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "Fixes boring changeling gameplay by making shrieks not work while ventcrawling." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18606.yml b/html/changelogs/AutoChangeLog-pr-18606.yml deleted file mode 100644 index 554c4af42fd..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18606.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "The small carton no longer randomly disappears." - - bugfix: "Pre-filled bottles of cola & nuka cola, and glasses of soda now have the correct sprite." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18609.yml b/html/changelogs/AutoChangeLog-pr-18609.yml deleted file mode 100644 index 3cc09f0e72d..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18609.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "Fix antags being revealed by hallucinations" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-18613.yml b/html/changelogs/AutoChangeLog-pr-18613.yml deleted file mode 100644 index faa5bc51aa6..00000000000 --- a/html/changelogs/AutoChangeLog-pr-18613.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "fixed biosuits, nun robes, narsien hardened armor making your shoes invisible" \ No newline at end of file diff --git a/html/changelogs/archive/2023-01.yml b/html/changelogs/archive/2023-01.yml index ab7f15dee74..0c7b77311b5 100644 --- a/html/changelogs/archive/2023-01.yml +++ b/html/changelogs/archive/2023-01.yml @@ -308,3 +308,128 @@ can be alcohol free! - admin: Admins can now creature custom reagent scrubber overflows, TC trade 20TC for superlube flood? +2023-01-10: + Big chungus wholesome 100: + - bugfix: Amputated and reattached limbs now get wounded based on their own biology, + not the current owner's biology. + Fikou: + - admin: admins can now give someone a holoparasite through a new menu in vv dropdown + - qol: alt click holopara abilities were moved to right click + - qol: support holoparas heal with right click + - admin: holoparas have less hardcoded stuff so admins can edit them easier + - qol: holoparasites now get their light color from their guardian color + - bugfix: holoparasites no longer have the hostile faction, things will attack them + - bugfix: holoparasites fly over chasms and stuff properly again + - qol: holoparasites update their health every time the summoner gets damaged, rather + than every 2 seconds. they also instantly react to the summoner's death, deletion + and have a screen overlay of how damaged the summoner is + - qol: holoparasite creation now uses a radial menu with tooltips for each subtype, + as such, the guide papers no longer exist. it also shows ghosts which type you + picked + - bugfix: holoparasites can no longer be fugu'd + - bugfix: fixes overlay lighting runtiming if deleted during a signal queue + - bugfix: fixes negative gravity being weird, and gravitokinetic holoparasite's + turf slams not working + - bugfix: fixes invisible info tooltips for radial menus + - admin: you can now make holoparas not controlled by anyone + Gofawful5: + - rscadd: Added a plushie based on a strange white-haired cat-thing. + GoldenAlpharex: + - bugfix: Changing species will now by default update the visuals of the affected + mob. This should hopefully provide more consistent behavior all around. + - bugfix: Xenobiological Slime Hybrids no longer have grown a third eye overnight. + - bugfix: Fixed bad armor values on some clothes available on Interdyne. + Jolly: + - code_imp: The lists in admin_verbs.dm was organized to be made better. This shouldn't + affect the panels admins use at all, since they're already alphabetized. + LT3: + - bugfix: Disposal pipes and cable wires now co-exist with the tram bridge + Melbert: + - bugfix: Wedding dresses no longer render their shoes over the dress + - bugfix: Things which have inv flags set should more consistently actually hide + the things they mean to hide + - qol: The preview dummy in the preferences menu now shows some visual quirks, like + Heterochromia or nearsighted. + - bugfix: Fixed some quirks which read a preference roundstart not applying the + preference. + - refactor: Refactored some bits of quirk datums and the quirk application process. + - refactor: Drowsiness and Blurred Eyes are now tracked via status effect. + SkyratBot: + - rscadd: Carp will now run away if their health gets low, meaning they may have + a chance to regenerate. + - rscadd: Lia will now fight back if attacked instead of letting herself get killed, + watch out! + - balance: Magicarp will now aim their spells more intelligently. + - rscadd: Tame Magicarp can be ordered to use their spells on things. + - refactor: Carp are now "Basic Mobs" instead of "Simple Mobs" + - bugfix: Dehydrated carp no longer give you a bad feeling when they're your friend + and a good feeling when they're going to attack you. + - balance: Tamed carp are now friendly only to their tamer rather than their whole + faction, which should make dehydrated carp more active. Order them to stay or + follow you if you want them to behave around your friends. + - bugfix: The small carton no longer randomly disappears. + - bugfix: Pre-filled bottles of cola & nuka cola, and glasses of soda now have the + correct sprite. + - bugfix: guardian spirits check for death before they add themselves to you + - bugfix: Starlight will actually show now, instead of just being replaced by fullbright + most of the time + - bugfix: Emissive lighting will once again work. Sorry lads + - rscadd: Added new fishnet style socks, in a choice of three lengths + - imageadd: New look and animations for the Heretic's transmutation rune + - rscadd: Space Carp seem to have begun associating the station with food and attempting + to enter from the outside, rather than simply congregating around solar panels. + Employees are advised that these are wild animals, and should not be fed. + - rscadd: Space Carp can intermittently teleport short distances, leaving a short + lived rift which other nearby carp will be attracted to follow them through. + - bugfix: Fixes boring changeling gameplay by making shrieks not work while ventcrawling. + - code_imp: Ghosts are now basic mobs! You might not notice any difference, but... + - code_imp: Ghost mobs now spawn with hair and sometimes facial hair. + - balance: While Ian still enjoys being petted, his heart will now most closely + belong to anyone who gives him an expensive luxury dog bone. + - code_imp: Using an item which _can_ deal damage on a mob tracking hostile actions + (such as a dog) won't automatically be considered to be a hostile action if + you aren't actually hitting it with the item. + - bugfix: fixes moonicorns not applying pax + - rscadd: Ian has learned some new tricks, tell him what a good boy he is! + - rscadd: Ian will come on a walk with you, if you are his friend. + - refactor: Ian's tricks work the same way as some other mobs' tricks and should + be extendable to future mobs. + - bugfix: Dogs no longer run at the maximum possible speed for a mob at all times. + - rscadd: When Ian gets old, he also slows down. Poor little guy. + - rscadd: Dogs will no longer dislike the presence of Felinids who have taken the + time to befriend them. + - balance: standard holoparasites and assassin holoparasites in stealth mode can + deal wounds + - balance: you can now ride charger holoparasites + - balance: charger holoparasites have a bit less armor and speed + - bugfix: burn chambers will not get stuck on depressurizing while cycling to exterior + airlocks + - bugfix: using an airlock sensor will properly cycle the air inside the chamber + - bugfix: Fix antags being revealed by hallucinations + - bugfix: fixed biosuits, nun robes, narsien hardened armor making your shoes invisible + - admin: Added config for disabling station traits + - bugfix: New players connecting via an active Panic Bunker Interview System can + now close out the window once they have their interview approved by an admin. + - rscadd: you can flip eyepatches + - bugfix: blindfolds now take into consideration both eye colors for their color + - bugfix: Space Carp can now breathe in space +2023-01-11: + Guillaume Prata: + - bugfix: Legion infested golem corpses can drop power tools again (Drill, Jaws, + Experimental Welder) but they were moved away from their pockets and into the + belt slot. + ShizCalev, GoldenAlpharex for the Skyrat fixes: + - code_imp: Added a unit test for ALL worn icons. + - bugfix: Fixed a bunch of broken worn icons! + - bugfix: Fixes a whole bunch more broken worn icons on Skyrat's items! + SkyratBot: + - bugfix: You can now properly start drifting after moving out of a drift + - balance: Due to materials costing a lot more than ever, Nanotrasen's Spare ID + Safe Supplier have cut down on the space inside of the ID Safe, meaning you + can only cram in things as thin as an ID Card. + - qol: New players will now get a contextual tutorial for how to switch hands and + drop items. + - bugfix: don't call after attack twice + - rscadd: RPED can now pick up & install machine circuit boards in machine frames + - rscadd: RPED can pick up computer circuit boards for storage convenience but doesn't + install them diff --git a/icons/mob/clothing/back.dmi b/icons/mob/clothing/back.dmi index 21d49fc738c..1de907be97c 100644 Binary files a/icons/mob/clothing/back.dmi and b/icons/mob/clothing/back.dmi differ diff --git a/icons/mob/clothing/belt.dmi b/icons/mob/clothing/belt.dmi index 6c0e5014909..3bb1c17e35d 100644 Binary files a/icons/mob/clothing/belt.dmi and b/icons/mob/clothing/belt.dmi differ diff --git a/icons/mob/clothing/id.dmi b/icons/mob/clothing/id.dmi index 1b3f320c753..d5ed308f5d9 100644 Binary files a/icons/mob/clothing/id.dmi and b/icons/mob/clothing/id.dmi differ diff --git a/icons/mob/clothing/id_card.dmi b/icons/mob/clothing/id_card.dmi deleted file mode 100644 index ab573279f30..00000000000 Binary files a/icons/mob/clothing/id_card.dmi and /dev/null differ diff --git a/icons/ui_icons/common/tg_16.png b/icons/ui_icons/common/tg_16.png new file mode 100644 index 00000000000..2b08bdd29cd Binary files /dev/null and b/icons/ui_icons/common/tg_16.png differ diff --git a/interface/VCR_OSD_Mono.ttf b/interface/VCR_OSD_Mono.ttf new file mode 100644 index 00000000000..dcca687a434 Binary files /dev/null and b/interface/VCR_OSD_Mono.ttf differ diff --git a/interface/fonts.dm b/interface/fonts.dm new file mode 100644 index 00000000000..0bfc9c728c7 --- /dev/null +++ b/interface/fonts.dm @@ -0,0 +1,10 @@ +/// A font datum, it exists to define a custom font to use in a span style later. +/datum/font + /// Font name, just so people know what to put in their span style. + var/name + /// The font file we link to. + var/font_family + +/datum/font/vcr_osd_mono + name = "VCR OSD Mono" + font_family = 'interface/VCR_OSD_Mono.ttf' diff --git a/interface/license.txt b/interface/license.txt new file mode 100644 index 00000000000..5f74403c50a --- /dev/null +++ b/interface/license.txt @@ -0,0 +1,2 @@ +VCR OSD Mono created by Riciery Leal/mrmanet. Website indicates 100% free, author confirms it's free for all to use. +(https://www.dafont.com/font-comment.php?file=vcr_osd_mono) diff --git a/modular_skyrat/master_files/code/game/objects/items/holy_weapons.dm b/modular_skyrat/master_files/code/game/objects/items/holy_weapons.dm index c36ecf47a99..ed81df0e26e 100644 --- a/modular_skyrat/master_files/code/game/objects/items/holy_weapons.dm +++ b/modular_skyrat/master_files/code/game/objects/items/holy_weapons.dm @@ -153,6 +153,7 @@ desc = "A set of prayer beads used by many of the more traditional religions in space" icon = 'modular_skyrat/modules/chaplain/icons/holy_weapons.dmi' icon_state = "rosary" + worn_icon_state = "nullrod" force = 4 throwforce = 0 attack_verb_simple = list("whipped", "repented", "lashed", "flagellated") @@ -213,3 +214,4 @@ desc = "Made of clear crystal, the blade refracts the light slightly. Purity, so close yet unattainable in this form." icon_state = "void_blade" inhand_icon_state = "void_blade" + worn_icon_state = "dark_blade" diff --git a/modular_skyrat/master_files/icons/mob/clothing/belt.dmi b/modular_skyrat/master_files/icons/mob/clothing/belt.dmi index c108ebec629..499d2ddda02 100644 Binary files a/modular_skyrat/master_files/icons/mob/clothing/belt.dmi and b/modular_skyrat/master_files/icons/mob/clothing/belt.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/clothing/hands.dmi b/modular_skyrat/master_files/icons/mob/clothing/hands.dmi index ac536c4aa37..d4de869258d 100644 Binary files a/modular_skyrat/master_files/icons/mob/clothing/hands.dmi and b/modular_skyrat/master_files/icons/mob/clothing/hands.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/clothing/head.dmi b/modular_skyrat/master_files/icons/mob/clothing/head.dmi index 569f5734986..5d1c7273e1a 100644 Binary files a/modular_skyrat/master_files/icons/mob/clothing/head.dmi and b/modular_skyrat/master_files/icons/mob/clothing/head.dmi differ diff --git a/modular_skyrat/modules/aesthetics/guns/code/guns.dm b/modular_skyrat/modules/aesthetics/guns/code/guns.dm index c21f19f0d5e..63e651ed1ff 100644 --- a/modular_skyrat/modules/aesthetics/guns/code/guns.dm +++ b/modular_skyrat/modules/aesthetics/guns/code/guns.dm @@ -201,6 +201,7 @@ /obj/item/gun/ballistic/automatic/sniper_rifle/syndicate icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns_gubman2.dmi' icon_state = "sniper2" + worn_icon_state = "sniper" fire_delay = 5.5 SECONDS /obj/item/gun/ballistic/automatic/sniper_rifle/modular @@ -208,6 +209,7 @@ desc = "A devastating Aussec Armory heavy sniper rifle, fitted with a modern scope." icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns_gubman2.dmi' icon_state = "sniper" + worn_icon_state = "sniper" fire_sound = 'modular_skyrat/modules/aesthetics/guns/sound/sniperrifle.ogg' suppressed_sound = 'modular_skyrat/modules/aesthetics/guns/sound/sniperrifle_s.ogg' w_class = WEIGHT_CLASS_BULKY diff --git a/modular_skyrat/modules/blueshield/code/blueshield.dm b/modular_skyrat/modules/blueshield/code/blueshield.dm index b41d9aec430..c962c011332 100644 --- a/modular_skyrat/modules/blueshield/code/blueshield.dm +++ b/modular_skyrat/modules/blueshield/code/blueshield.dm @@ -105,5 +105,6 @@ lefthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_lefthand.dmi' righthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_righthand.dmi' icon_state = "hellfirepdw" + worn_icon_state = "hellfirepdw" ammo_type = list(/obj/item/ammo_casing/energy/laser/hellfire/bs) company_flag = COMPANY_ALLSTAR diff --git a/modular_skyrat/modules/blueshield/code/blueshield_clothing.dm b/modular_skyrat/modules/blueshield/code/blueshield_clothing.dm index 2b951907302..1074ecec5e9 100644 --- a/modular_skyrat/modules/blueshield/code/blueshield_clothing.dm +++ b/modular_skyrat/modules/blueshield/code/blueshield_clothing.dm @@ -20,11 +20,13 @@ icon = 'modular_skyrat/modules/blueshield/icons/radio.dmi' worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/ears.dmi' icon_state = "bshield_headset" + worn_icon_state = "bshield_headset" keyslot = new /obj/item/encryptionkey/heads/blueshield keyslot2 = new /obj/item/encryptionkey/headset_cent /obj/item/radio/headset/headset_bs/alt icon_state = "bshield_headset_alt" + worn_icon_state = "bshield_headset_alt" /obj/item/radio/headset/headset_bs/alt/Initialize(mapload) . = ..() diff --git a/modular_skyrat/modules/company_imports/icons/ak25/ak25_back.dmi b/modular_skyrat/modules/company_imports/icons/ak25/ak25_back.dmi index 0febf3e1e56..fdd355aa837 100644 Binary files a/modular_skyrat/modules/company_imports/icons/ak25/ak25_back.dmi and b/modular_skyrat/modules/company_imports/icons/ak25/ak25_back.dmi differ diff --git a/modular_skyrat/modules/customization/game/objects/items/tanks/n2_tanks.dm b/modular_skyrat/modules/customization/game/objects/items/tanks/n2_tanks.dm index a98fff8f5b4..a31e89aaa08 100644 --- a/modular_skyrat/modules/customization/game/objects/items/tanks/n2_tanks.dm +++ b/modular_skyrat/modules/customization/game/objects/items/tanks/n2_tanks.dm @@ -37,6 +37,7 @@ name = "emergency nitrogen tank" desc = "Used for emergencies. Contains very little nitrogen, so try to conserve it until you actually need it." icon_state = "nitrogen" + worn_icon_state = "nitrogen_extended" volume = 3 /obj/item/tank/internals/nitrogen/belt/emergency/populate_gas() diff --git a/modular_skyrat/modules/customization/modules/clothing/storage/belts.dm b/modular_skyrat/modules/customization/modules/clothing/storage/belts.dm index 024975648c1..9a97638959b 100644 --- a/modular_skyrat/modules/customization/modules/clothing/storage/belts.dm +++ b/modular_skyrat/modules/customization/modules/clothing/storage/belts.dm @@ -108,7 +108,7 @@ name = "storage pouch" desc = span_notice("Click on this to open your belt's inventory!") icon_state = "storage_pouch_icon" - worn_icon_state = "no name" //Intentionally sets the worn icon to an error + worn_icon_state = "no_name" //Intentionally sets the worn icon to an error w_class = WEIGHT_CLASS_BULKY //Still cant put it in your bags, its technically a belt anchored = 1 //Dont want people taking it out with their hands diff --git a/modular_skyrat/modules/customization/modules/clothing/~donator/donator_clothing.dm b/modular_skyrat/modules/customization/modules/clothing/~donator/donator_clothing.dm index 7b131a1b99b..0325b181380 100644 --- a/modular_skyrat/modules/customization/modules/clothing/~donator/donator_clothing.dm +++ b/modular_skyrat/modules/customization/modules/clothing/~donator/donator_clothing.dm @@ -503,6 +503,7 @@ icon = 'modular_skyrat/master_files/icons/donator/obj/custom.dmi' worn_icon = 'modular_skyrat/master_files/icons/donator/mob/clothing/custom_w.dmi' icon_state = "darksheath" + worn_icon_state = "darksheath" /obj/item/storage/belt/sabre/darksabre/Initialize(mapload) . = ..() diff --git a/modular_skyrat/modules/energy_axe/code/energy_fireaxe.dm b/modular_skyrat/modules/energy_axe/code/energy_fireaxe.dm index 6ba444419b8..a956ebce1bf 100644 --- a/modular_skyrat/modules/energy_axe/code/energy_fireaxe.dm +++ b/modular_skyrat/modules/energy_axe/code/energy_fireaxe.dm @@ -4,6 +4,7 @@ icon = 'modular_skyrat/master_files/icons/obj/energy_axe.dmi' icon_state = "energy_axe0" base_icon_state = "energy_axe" + worn_icon_state = "energy_axe" lefthand_file = 'modular_skyrat/master_files/icons/mob/energyaxe_lefthand.dmi' righthand_file = 'modular_skyrat/master_files/icons/mob/energyaxe_righthand.dmi' worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/back.dmi' diff --git a/modular_skyrat/modules/faction/code/id.dm b/modular_skyrat/modules/faction/code/id.dm index 43ee05ff58b..c7b858989d0 100644 --- a/modular_skyrat/modules/faction/code/id.dm +++ b/modular_skyrat/modules/faction/code/id.dm @@ -10,7 +10,6 @@ name = "command card" access = list(ACCESS_FACTION_PUBLIC, ACCESS_FACTION_CREW, ACCESS_FACTION_COMMAND) icon_state = "card_silver" - worn_icon_state = "card_silver" inhand_icon_state = "silver_id" /obj/item/card/faction_access diff --git a/modular_skyrat/modules/ghostcafe/code/ghost_role_spawners.dm b/modular_skyrat/modules/ghostcafe/code/ghost_role_spawners.dm index ac42415d431..48e61b07b57 100644 --- a/modular_skyrat/modules/ghostcafe/code/ghost_role_spawners.dm +++ b/modular_skyrat/modules/ghostcafe/code/ghost_role_spawners.dm @@ -115,7 +115,6 @@ name = "\improper Cafe ID" desc = "An ID straight from God." icon_state = "card_centcom" - worn_icon_state = "card_centcom" assigned_icon_state = "assigned_centcom" registered_age = null trim = /datum/id_trim/admin diff --git a/modular_skyrat/modules/hyposprays/code/hypospray_kits.dm b/modular_skyrat/modules/hyposprays/code/hypospray_kits.dm index 12ef4ca0702..25565fc7e57 100644 --- a/modular_skyrat/modules/hyposprays/code/hypospray_kits.dm +++ b/modular_skyrat/modules/hyposprays/code/hypospray_kits.dm @@ -3,6 +3,8 @@ desc = "It's a kit containing a hypospray and specific treatment chemical-filled vials." icon = 'modular_skyrat/modules/hyposprays/icons/hypokits.dmi' icon_state = "firstaid-mini" + worn_icon_state = "healthanalyzer" // Get a better sprite later + inhand_icon_state = "medkit" lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' slot_flags = ITEM_SLOT_BELT @@ -94,6 +96,7 @@ name = "deluxe hypospray kit" desc = "A kit containing a deluxe hypospray and vials." icon_state = "tactical-mini" + inhand_icon_state = "medkit-tactical" current_case = "tactical" cmo_case = TRUE diff --git a/modular_skyrat/modules/icspawning/code/cards_ids.dm b/modular_skyrat/modules/icspawning/code/cards_ids.dm index cdfa031ac13..345b5b6f4e6 100644 --- a/modular_skyrat/modules/icspawning/code/cards_ids.dm +++ b/modular_skyrat/modules/icspawning/code/cards_ids.dm @@ -3,7 +3,6 @@ name = "\improper Bluespace ID" desc = "A Bluespace ID card. Has ALL the all access, you really shouldn't have this." icon_state = "card_centcom" - worn_icon_state = "card_centcom" assigned_icon_state = "assigned_centcom" trim = /datum/id_trim/admin/bst wildcard_slots = WILDCARD_LIMIT_ADMIN diff --git a/modular_skyrat/modules/implants/code/augments_arms.dm b/modular_skyrat/modules/implants/code/augments_arms.dm index 0620dbba5ea..cdf1c905e68 100644 --- a/modular_skyrat/modules/implants/code/augments_arms.dm +++ b/modular_skyrat/modules/implants/code/augments_arms.dm @@ -7,7 +7,6 @@ icon_state = "mantis_blade" w_class = WEIGHT_CLASS_BULKY flags_1 = CONDUCT_1 - slot_flags = ITEM_SLOT_BELT force = 25 armour_penetration = 20 item_flags = NEEDS_PERMIT //Beepers gets angry if you get caught with this. diff --git a/modular_skyrat/modules/mapping/code/dungeon.dm b/modular_skyrat/modules/mapping/code/dungeon.dm index 4c5778ae8aa..865ac02d6a1 100644 --- a/modular_skyrat/modules/mapping/code/dungeon.dm +++ b/modular_skyrat/modules/mapping/code/dungeon.dm @@ -8,7 +8,7 @@ icon = 'modular_skyrat/modules/mapping/icons/unique/dungeon.dmi' icon_state = "wall" base_icon_state = "wall" - explosion_block = INFINITY + explosive_resistance = INFINITY /turf/closed/indestructible/dungeon/corner icon_state = "wall-corner" diff --git a/modular_skyrat/modules/medical/code/smartdarts.dm b/modular_skyrat/modules/medical/code/smartdarts.dm index e9493984b50..558d9a84f2d 100644 --- a/modular_skyrat/modules/medical/code/smartdarts.dm +++ b/modular_skyrat/modules/medical/code/smartdarts.dm @@ -46,6 +46,7 @@ w_class = WEIGHT_CLASS_NORMAL //I might need to look into changing this later depending on feedback icon = 'modular_skyrat/modules/medical/icons/obj/dartguns.dmi' icon_state = "smartdartgun" + worn_icon_state = "medicalsyringegun" has_gun_safety = TRUE item_flags = null diff --git a/modular_skyrat/modules/modular_items/code/makeshift.dm b/modular_skyrat/modules/modular_items/code/makeshift.dm index 471e755be9d..605a5bc5994 100644 --- a/modular_skyrat/modules/modular_items/code/makeshift.dm +++ b/modular_skyrat/modules/modular_items/code/makeshift.dm @@ -5,6 +5,7 @@ desc = "A makeshift crowbar, flimsily constructed with miscellaneous parts. It's got a strong head that looks like it could be used for hammering." icon = 'modular_skyrat/modules/modular_items/icons/tools.dmi' icon_state = "makeshift_crowbar" + worn_icon_state = "crowbar" force = 2 throwforce = 2 w_class = WEIGHT_CLASS_NORMAL diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/bdsm_mask.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/bdsm_mask.dm index 84ddbe5287c..3b7f142a2d2 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/bdsm_mask.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/bdsm_mask.dm @@ -12,7 +12,8 @@ worn_icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_clothing/lewd_masks.dmi' worn_icon_muzzled = 'modular_skyrat/master_files/icons/mob/clothing/mask_muzzled.dmi' icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_masks.dmi' - icon_state = "mask" + icon_state = "mask_pink_off" + base_icon_state = "mask" slot_flags = ITEM_SLOT_MASK var/mask_on = FALSE var/current_mask_color = "pink" @@ -31,9 +32,6 @@ var/list/moans_alt = list("Mhgm...", "Hmmmp!...", "Gmmmhp!") // Power probability phrases to be said when talking. var/moans_alt_probability = 5 // Probability for alternative sounds to play. var/temp_check = TRUE //Used to check if user unconsious to prevent choking him until he wakes up - -// We can only moan with that thing on -/obj/item/clothing/mask/gas/bdsm_mask w_class = WEIGHT_CLASS_SMALL modifies_speech = TRUE flags_cover = MASKCOVERSMOUTH @@ -104,8 +102,8 @@ // To update icon state properly /obj/item/clothing/mask/gas/bdsm_mask/update_icon_state() . = ..() - icon_state = "[initial(icon_state)]_[current_mask_color]_[mask_on? "on" : "off"]" - inhand_icon_state = "[initial(icon_state)]_[current_mask_color]_[mask_on? "on" : "off"]" + icon_state = "[base_icon_state]_[current_mask_color]_[mask_on? "on" : "off"]" + inhand_icon_state = "[base_icon_state]_[current_mask_color]_[mask_on? "on" : "off"]" // To make in unremovable without helping when mask is on /obj/item/clothing/mask/gas/bdsm_mask/attack_hand(mob/user) diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/deprivation_helmet.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/deprivation_helmet.dm index 5460f566528..775fcbb3da2 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/deprivation_helmet.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/deprivation_helmet.dm @@ -3,8 +3,9 @@ /obj/item/clothing/head/helmet/space/deprivation_helmet name = "deprivation helmet" - desc = "Сompletely cuts off the wearer from the outside world." - icon_state = "dephelmet" + desc = "Completely cuts off the wearer from the outside world." + icon_state = "dephelmet_pink" + base_icon_state = "dephelmet" inhand_icon_state = "dephelmet_pinkn" icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_hats.dmi' worn_icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_clothing/lewd_hats.dmi' @@ -20,7 +21,7 @@ var/muzzle = FALSE var/earmuffs = FALSE var/prevent_vision = FALSE - // + /// The current color of the helmet. var/current_helmet_color = "pink" var/static/list/helmet_designs actions_types = list( @@ -186,8 +187,8 @@ // Updating both and icon in hands and icon worn /obj/item/clothing/head/helmet/space/deprivation_helmet/update_icon_state() .=..() - icon_state = "[initial(icon_state)]_[current_helmet_color]" - inhand_icon_state = "[initial(icon_state)]_[current_helmet_color]" + icon_state = "[base_icon_state]_[current_helmet_color]" + inhand_icon_state = "[base_icon_state]_[current_helmet_color]" // Here goes code that applies stuff on the wearer /obj/item/clothing/head/helmet/space/deprivation_helmet/equipped(mob/living/carbon/human/user, slot) diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/hypnogoggles.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/hypnogoggles.dm index f9f3e30c10a..c665f5813f0 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/hypnogoggles.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/hypnogoggles.dm @@ -1,7 +1,8 @@ /obj/item/clothing/glasses/hypno name = "hypnotic goggles" desc = "Woaa-a-ah... This is lewd." - icon_state = "hypnogoggles" + icon_state = "hypnogoggles_pink" + base_icon_state = "hypnogoggles" inhand_icon_state = "hypnogoggles_pink" icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_eyes.dmi' worn_icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_clothing/lewd_eyes.dmi' @@ -88,8 +89,8 @@ /obj/item/clothing/glasses/hypno/update_icon_state() . = ..() - icon_state = icon_state = "[initial(icon_state)]_[current_hypnogoggles_color]" - inhand_icon_state = "[initial(icon_state)]_[current_hypnogoggles_color]" + icon_state = "[base_icon_state]_[current_hypnogoggles_color]" + inhand_icon_state = "[base_icon_state]_[current_hypnogoggles_color]" /datum/brain_trauma/very_special/induced_hypnosis name = "Hypnosis" diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/kinky_blindfold.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/kinky_blindfold.dm index 05b99f51f0d..40a716f3175 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/kinky_blindfold.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/kinky_blindfold.dm @@ -1,7 +1,8 @@ /obj/item/clothing/glasses/blindfold/kinky name = "kinky blindfold" desc = "Covers the eyes, preventing sight. But it looks so nice..." - icon_state = "kblindfold" + icon_state = "kblindfold_pink" + base_icon_state = "kblindfold" inhand_icon_state = "kblindfold_pink" icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_eyes.dmi' worn_icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_clothing/lewd_eyes.dmi' @@ -53,8 +54,8 @@ /obj/item/clothing/glasses/blindfold/kinky/update_icon_state() . = ..() - icon_state = "[initial(icon_state)]_[current_kinkfold_color]" - inhand_icon_state = "[initial(icon_state)]_[current_kinkfold_color]" + icon_state = "[base_icon_state]_[current_kinkfold_color]" + inhand_icon_state = "[base_icon_state]_[current_kinkfold_color]" //message when equipping that thing /obj/item/clothing/glasses/blindfold/kinky/equipped(mob/living/carbon/user, slot) diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/kinky_headphones.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/kinky_headphones.dm index a3d025b89cc..eb4ed5bf142 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/kinky_headphones.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/kinky_headphones.dm @@ -1,7 +1,8 @@ /obj/item/clothing/ears/kinky_headphones name = "kinky headphones" desc = "Protect your ears from loud noises. It has a switch on the right hand side." - icon_state = "kinkphones" + icon_state = "kinkphones_pink_off" + base_icon_state = "kinkphones" inhand_icon_state = "kinkphones_pink_off" icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_ears.dmi' worn_icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_clothing/lewd_ears.dmi' @@ -79,8 +80,8 @@ /obj/item/clothing/ears/kinky_headphones/update_icon_state() . = ..() - icon_state = "[initial(icon_state)]_[current_kinkphones_color]_[kinky_headphones_on? "on" : "off"]" - inhand_icon_state = "[initial(icon_state)]_[current_kinkphones_color]_[kinky_headphones_on? "on" : "off"]" + icon_state = "[base_icon_state]_[current_kinkphones_color]_[kinky_headphones_on? "on" : "off"]" + inhand_icon_state = "[base_icon_state]_[current_kinkphones_color]_[kinky_headphones_on? "on" : "off"]" /obj/item/clothing/ears/kinky_headphones/proc/toggle(owner) kinky_headphones_on = !kinky_headphones_on diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/kinky_sleepbag.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/kinky_sleepbag.dm index 3cc03b946e0..47683f2e269 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/kinky_sleepbag.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/kinky_sleepbag.dm @@ -8,7 +8,8 @@ worn_icon_taur_paw = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_clothing/lewd_suit/sleepbag_special.dmi' worn_icon_taur_hoof = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_clothing/lewd_suit/sleepbag_special.dmi' supports_variations_flags = CLOTHING_DIGITIGRADE_VARIATION|STYLE_TAUR_ALL - icon_state = "sleepbag" + icon_state = "sleepbag_pink_deflated_folded" + base_icon_state = "sleepbag" w_class = WEIGHT_CLASS_SMALL var/bag_state = "deflated" var/bag_fold = TRUE @@ -97,8 +98,8 @@ /obj/item/clothing/suit/straight_jacket/kinky_sleepbag/update_icon_state() . = ..() - icon_state = "[initial(icon_state)]_[bag_color]_[bag_state]_[bag_fold? "folded" : "unfolded"]" - inhand_icon_state = "[initial(icon_state)]_[bag_color]_[bag_state]_[bag_fold? "folded" : "unfolded"]" + icon_state = "[base_icon_state]_[bag_color]_[bag_state]_[bag_fold? "folded" : "unfolded"]" + inhand_icon_state = "[base_icon_state]_[bag_color]_[bag_state]_[bag_fold? "folded" : "unfolded"]" /obj/item/clothing/suit/straight_jacket/kinky_sleepbag/equipped(mob/user, slot) var/mob/living/carbon/human/affected_human = user diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/shackles.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/shackles.dm index bf8dce91462..e062af59494 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/shackles.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/shackles.dm @@ -8,13 +8,15 @@ worn_icon_taur_snake = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_clothing/lewd_suit/lewd_suits-snake.dmi' worn_icon_taur_paw = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_clothing/lewd_suit/lewd_suits-paw.dmi' worn_icon_taur_hoof = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_clothing/lewd_suit/lewd_suits-hoof.dmi' - icon_state = "shackles" + icon_state = "shackles_metal" + base_icon_state = "shackles" body_parts_covered = null//they don't cover anything, but these code parts need to be here, because if they are not here - they make clothing disappear. Magic. flags_inv = null equip_delay_self = NONE strip_delay = 120 breakouttime = 10 slowdown = 1 + /// The current variant of the shackles' color. var/current_color = "metal" //yes, metal color. Don't ask. var/color_changed = FALSE var/static/list/shackles_designs @@ -63,8 +65,8 @@ /obj/item/clothing/suit/straight_jacket/shackles/update_icon_state() . = ..() - icon_state = "[initial(icon_state)]_[current_color]" - inhand_icon_state = "[initial(icon_state)]_[current_color]" + icon_state = "[base_icon_state]_[current_color]" + inhand_icon_state = "[base_icon_state]_[current_color]" //message when equipping that thing /obj/item/clothing/suit/straight_jacket/shackles/equipped(mob/user, slot) diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/strapon.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/strapon.dm index 4f6aab8618e..fd02ce085e3 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/strapon.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_clothing/strapon.dm @@ -1,7 +1,8 @@ /obj/item/clothing/strapon name = "strapon" desc = "Sometimes you need a special way to humiliate someone." - icon_state = "strapon" + icon_state = "strapon_human" + base_icon_state = "strapon" icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi' worn_icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_items/lewd_items.dmi' slot_flags = ITEM_SLOT_BELT @@ -95,7 +96,7 @@ /obj/item/clothing/strapon/update_icon_state() .=..() - icon_state = "[initial(icon_state)]_[strapon_type]" + icon_state = "[base_icon_state]_[strapon_type]" //Functionality stuff /obj/item/clothing/strapon/proc/update_mob_action_buttonss() @@ -169,7 +170,8 @@ name = "strapon" desc = "An item with which to be menacing and merciless." icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi' - icon_state = "dildo" + icon_state = "dildo_human" + base_icon_state = "dildo" inhand_icon_state = "nothing" force = 0 throwforce = 0 @@ -183,8 +185,8 @@ ADD_TRAIT(src, TRAIT_NODROP, STRAPON_TRAIT) /obj/item/strapon_dildo/update_icon_state() - .=..() - icon_state = "[initial(icon_state)]_[strapon_type]" + . = ..() + icon_state = "[base_icon_state]_[strapon_type]" /obj/item/strapon_dildo/attack(mob/living/carbon/human/hit_mob, mob/living/carbon/human/user) if(hit_mob == user) diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/attachable_vibrator.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/attachable_vibrator.dm index 60d12aff147..c368a5f8189 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/attachable_vibrator.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/attachable_vibrator.dm @@ -5,8 +5,9 @@ /obj/item/clothing/sextoy/eggvib name = "vibrating egg" desc = "A simple, vibrating sex toy." - icon_state = "eggvib" - inhand_icon_state = "eggvib_teal" + icon_state = "eggvib_pink_off" + base_icon_state = "eggvib" + inhand_icon_state = "eggvib_pink" icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi' lefthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_left.dmi' righthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_right.dmi' @@ -83,8 +84,8 @@ /obj/item/clothing/sextoy/eggvib/update_icon_state() . = ..() - icon_state = "[initial(icon_state)]_[current_color]_[vibration_mode][(istype(src, /obj/item/clothing/sextoy/eggvib/signalvib)) ? (toy_on ? "_on" : "_off") : ""]" - inhand_icon_state = "[initial(icon_state)]_[current_color]" + icon_state = "[base_icon_state]_[current_color]_[vibration_mode]" + inhand_icon_state = "[base_icon_state]_[current_color]" /// Toggles between vibration modes seuentially /obj/item/clothing/sextoy/eggvib/proc/toggle_mode() @@ -143,8 +144,9 @@ /obj/item/clothing/sextoy/eggvib/signalvib name = "signal vibrating egg" desc = "A vibrating sex toy with remote control capability. Use a signaller to turn it on." - icon_state = "signalvib" - inhand_icon_state = "signalvib_teal" + icon_state = "signalvib_pink_low_off" + base_icon_state = "signalvib" + inhand_icon_state = "signalvib_pink" modes = list("low" = "medium", "medium" = "high", "high" = "low") vibration_mode = "low" /// If TRUE, the code and frequency will be random on initialize() @@ -175,8 +177,8 @@ /obj/item/clothing/sextoy/eggvib/signalvib/update_icon_state() . = ..() - icon_state = "[initial(icon_state)]_[current_color]_[vibration_mode == "off" ? "low_off" : (toy_on ? "[vibration_mode]_on" : "[vibration_mode]_off")]" - inhand_icon_state = "[initial(icon_state)]_[current_color]" + icon_state = "[base_icon_state]_[current_color]_[vibration_mode == "off" ? "low_off" : (toy_on ? "[vibration_mode]_on" : "[vibration_mode]_off")]" + inhand_icon_state = "[base_icon_state]_[current_color]" /obj/item/clothing/sextoy/eggvib/signalvib/proc/set_frequency(new_frequency) SSradio.remove_object(src, frequency) diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/buttplug.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/buttplug.dm index bc4fb5b9c04..1ad9e101588 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/buttplug.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/buttplug.dm @@ -1,8 +1,9 @@ /obj/item/clothing/sextoy/buttplug name = "buttplug" desc = "I'm meant to put that WHERE?!" - icon_state = "buttplug" - worn_icon_state = "buttplug" + icon_state = "buttplug_pink_small" + base_icon_state = "buttplug" + worn_icon_state = "buttplug_pink" worn_icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_items/lewd_items.dmi' icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi' lefthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_left.dmi' @@ -79,8 +80,8 @@ /obj/item/clothing/sextoy/buttplug/update_icon_state() . = ..() - icon_state = "[initial(icon_state)]_[current_color]_[current_size]" - worn_icon_state = "[initial(icon_state)]_[current_color]" + icon_state = "[base_icon_state]_[current_color]_[current_size]" + worn_icon_state = "[base_icon_state]_[current_color]" /obj/item/clothing/sextoy/buttplug/equipped(mob/living/carbon/human/user, slot) . = ..() diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/condom.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/condom.dm index 4d74690b773..f583dd129eb 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/condom.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/condom.dm @@ -7,7 +7,8 @@ /obj/item/condom_pack name = "condom pack" desc = "Don't worry, I have protection." - icon_state = "condom_pack" + icon_state = "condom_pack_pink" + base_icon_state = "condom_pack" icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi' w_class = WEIGHT_CLASS_TINY /// The current color of the condom, can be changed and affects sprite @@ -24,7 +25,7 @@ /obj/item/condom_pack/update_icon_state() . = ..() - icon_state = "[initial(icon_state)]_[current_color]" + icon_state = "[base_icon_state]_[current_color]" /obj/item/condom_pack/attack_self(mob/user) to_chat(user, span_notice("You start to open the condom pack...")) diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/dildo.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/dildo.dm index 0f89ba4c6bf..00a9004805a 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/dildo.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/dildo.dm @@ -7,13 +7,14 @@ /obj/item/clothing/sextoy/dildo name = "dildo" desc = "A large plastic penis, much like the one in your mother's bedside drawer." - icon_state = "dildo" - inhand_icon_state = "dildo_canine" + icon_state = "dildo_human" + base_icon_state = "dildo" + inhand_icon_state = "dildo_human" icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi' lefthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_left.dmi' righthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_right.dmi' /// Current design of the toy, affects sprite and can change - var/current_color = "human" + var/current_type = "human" /// If the design has been changed before var/color_changed = FALSE /// Assoc list of designs, used in the radial menu for picking one @@ -33,12 +34,12 @@ /// Create an assoc list of designs for the radial color/design menu /obj/item/clothing/sextoy/dildo/proc/populate_dildo_designs() dildo_designs = list( - "avian" = image (icon = src.icon, icon_state = "[initial(icon_state)]_avian"), - "canine" = image(icon = src.icon, icon_state = "[initial(icon_state)]_canine"), - "equine" = image(icon = src.icon, icon_state = "[initial(icon_state)]_equine"), - "dragon" = image(icon = src.icon, icon_state = "[initial(icon_state)]_dragon"), - "human" = image(icon = src.icon, icon_state = "[initial(icon_state)]_human"), - "tentacle" = image(icon = src.icon, icon_state = "[initial(icon_state)]_tentacle")) + "avian" = image(icon = src.icon, icon_state = "[base_icon_state]_avian"), + "canine" = image(icon = src.icon, icon_state = "[base_icon_state]_canine"), + "equine" = image(icon = src.icon, icon_state = "[base_icon_state]_equine"), + "dragon" = image(icon = src.icon, icon_state = "[base_icon_state]_dragon"), + "human" = image(icon = src.icon, icon_state = "[base_icon_state]_human"), + "tentacle" = image(icon = src.icon, icon_state = "[base_icon_state]_tentacle")) /obj/item/clothing/sextoy/dildo/AltClick(mob/user) if(color_changed) @@ -49,7 +50,7 @@ var/choice = show_radial_menu(user, src, dildo_designs, custom_check = CALLBACK(src, PROC_REF(check_menu), user), radius = 36, require_near = TRUE) if(!choice) return FALSE - current_color = choice + current_type = choice update_icon() color_changed = TRUE @@ -62,8 +63,8 @@ /obj/item/clothing/sextoy/dildo/update_icon_state() . = ..() - icon_state = "[initial(icon_state)][change_sprite ? "_[current_color]" : ""]" - inhand_icon_state = "[initial(icon_state)][change_sprite ? "_[current_color]" : ""]" + icon_state = "[base_icon_state][change_sprite ? "_[current_type]" : ""]" + inhand_icon_state = "[base_icon_state][change_sprite ? "_[current_type]" : ""]" /obj/item/clothing/sextoy/dildo/equipped(mob/living/carbon/human/user, slot) . = ..() @@ -179,14 +180,15 @@ GLOBAL_LIST_INIT(dildo_colors, list(//mostly neon colors /obj/item/clothing/sextoy/dildo/custom_dildo name = "custom dildo" desc = "A dildo that can be customized to your specification." - icon_state = "polydildo" + icon_state = "polydildo_small" + base_icon_state = "polydildo" inhand_icon_state = "polydildo_small" icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi' lefthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_left.dmi' righthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_right.dmi' /// Static list of possible colors for the toy var/static/list/poly_colors = list("#FFFFFF", "#FF8888", "#888888") - current_color = null + current_type = null var/static/list/dildo_sizes = list() w_class = WEIGHT_CLASS_TINY @@ -194,9 +196,9 @@ GLOBAL_LIST_INIT(dildo_colors, list(//mostly neon colors /obj/item/clothing/sextoy/dildo/custom_dildo/populate_dildo_designs() dildo_sizes = list( - "small" = image (icon = src.icon, icon_state = "[initial(icon_state)]_small"), - "medium" = image(icon = src.icon, icon_state = "[initial(icon_state)]_medium"), - "big" = image(icon = src.icon, icon_state = "[initial(icon_state)]_big")) + "small" = image (icon = src.icon, icon_state = "[base_icon_state]_small"), + "medium" = image(icon = src.icon, icon_state = "[base_icon_state]_medium"), + "big" = image(icon = src.icon, icon_state = "[base_icon_state]_big")) /obj/item/clothing/sextoy/dildo/custom_dildo/AltClick(mob/living/user) if(!size_changed) @@ -238,8 +240,8 @@ GLOBAL_LIST_INIT(dildo_colors, list(//mostly neon colors /obj/item/clothing/sextoy/dildo/custom_dildo/update_icon_state() . = ..() - icon_state = "[initial(icon_state)]_[poly_size]" - inhand_icon_state = "[initial(icon_state)]_[poly_size]" + icon_state = "[base_icon_state]_[poly_size]" + inhand_icon_state = "[base_icon_state]_[poly_size]" /* * DOUBLE DILDO diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/fleshlight.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/fleshlight.dm index 6106cf30eb4..1a80c6caadd 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/fleshlight.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/fleshlight.dm @@ -1,7 +1,8 @@ /obj/item/clothing/sextoy/fleshlight name = "fleshlight" desc = "What a strange flashlight." - icon_state = "fleshlight" + icon_state = "fleshlight_pink" + base_icon_state = "fleshlight" inhand_icon_state = "fleshlight_pink" icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi' lefthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_left.dmi' @@ -19,11 +20,11 @@ /// Generates a list of toy colors (or designs) for use in the radial color choice menu /obj/item/clothing/sextoy/fleshlight/proc/populate_fleshlight_designs() fleshlight_designs = list( - "green" = image(icon = src.icon, icon_state = "[initial(icon_state)]_green"), - "pink" = image(icon = src.icon, icon_state = "[initial(icon_state)]_pink"), - "teal" = image(icon = src.icon, icon_state = "[initial(icon_state)]_teal"), - "red" = image(icon = src.icon, icon_state = "[initial(icon_state)]_red"), - "yellow" = image(icon = src.icon, icon_state = "[initial(icon_state)]_yellow"), + "green" = image(icon = src.icon, icon_state = "[base_icon_state]_green"), + "pink" = image(icon = src.icon, icon_state = "[base_icon_state]_pink"), + "teal" = image(icon = src.icon, icon_state = "[base_icon_state]_teal"), + "red" = image(icon = src.icon, icon_state = "[base_icon_state]_red"), + "yellow" = image(icon = src.icon, icon_state = "[base_icon_state]_yellow"), ) /obj/item/clothing/sextoy/fleshlight/Initialize(mapload) @@ -35,8 +36,8 @@ /obj/item/clothing/sextoy/fleshlight/update_icon_state() . = ..() - icon_state = "[initial(icon_state)]_[current_color]" - inhand_icon_state = "[initial(icon_state)]_[current_color]" + icon_state = "[base_icon_state]_[current_color]" + inhand_icon_state = "[base_icon_state]_[current_color]" /obj/item/clothing/sextoy/fleshlight/AltClick(mob/user) if(color_changed) diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/kinky_shocker.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/kinky_shocker.dm index 1b5a2cf7dfa..cfa4d38a870 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/kinky_shocker.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/kinky_shocker.dm @@ -1,7 +1,8 @@ /obj/item/kinky_shocker name = "kinky shocker" desc = "A small toy that can weakly shock someone." - icon_state = "shocker" + icon_state = "shocker_off" + base_icon_state = "shocker" inhand_icon_state = "shocker_off" icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi' lefthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_left.dmi' @@ -100,8 +101,8 @@ /obj/item/kinky_shocker/update_icon_state() . = ..() - icon_state = "[initial(icon_state)]_[shocker_on? "on" : "off"]" - inhand_icon_state = "[initial(icon_state)]_[shocker_on? "on" : "off"]" + icon_state = "[base_icon_state]_[shocker_on? "on" : "off"]" + inhand_icon_state = "[base_icon_state]_[shocker_on? "on" : "off"]" /obj/item/kinky_shocker/attack(mob/living/carbon/human/target, mob/living/carbon/human/user) . = ..() diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/leather_whip.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/leather_whip.dm index e41cc5465fc..ba633541e8b 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/leather_whip.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/leather_whip.dm @@ -3,8 +3,9 @@ /obj/item/clothing/mask/leatherwhip name = "leather whip" desc = "A tool used for domination. Hurts in a way you like it." - icon_state = "leather" - worn_icon_state = "leather" + icon_state = "leather_whip_pink_hard" + worn_icon_state = "leather_whip" + base_icon_state = "leather" inhand_icon_state = null icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi' worn_icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_clothing/lewd_masks.dmi' @@ -80,7 +81,7 @@ update_icon_state() - whip_overlay = mutable_appearance('modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_clothing/lewd_masks.dmi', "[initial(icon_state)]_[current_whip_form]", ABOVE_MOB_LAYER + 0.1) //two arguments. Yes, all mob layer. Fuck person who was working on genitals, they're working wrong.ABOVE_NORMAL_TURF_LAYER + whip_overlay = mutable_appearance('modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_clothing/lewd_masks.dmi', "[base_icon_state]_[current_whip_form]", ABOVE_MOB_LAYER + 0.1) //two arguments. Yes, all mob layer. Fuck person who was working on genitals, they're working wrong.ABOVE_NORMAL_TURF_LAYER update_icon() update_appearance() @@ -136,7 +137,7 @@ update_icon_state() - whip_overlay = mutable_appearance('modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_clothing/lewd_masks.dmi', "[initial(icon_state)]_[current_whip_form]", ABOVE_MOB_LAYER + 0.1) //two arguments. Yes, all mob layer. Fuck person who was working on genitals, they're working wrong.ABOVE_NORMAL_TURF_LAYER + whip_overlay = mutable_appearance('modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_clothing/lewd_masks.dmi', "[base_icon_state]_[current_whip_form]", ABOVE_MOB_LAYER + 0.1) //two arguments. Yes, all mob layer. Fuck person who was working on genitals, they're working wrong.ABOVE_NORMAL_TURF_LAYER update_icon() update_appearance() @@ -144,9 +145,9 @@ /obj/item/clothing/mask/leatherwhip/update_icon_state() . = ..() - icon_state = icon_state = "[initial(icon_state)]_[current_whip_form]_[current_whip_color]_[current_whip_type]" - inhand_icon_state = "[initial(icon_state)]_[current_whip_form]_[current_whip_color]_[current_whip_type]" - worn_icon_state = "[initial(icon_state)]_[current_whip_form]" + icon_state = icon_state = "[base_icon_state]_[current_whip_form]_[current_whip_color]_[current_whip_type]" + inhand_icon_state = "[base_icon_state]_[current_whip_form]_[current_whip_color]_[current_whip_type]" + worn_icon_state = "[base_icon_state]_[current_whip_form]" //safely discipline someone without damage /obj/item/clothing/mask/leatherwhip/attack(mob/living/carbon/human/target, mob/living/carbon/human/user) diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/magic_wand.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/magic_wand.dm index 706d4568f65..d484600d9c7 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/magic_wand.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/magic_wand.dm @@ -1,7 +1,8 @@ /obj/item/clothing/sextoy/magic_wand name = "magic wand" desc = "Not sure where is magic in this thing, but if you press button - it makes funny vibrations" - icon_state = "magicwand" + icon_state = "magicwand_off" + base_icon_state = "magicwand" worn_icon_state = "magicwand" inhand_icon_state = "magicwand" worn_icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_items/lewd_items.dmi' @@ -55,7 +56,7 @@ /obj/item/clothing/sextoy/magic_wand/update_icon_state() . = ..() - icon_state = "[initial(icon_state)]_[vibration_mode]" + icon_state = "[base_icon_state]_[vibration_mode]" /obj/item/clothing/sextoy/magic_wand/equipped(mob/living/carbon/human/user, slot) . = ..() diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/serviette.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/serviette.dm index 8bf2a678ba0..fc51887bf76 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/serviette.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/serviette.dm @@ -73,7 +73,8 @@ /obj/item/serviette_pack name = "pack of serviettes" desc = "I wonder why LustWish makes them..." - icon_state = "serviettepack" + icon_state = "serviettepack_4" + base_icon_state = "serviettepack" icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi' /// A count of how many serviettes are left in the pack var/number_remaining = 4 @@ -81,7 +82,7 @@ /obj/item/serviette_pack/update_icon_state() . = ..() - icon_state = "[initial(icon_state)]_[number_remaining]" + icon_state = "[base_icon_state]_[number_remaining]" /obj/item/serviette_pack/Initialize(mapload) . = ..() diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/spanking_pad.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/spanking_pad.dm index 333de4ecf11..a0e9fe15e9e 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/spanking_pad.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/spanking_pad.dm @@ -1,7 +1,8 @@ /obj/item/spanking_pad name = "spanking pad" desc = "A leather pad with a handle." - icon_state = "spankpad" + icon_state = "spankpad_pink" + base_icon_state = "spankpad" inhand_icon_state = "spankpad_pink" icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi' lefthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_left.dmi' @@ -39,8 +40,8 @@ /obj/item/spanking_pad/update_icon_state() . = ..() - icon_state = "[initial(icon_state)]_[current_color]" - inhand_icon_state = "[initial(icon_state)]_[current_color]" + icon_state = "[base_icon_state]_[current_color]" + inhand_icon_state = "[base_icon_state]_[current_color]" /obj/item/spanking_pad/AltClick(mob/user) if(color_changed) diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/torture_candle.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/torture_candle.dm index 1b43674e9c3..0bad0059cd2 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/torture_candle.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/torture_candle.dm @@ -7,7 +7,8 @@ icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi' lefthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_left.dmi' righthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_right.dmi' - icon_state = "candle" + icon_state = "candle_pink_off" + base_icon_state = "candle" inhand_icon_state = "candle_pink_off" w_class = WEIGHT_CLASS_TINY light_color = LIGHT_COLOR_FIRE @@ -58,8 +59,8 @@ /obj/item/bdsm_candle/update_icon_state() . = ..() - icon_state = "[initial(icon_state)]_[current_color]_[lit ? "lit" : "off"]" - inhand_icon_state = "[initial(icon_state)]_[current_color]_[lit ? "lit" : "off"]" + icon_state = "[base_icon_state]_[current_color]_[lit ? "lit" : "off"]" + inhand_icon_state = "[base_icon_state]_[current_color]_[lit ? "lit" : "off"]" /obj/item/bdsm_candle/attackby(obj/item/object, mob/user, params) var/msg = object.ignition_effect(src, user) diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/vibrator.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/vibrator.dm index 9249e4b1f2a..c0da6760282 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/vibrator.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/vibrator.dm @@ -5,7 +5,8 @@ /obj/item/clothing/sextoy/vibrator name = "vibrator" desc = "Woah. What an... Interesting item. I wonder what this red button does..." - icon_state = "vibrator" + icon_state = "vibrator_pink_off" + base_icon_state = "vibrator" inhand_icon_state = "vibrator_pink" icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi' lefthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_left.dmi' @@ -75,8 +76,8 @@ /obj/item/clothing/sextoy/vibrator/update_icon_state() . = ..() - icon_state = "[initial(icon_state)]_[current_color]_[vibration_mode]" - inhand_icon_state = "[initial(icon_state)]_[current_color]" + icon_state = "[base_icon_state]_[current_color]_[vibration_mode]" + inhand_icon_state = "[base_icon_state]_[current_color]" /obj/item/clothing/sextoy/vibrator/equipped(mob/user, slot) . = ..() diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/vibroring.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/vibroring.dm index a1ad4a7a580..92b0559d5ea 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/vibroring.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_items/vibroring.dm @@ -1,7 +1,8 @@ /obj/item/clothing/sextoy/vibroring name = "vibrating ring" desc = "A ring toy used to keep your erection going strong." - icon_state = "vibroring" + icon_state = "vibroring_pink_off" + base_icon_state = "vibroring" icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi' /// If the toy is currently on or not var/toy_on = FALSE @@ -63,8 +64,8 @@ /obj/item/clothing/sextoy/vibroring/update_icon_state() . = ..() - icon_state = "[initial(icon_state)]_[current_color]_[toy_on? "on" : "off"]" - inhand_icon_state = "[initial(icon_state)]_[current_color]" + icon_state = "[base_icon_state]_[current_color]_[toy_on? "on" : "off"]" + inhand_icon_state = "[base_icon_state]_[current_color]" /obj/item/clothing/sextoy/vibroring/equipped(mob/living/carbon/human/user, slot, initial) . = ..() diff --git a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_structures/pillow.dm b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_structures/pillow.dm index a20f910eb2c..284d6161d58 100644 --- a/modular_skyrat/modules/modular_items/lewd_items/code/lewd_structures/pillow.dm +++ b/modular_skyrat/modules/modular_items/lewd_items/code/lewd_structures/pillow.dm @@ -10,7 +10,8 @@ icon = 'modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi' lefthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_left.dmi' righthand_file = 'modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_inhands/lewd_inhand_right.dmi' - icon_state = "pillow" + icon_state = "pillow_pink_round" + base_icon_state = "pillow" inhand_icon_state = "pillow_pink_round" var/datum/effect_system/feathers/pillow_feathers var/current_color = "pink" @@ -84,8 +85,8 @@ /obj/item/fancy_pillow/update_icon_state() . = ..() - icon_state = "[initial(icon_state)]_[current_color]_[current_form]" - inhand_icon_state = "[initial(icon_state)]_[current_color]_[current_form]" + icon_state = "[base_icon_state]_[current_color]_[current_form]" + inhand_icon_state = "[base_icon_state]_[current_color]_[current_form]" /obj/item/fancy_pillow/Destroy() if(pillow_feathers) diff --git a/modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_clothing/lewd_suit/lewd_suits-paw.dmi b/modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_clothing/lewd_suit/lewd_suits-paw.dmi index 19e836897b6..0215909d6e3 100644 Binary files a/modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_clothing/lewd_suit/lewd_suits-paw.dmi and b/modular_skyrat/modules/modular_items/lewd_items/icons/mob/lewd_clothing/lewd_suit/lewd_suits-paw.dmi differ diff --git a/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_ears.dmi b/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_ears.dmi index e2891698d5e..ca94d5f3e0d 100644 Binary files a/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_ears.dmi and b/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_ears.dmi differ diff --git a/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_eyes.dmi b/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_eyes.dmi index 1780350ed3c..681a9d515b1 100644 Binary files a/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_eyes.dmi and b/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_eyes.dmi differ diff --git a/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_hats.dmi b/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_hats.dmi index 25cb44f0a9d..43e9a3d9a42 100644 Binary files a/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_hats.dmi and b/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_hats.dmi differ diff --git a/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_masks.dmi b/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_masks.dmi index 39864db11fa..c3766155318 100644 Binary files a/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_masks.dmi and b/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_masks.dmi differ diff --git a/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_neck.dmi b/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_neck.dmi index 998a99ece19..8ff216b38b4 100644 Binary files a/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_neck.dmi and b/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_neck.dmi differ diff --git a/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_suits.dmi b/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_suits.dmi index bd0161a9df2..8b07c5fc9fb 100644 Binary files a/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_suits.dmi and b/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_suits.dmi differ diff --git a/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_uniform.dmi b/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_uniform.dmi index aaacbad642e..0e1dfb0fd63 100644 Binary files a/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_uniform.dmi and b/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_clothing/lewd_uniform.dmi differ diff --git a/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi b/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi index 6a4537d2f93..7f8b7a07ff5 100644 Binary files a/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi and b/modular_skyrat/modules/modular_items/lewd_items/icons/obj/lewd_items/lewd_items.dmi differ diff --git a/modular_skyrat/modules/modular_weapons/code/rifle.dm b/modular_skyrat/modules/modular_weapons/code/rifle.dm index 64a0c1835e9..60cbda5e5d1 100644 --- a/modular_skyrat/modules/modular_weapons/code/rifle.dm +++ b/modular_skyrat/modules/modular_weapons/code/rifle.dm @@ -14,7 +14,8 @@ icon = 'modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile40x32.dmi' icon_state = "irifle" inhand_icon_state = "irifle" - worn_icon_state = null + worn_icon = 'modular_skyrat/modules/sec_haul/icons/guns/norwind.dmi' + worn_icon_state = "norwind_worn" mag_type = /obj/item/ammo_box/magazine/internal/boltaction/improvised inhand_x_dimension = 64 inhand_y_dimension = 64 @@ -122,7 +123,7 @@ inhand_y_dimension = 64 lefthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/inhands/weapons/64x_guns_left.dmi' righthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/inhands/weapons/64x_guns_right.dmi' - worn_icon_state = null + worn_icon_state = "gun" mag_type = /obj/item/ammo_box/magazine/cm68 fire_delay = 5 can_suppress = FALSE diff --git a/modular_skyrat/modules/morenarcotics/code/opiumpoppy.dm b/modular_skyrat/modules/morenarcotics/code/opiumpoppy.dm index 73a17912782..76cae58a0ea 100644 --- a/modular_skyrat/modules/morenarcotics/code/opiumpoppy.dm +++ b/modular_skyrat/modules/morenarcotics/code/opiumpoppy.dm @@ -18,7 +18,8 @@ desc = "The seedpod of the opium poppy plant, which contain opium latex." icon = 'modular_skyrat/master_files/icons/obj/hydroponics/harvest.dmi' icon_state = "opiumpoppy" + worn_icon_state = "map_flower" greyscale_config = null - greyscale_config_worn = null - greyscale_colors = null + greyscale_config_worn = /datum/greyscale_config/flower_simple_worn + greyscale_colors = "#01690f" distill_reagent = /datum/reagent/consumable/ethanol/turbo //How can a slow drug make fast drink? Don't question it. diff --git a/modular_skyrat/modules/novaya_ert/code/head.dm b/modular_skyrat/modules/novaya_ert/code/head.dm index 3bfeb9d229f..b8b3891be8d 100644 --- a/modular_skyrat/modules/novaya_ert/code/head.dm +++ b/modular_skyrat/modules/novaya_ert/code/head.dm @@ -82,6 +82,7 @@ name = "\improper REDUT helmet" desc = "A heavy Russian combat helmet with a strong ballistic visor. Alt+click to adjust." icon_state = "russian_heavy_helmet_old" + worn_icon_state = "russian_heavy_helmet" // Add a proper worn icon state if you still want it to look like the old one, can't be bothered to find it myself. armor_type = /datum/armor/nri_heavy_old resistance_flags = FIRE_PROOF|ACID_PROOF|FREEZE_PROOF clothing_flags = SNUG_FIT|THICKMATERIAL diff --git a/modular_skyrat/modules/novaya_ert/code/id.dm b/modular_skyrat/modules/novaya_ert/code/id.dm index d26553dac15..e265ba8b34e 100644 --- a/modular_skyrat/modules/novaya_ert/code/id.dm +++ b/modular_skyrat/modules/novaya_ert/code/id.dm @@ -2,7 +2,6 @@ name = "\improper NRI ID" desc = "An ID straight from the NRI." icon_state = "card_black" - worn_icon_state = "card_black" assigned_icon_state = "assigned_centcom" /datum/id_trim/nri diff --git a/modular_skyrat/modules/sec_haul/code/guns/guns.dm b/modular_skyrat/modules/sec_haul/code/guns/guns.dm index ec37336bac3..95ac8ae711a 100644 --- a/modular_skyrat/modules/sec_haul/code/guns/guns.dm +++ b/modular_skyrat/modules/sec_haul/code/guns/guns.dm @@ -785,6 +785,7 @@ name = "\improper Model 23-37" desc = "An outdated police shotgun sporting an eight-round tube, chambered in twelve-gauge." icon_state = "riotshotgun" + worn_icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns_back.dmi' inhand_icon_state = "shotgun" mag_type = /obj/item/ammo_box/magazine/internal/shot/m23 w_class = WEIGHT_CLASS_BULKY @@ -802,6 +803,7 @@ desc = "A semi-automatic twelve-gauge shotgun with a four-round internal tube." icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns.dmi' icon_state = "as2" + worn_icon_state = "riotshotgun" worn_icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns_back.dmi' lefthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_lefthand.dmi' righthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_righthand.dmi' diff --git a/modular_skyrat/modules/sec_haul/code/peacekeeper/armadyne_clothing.dm b/modular_skyrat/modules/sec_haul/code/peacekeeper/armadyne_clothing.dm index 6e7be546b8b..638fcc1a2df 100644 --- a/modular_skyrat/modules/sec_haul/code/peacekeeper/armadyne_clothing.dm +++ b/modular_skyrat/modules/sec_haul/code/peacekeeper/armadyne_clothing.dm @@ -187,7 +187,6 @@ name = "\improper Armadyne ID" desc = "An Armadyne ID card." icon_state = "card_centcom" - worn_icon_state = "card_centcom" assigned_icon_state = "assigned_centcom" registered_age = null trim = /datum/id_trim/centcom/armadyne diff --git a/modular_skyrat/modules/stone/code/stone.dm b/modular_skyrat/modules/stone/code/stone.dm index 0bccad99f23..226d54b1b8d 100644 --- a/modular_skyrat/modules/stone/code/stone.dm +++ b/modular_skyrat/modules/stone/code/stone.dm @@ -85,7 +85,7 @@ GLOBAL_LIST_INIT(stone_recipes, list ( \ icon_state = "wall-0" base_icon_state = "wall" sheet_type = /obj/item/stack/sheet/mineral/stone - explosion_block = 2 // Rock and stone to the bone, or at least a bit longer than walls made of metal sheets! + explosive_resistance = 2 // Rock and stone to the bone, or at least a bit longer than walls made of metal sheets! smoothing_flags = SMOOTH_BITMASK smoothing_groups = SMOOTH_GROUP_STONE_WALLS + SMOOTH_GROUP_WALLS + SMOOTH_GROUP_CLOSED_TURFS canSmoothWith = SMOOTH_GROUP_STONE_WALLS diff --git a/tgstation.dme b/tgstation.dme index 4f9415f70c9..ddbb150e0b4 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -664,6 +664,7 @@ #include "code\controllers\subsystem\timer.dm" #include "code\controllers\subsystem\title.dm" #include "code\controllers\subsystem\traitor.dm" +#include "code\controllers\subsystem\tutorials.dm" #include "code\controllers\subsystem\verb_manager.dm" #include "code\controllers\subsystem\vis_overlays.dm" #include "code\controllers\subsystem\vote.dm" @@ -1147,6 +1148,7 @@ #include "code\datums\elements\beauty.dm" #include "code\datums\elements\bed_tucking.dm" #include "code\datums\elements\befriend_petting.dm" +#include "code\datums\elements\blocks_explosives.dm" #include "code\datums\elements\bsa_blocker.dm" #include "code\datums\elements\bump_click.dm" #include "code\datums\elements\can_barricade.dm" @@ -4792,6 +4794,10 @@ #include "code\modules\tgui_panel\telemetry.dm" #include "code\modules\tgui_panel\tgui_panel.dm" #include "code\modules\tooltip\tooltip.dm" +#include "code\modules\tutorials\_tutorial.dm" +#include "code\modules\tutorials\tutorial_instruction.dm" +#include "code\modules\tutorials\tutorials\drop.dm" +#include "code\modules\tutorials\tutorials\switch_hands.dm" #include "code\modules\unit_tests\_unit_tests.dm" #include "code\modules\uplink\uplink_devices.dm" #include "code\modules\uplink\uplink_items.dm" @@ -5022,6 +5028,7 @@ #include "code\modules\wiremod\shell\shell_items.dm" #include "code\modules\zombie\items.dm" #include "code\modules\zombie\organs.dm" +#include "interface\fonts.dm" #include "interface\interface.dm" #include "interface\menu.dm" #include "interface\stylesheet.dm" diff --git a/tools/HubMigrator/HubMigrator.dm b/tools/HubMigrator/HubMigrator.dm index cd7f7e6020e..89eb4c8c6b7 100644 --- a/tools/HubMigrator/HubMigrator.dm +++ b/tools/HubMigrator/HubMigrator.dm @@ -1,45 +1,45 @@ //Misc Medal hub IDs -#define MEDAL_METEOR "Your Life Before Your Eyes" -#define MEDAL_PULSE "Jackpot" -#define MEDAL_TIMEWASTE "Overextended The Joke" -#define MEDAL_RODSUPLEX "Feat of Strength" -#define MEDAL_CLOWNCARKING "Round and Full" -#define MEDAL_THANKSALOT "The Best Driver" -#define MEDAL_HELBITALJANKEN "Hel-bent on Winning" -#define MEDAL_MATERIALCRAFT "Getting an Upgrade" +#define MEDAL_METEOR "Your Life Before Your Eyes" +#define MEDAL_PULSE "Jackpot" +#define MEDAL_TIMEWASTE "Overextended The Joke" +#define MEDAL_RODSUPLEX "Feat of Strength" +#define MEDAL_CLOWNCARKING "Round and Full" +#define MEDAL_THANKSALOT "The Best Driver" +#define MEDAL_HELBITALJANKEN "Hel-bent on Winning" +#define MEDAL_MATERIALCRAFT "Getting an Upgrade" //Boss medals // Medal hub IDs for boss medals (Pre-fixes) -#define BOSS_MEDAL_ANY "Boss Killer" -#define BOSS_MEDAL_MINER "Blood-drunk Miner Killer" -#define BOSS_MEDAL_BUBBLEGUM "Bubblegum Killer" -#define BOSS_MEDAL_COLOSSUS "Colossus Killer" -#define BOSS_MEDAL_DRAKE "Drake Killer" +#define BOSS_MEDAL_ANY "Boss Killer" +#define BOSS_MEDAL_MINER "Blood-drunk Miner Killer" +#define BOSS_MEDAL_BUBBLEGUM "Bubblegum Killer" +#define BOSS_MEDAL_COLOSSUS "Colossus Killer" +#define BOSS_MEDAL_DRAKE "Drake Killer" #define BOSS_MEDAL_HIEROPHANT "Hierophant Killer" -#define BOSS_MEDAL_LEGION "Legion Killer" -#define BOSS_MEDAL_TENDRIL "Tendril Exterminator" -#define BOSS_MEDAL_SWARMERS "Swarmer Beacon Killer" +#define BOSS_MEDAL_LEGION "Legion Killer" +#define BOSS_MEDAL_TENDRIL "Tendril Exterminator" +#define BOSS_MEDAL_SWARMERS "Swarmer Beacon Killer" -#define BOSS_MEDAL_MINER_CRUSHER "Blood-drunk Miner Crusher" -#define BOSS_MEDAL_BUBBLEGUM_CRUSHER "Bubblegum Crusher" -#define BOSS_MEDAL_COLOSSUS_CRUSHER "Colossus Crusher" -#define BOSS_MEDAL_DRAKE_CRUSHER "Drake Crusher" -#define BOSS_MEDAL_HIEROPHANT_CRUSHER "Hierophant Crusher" -#define BOSS_MEDAL_LEGION_CRUSHER "Legion Crusher" -#define BOSS_MEDAL_SWARMERS_CRUSHER "Swarmer Beacon Crusher" +#define BOSS_MEDAL_MINER_CRUSHER "Blood-drunk Miner Crusher" +#define BOSS_MEDAL_BUBBLEGUM_CRUSHER "Bubblegum Crusher" +#define BOSS_MEDAL_COLOSSUS_CRUSHER "Colossus Crusher" +#define BOSS_MEDAL_DRAKE_CRUSHER "Drake Crusher" +#define BOSS_MEDAL_HIEROPHANT_CRUSHER "Hierophant Crusher" +#define BOSS_MEDAL_LEGION_CRUSHER "Legion Crusher" +#define BOSS_MEDAL_SWARMERS_CRUSHER "Swarmer Beacon Crusher" // Medal hub IDs for boss-kill scores -#define BOSS_SCORE "Bosses Killed" -#define MINER_SCORE "BDMs Killed" -#define BUBBLEGUM_SCORE "Bubblegum Killed" -#define COLOSSUS_SCORE "Colossus Killed" -#define DRAKE_SCORE "Drakes Killed" -#define HIEROPHANT_SCORE "Hierophants Killed" -#define LEGION_SCORE "Legion Killed" +#define BOSS_SCORE "Bosses Killed" +#define MINER_SCORE "BDMs Killed" +#define BUBBLEGUM_SCORE "Bubblegum Killed" +#define COLOSSUS_SCORE "Colossus Killed" +#define DRAKE_SCORE "Drakes Killed" +#define HIEROPHANT_SCORE "Hierophants Killed" +#define LEGION_SCORE "Legion Killed" #define SWARMER_BEACON_SCORE "Swarmer Beacs Killed" -#define TENDRIL_CLEAR_SCORE "Tendrils Killed" +#define TENDRIL_CLEAR_SCORE "Tendrils Killed" @@ -52,41 +52,43 @@ var/hub_password = "REPLACEME" var/list/valid_medals = list( - MEDAL_METEOR, - MEDAL_PULSE, - MEDAL_TIMEWASTE, - MEDAL_RODSUPLEX, - MEDAL_CLOWNCARKING, - MEDAL_THANKSALOT, - MEDAL_HELBITALJANKEN, - MEDAL_MATERIALCRAFT, - BOSS_MEDAL_ANY, - BOSS_MEDAL_MINER, - BOSS_MEDAL_BUBBLEGUM, - BOSS_MEDAL_COLOSSUS, - BOSS_MEDAL_DRAKE, - BOSS_MEDAL_HIEROPHANT, - BOSS_MEDAL_LEGION, - BOSS_MEDAL_TENDRIL, - BOSS_MEDAL_SWARMERS, - BOSS_MEDAL_MINER_CRUSHER, - BOSS_MEDAL_BUBBLEGUM_CRUSHER, - BOSS_MEDAL_COLOSSUS_CRUSHER, - BOSS_MEDAL_DRAKE_CRUSHER, - BOSS_MEDAL_HIEROPHANT_CRUSHER, - BOSS_MEDAL_LEGION_CRUSHER, - BOSS_MEDAL_SWARMERS_CRUSHER) + MEDAL_METEOR, + MEDAL_PULSE, + MEDAL_TIMEWASTE, + MEDAL_RODSUPLEX, + MEDAL_CLOWNCARKING, + MEDAL_THANKSALOT, + MEDAL_HELBITALJANKEN, + MEDAL_MATERIALCRAFT, + BOSS_MEDAL_ANY, + BOSS_MEDAL_MINER, + BOSS_MEDAL_BUBBLEGUM, + BOSS_MEDAL_COLOSSUS, + BOSS_MEDAL_DRAKE, + BOSS_MEDAL_HIEROPHANT, + BOSS_MEDAL_LEGION, + BOSS_MEDAL_TENDRIL, + BOSS_MEDAL_SWARMERS, + BOSS_MEDAL_MINER_CRUSHER, + BOSS_MEDAL_BUBBLEGUM_CRUSHER, + BOSS_MEDAL_COLOSSUS_CRUSHER, + BOSS_MEDAL_DRAKE_CRUSHER, + BOSS_MEDAL_HIEROPHANT_CRUSHER, + BOSS_MEDAL_LEGION_CRUSHER, + BOSS_MEDAL_SWARMERS_CRUSHER, + ) var/list/valid_scores = list( - BOSS_SCORE, - MINER_SCORE, - BUBBLEGUM_SCORE, - COLOSSUS_SCORE, - DRAKE_SCORE, - HIEROPHANT_SCORE, - LEGION_SCORE, - SWARMER_BEACON_SCORE, - TENDRIL_CLEAR_SCORE) + BOSS_SCORE, + MINER_SCORE, + BUBBLEGUM_SCORE, + COLOSSUS_SCORE, + DRAKE_SCORE, + HIEROPHANT_SCORE, + LEGION_SCORE, + SWARMER_BEACON_SCORE, + TENDRIL_CLEAR_SCORE, + ) var/ach = "achievements" //IMPORTANT : ADD PREFIX HERE IF YOU'RE USING PREFIXED SCHEMA diff --git a/tools/deploy.sh b/tools/deploy.sh index 8a0cf9d29a3..b91eee1331e 100755 --- a/tools/deploy.sh +++ b/tools/deploy.sh @@ -11,9 +11,10 @@ fi mkdir -p \ $1/_maps \ - $1/icons/effects \ - $1/icons/mob/clothing \ + $1/icons/effects \ + $1/icons/mob/clothing \ $1/icons/mob/inhands \ + $1/icons/mob/simple \ $1/icons/obj \ $1/icons/runtime \ $1/sound/runtime \ @@ -31,6 +32,7 @@ cp -r _maps/* $1/_maps/ cp -r icons/effects/* $1/icons/effects/ cp -r icons/mob/clothing/* $1/icons/mob/clothing/ cp -r icons/mob/inhands/* $1/icons/mob/inhands/ +cp -r icons/mob/simple/* $1/icons/mob/simple/ cp -r icons/obj/* $1/icons/obj/ cp -r icons/runtime/* $1/icons/runtime/ cp -r sound/runtime/* $1/sound/runtime/ diff --git a/tools/initToast/initToast.ps1 b/tools/initToast/initToast.ps1 new file mode 100644 index 00000000000..9b7714f3a2c --- /dev/null +++ b/tools/initToast/initToast.ps1 @@ -0,0 +1,32 @@ +param([string]$name, [string]$icon, [Int32]$port=80) + +$hkcu = [Microsoft.Win32.RegistryKey]::OpenBaseKey('CurrentUser','default') + +$amuid_hkey = $hkcu.CreateSubKey('SOFTWARE\Classes\AppUserModelId\Tgstation.Tgstation', $true, [Microsoft.Win32.RegistryOptions]::Volatile) + +if ($name) { $amuid_hkey.SetValue('DisplayName', $name) } +if ($icon) { $amuid_hkey.SetValue('IconUri', $icon) } + +[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null +$notifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier('Tgstation.Tgstation') + +[Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom, ContentType = WindowsRuntime] > $null +$xml = New-Object Windows.Data.Xml.Dom.XmlDocument + +$xml.LoadXml(@" + + + + Initialization Complete + + + + + + +"@) + +[Windows.UI.Notifications.ToastNotification, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null +$toast = New-Object Windows.UI.Notifications.ToastNotification $xml + +$notifier.Show($toast)