Compare commits

..

1 Commits

Author SHA1 Message Date
2eeacbf746 Add mandlers for all the trigger related waypoint commands
And add a call to the cppscript for reaching a waypoint
2025-06-13 01:05:12 -05:00
15 changed files with 79 additions and 71 deletions

View File

@@ -237,7 +237,3 @@ bool ModelComponent::TrySetVelocity(const NiPoint3& velocity) const {
void ModelComponent::SetVelocity(const NiPoint3& velocity) const {
m_Parent->SetVelocity(velocity);
}
void ModelComponent::OnChatMessageReceived(const std::string& sMessage) {
for (auto& behavior : m_Behaviors) behavior.OnChatMessageReceived(sMessage);
}

View File

@@ -138,8 +138,6 @@ public:
// Force sets the velocity to a value.
void SetVelocity(const NiPoint3& velocity) const;
void OnChatMessageReceived(const std::string& sMessage);
private:
// Number of Actions that are awaiting an UnSmash to finish.
uint32_t m_NumActiveUnSmash{};

View File

@@ -66,6 +66,67 @@ void MovementAIComponent::SetPath(const std::string pathName) {
SetMaxSpeed(1);
SetCurrentSpeed(m_BaseSpeed);
SetPath(m_Path->pathWaypoints);
auto start_index = m_Parent->GetVarAs<uint32_t>(u"attached_path_start");
if (start_index >= m_Path->waypointCount) start_index = 0;
SetDestination(m_Path->pathWaypoints[m_PathIndex].position);
m_PathIndex = start_index;
}
void MovementAIComponent::SetPath(const std::string pathName, uint32_t startIndex, bool reverse) {
m_Path = Game::zoneManager->GetZone()->GetPath(pathName);
if (!pathName.empty()) LOG("WARNING: %s path %s", m_Path ? "Found" : "Failed to find", pathName.c_str());
if (!m_Path) return;
SetMaxSpeed(1);
SetCurrentSpeed(m_BaseSpeed);
if (reverse) {
m_IsBounced = !m_IsBounced;
auto pathWaypoints = m_Path->pathWaypoints;
std::reverse(pathWaypoints.begin(), pathWaypoints.end());
SetPath(pathWaypoints);
} else {
SetPath(m_Path->pathWaypoints);
}
SetDestination(m_Path->pathWaypoints[startIndex].position);
m_PathIndex = startIndex;
}
void MovementAIComponent::TurnAroundOnPath() {
if (m_Path) {
auto currentIndex = m_PathIndex;
m_IsBounced = !m_IsBounced;
std::vector<PathWaypoint> waypoints = m_Path->pathWaypoints;
if (m_IsBounced) std::reverse(waypoints.begin(), waypoints.end());
SetPath(waypoints);
SetDestination(waypoints[currentIndex].position);
m_PathIndex = currentIndex;
}
}
void MovementAIComponent::GoForwardOnPath() {
if (m_Path) {
auto currentIndex = m_PathIndex;
m_IsBounced = false;
SetPath(m_Path->pathWaypoints);
SetDestination(m_Path->pathWaypoints[currentIndex].position);
m_PathIndex = currentIndex;
}
}
void MovementAIComponent::GoBackwardOnPath() {
if (m_Path) {
auto currentIndex = m_PathIndex;
m_IsBounced = true;
std::vector<PathWaypoint> waypoints = m_Path->pathWaypoints;
std::reverse(waypoints.begin(), waypoints.end());
SetPath(waypoints);
SetDestination(waypoints[currentIndex].position);
m_PathIndex = currentIndex;
}
}
void MovementAIComponent::Pause() {
@@ -188,7 +249,7 @@ bool MovementAIComponent::AdvanceWaypointIndex() {
if (m_PathIndex >= m_InterpolatedWaypoints.size()) {
return false;
}
m_Parent->GetScript()->OnWaypointReached(m_Parent, m_PathIndex);
m_PathIndex++;
return true;

View File

@@ -65,6 +65,10 @@ public:
MovementAIComponent(Entity* parentEntity, MovementAIInfo info);
void SetPath(const std::string pathName);
void SetPath(const std::string pathName, uint32_t startIndex, bool reverse);
void TurnAroundOnPath();
void GoForwardOnPath();
void GoBackwardOnPath();
void Update(float deltaTime) override;

View File

@@ -817,14 +817,3 @@ void PropertyManagementComponent::SetOwnerId(const LWOOBJID value) {
const std::map<LWOOBJID, LWOOBJID>& PropertyManagementComponent::GetModels() const {
return models;
}
void PropertyManagementComponent::OnChatMessageReceived(const std::string& sMessage) const {
for (const auto& modelID : models | std::views::keys) {
auto* const model = Game::entityManager->GetEntity(modelID);
if (!model) continue;
auto* const modelComponent = model->GetComponent<ModelComponent>();
if (!modelComponent) continue;
modelComponent->OnChatMessageReceived(sMessage);
}
}

View File

@@ -164,8 +164,6 @@ public:
LWOOBJID GetId() const noexcept { return propertyId; }
void OnChatMessageReceived(const std::string& sMessage) const;
private:
/**
* This
@@ -195,7 +193,7 @@ private:
/**
* The models that are placed on this property
*/
std::map<LWOOBJID /* ObjectID */, LWOOBJID /* SpawnerID */> models = {};
std::map<LWOOBJID, LWOOBJID> models = {};
/**
* The name of this property

View File

@@ -457,40 +457,43 @@ void TriggerComponent::HandleActivatePhysics(Entity* targetEntity, std::string a
void TriggerComponent::HandleSetPath(Entity* targetEntity, std::vector<std::string> argArray) {
auto* movementAIComponent = targetEntity->GetComponent<MovementAIComponent>();
if (!movementAIComponent) return;
// movementAIComponent->SetupPath(argArray.at(0));
uint32_t start_index = 0;
bool reverse = false;
if (argArray.size() >= 2) {
auto index = GeneralUtils::TryParse<int32_t>(argArray.at(1));
if (!index) return;
// movementAIComponent->SetPathStartingWaypointIndex(index.value());
if (index) {
start_index = index.value();
}
}
if (argArray.size() >= 3 && argArray.at(2) == "1") {
// movementAIComponent->ReversePath();
reverse = true;
}
movementAIComponent->SetPath(argArray.at(0), start_index, reverse);
}
void TriggerComponent::HandleTurnAroundOnPath(Entity* targetEntity) {
auto* movementAIComponent = targetEntity->GetComponent<MovementAIComponent>();
// if (movementAIComponent) movementAIComponent->ReversePath();
if (movementAIComponent) movementAIComponent->TurnAroundOnPath();
}
void TriggerComponent::HandleGoForwardOnPath(Entity* targetEntity) {
auto* movementAIComponent = targetEntity->GetComponent<MovementAIComponent>();
if (!movementAIComponent) return;
// if (movementAIComponent->GetIsInReverse()) movementAIComponent->ReversePath();
movementAIComponent->GoForwardOnPath();
}
void TriggerComponent::HandleGoBackwardOnPath(Entity* targetEntity) {
auto* movementAIComponent = targetEntity->GetComponent<MovementAIComponent>();
if (!movementAIComponent) return;
// if (!movementAIComponent->GetIsInReverse()) movementAIComponent->ReversePath();
movementAIComponent->GoBackwardOnPath();
}
void TriggerComponent::HandleStopPathing(Entity* targetEntity) {
auto* movementAIComponent = targetEntity->GetComponent<MovementAIComponent>();
// if (movementAIComponent) movementAIComponent->Pause();
if (movementAIComponent) movementAIComponent->Pause();
}
void TriggerComponent::HandleStartPathing(Entity* targetEntity) {
auto* movementAIComponent = targetEntity->GetComponent<MovementAIComponent>();
// if (movementAIComponent) movementAIComponent->Resume();
if (movementAIComponent) movementAIComponent->Resume();
}

View File

@@ -20,7 +20,6 @@ target_include_directories(dPropertyBehaviors PUBLIC "." "ControlBehaviorMessage
"${PROJECT_SOURCE_DIR}/dGame/dUtilities" # ObjectIdManager.h
"${PROJECT_SOURCE_DIR}/dGame/dGameMessages" # GameMessages.h
"${PROJECT_SOURCE_DIR}/dGame/dComponents" # ModelComponent.h
"${PROJECT_SOURCE_DIR}/dChatFilter" # dChatFilter.h
)
target_precompile_headers(dPropertyBehaviors REUSE_FROM dGameBase)

View File

@@ -172,7 +172,3 @@ void PropertyBehavior::Deserialize(const tinyxml2::XMLElement& behavior) {
void PropertyBehavior::Update(float deltaTime, ModelComponent& modelComponent) {
for (auto& state : m_States | std::views::values) state.Update(deltaTime, modelComponent);
}
void PropertyBehavior::OnChatMessageReceived(const std::string& sMessage) {
for (auto& state : m_States | std::views::values) state.OnChatMessageReceived(sMessage);
}

View File

@@ -34,7 +34,6 @@ public:
void Deserialize(const tinyxml2::XMLElement& behavior);
void Update(float deltaTime, ModelComponent& modelComponent);
void OnChatMessageReceived(const std::string& sMessage);
private:
// The current active behavior state. Behaviors can only be in ONE state at a time.

View File

@@ -166,7 +166,3 @@ void State::Deserialize(const tinyxml2::XMLElement& state) {
void State::Update(float deltaTime, ModelComponent& modelComponent) {
for (auto& strip : m_Strips) strip.Update(deltaTime, modelComponent);
}
void State::OnChatMessageReceived(const std::string& sMessage) {
for (auto& strip : m_Strips) strip.OnChatMessageReceived(sMessage);
}

View File

@@ -22,8 +22,6 @@ public:
void Deserialize(const tinyxml2::XMLElement& state);
void Update(float deltaTime, ModelComponent& modelComponent);
void OnChatMessageReceived(const std::string& sMessage);
private:
// The strips contained within this state.

View File

@@ -5,12 +5,8 @@
#include "tinyxml2.h"
#include "dEntity/EntityInfo.h"
#include "ModelComponent.h"
#include "ChatPackets.h"
#include "PropertyManagementComponent.h"
#include "PlayerManager.h"
#include "dChatFilter.h"
#include "DluAssert.h"
template <>
@@ -107,16 +103,6 @@ void Strip::HandleMsg(GameMessages::ResetModelToDefaults& msg) {
m_PreviousFramePosition = NiPoint3Constant::ZERO;
}
void Strip::OnChatMessageReceived(const std::string& sMessage) {
if (m_PausedTime > 0.0f || !HasMinimumActions()) return;
const auto& nextAction = GetNextAction();
if (nextAction.GetValueParameterString() == sMessage) {
IncrementAction();
m_WaitingForAction = false;
}
}
void Strip::IncrementAction() {
if (m_Actions.empty()) return;
m_NextActionIndex++;
@@ -145,7 +131,6 @@ void Strip::ProcNormalAction(float deltaTime, ModelComponent& modelComponent) {
auto& entity = *modelComponent.GetParent();
auto& nextAction = GetNextAction();
auto number = nextAction.GetValueParameterDouble();
auto valueStr = nextAction.GetValueParameterString();
auto numberAsInt = static_cast<int32_t>(number);
auto nextActionType = GetNextAction().GetType();
@@ -198,14 +183,6 @@ void Strip::ProcNormalAction(float deltaTime, ModelComponent& modelComponent) {
m_PausedTime = number;
} else if (nextActionType == "Wait") {
m_PausedTime = number;
} else if (nextActionType == "Chat") {
bool isOk = Game::chatFilter->IsSentenceOkay(valueStr.data(), eGameMasterLevel::CIVILIAN).empty();
// In case a word is removed from the whitelist after it was approved
const auto modelName = "%[Objects_" + std::to_string(entity.GetLOT()) + "_name]";
if (isOk) ChatPackets::SendChatMessage(UNASSIGNED_SYSTEM_ADDRESS, 12, modelName, entity.GetObjectID(), false, GeneralUtils::ASCIIToUTF16(valueStr));
PropertyManagementComponent::Instance()->OnChatMessageReceived(valueStr.data());
} else if (nextActionType == "PrivateMessage") {
PropertyManagementComponent::Instance()->OnChatMessageReceived(valueStr.data());
} else if (nextActionType == "PlaySound") {
GameMessages::PlayBehaviorSound sound;
sound.target = modelComponent.GetParent()->GetObjectID();
@@ -327,9 +304,6 @@ void Strip::Update(float deltaTime, ModelComponent& modelComponent) {
Game::entityManager->SerializeEntity(entity);
m_WaitingForAction = true;
} else if (nextAction.GetType() == "OnChat") {
Game::entityManager->SerializeEntity(entity);
m_WaitingForAction = true;
}
} else { // should be a normal block
ProcNormalAction(deltaTime, modelComponent);

View File

@@ -40,8 +40,6 @@ public:
// 2 actions are required for strips to work
bool HasMinimumActions() const { return m_Actions.size() >= 2; }
void OnChatMessageReceived(const std::string& sMessage);
private:
// Indicates this Strip is waiting for an action to be taken upon it to progress to its actions
bool m_WaitingForAction{ false };

View File

@@ -1367,7 +1367,6 @@ void HandlePacket(Packet* packet) {
std::string sMessage = GeneralUtils::UTF16ToWTF8(chatMessage.message);
LOG("%s: %s", playerName.c_str(), sMessage.c_str());
ChatPackets::SendChatMessage(packet->systemAddress, chatMessage.chatChannel, playerName, user->GetLoggedInChar(), isMythran, chatMessage.message);
if (PropertyManagementComponent::Instance()) PropertyManagementComponent::Instance()->OnChatMessageReceived(sMessage);
}
break;