DarkflameServer/dGame/dComponents/MovingPlatformComponent.cpp

424 lines
14 KiB
C++
Raw Normal View History

/*
* Darkflame Universe
* Copyright 2019
*/
#include "MovingPlatformComponent.h"
#include "BitStream.h"
#include "GeneralUtils.h"
#include "dZoneManager.h"
#include "EntityManager.h"
#include "dLogger.h"
#include "GameMessages.h"
#include "CppScripts.h"
#include "SimplePhysicsComponent.h"
#include "CDClientManager.h"
#include "CDMovingPlatformComponentTable.h"
#include "Zone.h"
//------------- PlatformSubComponent begin --------------
PlatformSubComponent::PlatformSubComponent(MovingPlatformComponent* parentComponent) {
2023-07-31 09:13:19 +00:00
m_Position = NiPoint3::ZERO;
m_ParentComponent = parentComponent;
2023-07-31 09:13:19 +00:00
m_State = eMovementPlatformState::Stopped | eMovementPlatformState::ReachedDesiredWaypoint;
m_DesiredWaypointIndex = 0;
m_InReverse = false;
m_ShouldStopAtDesiredWaypoint = false;
2023-07-31 09:13:19 +00:00
m_PercentBetweenPoints = 0.0f;
2023-07-31 09:13:19 +00:00
m_CurrentWaypointIndex = 0;
m_NextWaypointIndex = 0;
2023-07-31 09:13:19 +00:00
m_IdleTimeElapsed = 0.0f;
}
2023-07-31 09:13:19 +00:00
void PlatformSubComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
outBitStream->Write(bIsInitialUpdate || m_IsDirty);
if (!(bIsInitialUpdate || m_IsDirty)) return;
2023-07-31 09:13:19 +00:00
outBitStream->Write(m_State);
outBitStream->Write(m_DesiredWaypointIndex);
outBitStream->Write(m_ShouldStopAtDesiredWaypoint);
outBitStream->Write(m_InReverse);
outBitStream->Write(m_PercentBetweenPoints);
outBitStream->Write(m_Position.x);
outBitStream->Write(m_Position.y);
outBitStream->Write(m_Position.z);
outBitStream->Write(m_CurrentWaypointIndex);
outBitStream->Write(m_NextWaypointIndex);
outBitStream->Write(m_IdleTimeElapsed);
outBitStream->Write(m_MoveTimeElapsed);
if (!bIsInitialUpdate) m_IsDirty = false;
}
//------------- PlatformSubComponent end --------------
//------------- MoverPlatformSubComponent begin --------------
MoverPlatformSubComponent::MoverPlatformSubComponent(MovingPlatformComponent* parentComponent) : PlatformSubComponent(parentComponent) {
}
//------------- MoverPlatformSubComponent end --------------
//------------- RotatorPlatformSubComponent begin --------------
RotatorPlatformSubComponent::RotatorPlatformSubComponent(MovingPlatformComponent* parentComponent) : PlatformSubComponent(parentComponent) {
}
//------------- RotatorPlatformSubComponent end --------------
//------------- SimpleMoverPlatformSubComponent begin --------------
void SimpleMoverPlatformSubComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
outBitStream->Write(bIsInitialUpdate || m_DirtyStartingPoint);
if (bIsInitialUpdate || m_DirtyStartingPoint) {
outBitStream->Write(m_HasStartingPoint);
if (m_HasStartingPoint) {
outBitStream->Write(m_StartingPoint.x);
outBitStream->Write(m_StartingPoint.y);
outBitStream->Write(m_StartingPoint.z);
outBitStream->Write(m_StartingRotation.w);
outBitStream->Write(m_StartingRotation.x);
outBitStream->Write(m_StartingRotation.y);
outBitStream->Write(m_StartingRotation.z);
}
if (!bIsInitialUpdate) m_DirtyStartingPoint = false;
}
outBitStream->Write(bIsInitialUpdate || m_IsDirty);
if (bIsInitialUpdate || m_IsDirty) {
outBitStream->Write(m_State);
outBitStream->Write(m_CurrentWaypointIndex);
outBitStream->Write(m_InReverse);
if (!bIsInitialUpdate) m_IsDirty = false;
}
}
void SimpleMoverPlatformSubComponent::LoadConfigData() {
if (m_ParentComponent->GetParent()->GetVar<bool>(u"dbonly")) return;
NiPoint3 platformMove(
m_ParentComponent->GetParent()->GetVar<float>(u"platformMoveX"),
m_ParentComponent->GetParent()->GetVar<float>(u"platformMoveY"),
m_ParentComponent->GetParent()->GetVar<float>(u"platformMoveZ")
);
m_PlatformMove = platformMove;
m_MoveTime = m_ParentComponent->GetParent()->GetVar<float>(u"platformMoveTime");
// idk either. client does it!
m_StartAtEnd = m_ParentComponent->GetParent()->GetVar<uint32_t>(u"attached_path_start") != 0;
m_StartAtEnd = m_ParentComponent->GetParent()->GetVar<bool>(u"platformStartAtEnd");
}
void SimpleMoverPlatformSubComponent::LoadDataFromTemplate() {
if (!m_ParentComponent->GetParent()->GetVar<bool>(u"dbonly")) return;
auto* movingPlatformTable = CDClientManager::Instance().GetTable<CDMovingPlatformComponentTable>();
if (movingPlatformTable == nullptr) return;
const auto& platformEntry = movingPlatformTable->GetPlatformEntry(m_ParentComponent->GetComponentId());
if (!platformEntry || !platformEntry->platformIsSimpleMover) return;
NiPoint3 platformMove = platformEntry->platformMove;
float moveTime = platformEntry->moveTime;
2023-08-01 08:36:24 +00:00
m_PlatformMove = platformMove;
m_MoveTime = moveTime;
}
SimpleMoverPlatformSubComponent::SimpleMoverPlatformSubComponent(MovingPlatformComponent* parentComponent, const NiPoint3& platformMove, const bool startsInReverse) : PlatformSubComponent(parentComponent) {
m_PlatformMove = platformMove;
m_InReverse = startsInReverse;
m_HasStartingPoint = true;
m_DirtyStartingPoint = true;
m_IsDirty = true;
m_StartingPoint = m_ParentComponent->GetParent()->GetPosition();
m_StartingRotation = m_ParentComponent->GetParent()->GetRotation();
}
//------------- SimpleMoverPlatformSubComponent end --------------
//------------- MovingPlatformComponent begin --------------
MovingPlatformComponent::MovingPlatformComponent(Entity* parent, const std::string& pathName) : Component(parent) {
}
2023-08-01 08:36:24 +00:00
void MovingPlatformComponent::LoadDataFromTemplate() {
std::for_each(m_Platforms.begin(), m_Platforms.end(), [](const std::unique_ptr<PlatformSubComponent>& platform) { platform->LoadDataFromTemplate(); });
}
void MovingPlatformComponent::LoadConfigData() {
2023-07-31 09:13:19 +00:00
if (m_Parent->GetVar<bool>(u"platformIsSimpleMover")) {
AddMovingPlatform<SimpleMoverPlatformSubComponent>(NiPoint3::ZERO, false);
2023-07-31 09:13:19 +00:00
}
if (m_Parent->GetVar<bool>(u"platformIsMover")) {
AddMovingPlatform<MoverPlatformSubComponent>();
2023-07-31 09:13:19 +00:00
}
if (m_Parent->GetVar<bool>(u"platformIsRotater")) {
AddMovingPlatform<RotatorPlatformSubComponent>();
2023-07-31 09:13:19 +00:00
}
m_DirtyPathInfo = true;
}
void MovingPlatformComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) {
2023-07-31 09:13:19 +00:00
// For some reason we need to write this here instead of later on.
outBitStream->Write(!m_Platforms.empty());
outBitStream->Write(bIsInitialUpdate || m_DirtyPathInfo);
if (bIsInitialUpdate || m_DirtyPathInfo) {
outBitStream->Write(!m_PathName.empty());
if (!m_PathName.empty()) {
outBitStream->Write(static_cast<uint16_t>(m_PathName.size()));
for (const auto& c : m_PathName) {
outBitStream->Write(static_cast<uint16_t>(c));
}
outBitStream->Write(m_StartingWaypointIndex);
outBitStream->Write(m_StartsIsInReverse);
2022-07-28 13:39:57 +00:00
}
2023-07-31 09:13:19 +00:00
if (!bIsInitialUpdate) m_DirtyPathInfo = false;
2022-07-28 13:39:57 +00:00
}
if (m_Platforms.empty()) return;
2023-07-31 09:13:19 +00:00
for (const auto& platform : m_Platforms) {
outBitStream->Write1(); // Has platform to write
outBitStream->Write(platform->GetPlatformType());
platform->Serialize(outBitStream, bIsInitialUpdate);
2022-07-28 13:39:57 +00:00
}
2023-07-31 09:13:19 +00:00
outBitStream->Write0(); // No more platforms to write
}
void MovingPlatformComponent::OnRebuildInitilized() {
2022-07-28 13:39:57 +00:00
StopPathing();
}
void MovingPlatformComponent::OnCompleteRebuild() {
2023-07-31 09:13:19 +00:00
if (m_NoAutoStart) return;
2022-07-28 13:39:57 +00:00
StartPathing();
}
void MovingPlatformComponent::SetMovementState(eMovementPlatformState value) {
2023-07-31 09:13:19 +00:00
// auto* subComponent = static_cast<MoverSubComponent*>(m_MoverSubComponent);
2023-07-31 09:13:19 +00:00
// subComponent->mState = value;
2023-07-31 09:13:19 +00:00
// Game::entityManager->SerializeEntity(m_Parent);
}
2022-07-28 13:39:57 +00:00
void MovingPlatformComponent::GotoWaypoint(uint32_t index, bool stopAtWaypoint) {
2023-07-31 09:13:19 +00:00
// auto* subComponent = static_cast<MoverSubComponent*>(m_MoverSubComponent);
2023-07-31 09:13:19 +00:00
// subComponent->mDesiredWaypointIndex = index;
// subComponent->mNextWaypointIndex = index;
// subComponent->mShouldStopAtDesiredWaypoint = stopAtWaypoint;
2023-07-31 09:13:19 +00:00
// StartPathing();
}
2022-07-28 13:39:57 +00:00
void MovingPlatformComponent::StartPathing() {
2023-08-01 08:36:24 +00:00
// state == Travelling
2023-07-31 09:13:19 +00:00
// //GameMessages::SendStartPathing(m_Parent);
// m_PathingStopped = false;
2023-07-31 09:13:19 +00:00
// auto* subComponent = static_cast<MoverSubComponent*>(m_MoverSubComponent);
2023-07-31 09:13:19 +00:00
// subComponent->mShouldStopAtDesiredWaypoint = true;
// subComponent->mState = eMovementPlatformState::Stationary;
2023-07-31 09:13:19 +00:00
// NiPoint3 targetPosition;
2023-07-31 09:13:19 +00:00
// if (m_Path != nullptr) {
// const auto& currentWaypoint = m_Path->pathWaypoints[subComponent->mCurrentWaypointIndex];
// const auto& nextWaypoint = m_Path->pathWaypoints[subComponent->mNextWaypointIndex];
2023-07-31 09:13:19 +00:00
// subComponent->mPosition = currentWaypoint.position;
// subComponent->mSpeed = currentWaypoint.movingPlatform.speed;
// subComponent->mWaitTime = currentWaypoint.movingPlatform.wait;
2023-07-31 09:13:19 +00:00
// targetPosition = nextWaypoint.position;
// } else {
// subComponent->mPosition = m_Parent->GetPosition();
// subComponent->mSpeed = 1.0f;
// subComponent->mWaitTime = 2.0f;
2023-07-31 09:13:19 +00:00
// targetPosition = m_Parent->GetPosition() + NiPoint3(0.0f, 10.0f, 0.0f);
// }
2023-07-31 09:13:19 +00:00
// m_Parent->AddCallbackTimer(subComponent->mWaitTime, [this] {
// SetMovementState(eMovementPlatformState::Moving);
// });
2023-07-31 09:13:19 +00:00
// const auto travelTime = Vector3::Distance(targetPosition, subComponent->mPosition) / subComponent->mSpeed + 1.5f;
2023-07-31 09:13:19 +00:00
// const auto travelNext = subComponent->mWaitTime + travelTime;
2023-07-31 09:13:19 +00:00
// m_Parent->AddCallbackTimer(travelTime, [subComponent, this] {
// for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) {
// script->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex);
// }
// });
2023-07-31 09:13:19 +00:00
// m_Parent->AddCallbackTimer(travelNext, [this] {
// ContinuePathing();
// });
2023-07-31 09:13:19 +00:00
// //GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS);
2023-07-31 09:13:19 +00:00
// Game::entityManager->SerializeEntity(m_Parent);
}
2022-07-28 13:39:57 +00:00
void MovingPlatformComponent::ContinuePathing() {
2023-08-01 08:36:24 +00:00
// state == Travelling
2023-07-31 09:13:19 +00:00
// auto* subComponent = static_cast<MoverSubComponent*>(m_MoverSubComponent);
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// subComponent->mState = eMovementPlatformState::Stationary;
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// subComponent->mCurrentWaypointIndex = subComponent->mNextWaypointIndex;
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// NiPoint3 targetPosition;
// uint32_t pathSize;
// PathBehavior behavior;
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// if (m_Path != nullptr) {
// const auto& currentWaypoint = m_Path->pathWaypoints[subComponent->mCurrentWaypointIndex];
// const auto& nextWaypoint = m_Path->pathWaypoints[subComponent->mNextWaypointIndex];
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// subComponent->mPosition = currentWaypoint.position;
// subComponent->mSpeed = currentWaypoint.movingPlatform.speed;
// subComponent->mWaitTime = currentWaypoint.movingPlatform.wait; // + 2;
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// pathSize = m_Path->pathWaypoints.size() - 1;
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// behavior = static_cast<PathBehavior>(m_Path->pathBehavior);
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// targetPosition = nextWaypoint.position;
// } else {
// subComponent->mPosition = m_Parent->GetPosition();
// subComponent->mSpeed = 1.0f;
// subComponent->mWaitTime = 2.0f;
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// targetPosition = m_Parent->GetPosition() + NiPoint3(0.0f, 10.0f, 0.0f);
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// pathSize = 1;
// behavior = PathBehavior::Loop;
// }
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// if (m_Parent->GetLOT() == 9483) {
// behavior = PathBehavior::Bounce;
// } else {
// return;
// }
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// if (subComponent->mCurrentWaypointIndex >= pathSize) {
// subComponent->mCurrentWaypointIndex = pathSize;
// switch (behavior) {
// case PathBehavior::Once:
// Game::entityManager->SerializeEntity(m_Parent);
// return;
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// case PathBehavior::Bounce:
// subComponent->mInReverse = true;
// break;
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// case PathBehavior::Loop:
// subComponent->mNextWaypointIndex = 0;
// break;
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// default:
// break;
// }
// } else if (subComponent->mCurrentWaypointIndex == 0) {
// subComponent->mInReverse = false;
// }
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// if (subComponent->mInReverse) {
// subComponent->mNextWaypointIndex = subComponent->mCurrentWaypointIndex - 1;
// } else {
// subComponent->mNextWaypointIndex = subComponent->mCurrentWaypointIndex + 1;
// }
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// /*
// subComponent->mNextWaypointIndex = 0;
// subComponent->mCurrentWaypointIndex = 1;
// */
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// //GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS);
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// if (subComponent->mCurrentWaypointIndex == subComponent->mDesiredWaypointIndex) {
// // TODO: Send event?
// StopPathing();
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// return;
// }
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// m_Parent->CancelCallbackTimers();
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// m_Parent->AddCallbackTimer(subComponent->mWaitTime, [this] {
// SetMovementState(eMovementPlatformState::Moving);
// });
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// auto travelTime = Vector3::Distance(targetPosition, subComponent->mPosition) / subComponent->mSpeed + 1.5;
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// if (m_Parent->GetLOT() == 9483) {
// travelTime += 20;
// }
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// const auto travelNext = subComponent->mWaitTime + travelTime;
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// m_Parent->AddCallbackTimer(travelTime, [subComponent, this] {
// for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) {
// script->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex);
// }
// });
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// m_Parent->AddCallbackTimer(travelNext, [this] {
// ContinuePathing();
// });
2022-07-28 13:39:57 +00:00
2023-07-31 09:13:19 +00:00
// Game::entityManager->SerializeEntity(m_Parent);
}
2022-07-28 13:39:57 +00:00
void MovingPlatformComponent::StopPathing() {
2023-08-01 08:36:24 +00:00
// state == Stopped
2022-07-28 13:39:57 +00:00
//m_Parent->CancelCallbackTimers();
2023-07-31 09:13:19 +00:00
// auto* subComponent = static_cast<MoverSubComponent*>(m_MoverSubComponent);
2023-07-31 09:13:19 +00:00
// m_PathingStopped = true;
2023-07-31 09:13:19 +00:00
// subComponent->mState = eMovementPlatformState::Stopped;
// subComponent->mDesiredWaypointIndex = -1;
// subComponent->mShouldStopAtDesiredWaypoint = false;
2023-07-31 09:13:19 +00:00
// Game::entityManager->SerializeEntity(m_Parent);
2022-07-28 13:39:57 +00:00
//GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS);
}
2022-07-28 13:39:57 +00:00
bool MovingPlatformComponent::GetNoAutoStart() const {
2023-07-31 09:13:19 +00:00
return false;
// return m_NoAutoStart;
}
2022-07-28 13:39:57 +00:00
void MovingPlatformComponent::SetNoAutoStart(const bool value) {
2023-07-31 09:13:19 +00:00
// m_NoAutoStart = value;
}
2022-07-28 13:39:57 +00:00
void MovingPlatformComponent::WarpToWaypoint(size_t index) {
2023-07-31 09:13:19 +00:00
// const auto& waypoint = m_Path->pathWaypoints[index];
2023-07-31 09:13:19 +00:00
// m_Parent->SetPosition(waypoint.position);
// m_Parent->SetRotation(waypoint.rotation);
2023-07-31 09:13:19 +00:00
// Game::entityManager->SerializeEntity(m_Parent);
}
2022-07-28 13:39:57 +00:00
size_t MovingPlatformComponent::GetLastWaypointIndex() const {
2023-07-31 09:13:19 +00:00
return 0;
// return m_Path->pathWaypoints.size() - 1;
}
//------------- MovingPlatformComponent end --------------