diff --git a/code/__DEFINES/ai.dm b/code/__DEFINES/ai.dm index 4b6ca39d33e..18515b5241d 100644 --- a/code/__DEFINES/ai.dm +++ b/code/__DEFINES/ai.dm @@ -35,6 +35,14 @@ //Generic BB keys #define BB_CURRENT_MIN_MOVE_DISTANCE "min_move_distance" +//for songs + +///song datum blackboard, set by instrument subtrees +#define BB_SONG_DATUM "BB_SONG_DATUM" +///song lines blackboard, set by default on controllers +#define BB_SONG_LINES "song_lines" + + // Monkey AI controller blackboard keys #define BB_MONKEY_AGGRESSIVE "BB_monkey_aggressive" @@ -53,7 +61,6 @@ #define BB_MONKEY_RECRUIT_COOLDOWN "BB_monkey_recruit_cooldown" #define BB_MONKEY_NEXT_HUNGRY "BB_monkey_next_hungry" - ///Haunted item controller defines ///Chance for haunted item to haunt someone diff --git a/code/__DEFINES/song.dm b/code/__DEFINES/song.dm new file mode 100644 index 00000000000..26121707f7d --- /dev/null +++ b/code/__DEFINES/song.dm @@ -0,0 +1,6 @@ +#define MUSICIAN_HEARCHECK_MINDELAY 4 +#define MUSIC_MAXLINES 1000 +#define MUSIC_MAXLINECHARS 300 + +///it's what monkeys play! +#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" diff --git a/code/datums/ai/generic_actions.dm b/code/datums/ai/generic/generic_behaviors.dm similarity index 92% rename from code/datums/ai/generic_actions.dm rename to code/datums/ai/generic/generic_behaviors.dm index a26d8e629ee..2978b22fb38 100644 --- a/code/datums/ai/generic_actions.dm +++ b/code/datums/ai/generic/generic_behaviors.dm @@ -280,4 +280,29 @@ living_pawn.say(speech, forced = "AI Controller") finish_action(controller, TRUE) +//song behaviors +/datum/ai_behavior/setup_instrument + +/datum/ai_behavior/setup_instrument/perform(delta_time, datum/ai_controller/controller, song_datum_key, song_lines_key) + . = ..() + + var/datum/song/song = controller.blackboard[song_datum_key] + var/song_lines = controller.blackboard[song_lines_key] + + //just in case- it won't do anything if the instrument isn't playing + song.stop_playing() + song.ParseSong(song_lines) + song.repeat = 10 + song.volume = song.max_volume - 10 + finish_action(controller, TRUE) + +/datum/ai_behavior/play_instrument + +/datum/ai_behavior/play_instrument/perform(delta_time, datum/ai_controller/controller, song_datum_key) + . = ..() + + var/datum/song/song = controller.blackboard[song_datum_key] + + song.start_playing(controller.pawn) + finish_action(controller, TRUE) diff --git a/code/datums/ai/generic/generic_subtrees.dm b/code/datums/ai/generic/generic_subtrees.dm new file mode 100644 index 00000000000..cfb6ec6fb6e --- /dev/null +++ b/code/datums/ai/generic/generic_subtrees.dm @@ -0,0 +1,16 @@ +/datum/ai_planning_subtree/play_instrument/SelectBehaviors(datum/ai_controller/monkey/controller, delta_time) + var/mob/living/living_pawn = controller.pawn + var/obj/item/instrument/song_player = locate(/obj/item/instrument) in living_pawn.held_items + if(!song_player) + controller.blackboard[BB_SONG_DATUM] = null + return //we can't play a song since we do not have an instrument + + controller.blackboard[BB_SONG_DATUM] = song_player.song + + var/list/donkey_kong_lines = splittext(MONKEY_SONG, "\n") + popleft(donkey_kong_lines) //remove BPM as it is parsed out + if(!compare_list(song_player.song.lines, donkey_kong_lines) || !song_player.song.repeat) + controller.queue_behavior(/datum/ai_behavior/setup_instrument, BB_SONG_DATUM, BB_SONG_LINES) + + if(!song_player.song.playing) //we may stop playing if we weren't playing before, were setting up dk theme, or ran out of repeats (also causing setup behavior) + controller.queue_behavior(/datum/ai_behavior/play_instrument, BB_SONG_DATUM) diff --git a/code/datums/ai/monkey/monkey_controller.dm b/code/datums/ai/monkey/monkey_controller.dm index 154b652c46c..55266890360 100644 --- a/code/datums/ai/monkey/monkey_controller.dm +++ b/code/datums/ai/monkey/monkey_controller.dm @@ -6,7 +6,11 @@ have ways of interacting with a specific mob and control it. /datum/ai_controller/monkey movement_delay = 0.4 SECONDS - planning_subtrees = list(/datum/ai_planning_subtree/monkey_tree) + planning_subtrees = list( + /datum/ai_planning_subtree/monkey_tree, + //the monkey tree is mostly combat related, if it isn't busy with that then it may do instrument related things + /datum/ai_planning_subtree/play_instrument, + ) blackboard = list( BB_MONKEY_AGGRESSIVE = FALSE, BB_MONKEY_BEST_FORCE_FOUND = 0, @@ -19,7 +23,8 @@ have ways of interacting with a specific mob and control it. BB_MONKEY_CURRENT_ATTACK_TARGET = null, BB_MONKEY_GUN_NEURONS_ACTIVATED = FALSE, BB_MONKEY_GUN_WORKED = TRUE, - BB_MONKEY_NEXT_HUNGRY = 0 + BB_MONKEY_NEXT_HUNGRY = 0, + BB_SONG_LINES = MONKEY_SONG, ) var/static/list/loc_connections = list( COMSIG_ATOM_ENTERED = .proc/on_entered, diff --git a/code/modules/instruments/songs/_song.dm b/code/modules/instruments/songs/_song.dm index 33e6cb31c33..afe19090ff4 100644 --- a/code/modules/instruments/songs/_song.dm +++ b/code/modules/instruments/songs/_song.dm @@ -1,7 +1,3 @@ -#define MUSICIAN_HEARCHECK_MINDELAY 4 -#define MUSIC_MAXLINES 1000 -#define MUSIC_MAXLINECHARS 300 - /** * # Song datum * diff --git a/tgstation.dme b/tgstation.dme index 75a7efa3434..79881fa8dc1 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -132,6 +132,7 @@ #include "code\__DEFINES\shuttles.dm" #include "code\__DEFINES\sight.dm" #include "code\__DEFINES\skills.dm" +#include "code\__DEFINES\song.dm" #include "code\__DEFINES\sound.dm" #include "code\__DEFINES\space.dm" #include "code\__DEFINES\spaceman_dmm.dm" @@ -513,7 +514,6 @@ #include "code\datums\ai\_ai_controller.dm" #include "code\datums\ai\_ai_planning_subtree.dm" #include "code\datums\ai\_item_behaviors.dm" -#include "code\datums\ai\generic_actions.dm" #include "code\datums\ai\telegraph_effects.dm" #include "code\datums\ai\bane\bane_behaviors.dm" #include "code\datums\ai\bane\bane_controller.dm" @@ -533,6 +533,8 @@ #include "code\datums\ai\dog\dog_behaviors.dm" #include "code\datums\ai\dog\dog_controller.dm" #include "code\datums\ai\dog\dog_subtrees.dm" +#include "code\datums\ai\generic\generic_behaviors.dm" +#include "code\datums\ai\generic\generic_subtrees.dm" #include "code\datums\ai\hauntium\haunted_controller.dm" #include "code\datums\ai\hauntium\hauntium_subtrees.dm" #include "code\datums\ai\hunting_behavior\hunting_behaviors.dm"