From 14d4c87a2f4799eb8e7e83c460b452e0f7a88a00 Mon Sep 17 00:00:00 2001 From: wincent Date: Tue, 14 Nov 2023 13:24:09 +0100 Subject: [PATCH] More record types: + Can now specify a cordinate to path find to + Can now enable/disable the combat AI --- dGame/dCinema/Recorder.cpp | 121 +++++++++++++++++++++++++++++++++++++ dGame/dCinema/Recorder.h | 38 +++++++++++- 2 files changed, 158 insertions(+), 1 deletion(-) diff --git a/dGame/dCinema/Recorder.cpp b/dGame/dCinema/Recorder.cpp index ce07355e..7e82fb7d 100644 --- a/dGame/dCinema/Recorder.cpp +++ b/dGame/dCinema/Recorder.cpp @@ -8,6 +8,8 @@ #include "EntityManager.h" #include "EntityInfo.h" #include "ServerPreconditions.hpp" +#include "MovementAIComponent.h" +#include "BaseCombatAIComponent.h" using namespace Cinema::Recording; @@ -273,6 +275,24 @@ void Recorder::ActingDispatch(Entity* actor, const std::vector& records }); } + // Check if the record is a path find record + auto* pathFindRecord = dynamic_cast(record); + + if (pathFindRecord) { + auto* movementAiComponent = actor->GetComponent(); + + if (movementAiComponent == nullptr) { + movementAiComponent = actor->AddComponent(MovementAIInfo{}); + } + + movementAiComponent->SetDestination(pathFindRecord->position); + movementAiComponent->SetMaxSpeed(pathFindRecord->speed); + + PathFindDispatch(actor, records, index, variables); + + return; + } + actor->AddCallbackTimer(delay, [actor, records, index, variables]() { ActingDispatch(actor, records, index + 1, variables); }); @@ -310,6 +330,29 @@ void Cinema::Recording::Recorder::PlayerProximityDispatch(Entity* actor, const s }); } +void Cinema::Recording::Recorder::PathFindDispatch(Entity* actor, const std::vector& records, size_t index, Play* variables) { + auto* record = dynamic_cast(records[index]); + + if (record == nullptr) { + return; + } + + auto* movementAiComponent = actor->GetComponent(); + + if (movementAiComponent == nullptr) { + return; + } + + if (movementAiComponent->AtFinalWaypoint()) { + ActingDispatch(actor, records, index + 1, variables); + return; + } + + Game::entityManager->GetZoneControlEntity()->AddCallbackTimer(1.0f, [actor, records, index, variables]() { + PathFindDispatch(actor, records, index, variables); + }); +} + void Cinema::Recording::Recorder::LoadRecords(tinyxml2::XMLElement* root, std::vector& records) { for (auto* element = root->FirstChildElement(); element; element = element->NextSiblingElement()) { @@ -360,6 +403,13 @@ void Cinema::Recording::Recorder::LoadRecords(tinyxml2::XMLElement* root, std::v record = new PlayEffectRecord(); } else if (name == "CoroutineRecord") { record = new CoroutineRecord(); + } else if (name == "PathFindRecord") { + record = new PathFindRecord(); + } else if (name == "CombatAIRecord") { + record = new CombatAIRecord(); + } else { + LOG("Unknown record type: %s", name.c_str()); + continue; } record->Deserialize(element); @@ -1067,8 +1117,79 @@ void Cinema::Recording::CoroutineRecord::Act(Entity* actor) { } void Cinema::Recording::CoroutineRecord::Serialize(tinyxml2::XMLDocument& document, tinyxml2::XMLElement* parent) { + auto* element = document.NewElement("CoroutineRecord"); + + for (auto* record : records) { + record->Serialize(document, element); + } + + element->SetAttribute("t", m_Delay); + + parent->InsertEndChild(element); } void Cinema::Recording::CoroutineRecord::Deserialize(tinyxml2::XMLElement* element) { Recorder::LoadRecords(element, records); } + +Cinema::Recording::PathFindRecord::PathFindRecord(const NiPoint3& position, float speed) { + this->position = position; + this->speed = speed; +} + +void Cinema::Recording::PathFindRecord::Act(Entity* actor) { +} + +void Cinema::Recording::PathFindRecord::Serialize(tinyxml2::XMLDocument& document, tinyxml2::XMLElement* parent) { + auto* element = document.NewElement("PathFindRecord"); + + element->SetAttribute("x", position.x); + element->SetAttribute("y", position.y); + element->SetAttribute("z", position.z); + + element->SetAttribute("speed", speed); + + element->SetAttribute("t", m_Delay); + + parent->InsertEndChild(element); +} + +void Cinema::Recording::PathFindRecord::Deserialize(tinyxml2::XMLElement* element) { + position.x = element->FloatAttribute("x"); + position.y = element->FloatAttribute("y"); + position.z = element->FloatAttribute("z"); + + speed = element->FloatAttribute("speed"); + + m_Delay = element->DoubleAttribute("t"); +} + +Cinema::Recording::CombatAIRecord::CombatAIRecord(bool enabled) { + this->enabled = enabled; +} + +void Cinema::Recording::CombatAIRecord::Act(Entity* actor) { + auto* baseCombatAIComponent = actor->GetComponent(); + + if (baseCombatAIComponent == nullptr) { + return; + } + + baseCombatAIComponent->SetDisabled(!enabled); +} + +void Cinema::Recording::CombatAIRecord::Serialize(tinyxml2::XMLDocument& document, tinyxml2::XMLElement* parent) { + auto* element = document.NewElement("CombatAIRecord"); + + element->SetAttribute("enabled", enabled); + + element->SetAttribute("t", m_Delay); + + parent->InsertEndChild(element); +} + +void Cinema::Recording::CombatAIRecord::Deserialize(tinyxml2::XMLElement* element) { + enabled = element->BoolAttribute("enabled"); + + m_Delay = element->DoubleAttribute("t"); +} diff --git a/dGame/dCinema/Recorder.h b/dGame/dCinema/Recorder.h index abcd7dc0..7934841f 100644 --- a/dGame/dCinema/Recorder.h +++ b/dGame/dCinema/Recorder.h @@ -62,9 +62,11 @@ public: static void ActingDispatch(Entity* actor, const std::vector& records, size_t index, Play* variables); +private: static void PlayerProximityDispatch(Entity* actor, const std::vector& records, size_t index, Play* variables, std::shared_ptr actionTaken); -private: + static void PathFindDispatch(Entity* actor, const std::vector& records, size_t index, Play* variables); + std::vector m_Records; bool m_IsRecording; @@ -361,5 +363,39 @@ public: void Deserialize(tinyxml2::XMLElement* element) override; }; +class PathFindRecord : public Record +{ +public: + NiPoint3 position; + + float speed = 1.0f; + + PathFindRecord() = default; + + PathFindRecord(const NiPoint3& position, float speed); + + void Act(Entity* actor) override; + + void Serialize(tinyxml2::XMLDocument& document, tinyxml2::XMLElement* parent) override; + + void Deserialize(tinyxml2::XMLElement* element) override; +}; + +class CombatAIRecord : public Record +{ +public: + bool enabled = false; + + CombatAIRecord() = default; + + CombatAIRecord(bool enabled); + + void Act(Entity* actor) override; + + void Serialize(tinyxml2::XMLDocument& document, tinyxml2::XMLElement* parent) override; + + void Deserialize(tinyxml2::XMLElement* element) override; +}; + } \ No newline at end of file