diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 915dda724d53c..104b108bb9ccb 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -3,222 +3,3 @@ # This list is alphabetized by User -> Filename and separated into sections for Maintainers/Contributors KEEP IT THAT WAY # In the event that people are to be informed of changes # to the same file or dir, add them to the end of under Multiple Owners - -# MAINTAINERS - -# Dominion/Cyberboss - -/.github/workflows/update_tgs_dmapi.yml @Cyberboss -/.tgs.yml @Cyberboss -/code/world.dm @Cyberboss -/code/__DEFINES/tgs.config.dm @Cyberboss -/code/__DEFINES/tgs.dm @Cyberboss -/code/__DEFINES/_globals.dm @Cyberboss -/code/__HELPERS/chat.dm @Cyberboss -/code/__HELPERS/jatum.dm @Cyberboss -/code/game/world.dm @Cyberboss -/code/controllers/subsystem/atoms.dm @Cyberboss -/code/controllers/globals.dm @Cyberboss -/code/datums/helper_datums/getrev.dm @Cyberboss -/code/modules/tgs/ @Cyberboss -/code/ze_genesis_call/ @Cyberboss -/tools/tgs_test/ @Cyberboss - -# Cobby - -/code/modules/reagents/ @ExcessiveUseOfCobblestone -/code/modules/research/designs/medical_designs.dm @ExcessiveUseOfCobblestone -/code/game/objects/items/storage/medkit.dm @ExcessiveUseOfCobblestone - -# Fikou - -/code/modules/awaymissions/ @Fikou -/code/modules/mining/ @Fikou -/code/modules/mod/ @Fikou -/code/modules/mapfluff/ruins/lavalandruin_code/ @Fikou -/code/modules/mapfluff/ruins/lavaland_ruin_code.dm @Fikou - -# JohnFulpWizard - -/code/modules/mob/living/simple_animal/bot/ @JohnFulpWillard -/code/modules/modular_computers/ @JohnFulpWillard - -# Kylerace - -/code/__DEFINES/spatial_gridmap.dm @Kylerace -/code/controllers/subsystem/spatial_gridmap.dm @Kylerace - -# LemonInTheDark - -/.github/guides/VISUALS.md @LemonInTheDark -/code/_onclick/hud/ @LemonInTheDark -/code/__DEFINES/layers.dm @LemonInTheDark - -# Mothblocks - -/.github/workflows/ @Mothblocks -/code/game/gamemodes/ @Mothblocks -/code/modules/autowiki/ @Mothblocks -/code/modules/unit_tests/ @Mothblocks -/code/modules/client/preferences/ @Mothblocks -/code/modules/client/preferences_menu.dm @Mothblocks -/tgui/packages/tgui/interfaces/PreferencesMenu/ @Mothblocks -/tools/ezdb/ @Mothblocks -/tools/maplint/source/ @Mothblocks -/tools/pull_request_hooks/ @Mothblocks -/tools/screenshot-test-comparison/ @Mothblocks -/tools/test_merge_bot/ @Mothblocks - -# MrMelbert - -/code/modules/hydroponics/ @MrMelbert - -# ninjanomnom - -/code/controllers/subsystem/dcs.dm @ninjanomnom -/code/datums/signals.dm @ninjanomnom -/code/datums/components/_component.dm @ninjanomnom -/code/datums/elements/_element.dm @ninjanomnom -/code/datums/greyscale/_greyscale_config.dm @ninjanomnom -/code/datums/greyscale/json_reader.dm @ninjanomnom -/code/datums/greyscale/layer.dm @ninjanomnom - -# Ryll-Ryll/Shaps - -/code/datums/wounds/ @Ryll-Ryll -/code/datums/status_effects/wound_effects.dm @Ryll-Ryll -/code/__DEFINES/wounds.dm @Ryll-Ryll - -# san7890 - -/code/game/area/ @san7890 -/icons/area/ @san7890 - -# stylemistake - -/code/__DEFINES/chat.dm @stylemistake -/code/__DEFINES/tgui.dm @stylemistake -/code/controllers/subsystem/chat.dm @stylemistake -/code/controllers/subsystem/ping.dm @stylemistake -/code/controllers/subsystem/tgui.dm @stylemistake -/code/modules/tgchat/ @stylemistake -/code/modules/tgui/ @stylemistake -/code/modules/tgui_panel/ @stylemistake -/tgui/ @stylemistake - -# stylemistake (explicitly disowned) - -/tgui/packages/tgui/interfaces/ -/tgui/packages/tgui/styles/interfaces/ -/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss -/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss - -# SuperNovaa41 - -/code/modules/forensics/ @SuperNovaa41 -/code/datums/mood.dm @SuperNovaa41 - -# Time-Green - -/code/modules/plumbing/ @Time-Green -/code/modules/surgery/organs/external/ @Time-Green - -# tralezab -/code/__DEFINES/basic_mobs.dm @tralezab -/code/datums/ai/ @tralezab -/code/modules/religion/ @tralezab - -# Watermelon914 - -/code/modules/wiremod/ @Watermelon914 -/code/modules/antagonists/traitor/ @Watermelon914 -/code/controllers/subsystem/tts.dm @Watermelon914 - -# ZephyrTFA - -/code/__HELPERS/admin_verb.dm @ZephyrTFA -/code/controllers/subsystem/admin_verbs.dm @ZephyrTFA -/code/datums/json_savefile.dm @ZephyrTFA -/code/datums/armor/ @ZephyrTFA -/code/modules/admin/verbs/ @ZephyrTFA -/code/modules/logging/ @ZephyrTFA -/tools/ci/check_grep.sh @ZephyrTFA - - -# CONTRIBUTORS - -# Jordie0608 - -/code/controllers/subsystem/dbcore.dm @Jordie0608 -/tools/SQLAlertEmail/ @Jordie0608 - -# Kapu1178 - -/code/modules/surgery/bodyparts/ @Kapu1178 -/code/modules/surgery/organs/ @Kapu1178 -/code/modules/mob/living/carbon/carbon_update_icons.dm @Kapu1178 -/code/modules/mob/living/carbon/human/human_update_icons.dm @Kapu1178 - -# MrStonedOne - -/code/__DEFINES/MC.dm @MrStonedOne -/code/controllers/admin.dm @MrStonedOne -/code/controllers/master.dm @MrStonedOne -/code/controllers/failsafe.dm @MrStonedOne -/code/controllers/subsystem.dm @MrStonedOne -/code/controllers/subsystem/timer.dm @MrStonedOne -/code/controllers/configuration/entries @MrStonedOne -/config/ @MrStonedOne - -# NamelessFairy - -/code/modules/capture_the_flag/ @NamelessFairy -/_maps/map_files/CTF/ @NamelessFairy - -# Pickle-Coding - -/code/__DEFINES/atmospherics/ @Pickle-Coding -/code/__DEFINES/reactions.dm @Pickle-Coding -/code/modules/atmospherics/ @Pickle-Coding -/code/modules/power/ @Pickle-Coding - -# MULTIPLE OWNERS - -/SQL/ @Jordie0608 @MrStonedOne - -/_maps/ @EOBGames @Maurukas @MMMiracles @san7890 @ShizCalev - -/icons/ @Imaginos16 @Krysonism @Twaticus @Wallemations -/icons/ass/ @Ghilker @tralezab - -/code/__DEFINES/atmospherics/ @Ghilker @LemonInTheDark - -/code/__HELPERS/logging/ @dragomagol @ZephyrTFA - -/code/controllers/subsystem/air.dm @LemonInTheDark @MrStonedOne - -/code/modules/atmospherics/ @Ghilker @LemonInTheDark - -/code/modules/client/preferences.dm @Mothblocks @ZephyrTFA -/code/modules/client/preferences_savefile.dm @Mothblocks @ZephyrTFA - -/code/modules/jobs/job_types/chief_medical_officer.dm @ExcessiveUseOfCobblestone @Ryll-Ryll -/code/modules/jobs/job_types/medical_doctor.dm @ExcessiveUseOfCobblestone @Ryll-Ryll -/code/modules/jobs/job_types/paramedic.dm @ExcessiveUseOfCobblestone @Ryll-Ryll - -/code/modules/mob/living/basic/ @Jacquerel @san7890 @tralezab - -/code/modules/surgery/ @ExcessiveUseOfCobblestone @Ryll-Ryll - -/tools/build/ @MrStonedOne @stylemistake -/tools/tgs_scripts/ @Cyberboss @MrStonedOne - -/tools/WebhookProcessor/ @BraveMole @TiviPlus - -# Expensive files that touching basically always cause performance problems -## Init times -**/*_EXPENSIVE.dm @Mothblocks @LemonInTheDark - -# SIC SEMPER TYRANNIS - -/code/modules/hydroponics/grown/citrus.dm @optimumtact diff --git a/_maps/shuttles/emergency_cruise.dmm b/_maps/shuttles/emergency_cruise.dmm index 7e20dc7d47d58..8045930388cef 100644 --- a/_maps/shuttles/emergency_cruise.dmm +++ b/_maps/shuttles/emergency_cruise.dmm @@ -1648,7 +1648,7 @@ /turf/open/floor/carpet/executive, /area/shuttle/escape) "Jl" = ( -/mob/living/simple_animal/bot/vibebot, +/mob/living/basic/bot/vibebot, /turf/open/floor/iron, /area/shuttle/escape) "Jo" = ( diff --git a/code/__DEFINES/ai/bot_keys.dm b/code/__DEFINES/ai/bot_keys.dm index 61189861141d7..05c0b7aff1899 100644 --- a/code/__DEFINES/ai/bot_keys.dm +++ b/code/__DEFINES/ai/bot_keys.dm @@ -109,3 +109,16 @@ DEFINE_BITFIELD(honkbot_flags, list( ///key that holds our honk ability #define BB_HONK_ABILITY "honk_ability" +//vibebots +///key that holds our partying ability +#define BB_VIBEBOT_PARTY_ABILITY "party_ability" +///key that holds our birthday song +#define BB_VIBEBOT_BIRTHDAY_SONG "birthday_song" +///key that holds happy songs we play to depressed targets +#define BB_VIBEBOT_HAPPY_SONG "happy_song" +///key that holds grim song we play when emagged +#define BB_VIBEBOT_GRIM_SONG "GRIM_song" +///key that holds neutral targets we vibe with +#define BB_VIBEBOT_PARTY_TARGET "party_target" +///key that holds our instrument +#define BB_VIBEBOT_INSTRUMENT "instrument" diff --git a/code/__DEFINES/atom_hud.dm b/code/__DEFINES/atom_hud.dm index 7df79b7e57a26..86de96f07a1d1 100644 --- a/code/__DEFINES/atom_hud.dm +++ b/code/__DEFINES/atom_hud.dm @@ -81,6 +81,7 @@ #define SECHUD_ASSISTANT "hudassistant" #define SECHUD_ATMOSPHERIC_TECHNICIAN "hudatmospherictechnician" #define SECHUD_BARTENDER "hudbartender" +#define SECHUD_BITAVATAR "hudbitavatar" #define SECHUD_BITRUNNER "hudbitrunner" #define SECHUD_BOTANIST "hudbotanist" #define SECHUD_BRIDGE_ASSISTANT "hudbridgeassistant" diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index b8acef70a0648..f1a48df79faee 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -309,7 +309,7 @@ #define SLIME_EVOLUTION_THRESHOLD 10 //Slime evolution cost in nutrition -#define SLIME_EVOLUTION_COST 200 +#define SLIME_EVOLUTION_COST 100 //Slime extract crossing. Controls how many extracts is required to feed to a slime to core-cross. #define SLIME_EXTRACT_CROSSING_REQUIRED 10 diff --git a/code/__DEFINES/obj_flags.dm b/code/__DEFINES/obj_flags.dm index 62ae5a7394a0a..c050c73f23133 100644 --- a/code/__DEFINES/obj_flags.dm +++ b/code/__DEFINES/obj_flags.dm @@ -87,6 +87,8 @@ #define INEDIBLE_CLOTHING (1<<16) /// Headgear/helmet allows internals #define HEADINTERNALS (1<<17) +/// Prevents masks from getting adjusted from enabling internals +#define INTERNALS_ADJUST_EXEMPT (1<<18) /// Integrity defines for clothing (not flags but close enough) #define CLOTHING_PRISTINE 0 // We have no damage on the clothing diff --git a/code/__DEFINES/research/slimes.dm b/code/__DEFINES/research/slimes.dm index e03c6af8f581d..03671ee24d2a0 100644 --- a/code/__DEFINES/research/slimes.dm +++ b/code/__DEFINES/research/slimes.dm @@ -11,15 +11,15 @@ #define SLIME_MAX_POWER 10 ///The maximum amount of nutrition a slime can contain -#define SLIME_MAX_NUTRITION 1000 +#define SLIME_MAX_NUTRITION 200 ///The starting nutrition of a slime -#define SLIME_STARTING_NUTRITION 700 +#define SLIME_STARTING_NUTRITION 100 /// Above it we grow our amount_grown and our power_level, below it we can eat -#define SLIME_GROW_NUTRITION 800 +#define SLIME_GROW_NUTRITION 150 /// Below this, we feel hungry -#define SLIME_HUNGER_NUTRITION 500 +#define SLIME_HUNGER_NUTRITION 50 /// Below this, we feel starving -#define SLIME_STARVE_NUTRITION 200 +#define SLIME_STARVE_NUTRITION 10 ///The slime is not hungry. It might try to feed anyways. #define SLIME_HUNGER_NONE 0 diff --git a/code/__DEFINES/song.dm b/code/__DEFINES/song.dm index 782a7923ea14f..0e7e9f0ce0692 100644 --- a/code/__DEFINES/song.dm +++ b/code/__DEFINES/song.dm @@ -15,3 +15,9 @@ #define MONKEY_SONG "BPM: 200\nC4/0,14,C,A4-F2,F3,A3,F-F2,A-F,F4,G4,F,D4-Bb2-G2\nD3,G3,D-G2,G3-G2,D,D4-G3,D,B4-B2,G,B3,G-B2,B3-B2\nG4,A4,G,E4-C3,E3,G3,E-C,G-C,E,E4-G,E,C5-E-A3,C4\nA-E3,C,E4-C3,A4-C4,B4-A3-A2,C5-C4,D5-F-B3,D4,B-F3\nD,F4-D3,D4,F-B-B2,G4-D,A4-C-F3,F,C/2,B3/2,A3-C3/2\nB/2,C4,E-C3,F4,G-C,F-F3,F-C,C4/2,B/2,A-A2/2,G3/2\nF/I" ///song played by the mook bard #define MOOK_SONG "BPM: 240\nA5,B5,C#6,D6,E6/0.17,A/0.5,A/0.25,A3/0.25\nA4/0.25,C#5/0.25,E5/0.25,A/0.25,C#/0.25,E/0.12\nC#6/0.25,C#/0.25,E6/0.25,A3/0.25,A4/0.25\nC#5/0.25,E5/0.25,A/0.25,C#/0.25,E/0.25,D/0.25\nG6/0.25,D/0.17,F6/0.17,C#6/0.5,E6/0.5,D4/0.25\nA/0.25,D5/0.25,F5/0.25,A/0.25,D/0.25,F/0.25\nD6/0.08,F6/0.08,D4/0.25,A/0.25,D5/0.25,F5/0.25\nCn4/0.2,B/0.17,D6/0.17,G5/0.5,G/0.25,B3/0.25\nD4/0.25,G4/0.25,B4/0.25,D/0.25,G/0.25,B/0.12\nB5/0.25,B/0.25,D6/0.25,G3/0.25,G4/0.25,B4/0.25\nF/0.25,G/0.25,B/0.25,F/0.25,D/0.25,F6/0.25\nC6/0.17,E/0.17,B5/0.5,D#/0.5,C4/0.25,G/0.25\nC5/0.25,E5/0.25,G/0.25,C/0.25,E/0.25,C6/0.08\nE6/0.08,C4/0.25,Dn4/0.25,E4/0.25,A5/0.17,B/0.5\nC6/0.25,F5/0.08,F4/0.08,C5/0.08,E5/0.12,G5/0.12\nC6/0.25,E6/0.25,E4/0.08,C5/0.08,B/0.17,F6/0.17\nE6/0.5,B/0.25,E4/0.08,G#4/0.08,C6/0.17,D6/0.5\nE6/0.25,A3/0.25,E4/0.25,C5/0.25,Gn3/0.25\nF5/0.12,A5/0.12,A6/0.25,F3/0.25,F4/0.12,A4/0.12\nC/0.12,F6/0.17,A6/0.17,G#6/0.5,A/0.25,F3/0.25\nF4/0.12,A4/0.12,D#5/0.12,B/0.17,G#/0.17,B6/0.5\nB5/0.25,G#/0.25,E3/0.25,E4/0.12,G#4/0.12\nDn/0.12,E6/0.08,E3/0.25,F#3/0.25,G#3/0.25\nE5/0.17,A5/0.17,E/0.5,E/0.25,A3/0.25,C#4/0.25\nE4/0.25,C#/0.25,E/0.12,A5/0.5,B/0.5,C#6/0.5\nD6/0.5,A3/0.25,C#4/0.25,E/0.25,C#/0.25,E/0.25\nE6/0.08,Gn/0.25,E4/0.25,A4/0.25,C#5/0.25,E/0.25\nA/0.25,C#/0.25,E6/0.17,E/0.5,Fn6/0.5,G6/0.5\nG3/0.25,E4/0.25,A/0.25,C#/0.25,E/0.25,A/0.25\nC#/0.25,F/0.08,A6/0.08,F3/0.25,F4/0.25,A4/0.25\nCn/0.25,F/0.25,A/0.25,C/0.25,G6/0.12,A6/0.12\nG A G F6 G3/0.25 D4/0.25 G4/0.25 B4/0.25 D/0.25\nG/0.25 B/0.25 E6/0.12 G6/0.12 F/0.71 G/0.71 F/0.71\nE3/0.25 E4/0.25 G4/0.25 B/0.25 E/0.25 G/0.25 B/0.25\nA5/0.08 E6/0.08 A3/0.25 E4/0.25 A4/0.25 C#/0.25 E/0.25 A/0.25 C#/0.25 D6/0.17 E6/0.5 F/0.25 B3/0.25 D4/0.12 F4/0.12 B4/0.12 F6/0.25 E/0.25 D6/0.25 G#3/0.25 E4/0.12 G#4/0.12 B/0.12 Cn6/0.12 D/0.25 A3/0.25 A4/0.25 C5/0.25 E5/0.25 G#3/0.25 Gn/0.25 C4/0.25 E4/0.25 A/" +///song played by the vibebot when cheering people up +#define VIBEBOT_CHEER_SONG "BPM: 360\nE4/0.5,B4-G4/0.5,G-B-E/0.5,D4,Gb,A4-D-G/0.25\nGn-B3-E/0.5,G-B-E/0.5,A3-D-Gb/0.5,E-Gn-B/0.17,E,G\nB4/0.5,E-B-G/0.5,D,Gb,A4-D-G/0.25,B3-Gn-E/0.5\nG-B-E/0.5,A3-D-Gb/0.5,E-Gn-B/0.17,E-G-C5/0.5,G,E,G\nC,B4-Eb-Gb/0.5,B3-E-G/0.5,B-E-G3/0.5,C-Gn4-En/0.5\nG,E,G,C,Eb-Gb-B4/0.17,C-Gn-En/0.5,G,E,G,C\nB-C-Eb-Gb/0.5,B3-E-G/0.5,E-B-G3/0.5,C-En-Gn4,E,G,C\nE,G,A4-Gb-D5/0.17,E/0.5,B4-Gn/0.5,G-B-E/0.5,D4,Gb\nA-D-G/0.25,Gn-B3-E/0.5,G-B-E/0.5,A3-D-Gb/0.5\nE-Gn-B/0.17,E,G,B4/0.5,E-B-G/0.5,D,Gb,A4-D-G/0.25\nB3-Gn-E/0.5,G-B-E/0.5,A3-D-Gb/0.5,E-Gn-B/0.17\nE-G-C/0.5,G,E,G,C,B4-Eb-Gb/0.5,B3-E-G/0.5\nB-E-G3/0.5,C-Gn4-En/0.5,G,E,G,C,Eb-Gb-B4/0.17\nC-Gn-En/0.5,G,E,G,C,B-C-Eb-Gb/0.5,B3-E-G/0.5\nE-B-G3/0.5,C-En-Gn4,E,G,C,E,G,A4-Gb-D5/0.17\nGn-E-B/0.5,B-G3-E,E3-G-B,G4-E4-B/0.5,A3-D4-Gb/0.5\nA-D-G3/0.5,D3-G-A/0.5,Gn4-E-B/0.5,B-G3-E,E3-G-B\nG4-E4-B/0.5,A-D4-Gb/0.17,A4-F4-C4/0.5,C-A3-F\nF3-A-C,C-F4-A4/0.5,B-Gn-E/0.5,B-G3-E/0.5\nG-E3-B/0.5,A3-D-Gb4/0.5,D-A-G3/0.5,D3-A-G/0.5\nA-D4-G4/0.17,Gn-E4-B/0.5,B-G3-E,E3-G-B,G4-E4-B/0.5\nA-D-Gb/0.5,A-D-G3/0.5,D3-G-A/0.5,Gn4-E-B/0.5\nB-G3-E,E3-G-B,G4-E4-B/0.5,A-D4-Gb/0.17,A4-F-C/0.5\nC-A3-F,F3-A-C,C-F4-A4/0.5,B-Gn-E/0.5,B-G3-E/0.5\nG-E3-B/0.5,A3-D-Gb4/0.5,D-A-G3/0.5,D3-A-G/0.5\nE4-A-Db4/0.17,A2,E3,Gn-B-E4,A,E3,B-G-E4\nA3-Dn-F-D3/0.5,F3-A-D4/0.5,D3/0.5,A2,E3,B-E4-G,A\nE3,B-G-E4,F-D4-A3/0.17,A2,E3,B-E4-G,A,E3,B-G-E4\nB-A3-F4-D-D3/0.5,F3-D4-A/0.5,F-A-D3/0.5,A2,E3\nB-E4-G,A,E3,B-E4-G,F-A3-D4-D3/0.17,A2,E3,G-B-E4,A\nE3,B-G-E4,A3-D4-F4-D3/0.5,F3-A-D4/0.5,D3/0.5,A2,E3\nB-E4-G,A,E3,B-G-E4,F-D4-A3/0.17,A2,E3,B-E4-G,A,E3\nB-G-E4,B-A3-F4-D-D3/0.5,F3-D4-A/0.5,F-A-D3/0.5,A2\nE3,B-E4-G,A,E3,B-E4-G,F-A3-D4-D3/0.17,E/0.5\nB4-G4/0.5,G-B-E/0.5,D4,Gb,A4-D-G/0.25,Gn-B3-E/0.5\nG-B-E/0.5,A3-D-Gb/0.5,E-Gn-B/0.17,E,G,B4/0.5\nE-B-G/0.5,D,Gb,A4-D-G/0.25,B3-Gn-E/0.5,G-B-E/0.5\nA3-D-Gb/0.5,E-Gn-B/0.17,E-G-C5/0.5,G,E,G,C\nB4-Eb-Gb/0.5,B3-E-G/0.5,B-E-G3/0.5,C-Gn4-En/0.5,G\nE,G,C,Eb-Gb-B4/0.17,C-Gn-En/0.5,G,E,G,C\nB-Eb-Gb/0.5,B3-E-G/0.5,E-B-G3/0.53,En-Gn4/8,C,G,E\nB4,G,E,B3-E-G/0.07" +///grim music played by the vibebot +#define VIBEBOT_GRIM_MUSIC "BPM: 92\nG5/0.5,C#7-F#5/1.08,G6-G5/0.52,D6-D5,B6-E5/0.52\nG6-G5/1.08,D6-D5/0.34,Cn6-C5-G6/0.5,D,B5-F#6/13\nB4/0.52,C6-C5-G,A4/0.28,G-G5/0.5\nC#7-F#-F#5/1.08,G6-G5/0.52,D6-D5,B6-E/0.52,G-G6\nB5,D7/13,D6/0.52,Cn6,B6-B5,G-G5,G/0.5\nF#-C#7/1.08,G6-G5/0.22,G/0.5,C#-F#/1.08\nG6-G5/0.52,D-D5,B6-E/0.52,G6-G5/1.08,D6-D5/0.34\nCn6-C5-G6/0.5,D,B5-F#6/13,B4/0.52,C6-G-C5/0.25\nG-G5/0.5,C#7-F#-F#5/1.08,G6-G5/0.52,D6-D5\nB6-E/0.52,G-G6,B5,D7/13,D6/0.52,Cn6,B6-B5,G-G5\nG/0.5,F#-C#7/1.08,G6-G5/0.65" +///happy birthday music we play to the birthday boy +#define VIBEBOT_HAPPY_BIRTHDAY "BPM: 120\nG4/0.5,G4/0.25,A4/0.5,G4/0.5,C5/0.5,B4/1\nG4/0.5,G4/0.25,A4/0.5,G4/0.5,D5/0.5,C5/1\nG4/0.5,G4/0.5,G5/0.5,E5/0.5,C5/0.5,B4/0.5,A4/0.5\nF5/0.5,F5/0.5,E5/0.5,C5/0.5,D5/0.5,C5/1" diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 6cc90893c0f7e..8d2b54ab72f87 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -1167,4 +1167,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// This trait lets you attach limbs to any player without surgery. #define TRAIT_EASY_ATTACH "easy_attach" +///Trait given to the birthday boy +#define TRAIT_BIRTHDAY_BOY "birthday_boy" // END TRAIT DEFINES diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index ead7b324cea13..f98178d537fa3 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -99,6 +99,7 @@ DEFINE_BITFIELD(clothing_flags, list( "THICKMATERIAL" = THICKMATERIAL, "VOICEBOX_DISABLED" = VOICEBOX_DISABLED, "VOICEBOX_TOGGLABLE" = VOICEBOX_TOGGLABLE, + "INTERNALS_ADJUST_EXEMPT" = INTERNALS_ADJUST_EXEMPT, )) DEFINE_BITFIELD(datum_flags, list( diff --git a/code/_globalvars/lists/names.dm b/code/_globalvars/lists/names.dm index 81fe08373b31a..dce2dc69a50ae 100644 --- a/code/_globalvars/lists/names.dm +++ b/code/_globalvars/lists/names.dm @@ -24,6 +24,7 @@ GLOBAL_LIST_INIT(nightmare_names, world.file2list("strings/names/nightmare.txt") GLOBAL_LIST_INIT(megacarp_first_names, world.file2list("strings/names/megacarp1.txt")) GLOBAL_LIST_INIT(megacarp_last_names, world.file2list("strings/names/megacarp2.txt")) GLOBAL_LIST_INIT(cyberauth_names, world.file2list("strings/names/cyberauth.txt")) +GLOBAL_LIST_INIT(hacker_aliases, world.file2list("strings/names/hackers.txt")) GLOBAL_LIST_INIT(syndicate_monkey_names, world.file2list("strings/names/syndicate_monkey.txt")) GLOBAL_LIST_INIT(cargorilla_names, world.file2list("strings/names/cargorilla.txt")) GLOBAL_LIST_INIT(guardian_first_names, world.file2list("strings/names/guardian_descriptions.txt")) diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 62805b578d559..5d1e88667b738 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -140,6 +140,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_BATON_RESISTANCE" = TRAIT_BATON_RESISTANCE, "TRAIT_BEAST_EMPATHY" = TRAIT_BEAST_EMPATHY, "TRAIT_BEING_BLADE_SHIELDED" = TRAIT_BEING_BLADE_SHIELDED, + "TRAIT_BIRTHDAY_BOY" = TRAIT_BIRTHDAY_BOY, "TRAIT_BLOB_ALLY" = TRAIT_BLOB_ALLY, "TRAIT_BLOCK_SHUTTLE_MOVEMENT" = TRAIT_BLOCK_SHUTTLE_MOVEMENT, "TRAIT_BLOOD_CLANS" = TRAIT_BLOOD_CLANS, diff --git a/code/datums/ai/_ai_controller.dm b/code/datums/ai/_ai_controller.dm index 58e9746cbf086..7b46a7b06e803 100644 --- a/code/datums/ai/_ai_controller.dm +++ b/code/datums/ai/_ai_controller.dm @@ -625,7 +625,7 @@ multiple modular subtrees with behaviors /datum/ai_controller/proc/post_blackboard_key_set(key) if (isnull(pawn)) return - SEND_SIGNAL(pawn, COMSIG_AI_BLACKBOARD_KEY_SET(key)) + SEND_SIGNAL(pawn, COMSIG_AI_BLACKBOARD_KEY_SET(key), key) /** * Adds the passed "thing" to the associated key diff --git a/code/datums/components/crafting/robot.dm b/code/datums/components/crafting/robot.dm index 11a5887bf91c5..2398a8b54fbbe 100644 --- a/code/datums/components/crafting/robot.dm +++ b/code/datums/components/crafting/robot.dm @@ -119,7 +119,7 @@ /datum/crafting_recipe/vibebot name = "Vibebot" - result = /mob/living/simple_animal/bot/vibebot + result = /mob/living/basic/bot/vibebot reqs = list( /obj/item/light/bulb = 2, /obj/item/bodypart/head/robot = 1, diff --git a/code/datums/components/trapdoor.dm b/code/datums/components/trapdoor.dm index f76dcf35e705a..32b72c48853e5 100644 --- a/code/datums/components/trapdoor.dm +++ b/code/datums/components/trapdoor.dm @@ -349,8 +349,8 @@ . = ..() AddElement(/datum/element/openspace_item_click_handler) -/obj/item/trapdoor_kit/handle_openspace_click(turf/target, mob/user, click_parameters) - interact_with_atom(target, user, click_parameters) +/obj/item/trapdoor_kit/handle_openspace_click(turf/target, mob/user, list/modifiers) + interact_with_atom(target, user, modifiers) /obj/item/trapdoor_kit/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) var/turf/target_turf = get_turf(interacting_with) diff --git a/code/datums/elements/openspace_item_click_handler.dm b/code/datums/elements/openspace_item_click_handler.dm index f34bd0f0bda1f..9059223fb0c35 100644 --- a/code/datums/elements/openspace_item_click_handler.dm +++ b/code/datums/elements/openspace_item_click_handler.dm @@ -8,22 +8,19 @@ . = ..() if(!isitem(target)) return ELEMENT_INCOMPATIBLE - RegisterSignal(target, COMSIG_ITEM_INTERACTING_WITH_ATOM, PROC_REF(divert_interaction)) + RegisterSignal(target, COMSIG_RANGED_ITEM_INTERACTING_WITH_ATOM, PROC_REF(divert_interaction)) /datum/element/openspace_item_click_handler/Detach(datum/source) - UnregisterSignal(source, COMSIG_ITEM_INTERACTING_WITH_ATOM) + UnregisterSignal(source, COMSIG_RANGED_ITEM_INTERACTING_WITH_ATOM) return ..() //Invokes the proctype with a turf above as target. -/datum/element/openspace_item_click_handler/proc/divert_interaction(obj/item/source, mob/user, atom/target, click_parameters) +/datum/element/openspace_item_click_handler/proc/divert_interaction(obj/item/source, mob/user, atom/target, list/modifiers) SIGNAL_HANDLER if((target.z == 0) || (user.z == 0) || target.z == user.z) return NONE - var/turf/checked_turf = get_turf(target) - while(!isnull(checked_turf)) - checked_turf = GET_TURF_ABOVE(checked_turf) - if(checked_turf?.z == user.z && user.CanReach(checked_turf, source)) - INVOKE_ASYNC(source, TYPE_PROC_REF(/obj/item, handle_openspace_click), checked_turf, user, click_parameters) - return ITEM_INTERACT_BLOCKING - + var/turf/target_turf = parse_caught_click_modifiers(modifiers, get_turf(user.client?.eye || user), user.client) + if(target_turf?.z == user.z && user.CanReach(target_turf, source)) + INVOKE_ASYNC(source, TYPE_PROC_REF(/obj/item, handle_openspace_click), target_turf, user, modifiers) + return ITEM_INTERACT_BLOCKING return NONE diff --git a/code/datums/id_trim/outfits.dm b/code/datums/id_trim/outfits.dm index 2e7aebff26a1b..a2944a469f43e 100644 --- a/code/datums/id_trim/outfits.dm +++ b/code/datums/id_trim/outfits.dm @@ -62,6 +62,7 @@ trim_state = "trim_bitavatar" department_color = COLOR_BLACK subdepartment_color = COLOR_GREEN + sechud_icon_state = SECHUD_BITAVATAR /// Trim for cyber police in the Virtual Domain. /datum/id_trim/cyber_police diff --git a/code/datums/station_traits/neutral_traits.dm b/code/datums/station_traits/neutral_traits.dm index e066079802d7a..0ecb49f96a063 100644 --- a/code/datums/station_traits/neutral_traits.dm +++ b/code/datums/station_traits/neutral_traits.dm @@ -197,6 +197,7 @@ if(length(birthday_options)) birthday_person = pick(birthday_options) birthday_person_name = birthday_person.real_name + ADD_TRAIT(birthday_person, TRAIT_BIRTHDAY_BOY, REF(src)) addtimer(CALLBACK(src, PROC_REF(announce_birthday)), 10 SECONDS) /datum/station_trait/birthday/proc/check_valid_override() diff --git a/code/game/objects/effects/anomalies/_anomalies.dm b/code/game/objects/effects/anomalies/_anomalies.dm index ee02cab9e036b..ce9bab6a511cc 100644 --- a/code/game/objects/effects/anomalies/_anomalies.dm +++ b/code/game/objects/effects/anomalies/_anomalies.dm @@ -113,12 +113,13 @@ qdel(src) -/obj/effect/anomaly/attackby(obj/item/weapon, mob/user, params) - if(weapon.tool_behaviour == TOOL_ANALYZER && anomaly_core) +/obj/effect/anomaly/analyzer_act(mob/living/user, obj/item/analyzer/tool) + if(!isnull(anomaly_core)) to_chat(user, span_notice("Analyzing... [src]'s unstable field is fluctuating along frequency [format_frequency(anomaly_core.frequency)], code [anomaly_core.code].")) - return TRUE + return ITEM_INTERACT_SUCCESS + to_chat(user, span_notice("Analyzing... [src]'s unstable field is not fluctuating along a stable frequency.")) + return ITEM_INTERACT_BLOCKING - return ..() ///Stabilize an anomaly, letting it stay around forever or untill destabilizes by a player. An anomaly without a core can't be signalled, but can be destabilized /obj/effect/anomaly/proc/stabilize(anchor = FALSE, has_core = TRUE) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 79dd9d7e6ed05..6a63488d4cb8e 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -1426,7 +1426,7 @@ mob_loc.update_clothing(slot_flags) /// Called on [/datum/element/openspace_item_click_handler/proc/on_afterattack]. Check the relative file for information. -/obj/item/proc/handle_openspace_click(turf/target, mob/user, click_parameters) +/obj/item/proc/handle_openspace_click(turf/target, mob/user, list/modifiers) stack_trace("Undefined handle_openspace_click() behaviour. Ascertain the openspace_item_click_handler element has been attached to the right item and that its proc override doesn't call parent.") /** diff --git a/code/game/objects/items/holosign_creator.dm b/code/game/objects/items/holosign_creator.dm index ff4d0260c4f35..926131151e92b 100644 --- a/code/game/objects/items/holosign_creator.dm +++ b/code/game/objects/items/holosign_creator.dm @@ -26,8 +26,8 @@ AddElement(/datum/element/openspace_item_click_handler) RegisterSignal(src, COMSIG_OBJ_PAINTED, TYPE_PROC_REF(/obj/item/holosign_creator, on_color_change)) -/obj/item/holosign_creator/handle_openspace_click(turf/target, mob/user, click_parameters) - interact_with_atom(target, user, click_parameters) +/obj/item/holosign_creator/handle_openspace_click(turf/target, mob/user, list/modifiers) + interact_with_atom(target, user, modifiers) /obj/item/holosign_creator/examine(mob/user) . = ..() diff --git a/code/game/objects/items/rcd/RCD.dm b/code/game/objects/items/rcd/RCD.dm index 2a7611235310c..cf254e447818d 100644 --- a/code/game/objects/items/rcd/RCD.dm +++ b/code/game/objects/items/rcd/RCD.dm @@ -70,6 +70,7 @@ construction_mode = mode GLOB.rcd_list += src + AddElement(/datum/element/openspace_item_click_handler) /obj/item/construction/rcd/Destroy() QDEL_NULL(airlock_electronics) @@ -420,6 +421,9 @@ rcd_create(interacting_with, user) return ITEM_INTERACT_SUCCESS +/obj/item/construction/rcd/handle_openspace_click(turf/target, mob/user, list/modifiers) + interact_with_atom(target, user, modifiers) + /obj/item/construction/rcd/proc/detonate_pulse() audible_message("[src] begins to vibrate and \ buzz loudly!","[src] begins \ diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm index 6011e0b396159..82f19d09d9692 100644 --- a/code/game/objects/items/stacks/rods.dm +++ b/code/game/objects/items/stacks/rods.dm @@ -63,8 +63,8 @@ GLOBAL_LIST_INIT(rod_recipes, list ( \ slapcraft_recipes = slapcraft_recipe_list,\ ) -/obj/item/stack/rods/handle_openspace_click(turf/target, mob/user, click_parameters) - target.attackby(src, user, click_parameters) +/obj/item/stack/rods/handle_openspace_click(turf/target, mob/user, list/modifiers) + target.attackby(src, user, list2params(modifiers)) /obj/item/stack/rods/get_main_recipes() . = ..() diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index 700116ac1e18f..073a35ed1013c 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -101,8 +101,8 @@ playsound(target_plating, 'sound/weapons/genhit.ogg', 50, TRUE) return target_plating -/obj/item/stack/tile/handle_openspace_click(turf/target, mob/user, click_parameters) - target.attackby(src, user, click_parameters) +/obj/item/stack/tile/handle_openspace_click(turf/target, mob/user, list/modifiers) + target.attackby(src, user, list2params(modifiers)) //Grass /obj/item/stack/tile/grass diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index b4d35efdda12a..bdbfa79001ddf 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -415,6 +415,16 @@ if(tank_assembly) tank_assembly.attack_hand() +/obj/item/tank/attack_self(mob/user, modifiers) + if (tank_assembly) + tank_assembly.attack_self(user) + return TRUE + return ..() + +/obj/item/tank/attack_self_secondary(mob/user, modifiers) + . = ..() + ui_interact(user) + /obj/item/tank/Move() . = ..() if(tank_assembly) diff --git a/code/modules/antagonists/space_dragon/carp_rift.dm b/code/modules/antagonists/space_dragon/carp_rift.dm index 4b8a20acba8d1..828ee94587fcb 100644 --- a/code/modules/antagonists/space_dragon/carp_rift.dm +++ b/code/modules/antagonists/space_dragon/carp_rift.dm @@ -19,7 +19,7 @@ return var/area/rift_location = get_area(owner) if(!(rift_location in dragon.chosen_rift_areas)) - owner.balloon_alert(owner, "can't summon a rift here!") + owner.balloon_alert(owner, "can't summon a rift here! check your objectives!") return for(var/obj/structure/carp_rift/rift as anything in dragon.rift_list) var/area/used_location = get_area(rift) diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index 1d8936e6068da..5c7f5208254f0 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -153,7 +153,7 @@ * * user: The mob handling the trap */ /obj/item/assembly/mousetrap/proc/clumsy_check(mob/living/carbon/human/user) - if(!armed) + if(!armed || !user) return FALSE if((HAS_TRAIT(user, TRAIT_DUMB) || HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50)) var/which_hand = BODY_ZONE_PRECISE_L_HAND diff --git a/code/modules/bitrunning/components/avatar_connection.dm b/code/modules/bitrunning/components/avatar_connection.dm index b533e2b5661d6..a92e8ef3d2e6e 100644 --- a/code/modules/bitrunning/components/avatar_connection.dm +++ b/code/modules/bitrunning/components/avatar_connection.dm @@ -60,9 +60,16 @@ var/datum/action/avatar_domain_info/action = new(help_datum) action.Grant(avatar) + var/client/our_client = old_body.client + var/alias = our_client?.prefs?.read_preference(/datum/preference/name/hacker_alias) || pick(GLOB.hacker_aliases) + + if(alias && avatar.real_name != alias) + avatar.fully_replace_character_name(avatar.real_name, alias) + avatar.playsound_local(avatar, 'sound/magic/blink.ogg', 25, TRUE) avatar.set_static_vision(2 SECONDS) - avatar.set_temp_blindness(1 SECONDS) + avatar.set_temp_blindness(1 SECONDS) // I'm in + /datum/component/avatar_connection/PostTransfer() var/obj/machinery/netpod/pod = netpod_ref?.resolve() @@ -74,6 +81,7 @@ pod.avatar_ref = WEAKREF(parent) + /datum/component/avatar_connection/RegisterWithParent() ADD_TRAIT(parent, TRAIT_TEMPORARY_BODY, REF(src)) /** @@ -87,6 +95,7 @@ RegisterSignal(parent, COMSIG_LIVING_DEATH, PROC_REF(on_sever_connection)) RegisterSignal(parent, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(on_linked_damage)) + /datum/component/avatar_connection/UnregisterFromParent() REMOVE_TRAIT(parent, TRAIT_TEMPORARY_BODY, REF(src)) UnregisterSignal(parent, list( @@ -98,6 +107,7 @@ COMSIG_MOB_APPLY_DAMAGE, )) + /// Disconnects the avatar and returns the mind to the old_body. /datum/component/avatar_connection/proc/full_avatar_disconnect(cause_damage = FALSE, datum/source) #ifndef UNIT_TESTS @@ -115,6 +125,7 @@ qdel(src) + /// Triggers whenever the server gets a loot crate pushed to goal area /datum/component/avatar_connection/proc/on_domain_completed(datum/source, atom/entered) SIGNAL_HANDLER @@ -127,6 +138,7 @@ new_master = entered, ) + /// Transfers damage from the avatar to the old_body /datum/component/avatar_connection/proc/on_linked_damage(datum/source, damage, damage_type, def_zone, blocked, ...) SIGNAL_HANDLER @@ -147,6 +159,7 @@ if(old_body.stat > SOFT_CRIT) // KO! full_avatar_disconnect(cause_damage = TRUE) + /// Handles minds being swapped around in subsequent avatars /datum/component/avatar_connection/proc/on_mind_transfer(datum/mind/source, mob/living/previous_body) SIGNAL_HANDLER @@ -157,6 +170,7 @@ source.current.TakeComponent(src) + /// Triggers when someone starts prying open our netpod /datum/component/avatar_connection/proc/on_netpod_crowbar(datum/source, mob/living/intruder) SIGNAL_HANDLER @@ -171,6 +185,7 @@ alert.name = "Netpod Breached" alert.desc = "Someone is prying open the netpod. Find an exit." + /// Triggers when the netpod is taking damage and is under 50% /datum/component/avatar_connection/proc/on_netpod_damaged(datum/source) SIGNAL_HANDLER @@ -184,24 +199,28 @@ alert.name = "Integrity Compromised" alert.desc = "The netpod is damaged. Find an exit." + //if your bitrunning avatar somehow manages to acquire and consume a red pill, they will be ejected from the Matrix /datum/component/avatar_connection/proc/disconnect_if_red_pill(datum/source, obj/item/reagent_containers/pill/pill, mob/feeder) SIGNAL_HANDLER if(pill.icon_state == "pill4") full_avatar_disconnect() + /// Triggers when a safe disconnect is called /datum/component/avatar_connection/proc/on_safe_disconnect(datum/source) SIGNAL_HANDLER full_avatar_disconnect() + /// Received message to sever connection /datum/component/avatar_connection/proc/on_sever_connection(datum/source) SIGNAL_HANDLER full_avatar_disconnect(cause_damage = TRUE, source = source) + /// Triggers when the server is shutting down /datum/component/avatar_connection/proc/on_shutting_down(datum/source, mob/living/hackerman) SIGNAL_HANDLER @@ -216,6 +235,7 @@ alert.name = "Domain Rebooting" alert.desc = "The domain is rebooting. Find an exit." + /// Triggers whenever an antag steps onto an exit turf and the server is emagged /datum/component/avatar_connection/proc/on_station_spawn(datum/source) SIGNAL_HANDLER @@ -230,6 +250,7 @@ alert.name = "Security Breach" alert.desc = "A hostile entity is breaching the safehouse. Find an exit." + /// Server has spawned a ghost role threat /datum/component/avatar_connection/proc/on_threat_created(datum/source) SIGNAL_HANDLER @@ -243,6 +264,7 @@ alert.name = "Threat Detected" alert.desc = "Data stream abnormalities present." + /// Returns the mind to the old body /datum/component/avatar_connection/proc/return_to_old_body() var/datum/mind/old_mind = old_mind_ref?.resolve() diff --git a/code/modules/bitrunning/server/obj_generation.dm b/code/modules/bitrunning/server/obj_generation.dm index e8dbd72228c1d..34a870a3426d5 100644 --- a/code/modules/bitrunning/server/obj_generation.dm +++ b/code/modules/bitrunning/server/obj_generation.dm @@ -76,9 +76,6 @@ var/obj/item/card/id/outfit_id = avatar.wear_id if(outfit_id) - outfit_id.assignment = "Bit Avatar" - outfit_id.registered_name = avatar.real_name - outfit_id.registered_account = new() outfit_id.registered_account.replaceable = FALSE diff --git a/code/modules/client/preferences/names.dm b/code/modules/client/preferences/names.dm index 9afc8da18c1aa..8456eb9a62709 100644 --- a/code/modules/client/preferences/names.dm +++ b/code/modules/client/preferences/names.dm @@ -174,3 +174,15 @@ return TRUE return FALSE + + +/// The name to use while bitrunning +/datum/preference/name/hacker_alias + explanation = "Hacker alias" + group = "bitrunning" + savefile_key = "hacker_alias" + allow_numbers = TRUE + relevant_job = /datum/job/bitrunner + +/datum/preference/name/hacker_alias/create_default_value() + return pick(GLOB.hacker_aliases) diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index 807e795568821..ef90fcf97e10a 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -221,6 +221,7 @@ GLOBAL_LIST_INIT(clown_mask_options, list( visor_flags_cover = MASKCOVERSEYES visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT resistance_flags = FIRE_PROOF + clothing_flags = parent_type::clothing_flags | INTERNALS_ADJUST_EXEMPT /datum/armor/gas_welding melee = 10 diff --git a/code/modules/mob/living/basic/bots/vibebot/vibebot.dm b/code/modules/mob/living/basic/bots/vibebot/vibebot.dm new file mode 100644 index 0000000000000..c872e1ea5959c --- /dev/null +++ b/code/modules/mob/living/basic/bots/vibebot/vibebot.dm @@ -0,0 +1,30 @@ +/mob/living/basic/bot/vibebot + name = "\improper Vibebot" + desc = "A little robot. It's just vibing, doing its thing." + icon = 'icons/mob/silicon/aibots.dmi' + icon_state = "vibebot1" + base_icon_state = "vibebot" + pass_flags = PASSMOB | PASSFLAPS + light_system = OVERLAY_LIGHT + light_range = 6 + ai_controller = /datum/ai_controller/basic_controller/bot/vibebot + light_power = 2 + + hackables = "vibing scanners" + radio_key = /obj/item/encryptionkey/headset_service + radio_channel = RADIO_CHANNEL_SERVICE + bot_type = VIBE_BOT + data_hud_type = DATA_HUD_DIAGNOSTIC_BASIC + path_image_color = "#2cac12" + possessed_message = "You are a vibebot! Maintain the station's vibes to the best of your ability!" + +/mob/living/basic/bot/vibebot/Initialize(mapload) + . = ..() + var/static/list/innate_actions = list( + /datum/action/cooldown/mob_cooldown/bot/vibe = BB_VIBEBOT_PARTY_ABILITY, + ) + + grant_actions_by_list(innate_actions) + var/obj/item/instrument/piano_synth/piano = new(src) + ai_controller.set_blackboard_key(BB_SONG_INSTRUMENT, piano) + update_appearance(UPDATE_ICON) diff --git a/code/modules/mob/living/basic/bots/vibebot/vibebot_abilities.dm b/code/modules/mob/living/basic/bots/vibebot/vibebot_abilities.dm new file mode 100644 index 0000000000000..b3fcec9813b0b --- /dev/null +++ b/code/modules/mob/living/basic/bots/vibebot/vibebot_abilities.dm @@ -0,0 +1,59 @@ +/** + * Vibebot's vibe ability + * + * Given to vibebots so sentient ones can change/reset thier colors at will. + */ +#define VIBE_MOOD_TIMER 30 SECONDS +/datum/action/cooldown/mob_cooldown/bot/vibe + name = "Vibe" + desc = "Use on yourself to remove color!" + click_to_activate = TRUE + button_icon = 'icons/mob/actions/actions_minor_antag.dmi' + button_icon_state = "funk" + ///cooldown to apply a new mood + COOLDOWN_DECLARE(change_mood) + +/datum/action/cooldown/mob_cooldown/bot/vibe/Grant(mob/granted_to) + . = ..() + if(isnull(granted_to)) + return + RegisterSignal(granted_to, COMSIG_BOT_RESET, PROC_REF(remove_colors)) + +/datum/action/cooldown/mob_cooldown/bot/vibe/Activate(atom/target) + if(target == owner) + remove_colors() + return TRUE + vibe() + StartCooldown() + return TRUE + +///Gives a random color +/datum/action/cooldown/mob_cooldown/bot/vibe/proc/vibe() + var/mob/living/basic/bot/bot_owner = owner + var/final_color = (bot_owner.bot_access_flags & BOT_COVER_EMAGGED) ? COLOR_GRAY : "#[random_color()]" + owner.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY) + owner.add_atom_colour(final_color, TEMPORARY_COLOUR_PRIORITY) + owner.set_light_color(owner.color) + if(!COOLDOWN_FINISHED(src, change_mood)) + return + var/mood_to_add = bot_owner.bot_access_flags & BOT_COVER_EMAGGED ? /datum/mood_event/depressing_party : /datum/mood_event/festive_party + for(var/mob/living/carbon/human/human_target in oview(1, owner)) + human_target.add_mood_event("vibebot_party", mood_to_add) + COOLDOWN_START(src, change_mood, VIBE_MOOD_TIMER) + +///Removes all colors +/datum/action/cooldown/mob_cooldown/bot/vibe/proc/remove_colors() + owner.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY) + owner.set_light_color(null) + +/datum/mood_event/depressing_party + description = "That was a really grim party..." + mood_change = -1 + timeout = 30 SECONDS + +/datum/mood_event/festive_party + description = "That was a really fantastic party!" + mood_change = 2 + timeout = 30 SECONDS + +#undef VIBE_MOOD_TIMER diff --git a/code/modules/mob/living/basic/bots/vibebot/vibebot_ai.dm b/code/modules/mob/living/basic/bots/vibebot/vibebot_ai.dm new file mode 100644 index 0000000000000..945b09274d783 --- /dev/null +++ b/code/modules/mob/living/basic/bots/vibebot/vibebot_ai.dm @@ -0,0 +1,88 @@ +/datum/ai_controller/basic_controller/bot/vibebot + blackboard = list( + BB_UNREACHABLE_LIST_COOLDOWN = 2 MINUTES, + BB_VIBEBOT_HAPPY_SONG = VIBEBOT_CHEER_SONG, + BB_VIBEBOT_GRIM_SONG = VIBEBOT_GRIM_MUSIC, + BB_VIBEBOT_BIRTHDAY_SONG = VIBEBOT_HAPPY_BIRTHDAY, + ) + planning_subtrees = list( + /datum/ai_planning_subtree/respond_to_summon, + /datum/ai_planning_subtree/manage_unreachable_list, + /datum/ai_planning_subtree/find_party_friends, + /datum/ai_planning_subtree/find_patrol_beacon, + ) + reset_keys = list( + BB_BEACON_TARGET, + BB_PREVIOUS_BEACON_TARGET, + BB_VIBEBOT_PARTY_TARGET, + BB_BOT_SUMMON_TARGET, + ) + ai_traits = PAUSE_DURING_DO_AFTER + +/datum/ai_controller/basic_controller/bot/vibebot/TryPossessPawn(atom/new_pawn) + . = ..() + if(. & AI_CONTROLLER_INCOMPATIBLE) + return + RegisterSignal(new_pawn, COMSIG_AI_BLACKBOARD_KEY_SET(BB_VIBEBOT_PARTY_TARGET), PROC_REF(play_music)) + +/datum/ai_controller/basic_controller/bot/vibebot/proc/play_music(datum/source, blackboard_key) + SIGNAL_HANDLER + + var/mob/living/basic/bot/living_bot = pawn + var/obj/item/instrument/instrument = blackboard[BB_SONG_INSTRUMENT] + if(isnull(instrument)) + return + var/atom/target = blackboard[blackboard_key] + var/datum/song/song = instrument.song + song.stop_playing() + var/song_lines + if(living_bot.bot_access_flags & BOT_COVER_EMAGGED) + song_lines = blackboard[BB_VIBEBOT_GRIM_SONG] + else + song_lines = HAS_TRAIT(target, TRAIT_BIRTHDAY_BOY) ? blackboard[BB_VIBEBOT_BIRTHDAY_SONG] : blackboard[BB_VIBEBOT_HAPPY_SONG] + if(isnull(song_lines)) + return + song.ParseSong(new_song = song_lines) + song.start_playing(pawn) + addtimer(CALLBACK(song, TYPE_PROC_REF(/datum/song, stop_playing)), 10 SECONDS) //in 10 seconds, stop playing music + +///subtree we use to find party friends in general +/datum/ai_planning_subtree/find_party_friends + +/datum/ai_planning_subtree/find_party_friends/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + var/static/list/type_to_search = typecacheof(list(/mob/living/carbon/human)) + if(!controller.blackboard_key_exists(BB_VIBEBOT_PARTY_TARGET)) + controller.queue_behavior(/datum/ai_behavior/bot_search/party_friends, BB_VIBEBOT_PARTY_TARGET, type_to_search) + return + + controller.queue_behavior(/datum/ai_behavior/targeted_mob_ability/and_clear_target/vibebot_party, BB_VIBEBOT_PARTY_ABILITY, BB_VIBEBOT_PARTY_TARGET) + return SUBTREE_RETURN_FINISH_PLANNING + +///behavior we use to party with people +/datum/ai_behavior/targeted_mob_ability/and_clear_target/vibebot_party + behavior_flags = AI_BEHAVIOR_REQUIRE_REACH | AI_BEHAVIOR_REQUIRE_MOVEMENT + +/datum/ai_behavior/targeted_mob_ability/and_clear_target/vibebot_party/setup(datum/ai_controller/controller, ability_key, target_key) + . = ..() + var/atom/target = controller.blackboard[target_key] + if(QDELETED(target)) + return FALSE + set_movement_target(controller, target) + +/datum/ai_behavior/targeted_mob_ability/and_clear_target/vibebot_party/finish_action(datum/ai_controller/controller, succeeded, ability_key, target_key) + var/atom/target = controller.blackboard[target_key] + controller.set_blackboard_key_assoc_lazylist(BB_TEMPORARY_IGNORE_LIST, target, TRUE) + if(succeeded) + var/mob/living/living_pawn = controller.pawn + living_pawn.manual_emote("celebrates with [target]!") + living_pawn.emote("flip") + return ..() + +///behavior that searches for party friends +/datum/ai_behavior/bot_search/party_friends + action_cooldown = 5 SECONDS + +/datum/ai_behavior/bot_search/party_friends/valid_target(datum/ai_controller/basic_controller/bot/controller, mob/living/carbon/human/my_target) + if(my_target.stat != CONSCIOUS || isnull(my_target.mind)) + return FALSE + return (my_target.mob_mood.mood_level < MOOD_LEVEL_NEUTRAL || HAS_TRAIT(my_target, TRAIT_BIRTHDAY_BOY)) diff --git a/code/modules/mob/living/basic/slime/life.dm b/code/modules/mob/living/basic/slime/life.dm index 68cd33ce7750b..d101b48fea7a1 100644 --- a/code/modules/mob/living/basic/slime/life.dm +++ b/code/modules/mob/living/basic/slime/life.dm @@ -36,10 +36,10 @@ ///Handles the consumption of nutrition, and growth /mob/living/basic/slime/proc/handle_nutrition(seconds_per_tick = SSMOBS_DT) if(hunger_disabled) //God as my witness, I will never go hungry again - set_nutrition(700) + set_nutrition(100) return - if(SPT_PROB(7.5, seconds_per_tick)) + if(SPT_PROB(1.25, seconds_per_tick)) adjust_nutrition((life_stage == SLIME_LIFE_STAGE_ADULT ? -1 : -0.5) * seconds_per_tick) if(nutrition < SLIME_STARVE_NUTRITION) @@ -63,7 +63,7 @@ if (SLIME_GROW_NUTRITION <= nutrition) if(amount_grown < SLIME_EVOLUTION_THRESHOLD) - adjust_nutrition(-10 * seconds_per_tick) + adjust_nutrition(-2.5 * seconds_per_tick) amount_grown++ if(powerlevel < SLIME_MAX_POWER && SPT_PROB(30-powerlevel*2, seconds_per_tick)) diff --git a/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm b/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm index 2286f65b79758..1776e69358139 100644 --- a/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm +++ b/code/modules/mob/living/basic/space_fauna/space_dragon/space_dragon.dm @@ -4,7 +4,7 @@ #define DOAFTER_SOURCE_SPACE_DRAGON_INTERACTION "space dragon interaction" /** - * Advanced stage of the space carp life cycle, spawned as a midround antagonist or via traitor transformation. + * Advanced stage of the space carp life cycle, spawned as a midround antagonist * Can eat corpses to heal, blow people back with its wings, and obviously as a dragon it breathes fire. It can even tear through walls. * The midround even version also creates rifts which summon carp, and heals when near them. */ @@ -47,6 +47,9 @@ death_message = "screeches in agony as it collapses to the floor, its life extinguished." butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/bone = 30) can_buckle_to = FALSE + lighting_cutoff_red = 12 + lighting_cutoff_green = 15 + lighting_cutoff_blue = 34 /// The colour of the space dragon var/chosen_colour diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 19e4b7a43deb6..b1efa734321c5 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -292,8 +292,8 @@ return toggle_open_internals(tank, is_external) // Use mask in absence of tube. if(isclothing(wear_mask) && ((wear_mask.visor_flags & MASKINTERNALS) || (wear_mask.clothing_flags & MASKINTERNALS))) - // Adjust dishevelled breathing mask back onto face. - if (wear_mask.up) + // Adjust dishevelled breathing mask back onto face unless it is exempt. + if ((wear_mask.up) && !(wear_mask.clothing_flags & INTERNALS_ADJUST_EXEMPT)) wear_mask.adjust_visor(src) return toggle_open_internals(tank, is_external) // Use helmet in absence of tube or valid mask. diff --git a/code/modules/mob/living/simple_animal/bot/vibebot.dm b/code/modules/mob/living/simple_animal/bot/vibebot.dm deleted file mode 100644 index 582b1b5371da5..0000000000000 --- a/code/modules/mob/living/simple_animal/bot/vibebot.dm +++ /dev/null @@ -1,97 +0,0 @@ -/mob/living/simple_animal/bot/vibebot - name = "\improper Vibebot" - desc = "A little robot. It's just vibing, doing its thing." - icon = 'icons/mob/silicon/aibots.dmi' - icon_state = "vibebot1" - base_icon_state = "vibebot" - density = FALSE - anchored = FALSE - health = 25 - maxHealth = 25 - pass_flags = PASSMOB | PASSFLAPS - light_system = OVERLAY_LIGHT - light_range = 6 - light_power = 2 - - hackables = "vibing scanners" - radio_key = /obj/item/encryptionkey/headset_service - radio_channel = RADIO_CHANNEL_SERVICE - bot_type = VIBE_BOT - data_hud_type = DATA_HUD_DIAGNOSTIC_BASIC - path_image_color = "#2cac12" - possessed_message = "You are a vibebot! Maintain the station's vibes to the best of your ability!" - - ///The vibe ability given to vibebots, so sentient ones can still change their color. - var/datum/action/innate/vibe/vibe_ability - -/mob/living/simple_animal/bot/vibebot/Initialize(mapload) - . = ..() - vibe_ability = new(src) - vibe_ability.Grant(src) - update_appearance(UPDATE_ICON) - -/mob/living/simple_animal/bot/vibebot/Destroy() - QDEL_NULL(vibe_ability) - return ..() - -/mob/living/simple_animal/bot/vibebot/handle_automated_action() - . = ..() - if(!.) - return - - if(bot_mode_flags & BOT_MODE_ON) - vibe_ability.Trigger() - - if(!(bot_mode_flags & BOT_MODE_AUTOPATROL)) - return - - switch(mode) - if(BOT_IDLE, BOT_START_PATROL) - start_patrol() - if(BOT_PATROL) - bot_patrol() - -/mob/living/simple_animal/bot/vibebot/turn_off() - vibe_ability.remove_colors() - return ..() - -/** - * Vibebot's vibe ability - * - * Given to vibebots so sentient ones can change/reset thier colors at will. - */ -/datum/action/innate/vibe - name = "Vibe" - desc = "LMB: Change vibe color. RMB: Reset vibe color." - button_icon = 'icons/mob/actions/actions_minor_antag.dmi' - button_icon_state = "funk" - -/datum/action/innate/vibe/IsAvailable(feedback = FALSE) - . = ..() - if(!.) - return FALSE - if(isbot(owner)) - var/mob/living/simple_animal/bot/bot_mob = owner - if(!(bot_mob.bot_mode_flags & BOT_MODE_ON)) - return FALSE - return TRUE - -/datum/action/innate/vibe/Trigger(trigger_flags) - . = ..() - if(!.) - return - if(trigger_flags & TRIGGER_SECONDARY_ACTION) - remove_colors() - else - vibe() - -///Gives a random color -/datum/action/innate/vibe/proc/vibe() - owner.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY) - owner.add_atom_colour("#[random_color()]", TEMPORARY_COLOUR_PRIORITY) - owner.set_light_color(owner.color) - -///Removes all colors -/datum/action/innate/vibe/proc/remove_colors() - owner.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY) - owner.set_light_color(null) diff --git a/code/modules/research/techweb/_techweb.dm b/code/modules/research/techweb/_techweb.dm index b4b137d8e2187..3c920f6b9a6fe 100644 --- a/code/modules/research/techweb/_techweb.dm +++ b/code/modules/research/techweb/_techweb.dm @@ -108,7 +108,7 @@ /datum/techweb/proc/add_point_list(list/pointlist) for(var/i in pointlist) if((i in SSresearch.point_types) && pointlist[i] > 0) - research_points[i] += pointlist[i] + research_points[i] = FLOOR(research_points[i] + pointlist[i], 0.1) /datum/techweb/proc/add_points_all(amount) var/list/l = SSresearch.point_types.Copy() @@ -119,7 +119,7 @@ /datum/techweb/proc/remove_point_list(list/pointlist) for(var/i in pointlist) if((i in SSresearch.point_types) && pointlist[i] > 0) - research_points[i] = max(0, research_points[i] - pointlist[i]) + research_points[i] = FLOOR(max(0, research_points[i] - pointlist[i]), 0.1) /datum/techweb/proc/remove_points_all(amount) var/list/l = SSresearch.point_types.Copy() @@ -130,7 +130,7 @@ /datum/techweb/proc/modify_point_list(list/pointlist) for(var/i in pointlist) if((i in SSresearch.point_types) && pointlist[i] != 0) - research_points[i] = max(0, research_points[i] + pointlist[i]) + research_points[i] = FLOOR(max(0, research_points[i] + pointlist[i]), 0.1) /datum/techweb/proc/modify_points_all(amount) var/list/l = SSresearch.point_types.Copy() diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm index ea4ef0e9b7ed1..5dbe284026d59 100644 --- a/code/modules/research/xenobiology/xenobio_camera.dm +++ b/code/modules/research/xenobiology/xenobio_camera.dm @@ -426,13 +426,20 @@ Due to keyboard shortcuts, the second one is not necessarily the remote eye's lo if(!isopenturf(target_turf)) return + var/cleanup = FALSE var/mob/camera/ai_eye/remote/xenobio/remote_eye = user.remote_control var/obj/machinery/computer/camera_advanced/xenobio/xeno_console = remote_eye.origin if(!xeno_console.validate_area(user, remote_eye, target_turf)) return - xeno_console.feed_slime(user, target_turf) + for(var/mob/monkey in target_turf) + if(ismonkey(monkey) && monkey.stat == DEAD) + cleanup = TRUE + xeno_console.monkey_recycle(user, monkey) + + if(!cleanup) + xeno_console.feed_slime(user, target_turf) ///Picks up a dead monkey for recycling /obj/machinery/computer/camera_advanced/xenobio/proc/XenoMonkeyClickCtrl(mob/living/user, mob/living/carbon/human/target_mob) diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm index 5685b12b9ef62..66f42c1e039ba 100644 --- a/code/modules/surgery/bodyparts/head.dm +++ b/code/modules/surgery/bodyparts/head.dm @@ -76,6 +76,9 @@ ///Current lipstick trait, if any (such as TRAIT_KISS_OF_DEATH) var/stored_lipstick_trait + /// How many teeth the head's species has, humans have 32 so that's the default. Used for a limit to dental pill implants. + var/teeth_count = 32 + /// Offset to apply to equipment worn on the ears var/datum/worn_feature_offset/worn_ears_offset /// Offset to apply to equipment worn on the eyes diff --git a/code/modules/surgery/bodyparts/species_parts/ethereal_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/ethereal_bodyparts.dm index 20e4b58660795..05645ed20df2e 100644 --- a/code/modules/surgery/bodyparts/species_parts/ethereal_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/ethereal_bodyparts.dm @@ -103,3 +103,4 @@ icon_state = "lustrous_head" limb_id = SPECIES_ETHEREAL_LUSTROUS head_flags = NONE + teeth_count = 0 // bro you seen these thinsg. they got a crystal for a head aint no teeth here diff --git a/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm index 157e5b04fe68e..350e2f32883fb 100644 --- a/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm @@ -3,6 +3,8 @@ limb_id = SPECIES_LIZARD is_dimorphic = FALSE head_flags = HEAD_LIPS|HEAD_EYESPRITES|HEAD_EYECOLOR|HEAD_EYEHOLES|HEAD_DEBRAIN + // lizardshave many teeth + teeth_count = 72 /obj/item/bodypart/chest/lizard icon_greyscale = 'icons/mob/human/species/lizard/bodyparts.dmi' diff --git a/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm index fa3ab9cc49d39..f9a71a4e6d4dd 100644 --- a/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm @@ -5,6 +5,7 @@ burn_modifier = 2 head_flags = HEAD_EYESPRITES|HEAD_DEBRAIN biological_state = (BIO_FLESH|BIO_BLOODED) + teeth_count = 0 /obj/item/bodypart/chest/snail limb_id = SPECIES_SNAIL @@ -51,6 +52,7 @@ is_dimorphic = FALSE should_draw_greyscale = FALSE head_flags = NONE + teeth_count = 0 /obj/item/bodypart/chest/abductor limb_id = SPECIES_ABDUCTOR @@ -146,6 +148,7 @@ ///LUMINESCENT /obj/item/bodypart/head/jelly/luminescent limb_id = SPECIES_LUMINESCENT + teeth_count = 0 /obj/item/bodypart/chest/jelly/luminescent limb_id = SPECIES_LUMINESCENT @@ -250,6 +253,7 @@ is_dimorphic = FALSE should_draw_greyscale = FALSE head_flags = HEAD_EYESPRITES|HEAD_EYEHOLES|HEAD_DEBRAIN + teeth_count = 0 /obj/item/bodypart/chest/fly limb_id = SPECIES_FLYPERSON @@ -367,6 +371,7 @@ is_dimorphic = TRUE burn_modifier = 1.25 head_flags = NONE + teeth_count = 0 /obj/item/bodypart/chest/mushroom limb_id = SPECIES_MUSHROOM @@ -436,6 +441,8 @@ should_draw_greyscale = FALSE dmg_overlay_type = null head_flags = NONE + // too hard to drill through + teeth_count = 0 /obj/item/bodypart/head/golem/Initialize(mapload) worn_ears_offset = new( diff --git a/code/modules/surgery/bodyparts/species_parts/moth_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/moth_bodyparts.dm index 375b37ca434d6..323cef05b8c5d 100644 --- a/code/modules/surgery/bodyparts/species_parts/moth_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/moth_bodyparts.dm @@ -6,6 +6,7 @@ is_dimorphic = FALSE should_draw_greyscale = FALSE head_flags = HEAD_LIPS|HEAD_EYESPRITES|HEAD_EYEHOLES|HEAD_DEBRAIN //what the fuck, moths have lips? + teeth_count = 0 /obj/item/bodypart/chest/moth icon = 'icons/mob/human/species/moth/bodyparts.dmi' diff --git a/code/modules/surgery/dental_implant.dm b/code/modules/surgery/dental_implant.dm index d720039d56b7e..3c645f240d484 100644 --- a/code/modules/surgery/dental_implant.dm +++ b/code/modules/surgery/dental_implant.dm @@ -2,16 +2,35 @@ name = "Dental implant" possible_locs = list(BODY_ZONE_PRECISE_MOUTH) steps = list( - /datum/surgery_step/drill, + /datum/surgery_step/drill/pill, /datum/surgery_step/insert_pill, ) +/datum/surgery_step/drill/pill/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + . = ..() + var/count = 0 + var/obj/item/bodypart/head/teeth_receptangle = target.get_bodypart(BODY_ZONE_HEAD) + + ASSERT(teeth_receptangle) + + for(var/obj/item/reagent_containers/pill/dental in teeth_receptangle) + count++ + + if(teeth_receptangle.teeth_count == 0) + to_chat(user, span_notice("[user] has no teeth, doofus!")) + return SURGERY_STEP_FAIL + + if(count >= teeth_receptangle.teeth_count) + to_chat(user, span_notice("[user]'s teeth have all been replaced with pills already!")) + return SURGERY_STEP_FAIL + /datum/surgery_step/insert_pill name = "insert pill" implements = list(/obj/item/reagent_containers/pill = 100) time = 16 /datum/surgery_step/insert_pill/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + display_results( user, target, @@ -25,7 +44,8 @@ if(!istype(tool)) return FALSE - user.transferItemToLoc(tool, target, TRUE) + // Pills go into head + user.transferItemToLoc(tool, target.get_bodypart(BODY_ZONE_HEAD), TRUE) var/datum/action/item_action/activate_pill/pill_action = new(tool) pill_action.name = "Activate [tool.name]" diff --git a/code/modules/unit_tests/simple_animal_freeze.dm b/code/modules/unit_tests/simple_animal_freeze.dm index 7db63d6b48df6..706fe290cccf4 100644 --- a/code/modules/unit_tests/simple_animal_freeze.dm +++ b/code/modules/unit_tests/simple_animal_freeze.dm @@ -21,7 +21,6 @@ /mob/living/simple_animal/bot/secbot/grievous, /mob/living/simple_animal/bot/secbot/grievous/toy, /mob/living/simple_animal/bot/secbot/pingsky, - /mob/living/simple_animal/bot/vibebot, /mob/living/simple_animal/hostile, /mob/living/simple_animal/hostile/asteroid, /mob/living/simple_animal/hostile/asteroid/curseblob, diff --git a/code/modules/vehicles/mecha/combat/durand.dm b/code/modules/vehicles/mecha/combat/durand.dm index b44478582c031..c6fcae75bc98f 100644 --- a/code/modules/vehicles/mecha/combat/durand.dm +++ b/code/modules/vehicles/mecha/combat/durand.dm @@ -271,7 +271,9 @@ own integrity back to max. Shield is automatically dropped if we run out of powe return . = ..() flick("shield_impact", src) - if(!chassis.use_energy((max_integrity - atom_integrity) * 0.1 * STANDARD_CELL_CHARGE)) + if(!.) + return + if(!chassis.use_energy(. * (STANDARD_CELL_CHARGE / 15))) chassis.cell?.charge = 0 for(var/O in chassis.occupants) var/mob/living/occupant = O diff --git a/html/changelogs/AutoChangeLog-pr-83810.yml b/html/changelogs/AutoChangeLog-pr-83810.yml new file mode 100644 index 0000000000000..7ad0ea2812cd5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83810.yml @@ -0,0 +1,4 @@ +author: "NewyearnewmeUwu" +delete-after: True +changes: + - qol: " The xenobio console's monkey placing command also clears dead monkeys on the tile." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83811.yml b/html/changelogs/AutoChangeLog-pr-83811.yml new file mode 100644 index 0000000000000..2aaf9471f4b48 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83811.yml @@ -0,0 +1,4 @@ +author: "mc-oofert" +delete-after: True +changes: + - qol: "space dragon can see in the dark and the invalid rift location alert is more informative" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83831.yml b/html/changelogs/AutoChangeLog-pr-83831.yml new file mode 100644 index 0000000000000..b3e655a55ddf2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83831.yml @@ -0,0 +1,7 @@ +author: "carlarctg" +delete-after: True +changes: + - bugfix: "There's now a limit to how many dental implants you can cram into your mouth, which is governed by your species' teeth limit." + - refactor: "Most species have 32 teeth, due to being based on humans, weirding me out when thinking about their teeth, or lack of enough information" + - refactor: "Moths and flypeople have NO teeth. They CAN'T get dental implants. I'm NERFING moths." + - refactor: "Lizards have seventy-five (!!!) teeth. Lizards are weird." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84043.yml b/html/changelogs/AutoChangeLog-pr-84043.yml new file mode 100644 index 0000000000000..5397404f75b8d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84043.yml @@ -0,0 +1,5 @@ +author: "mc-oofert" +delete-after: True +changes: + - bugfix: "durand shield doesnt immediately depower the mech when taking stamina damage" + - balance: "durand shield is a bit stronger" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84072.yml b/html/changelogs/AutoChangeLog-pr-84072.yml new file mode 100644 index 0000000000000..c36813ba598d8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84072.yml @@ -0,0 +1,4 @@ +author: "GPeckman" +delete-after: True +changes: + - bugfix: "Analyzers should work on bioscrambler anomalies again." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84075.yml b/html/changelogs/AutoChangeLog-pr-84075.yml new file mode 100644 index 0000000000000..427cc4f1ae6d0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84075.yml @@ -0,0 +1,4 @@ +author: "GoblinBackwards" +delete-after: True +changes: + - bugfix: "Interacting with an assembly bomb in hand will now allow you to interact with the attached assembly instead of opening the gas tank UI. Right-clicking will display the gas tank UI instead." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84135.yml b/html/changelogs/AutoChangeLog-pr-84135.yml new file mode 100644 index 0000000000000..b503e29e311d5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84135.yml @@ -0,0 +1,4 @@ +author: "Guestify" +delete-after: True +changes: + - bugfix: "The visor of the welding mask no longer goes down when you enable internals" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84143.yml b/html/changelogs/AutoChangeLog-pr-84143.yml new file mode 100644 index 0000000000000..68b36d831d4f6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84143.yml @@ -0,0 +1,5 @@ +author: "Ben10Omintrix" +delete-after: True +changes: + - refactor: "vibebots are not basic bots" + - rscadd: "vibebots will now seek out the depressed and cheer them up" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84255.yml b/html/changelogs/AutoChangeLog-pr-84255.yml new file mode 100644 index 0000000000000..95d0dd0b54f27 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84255.yml @@ -0,0 +1,4 @@ +author: "FlufflesTheDog" +delete-after: True +changes: + - bugfix: "multi-z hole repair works better, especially when the turf below is blocked by items" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84278.yml b/html/changelogs/AutoChangeLog-pr-84278.yml new file mode 100644 index 0000000000000..e29caa1b8963f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84278.yml @@ -0,0 +1,4 @@ +author: "hyperjll" +delete-after: True +changes: + - balance: "Thanks to incredible strides in selective slime breeding, slimes require substantially less nutrients to grow into adults, and split into children." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84279.yml b/html/changelogs/AutoChangeLog-pr-84279.yml new file mode 100644 index 0000000000000..9fcd48259c7bb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84279.yml @@ -0,0 +1,5 @@ +author: "jlsnow301" +delete-after: True +changes: + - rscadd: "Bitrunning: You can now choose your hacker alias in prefs." + - rscadd: "Bit avatars get orbit icons." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-84282.yml b/html/changelogs/AutoChangeLog-pr-84282.yml new file mode 100644 index 0000000000000..fe26b6cb2c010 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-84282.yml @@ -0,0 +1,4 @@ +author: "SmArtKar" +delete-after: True +changes: + - bugfix: "RND console now properly rounds research points" \ No newline at end of file diff --git a/icons/mob/huds/hud.dmi b/icons/mob/huds/hud.dmi index a3bbdf2ede075..086e886bab7b2 100644 Binary files a/icons/mob/huds/hud.dmi and b/icons/mob/huds/hud.dmi differ diff --git a/strings/names/hackers.txt b/strings/names/hackers.txt new file mode 100644 index 0000000000000..e2722fb09fd21 --- /dev/null +++ b/strings/names/hackers.txt @@ -0,0 +1,46 @@ +Ne0Phyte +CipherX +Gh0stWire +L33tByt3 +Vortex9 +Syn4pse +DarkMatt3r +QuantumDr1ft +Crash0verr1de +Z3r0C00l +NyxShad0w +Gl1tchR3aper +CryptoWra1th +Raz0rEdge +VoidWalk3r +Neur0mancer +EchoH3xx +DataSt0rm +CyberS1ren +Rogu3Protocol +Nexu5Prim3 +CircuitBr3aker +EnigmaPulse +PhantomBit +FluxC4pac1tor +OmegaC0dec +Ne0nRon1n +Senpa1Sw1pe +MechaM0chii +SakuraSn1per +WaifuWarri0r +KatanaKid99 +xXDarkL0rd69Xx +H4xx0rNinja +CyberNinja1337 +Ub3r1337Sk1llz +PhrEaK420 +IRCWizard69 +EliteWar3zKing +Y2KPwn3r +BBSPh34r +BlackWill0w69 +2038Pr0blem +Sp4ceW1nd +B0bbyT4bles +C0deInjector diff --git a/tgstation.dme b/tgstation.dme index 722dd189bf7e4..c1b726fcc4cff 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -4679,6 +4679,9 @@ #include "code\modules\mob\living\basic\bots\hygienebot\hygienebot_ai.dm" #include "code\modules\mob\living\basic\bots\medbot\medbot.dm" #include "code\modules\mob\living\basic\bots\medbot\medbot_ai.dm" +#include "code\modules\mob\living\basic\bots\vibebot\vibebot.dm" +#include "code\modules\mob\living\basic\bots\vibebot\vibebot_abilities.dm" +#include "code\modules\mob\living\basic\bots\vibebot\vibebot_ai.dm" #include "code\modules\mob\living\basic\clown\clown.dm" #include "code\modules\mob\living\basic\clown\clown_ai.dm" #include "code\modules\mob\living\basic\cult\shade.dm" @@ -5129,7 +5132,6 @@ #include "code\modules\mob\living\simple_animal\bot\mulebot.dm" #include "code\modules\mob\living\simple_animal\bot\secbot.dm" #include "code\modules\mob\living\simple_animal\bot\SuperBeepsky.dm" -#include "code\modules\mob\living\simple_animal\bot\vibebot.dm" #include "code\modules\mob\living\simple_animal\hostile\dark_wizard.dm" #include "code\modules\mob\living\simple_animal\hostile\hostile.dm" #include "code\modules\mob\living\simple_animal\hostile\illusion.dm" diff --git a/tgui/packages/tgui/interfaces/Orbit/OrbitContent.tsx b/tgui/packages/tgui/interfaces/Orbit/OrbitContent.tsx index 91502644faade..24aab8eba74bc 100644 --- a/tgui/packages/tgui/interfaces/Orbit/OrbitContent.tsx +++ b/tgui/packages/tgui/interfaces/Orbit/OrbitContent.tsx @@ -15,7 +15,7 @@ type ContentSection = { /** * The primary content display for points of interest. - * Renders a scrollable section replete collapsibles for each + * Renders a scrollable section replete with collapsibles for each * observable group. */ export function OrbitContent(props) { diff --git a/tools/UpdatePaths/Scripts/84143_vibebots.txt b/tools/UpdatePaths/Scripts/84143_vibebots.txt new file mode 100644 index 0000000000000..e5474e517e350 --- /dev/null +++ b/tools/UpdatePaths/Scripts/84143_vibebots.txt @@ -0,0 +1 @@ +/mob/living/simple_animal/bot/secbot/vibebot/@SUBTYPES : /mob/living/basic/bot/vibebot/@SUBTYPES{@OLD} \ No newline at end of file