#include "stdafx.h" #include "SurvivalAgentPlugin.h" #include "IExamInterface.h" #include "Blackboard.h" #include "BehaviourTree.h" #include "Behaviour.h" //Called only once, during initialization void SurvivalAgentPlugin::Initialize(IBaseInterface* pInterface, PluginInfo& info) { //Retrieving the interface //This interface gives you access to certain actions the AI_Framework can perform for you m_pInterface = static_cast(pInterface); //Information for the leaderboards! info.BotName = "Cat"; info.Student_Name = "Bram Verhulst";//No special characters allowed. Highscores won't work with special characters. info.Student_Class = "2DAE11"; info.LB_Password = "ILikeCuteCats!";//Don't use a real password! This is only to prevent other students from overwriting your highscore! Blackboard* blackboard = CreateBlackboard(); m_BehaviourTree = new BT::BehaviorTree(blackboard, new BT::Selector({ new BT::PartialSequence({ new BT::Action(BT_Action::FindAHouse), new BT::Action(BT_Action::GoToTarget) }) }) ); } Blackboard* SurvivalAgentPlugin::CreateBlackboard() { Blackboard* blackboard = new Blackboard(); blackboard->AddData("Interface", m_pInterface); blackboard->AddData("Steering", SteeringPlugin_Output{}); blackboard->AddData("Target", m_Target); return blackboard; } void SurvivalAgentPlugin::UpdateBlackboard(const SteeringPlugin_Output& steering) { Blackboard* blackboard{ m_BehaviourTree->GetBlackboard() }; //blackboard->ChangeData("playerPos", m_pInterface->Agent_GetInfo().Position); blackboard->ChangeData("Steering", steering); } SurvivalAgentPlugin::~SurvivalAgentPlugin() { SAFE_DELETE(m_BehaviourTree); } //Called only once void SurvivalAgentPlugin::DllInit() { //Called when the plugin is loaded } //Called only once void SurvivalAgentPlugin::DllShutdown() { //Called when the plugin gets unloaded } //Called only once, during initialization. Only works in DEBUG Mode void SurvivalAgentPlugin::InitGameDebugParams(GameDebugParams& params) { params.AutoFollowCam = true; //Automatically follow the AI? (Default = true) params.RenderUI = true; //Render the IMGUI Panel? (Default = true) params.SpawnEnemies = true; //Do you want to spawn enemies? (Default = true) params.EnemyCount = 20; //How many enemies? (Default = 20) params.GodMode = false; //GodMode > You can't die, can be useful to inspect certain behaviors (Default = false) params.LevelFile = "GameLevel.gppl"; params.AutoGrabClosestItem = true; //A call to Item_Grab(...) returns the closest item that can be grabbed. (EntityInfo argument is ignored) params.StartingDifficultyStage = 1; params.InfiniteStamina = false; params.SpawnDebugPistol = true; params.SpawnDebugShotgun = true; params.SpawnPurgeZonesOnMiddleClick = true; params.PrintDebugMessages = true; params.ShowDebugItemNames = true; params.Seed = 0; //-1 = don't set seed. Any other number = fixed seed //TIP: use Seed = int(time(nullptr)) for pure randomness } //Only Active in DEBUG Mode //(=Use only for Debug Purposes) void SurvivalAgentPlugin::Update_Debug(float dt) { //Demo Event Code //In the end your Agent should be able to walk around without external input if (m_pInterface->Input_IsMouseButtonUp(Elite::InputMouseButton::eLeft)) { //Update_Debug target based on input Elite::MouseData mouseData = m_pInterface->Input_GetMouseData(Elite::InputType::eMouseButton, Elite::InputMouseButton::eLeft); const Elite::Vector2 pos = Elite::Vector2(static_cast(mouseData.X), static_cast(mouseData.Y)); m_Target = m_pInterface->Debug_ConvertScreenToWorld(pos); } else if (m_pInterface->Input_IsKeyboardKeyDown(Elite::eScancode_Space)) { m_CanRun = true; } else if (m_pInterface->Input_IsKeyboardKeyDown(Elite::eScancode_Left)) { m_AngSpeed -= Elite::ToRadians(10); } else if (m_pInterface->Input_IsKeyboardKeyDown(Elite::eScancode_Right)) { m_AngSpeed += Elite::ToRadians(10); } else if (m_pInterface->Input_IsKeyboardKeyDown(Elite::eScancode_G)) { m_GrabItem = true; } else if (m_pInterface->Input_IsKeyboardKeyDown(Elite::eScancode_U)) { m_UseItem = true; } else if (m_pInterface->Input_IsKeyboardKeyDown(Elite::eScancode_R)) { m_RemoveItem = true; } else if (m_pInterface->Input_IsKeyboardKeyDown(Elite::eScancode_X)) { m_DestroyItemsInFOV = true; } else if (m_pInterface->Input_IsKeyboardKeyUp(Elite::eScancode_Space)) { m_CanRun = false; } else if (m_pInterface->Input_IsKeyboardKeyDown(Elite::eScancode_Delete)) { m_pInterface->RequestShutdown(); } else if (m_pInterface->Input_IsKeyboardKeyDown(Elite::eScancode_KP_Minus)) { if (m_InventorySlot > 0) --m_InventorySlot; } else if (m_pInterface->Input_IsKeyboardKeyDown(Elite::eScancode_KP_Plus)) { if (m_InventorySlot < 4) ++m_InventorySlot; } else if (m_pInterface->Input_IsKeyboardKeyDown(Elite::eScancode_Q)) { ItemInfo info = {}; m_pInterface->Inventory_GetItem(m_InventorySlot, info); std::cout << (int)info.Type << std::endl; } } //This function calculates the new SteeringOutput, called once per frame SteeringPlugin_Output SurvivalAgentPlugin::UpdateSteering(float dt) { auto steering = SteeringPlugin_Output(); //Use the Interface (IAssignmentInterface) to 'interface' with the AI_Framework auto agentInfo = m_pInterface->Agent_GetInfo(); UpdateBlackboard(steering); m_BehaviourTree->Update(); m_BehaviourTree->GetBlackboard()->GetData("Steering", steering); steering.AngularVelocity = m_AngSpeed; steering.AutoOrient = false; return steering; } //This function should only be used for rendering debug elements void SurvivalAgentPlugin::Render(float dt) const { //This Render function should only contain calls to Interface->Draw_... functions m_pInterface->Draw_SolidCircle(m_Target, .7f, { 0,0 }, { 1, 0, 0 }); }