diff --git a/_maps/shuttles/emergency_cruise.dmm b/_maps/shuttles/emergency_cruise.dmm index 7e20dc7d47d..8045930388c 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 61189861141..05c0b7aff18 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/song.dm b/code/__DEFINES/song.dm index 782a7923ea1..0e7e9f0ce06 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 6cc90893c0f..8d2b54ab72f 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/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 62805b578d5..5d1e88667b7 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 58e9746cbf0..7b46a7b06e8 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 11a5887bf91..2398a8b54fb 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/station_traits/neutral_traits.dm b/code/datums/station_traits/neutral_traits.dm index e066079802d..0ecb49f96a0 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/modules/mob/living/basic/bots/vibebot/vibebot.dm b/code/modules/mob/living/basic/bots/vibebot/vibebot.dm new file mode 100644 index 00000000000..c872e1ea595 --- /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 00000000000..b3fcec9813b --- /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 00000000000..945b09274d7 --- /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/simple_animal/bot/vibebot.dm b/code/modules/mob/living/simple_animal/bot/vibebot.dm deleted file mode 100644 index 582b1b5371d..00000000000 --- 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/unit_tests/simple_animal_freeze.dm b/code/modules/unit_tests/simple_animal_freeze.dm index 7db63d6b48d..706fe290ccc 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/tgstation.dme b/tgstation.dme index f8e2a62d097..95898ab0e9d 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -4666,6 +4666,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" @@ -5116,7 +5119,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/tools/UpdatePaths/Scripts/84143_vibebots.txt b/tools/UpdatePaths/Scripts/84143_vibebots.txt new file mode 100644 index 00000000000..e5474e517e3 --- /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