mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-12-22 13:33:35 +00:00
Additional record types
This commit is contained in:
parent
dfe924061f
commit
04e9e74d7c
@ -10,6 +10,7 @@
|
||||
#include "ServerPreconditions.h"
|
||||
#include "MovementAIComponent.h"
|
||||
#include "BaseCombatAIComponent.h"
|
||||
#include "MissionComponent.h"
|
||||
|
||||
using namespace Cinema::Recording;
|
||||
|
||||
@ -84,7 +85,14 @@ void Recorder::ActingDispatch(Entity* actor, const std::vector<Record*>& records
|
||||
} else if (!forkRecord->precondition.empty()) {
|
||||
auto precondtion = Preconditions::CreateExpression(forkRecord->precondition);
|
||||
|
||||
success = precondtion.Check(actor);
|
||||
auto* playerEntity = Game::entityManager->GetEntity(variables->player);
|
||||
|
||||
if (playerEntity != nullptr) {
|
||||
success = precondtion.Check(playerEntity);
|
||||
}
|
||||
else {
|
||||
success = true;
|
||||
}
|
||||
} else {
|
||||
success = true;
|
||||
}
|
||||
@ -224,6 +232,96 @@ void Recorder::ActingDispatch(Entity* actor, const std::vector<Record*>& records
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the record is a companion record
|
||||
auto* companionRecord = dynamic_cast<CompanionRecord*>(record);
|
||||
|
||||
if (companionRecord && variables != nullptr) {
|
||||
EntityInfo info;
|
||||
info.lot = actor->GetLOT();
|
||||
info.pos = actor->GetPosition();
|
||||
info.rot = actor->GetRotation();
|
||||
info.scale = 1;
|
||||
info.spawner = nullptr;
|
||||
info.spawnerID = variables->player;
|
||||
info.spawnerNodeID = 0;
|
||||
info.settings = {
|
||||
new LDFData<std::vector<std::u16string>>(u"syncLDF", { u"custom_script_client" }),
|
||||
new LDFData<std::u16string>(u"custom_script_client", u"scripts\\ai\\SPEC\\MISSION_MINIGAME_CLIENT.lua")
|
||||
};
|
||||
|
||||
// Spawn it
|
||||
auto* companion = Game::entityManager->CreateEntity(info);
|
||||
|
||||
// Construct it
|
||||
Game::entityManager->ConstructEntity(companion);
|
||||
|
||||
CompanionRecord::SetCompanion(companion, variables->player);
|
||||
|
||||
if (!companionRecord->records.empty()) {
|
||||
ActingDispatch(companion, companionRecord->records, 0, variables);
|
||||
}
|
||||
|
||||
variables->entities.emplace(companion->GetObjectID());
|
||||
}
|
||||
|
||||
auto* spawnRecord = dynamic_cast<SpawnRecord*>(record);
|
||||
|
||||
if (spawnRecord && variables != nullptr) {
|
||||
EntityInfo info;
|
||||
info.lot = spawnRecord->lot;
|
||||
info.pos = spawnRecord->position;
|
||||
info.rot = spawnRecord->rotation;
|
||||
info.scale = 1;
|
||||
info.spawner = nullptr;
|
||||
info.spawnerID = variables->player;
|
||||
info.spawnerNodeID = 0;
|
||||
info.settings = {
|
||||
new LDFData<std::vector<std::u16string>>(u"syncLDF", { u"custom_script_client" }),
|
||||
new LDFData<std::u16string>(u"custom_script_client", u"scripts\\ai\\SPEC\\MISSION_MINIGAME_CLIENT.lua")
|
||||
};
|
||||
|
||||
// Spawn it
|
||||
auto* entity = Game::entityManager->CreateEntity(info);
|
||||
|
||||
// Construct it
|
||||
Game::entityManager->ConstructEntity(entity);
|
||||
|
||||
variables->entities.emplace(entity->GetObjectID());
|
||||
|
||||
if (!spawnRecord->onSpawnRecords.empty()) {
|
||||
ActingDispatch(entity, spawnRecord->onSpawnRecords, 0, variables);
|
||||
}
|
||||
|
||||
entity->AddDieCallback([entity, variables, spawnRecord]() {
|
||||
variables->entities.erase(entity->GetObjectID());
|
||||
|
||||
ActingDispatch(entity, spawnRecord->onDespawnRecords, 0, variables);
|
||||
});
|
||||
|
||||
auto* combatAIComponent = entity->GetComponent<BaseCombatAIComponent>();
|
||||
|
||||
if (combatAIComponent) {
|
||||
combatAIComponent->SetAggroRadius(200);
|
||||
combatAIComponent->SetSoftTetherRadius(200);
|
||||
combatAIComponent->SetHardTetherRadius(200);
|
||||
combatAIComponent->SetTarget(variables->player);
|
||||
}
|
||||
}
|
||||
|
||||
auto* missionRecord = dynamic_cast<MissionRecord*>(record);
|
||||
|
||||
if (missionRecord && variables != nullptr) {
|
||||
auto* playerEntity = Game::entityManager->GetEntity(variables->player);
|
||||
|
||||
if (playerEntity) {
|
||||
auto* missionComponent = playerEntity->GetComponent<MissionComponent>();
|
||||
|
||||
if (missionComponent) {
|
||||
missionComponent->CompleteMission(missionRecord->mission);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the record is a visibility record
|
||||
auto* visibilityRecord = dynamic_cast<VisibilityRecord*>(record);
|
||||
|
||||
@ -414,6 +512,12 @@ void Cinema::Recording::Recorder::LoadRecords(tinyxml2::XMLElement* root, std::v
|
||||
record = new PathFindRecord();
|
||||
} else if (name == "CombatAIRecord") {
|
||||
record = new CombatAIRecord();
|
||||
} else if (name == "CompanionRecord") {
|
||||
record = new CompanionRecord();
|
||||
} else if (name == "SpawnRecord") {
|
||||
record = new SpawnRecord();
|
||||
} else if (name == "MissionRecord") {
|
||||
record = new MissionRecord();
|
||||
} else {
|
||||
LOG("Unknown record type: %s", name.c_str());
|
||||
continue;
|
||||
@ -1198,3 +1302,170 @@ void Cinema::Recording::CombatAIRecord::Deserialize(tinyxml2::XMLElement* elemen
|
||||
|
||||
m_Delay = element->DoubleAttribute("t");
|
||||
}
|
||||
|
||||
void Cinema::Recording::CompanionRecord::Act(Entity* actor) {
|
||||
}
|
||||
|
||||
void Cinema::Recording::CompanionRecord::Serialize(tinyxml2::XMLDocument& document, tinyxml2::XMLElement* parent) {
|
||||
auto* element = document.NewElement("CompanionRecord");
|
||||
|
||||
element->SetAttribute("t", m_Delay);
|
||||
|
||||
parent->InsertEndChild(element);
|
||||
|
||||
}
|
||||
|
||||
void Cinema::Recording::CompanionRecord::Deserialize(tinyxml2::XMLElement* element) {
|
||||
m_Delay = element->DoubleAttribute("t");
|
||||
|
||||
records.clear();
|
||||
|
||||
Recorder::LoadRecords(element, records);
|
||||
}
|
||||
|
||||
void CompanionProtcol(Entity* entity, LWOOBJID follow) {
|
||||
auto* followEntity = Game::entityManager->GetEntity(follow);
|
||||
|
||||
if (followEntity == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* movementAI = entity->GetComponent<MovementAIComponent>();
|
||||
|
||||
if (movementAI == nullptr) {
|
||||
movementAI = entity->AddComponent<MovementAIComponent>(MovementAIInfo());
|
||||
}
|
||||
|
||||
if (movementAI == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* combatAI = entity->GetComponent<BaseCombatAIComponent>();
|
||||
|
||||
if (combatAI == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto distance = NiPoint3::Distance(entity->GetPosition(), followEntity->GetPosition());
|
||||
|
||||
combatAI->SetStartPosition(followEntity->GetPosition());
|
||||
combatAI->SetSoftTetherRadius(15.0f);
|
||||
combatAI->SetHardTetherRadius(25.0f);
|
||||
combatAI->SetFocusPosition(followEntity->GetPosition());
|
||||
combatAI->SetFocusRadius(5.0f);
|
||||
auto& info = movementAI->GetInfo();
|
||||
info.wanderChance = 1.0f;
|
||||
info.wanderDelayMin = 0.5f;
|
||||
info.wanderDelayMax = 1.0f;
|
||||
info.wanderSpeed = 1.0f;
|
||||
|
||||
/*if (distance > 50.0f) {
|
||||
movementAI->Warp(followEntity->GetPosition());
|
||||
|
||||
Game::entityManager->SerializeEntity(entity);
|
||||
}*/
|
||||
|
||||
/*if (distance > 30.0f) {
|
||||
movementAI->SetDestination(followEntity->GetPosition());
|
||||
movementAI->SetHaltDistance(5.0f);
|
||||
movementAI->SetMaxSpeed(1.0f);
|
||||
|
||||
if (combatAI) {
|
||||
combatAI->SetDisabled(true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (combatAI) {
|
||||
combatAI->SetDisabled(false);
|
||||
}
|
||||
}*/
|
||||
|
||||
entity->AddCallbackTimer(1.0f, [entity, follow]() {
|
||||
CompanionProtcol(entity, follow);
|
||||
});
|
||||
}
|
||||
|
||||
void Cinema::Recording::CompanionRecord::SetCompanion(Entity* actor, LWOOBJID player) {
|
||||
CompanionProtcol(actor, player);
|
||||
}
|
||||
|
||||
Cinema::Recording::SpawnRecord::SpawnRecord(LOT lot, const NiPoint3& position, const NiQuaternion& rotation) {
|
||||
this->lot = lot;
|
||||
this->position = position;
|
||||
this->rotation = rotation;
|
||||
}
|
||||
|
||||
void Cinema::Recording::SpawnRecord::Act(Entity* actor) {
|
||||
}
|
||||
|
||||
void Cinema::Recording::SpawnRecord::Serialize(tinyxml2::XMLDocument& document, tinyxml2::XMLElement* parent) {
|
||||
auto* element = document.NewElement("SpawnRecord");
|
||||
|
||||
element->SetAttribute("lot", lot);
|
||||
element->SetAttribute("x", position.x);
|
||||
element->SetAttribute("y", position.y);
|
||||
element->SetAttribute("z", position.z);
|
||||
|
||||
element->SetAttribute("qx", rotation.x);
|
||||
element->SetAttribute("qy", rotation.y);
|
||||
element->SetAttribute("qz", rotation.z);
|
||||
element->SetAttribute("qw", rotation.w);
|
||||
|
||||
element->SetAttribute("t", m_Delay);
|
||||
|
||||
parent->InsertEndChild(element);
|
||||
}
|
||||
|
||||
void Cinema::Recording::SpawnRecord::Deserialize(tinyxml2::XMLElement* element) {
|
||||
lot = element->IntAttribute("lot");
|
||||
|
||||
position.x = element->FloatAttribute("x");
|
||||
position.y = element->FloatAttribute("y");
|
||||
position.z = element->FloatAttribute("z");
|
||||
|
||||
if (element->Attribute("qx")) {
|
||||
rotation.x = element->FloatAttribute("qx");
|
||||
rotation.y = element->FloatAttribute("qy");
|
||||
rotation.z = element->FloatAttribute("qz");
|
||||
rotation.w = element->FloatAttribute("qw");
|
||||
}
|
||||
|
||||
m_Delay = element->DoubleAttribute("t");
|
||||
|
||||
auto* onSpawn = element->FirstChildElement("OnSpawn");
|
||||
|
||||
if (onSpawn) {
|
||||
Recorder::LoadRecords(onSpawn, onSpawnRecords);
|
||||
}
|
||||
|
||||
auto* onDespawn = element->FirstChildElement("OnDespawn");
|
||||
|
||||
if (onDespawn) {
|
||||
Recorder::LoadRecords(onDespawn, onDespawnRecords);
|
||||
}
|
||||
}
|
||||
|
||||
Cinema::Recording::MissionRecord::MissionRecord(const int32_t& mission) {
|
||||
this->mission = mission;
|
||||
}
|
||||
|
||||
void Cinema::Recording::MissionRecord::Act(Entity* actor) {
|
||||
}
|
||||
|
||||
void Cinema::Recording::MissionRecord::Serialize(tinyxml2::XMLDocument& document, tinyxml2::XMLElement* parent) {
|
||||
auto* element = document.NewElement("MissionRecord");
|
||||
|
||||
element->SetAttribute("mission", mission);
|
||||
|
||||
element->SetAttribute("t", m_Delay);
|
||||
|
||||
parent->InsertEndChild(element);
|
||||
}
|
||||
|
||||
void Cinema::Recording::MissionRecord::Deserialize(tinyxml2::XMLElement* element) {
|
||||
mission = element->IntAttribute("mission");
|
||||
|
||||
m_Delay = element->DoubleAttribute("t");
|
||||
}
|
||||
|
||||
|
||||
|
@ -398,5 +398,60 @@ public:
|
||||
void Deserialize(tinyxml2::XMLElement* element) override;
|
||||
};
|
||||
|
||||
class CompanionRecord : public Record
|
||||
{
|
||||
public:
|
||||
std::vector<Record*> records;
|
||||
|
||||
CompanionRecord() = default;
|
||||
|
||||
void Act(Entity* actor) override;
|
||||
|
||||
void Serialize(tinyxml2::XMLDocument& document, tinyxml2::XMLElement* parent) override;
|
||||
|
||||
void Deserialize(tinyxml2::XMLElement* element) override;
|
||||
|
||||
static void SetCompanion(Entity* actor, LWOOBJID player);
|
||||
};
|
||||
|
||||
class SpawnRecord : public Record
|
||||
{
|
||||
public:
|
||||
LOT lot = LOT_NULL;
|
||||
|
||||
NiPoint3 position;
|
||||
|
||||
NiQuaternion rotation;
|
||||
|
||||
std::vector<Record*> onSpawnRecords;
|
||||
|
||||
std::vector<Record*> onDespawnRecords;
|
||||
|
||||
SpawnRecord() = default;
|
||||
|
||||
SpawnRecord(LOT lot, const NiPoint3& position, const NiQuaternion& rotation);
|
||||
|
||||
void Act(Entity* actor) override;
|
||||
|
||||
void Serialize(tinyxml2::XMLDocument& document, tinyxml2::XMLElement* parent) override;
|
||||
|
||||
void Deserialize(tinyxml2::XMLElement* element) override;
|
||||
};
|
||||
|
||||
class MissionRecord : public Record
|
||||
{
|
||||
public:
|
||||
int32_t mission;
|
||||
|
||||
MissionRecord() = default;
|
||||
|
||||
MissionRecord(const int32_t& mission);
|
||||
|
||||
void Act(Entity* actor) override;
|
||||
|
||||
void Serialize(tinyxml2::XMLDocument& document, tinyxml2::XMLElement* parent) override;
|
||||
|
||||
void Deserialize(tinyxml2::XMLElement* element) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include "SlashCommandHandler.h"
|
||||
#include "ChatPackets.h"
|
||||
#include "InventoryComponent.h"
|
||||
#include "MovementAIComponent.h"
|
||||
#include "Recorder.h"
|
||||
|
||||
using namespace Cinema;
|
||||
|
||||
@ -185,6 +187,14 @@ void Cinema::Scene::AutoLoadScenesForZone(LWOMAPID zone) {
|
||||
.requiredLevel = eGameMasterLevel::LEAD_MODERATOR
|
||||
});
|
||||
|
||||
SlashCommandHandler::RegisterCommand(Command{
|
||||
.help = "",
|
||||
.info = "",
|
||||
.aliases = { "companion" },
|
||||
.handle = CommandCompanion,
|
||||
.requiredLevel = eGameMasterLevel::LEAD_MODERATOR
|
||||
});
|
||||
|
||||
const auto& scenesRoot = Game::config->GetValue("scenes_directory");
|
||||
|
||||
if (scenesRoot.empty()) {
|
||||
@ -643,3 +653,47 @@ void Cinema::Scene::CommandSceneSetup(Entity* entity, const SystemAddress& sysAd
|
||||
|
||||
scene.Rehearse();
|
||||
}
|
||||
|
||||
void Cinema::Scene::CommandCompanion(Entity* entity, const SystemAddress& sysAddr, const std::string args) {
|
||||
const auto splitArgs = GeneralUtils::SplitString(args, ' ');
|
||||
if (splitArgs.empty()) return;
|
||||
|
||||
EntityInfo info;
|
||||
info.lot = 0;
|
||||
info.pos = entity->GetPosition();
|
||||
info.rot = entity->GetRotation();
|
||||
info.scale = 1;
|
||||
info.spawner = nullptr;
|
||||
info.spawnerID = entity->GetObjectID();
|
||||
info.spawnerNodeID = 0;
|
||||
info.settings = {
|
||||
new LDFData<std::vector<std::u16string>>(u"syncLDF", { u"custom_script_client" }),
|
||||
new LDFData<std::u16string>(u"custom_script_client", u"scripts\\ai\\SPEC\\MISSION_MINIGAME_CLIENT.lua")
|
||||
};
|
||||
|
||||
// If there is an argument, set the lot
|
||||
const auto lotOptional = GeneralUtils::TryParse<LOT>(splitArgs[0]);
|
||||
if (lotOptional) {
|
||||
info.lot = lotOptional.value();
|
||||
} else {
|
||||
ChatPackets::SendSystemMessage(sysAddr, u"Invalid lot.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Spawn it
|
||||
auto* actor = Game::entityManager->CreateEntity(info);
|
||||
|
||||
// If there is an argument, set the actors name
|
||||
if (args.size() > 1) {
|
||||
actor->SetVar(u"npcName", args[1]);
|
||||
}
|
||||
|
||||
// Construct it
|
||||
Game::entityManager->ConstructEntity(actor);
|
||||
|
||||
const auto follow = entity->GetObjectID();
|
||||
|
||||
actor->AddCallbackTimer(1.0f, [actor, follow]() {
|
||||
Cinema::Recording::CompanionRecord::SetCompanion(actor, follow);
|
||||
});
|
||||
}
|
||||
|
@ -133,6 +133,7 @@ private:
|
||||
static void CommandPrefabDestroy(Entity* entity, const SystemAddress& sysAddr, const std::string args);
|
||||
static void CommandSceneAct(Entity* entity, const SystemAddress& sysAddr, const std::string args);
|
||||
static void CommandSceneSetup(Entity* entity, const SystemAddress& sysAddr, const std::string args);
|
||||
static void CommandCompanion(Entity* entity, const SystemAddress& sysAddr, const std::string args);
|
||||
};
|
||||
|
||||
} // namespace Cinema
|
||||
|
@ -630,7 +630,23 @@ void BaseCombatAIComponent::ClearThreat() {
|
||||
m_DirtyThreat = true;
|
||||
}
|
||||
|
||||
void BaseCombatAIComponent::SetStartPosition(const NiPoint3& position) {
|
||||
m_StartPosition = position;
|
||||
}
|
||||
|
||||
void BaseCombatAIComponent::Wander() {
|
||||
if (m_FocusPosition != NiPoint3Constant::ZERO) {
|
||||
m_MovementAI->SetHaltDistance(m_FocusRadius);
|
||||
|
||||
m_MovementAI->SetDestination(m_FocusPosition);
|
||||
|
||||
m_MovementAI->SetMaxSpeed(m_TetherSpeed);
|
||||
|
||||
m_Timer += 0.5f;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_MovementAI->AtFinalWaypoint()) {
|
||||
return;
|
||||
}
|
||||
@ -781,6 +797,38 @@ void BaseCombatAIComponent::SetAggroRadius(const float value) {
|
||||
m_AggroRadius = value;
|
||||
}
|
||||
|
||||
float BaseCombatAIComponent::GetSoftTetherRadius() const {
|
||||
return m_SoftTetherRadius;
|
||||
}
|
||||
|
||||
void BaseCombatAIComponent::SetSoftTetherRadius(const float value) {
|
||||
m_SoftTetherRadius = value;
|
||||
}
|
||||
|
||||
void BaseCombatAIComponent::SetHardTetherRadius(const float value) {
|
||||
m_HardTetherRadius = value;
|
||||
}
|
||||
|
||||
const NiPoint3& BaseCombatAIComponent::GetFocusPosition() const {
|
||||
return m_FocusPosition;
|
||||
}
|
||||
|
||||
void BaseCombatAIComponent::SetFocusPosition(const NiPoint3& value) {
|
||||
m_FocusPosition = value;
|
||||
}
|
||||
|
||||
float BaseCombatAIComponent::GetFocusRadius() const {
|
||||
return m_FocusRadius;
|
||||
}
|
||||
|
||||
void BaseCombatAIComponent::SetFocusRadius(const float value) {
|
||||
m_FocusRadius = value;
|
||||
}
|
||||
|
||||
float BaseCombatAIComponent::GetHardTetherRadius() const {
|
||||
return m_HardTetherRadius;
|
||||
}
|
||||
|
||||
void BaseCombatAIComponent::LookAt(const NiPoint3& point) {
|
||||
if (m_Stunned) {
|
||||
return;
|
||||
|
@ -120,6 +120,12 @@ public:
|
||||
*/
|
||||
const NiPoint3& GetStartPosition() const;
|
||||
|
||||
/**
|
||||
* Sets the position where the entity spawned
|
||||
* @param position the position where the entity spawned
|
||||
*/
|
||||
void SetStartPosition(const NiPoint3& position);
|
||||
|
||||
/**
|
||||
* Removes all threats for this entities, and thus chances for it attacking other entities
|
||||
*/
|
||||
@ -196,6 +202,54 @@ public:
|
||||
*/
|
||||
void SetAggroRadius(float value);
|
||||
|
||||
/**
|
||||
* Gets the soft tether radius
|
||||
* @return the soft tether radius
|
||||
*/
|
||||
float GetSoftTetherRadius() const;
|
||||
|
||||
/**
|
||||
* Sets the soft tether radius
|
||||
* @param value the soft tether radius
|
||||
*/
|
||||
void SetSoftTetherRadius(float value);
|
||||
|
||||
/**
|
||||
* Gets the hard tether radius
|
||||
* @return the hard tether radius
|
||||
*/
|
||||
float GetHardTetherRadius() const;
|
||||
|
||||
/**
|
||||
* Sets the hard tether radius
|
||||
* @param value the hard tether radius
|
||||
*/
|
||||
void SetHardTetherRadius(float value);
|
||||
|
||||
/**
|
||||
* Get the position that the entity should stay around
|
||||
* @return the focus position
|
||||
*/
|
||||
const NiPoint3& GetFocusPosition() const;
|
||||
|
||||
/**
|
||||
* Set the position that the entity should stay around
|
||||
* @param position the focus position
|
||||
*/
|
||||
void SetFocusPosition(const NiPoint3& position);
|
||||
|
||||
/**
|
||||
* Get the radius that the entity should stay around the focus position
|
||||
* @return the focus radius
|
||||
*/
|
||||
float GetFocusRadius() const;
|
||||
|
||||
/**
|
||||
* Set the radius that the entity should stay around the focus position
|
||||
* @param radius the focus radius
|
||||
*/
|
||||
void SetFocusRadius(float radius);
|
||||
|
||||
/**
|
||||
* Makes the entity look at a certain point in space
|
||||
* @param point the point to look at
|
||||
@ -382,6 +436,16 @@ private:
|
||||
*/
|
||||
bool m_DirtyStateOrTarget = false;
|
||||
|
||||
/**
|
||||
* A position that the entity should stay around
|
||||
*/
|
||||
NiPoint3 m_FocusPosition;
|
||||
|
||||
/**
|
||||
* How far the entity should stay from the focus position
|
||||
*/
|
||||
float m_FocusRadius = 0;
|
||||
|
||||
/**
|
||||
* Whether the current entity is a mech enemy, needed as mechs tether radius works differently
|
||||
* @return whether this entity is a mech
|
||||
|
@ -182,6 +182,10 @@ const MovementAIInfo& MovementAIComponent::GetInfo() const {
|
||||
return m_Info;
|
||||
}
|
||||
|
||||
MovementAIInfo& MovementAIComponent::GetInfo() {
|
||||
return m_Info;
|
||||
}
|
||||
|
||||
bool MovementAIComponent::AdvanceWaypointIndex() {
|
||||
if (m_PathIndex >= m_InterpolatedWaypoints.size()) {
|
||||
return false;
|
||||
|
@ -74,6 +74,12 @@ public:
|
||||
*/
|
||||
const MovementAIInfo& GetInfo() const;
|
||||
|
||||
/**
|
||||
* Returns a mutable reference to the basic settings that this entity uses to move around
|
||||
* @return a mutable reference to the basic settings that this entity uses to move around
|
||||
*/
|
||||
MovementAIInfo& GetInfo();
|
||||
|
||||
/**
|
||||
* Set a destination point for the entity to move towards
|
||||
* @param value the destination point to move towards
|
||||
|
Loading…
Reference in New Issue
Block a user