mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-05-14 03:15:05 +00:00
Refactor MovingPlatformComponent to support subcomponents for movement and rotation
- Introduced PlatformSubComponent as a base class for platform movement logic. - Added MoverSubComponent for standard path-following behavior. - Implemented SimpleMoverSubComponent for auto-generating two-waypoint paths. - Created RotatorSubComponent to handle angular velocity and rotation along paths. - Updated MovingPlatformComponent to manage multiple subcomponents and their states. - Modified serialization and update logic to accommodate new subcomponent architecture. - Adjusted GameMessages to include additional parameters for platform state synchronization. - Enhanced SimplePhysicsComponent to prevent double movement when on a moving platform. - Added new CMakeLists.txt for organizing MovingPlatformComponent files.
This commit is contained in:
@@ -4,80 +4,119 @@
|
||||
*/
|
||||
|
||||
#include "MovingPlatformComponent.h"
|
||||
#include "PlatformSubComponent.h"
|
||||
#include "MoverSubComponent.h"
|
||||
#include "SimpleMoverSubComponent.h"
|
||||
#include "RotatorSubComponent.h"
|
||||
#include "BitStream.h"
|
||||
#include "GeneralUtils.h"
|
||||
#include "dZoneManager.h"
|
||||
#include "EntityManager.h"
|
||||
#include "Logger.h"
|
||||
#include "GameMessages.h"
|
||||
#include "CppScripts.h"
|
||||
#include "SimplePhysicsComponent.h"
|
||||
#include "Zone.h"
|
||||
#include "eMovementPlatformState.h"
|
||||
|
||||
MoverSubComponent::MoverSubComponent(const NiPoint3& startPos) {
|
||||
mPosition = {};
|
||||
MovingPlatformComponent::MovingPlatformComponent(Entity* parent, const int32_t componentID, const std::string& pathName)
|
||||
: Component(parent, componentID) {
|
||||
|
||||
mState = eMovementPlatformState::Stopped;
|
||||
mDesiredWaypointIndex = 0; // -1;
|
||||
mInReverse = false;
|
||||
mShouldStopAtDesiredWaypoint = false;
|
||||
|
||||
mPercentBetweenPoints = 0.0f;
|
||||
|
||||
mCurrentWaypointIndex = 0;
|
||||
mNextWaypointIndex = 0; //mCurrentWaypointIndex + 1;
|
||||
|
||||
mIdleTimeElapsed = 0.0f;
|
||||
}
|
||||
|
||||
MoverSubComponent::~MoverSubComponent() = default;
|
||||
|
||||
void MoverSubComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream.Write<bool>(true);
|
||||
|
||||
outBitStream.Write(mState);
|
||||
outBitStream.Write<int32_t>(mDesiredWaypointIndex);
|
||||
outBitStream.Write(mShouldStopAtDesiredWaypoint);
|
||||
outBitStream.Write(mInReverse);
|
||||
|
||||
outBitStream.Write<float_t>(mPercentBetweenPoints);
|
||||
|
||||
outBitStream.Write<float_t>(mPosition.x);
|
||||
outBitStream.Write<float_t>(mPosition.y);
|
||||
outBitStream.Write<float_t>(mPosition.z);
|
||||
|
||||
outBitStream.Write<uint32_t>(mCurrentWaypointIndex);
|
||||
outBitStream.Write<uint32_t>(mNextWaypointIndex);
|
||||
|
||||
outBitStream.Write<float_t>(mIdleTimeElapsed);
|
||||
outBitStream.Write<float_t>(0.0f); // Move time elapsed
|
||||
}
|
||||
|
||||
//------------- MovingPlatformComponent below --------------
|
||||
|
||||
MovingPlatformComponent::MovingPlatformComponent(Entity* parent, const int32_t componentID, const std::string& pathName) : Component(parent, componentID) {
|
||||
m_MoverSubComponentType = eMoverSubComponentType::mover;
|
||||
m_MoverSubComponent = new MoverSubComponent(m_Parent->GetDefaultPosition());
|
||||
m_PathName = GeneralUtils::ASCIIToUTF16(pathName);
|
||||
m_Path = Game::zoneManager->GetZone()->GetPath(pathName);
|
||||
m_NoAutoStart = false;
|
||||
|
||||
if (m_Path == nullptr) {
|
||||
if (m_Path == nullptr && !pathName.empty()) {
|
||||
LOG("Path not found: %s", pathName.c_str());
|
||||
}
|
||||
|
||||
SetupPlatformSubComponents();
|
||||
}
|
||||
|
||||
MovingPlatformComponent::~MovingPlatformComponent() = default;
|
||||
|
||||
void MovingPlatformComponent::SetupPlatformSubComponents() {
|
||||
// Read component properties matching client SetupPlatform
|
||||
bool isMover = m_Parent->GetVar<bool>(u"platformIsMover");
|
||||
bool isSimpleMover = m_Parent->GetVar<bool>(u"platformIsSimpleMover");
|
||||
bool isRotater = m_Parent->GetVar<bool>(u"platformIsRotater");
|
||||
|
||||
// Read sound GUIDs
|
||||
m_PlatformSoundStart = m_Parent->GetVarAsString(u"platformSoundStart");
|
||||
m_PlatformSoundTravel = m_Parent->GetVarAsString(u"platformSoundTravel");
|
||||
m_PlatformSoundStop = m_Parent->GetVarAsString(u"platformSoundStop");
|
||||
|
||||
// If no flags set but we have a path, default to mover (backwards compatibility)
|
||||
if (!isMover && !isSimpleMover && !isRotater) {
|
||||
if (m_Path && m_Path->pathType == PathType::MovingPlatform) {
|
||||
isMover = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Create mover subcomponent
|
||||
if (isMover && m_Path) {
|
||||
m_MoverSubComponentType = eMoverSubComponentType::mover;
|
||||
auto mover = std::make_unique<MoverSubComponent>(m_Parent, m_Path);
|
||||
|
||||
if (!m_PathName.empty()) {
|
||||
bool reverse = m_Parent->GetVar<bool>(u"reverse");
|
||||
int32_t startPoint = m_Parent->GetVarAs<int32_t>(u"startPoint");
|
||||
mover->SetInReverse(reverse);
|
||||
if (startPoint >= 0 && startPoint < static_cast<int32_t>(m_Path->pathWaypoints.size())) {
|
||||
mover->SetupWaypointSegment(static_cast<uint32_t>(startPoint));
|
||||
}
|
||||
mover->SetActive(true);
|
||||
}
|
||||
|
||||
m_MoverSubComponent = std::move(mover);
|
||||
}
|
||||
|
||||
// Create simple mover subcomponent
|
||||
if (isSimpleMover) {
|
||||
m_MoverSubComponentType = eMoverSubComponentType::simpleMover;
|
||||
|
||||
NiPoint3 platformMove{};
|
||||
platformMove.x = m_Parent->GetVar<float>(u"platformMoveX");
|
||||
platformMove.y = m_Parent->GetVar<float>(u"platformMoveY");
|
||||
platformMove.z = m_Parent->GetVar<float>(u"platformMoveZ");
|
||||
|
||||
float platformMoveTime = m_Parent->GetVar<float>(u"platformMoveTime");
|
||||
|
||||
NiPoint3 startPos = m_Parent->GetDefaultPosition();
|
||||
NiQuaternion startRot = m_Parent->GetDefaultRotation();
|
||||
|
||||
m_MoverSubComponent = std::make_unique<SimpleMoverSubComponent>(
|
||||
m_Parent, startPos, startRot, platformMove, platformMoveTime);
|
||||
}
|
||||
|
||||
// Create rotator subcomponent (can coexist with mover)
|
||||
if (isRotater && m_Path) {
|
||||
auto rotator = std::make_unique<RotatorSubComponent>(m_Parent, m_Path);
|
||||
|
||||
if (!m_PathName.empty()) {
|
||||
bool reverse = m_Parent->GetVar<bool>(u"reverse");
|
||||
int32_t startPoint = m_Parent->GetVarAs<int32_t>(u"startPoint");
|
||||
rotator->SetInReverse(reverse);
|
||||
if (startPoint >= 0 && startPoint < static_cast<int32_t>(m_Path->pathWaypoints.size())) {
|
||||
rotator->SetupWaypointSegment(static_cast<uint32_t>(startPoint));
|
||||
}
|
||||
rotator->SetActive(true);
|
||||
}
|
||||
|
||||
m_RotatorSubComponent = std::move(rotator);
|
||||
}
|
||||
|
||||
// Fallback: if nothing was created, create a default mover
|
||||
if (!m_MoverSubComponent && !m_RotatorSubComponent) {
|
||||
m_MoverSubComponentType = eMoverSubComponentType::mover;
|
||||
m_MoverSubComponent = std::make_unique<MoverSubComponent>(m_Parent, m_Path);
|
||||
}
|
||||
}
|
||||
|
||||
MovingPlatformComponent::~MovingPlatformComponent() {
|
||||
delete static_cast<MoverSubComponent*>(m_MoverSubComponent);
|
||||
}
|
||||
|
||||
void MovingPlatformComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
// Here we don't serialize the moving platform to let the client simulate the movement
|
||||
|
||||
if (!m_Serialize) {
|
||||
outBitStream.Write<bool>(false);
|
||||
outBitStream.Write<bool>(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -87,7 +126,6 @@ void MovingPlatformComponent::Serialize(RakNet::BitStream& outBitStream, bool bI
|
||||
outBitStream.Write(hasPath);
|
||||
|
||||
if (hasPath) {
|
||||
// Is on rail
|
||||
outBitStream.Write1();
|
||||
|
||||
outBitStream.Write<uint16_t>(m_PathName.size());
|
||||
@@ -95,25 +133,50 @@ void MovingPlatformComponent::Serialize(RakNet::BitStream& outBitStream, bool bI
|
||||
outBitStream.Write<uint16_t>(c);
|
||||
}
|
||||
|
||||
// Starting point
|
||||
outBitStream.Write<uint32_t>(0);
|
||||
|
||||
// Reverse
|
||||
outBitStream.Write<bool>(false);
|
||||
outBitStream.Write<uint32_t>(m_MoverSubComponent ? m_MoverSubComponent->GetCurrentWaypointIndex() : 0);
|
||||
outBitStream.Write<bool>(m_MoverSubComponent ? m_MoverSubComponent->GetInReverse() : false);
|
||||
}
|
||||
|
||||
const auto hasPlatform = m_MoverSubComponent != nullptr;
|
||||
outBitStream.Write<bool>(hasPlatform);
|
||||
|
||||
if (hasPlatform) {
|
||||
auto* mover = static_cast<MoverSubComponent*>(m_MoverSubComponent);
|
||||
outBitStream.Write(m_MoverSubComponentType);
|
||||
m_MoverSubComponent->Serialize(outBitStream, bIsInitialUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_MoverSubComponentType == eMoverSubComponentType::simpleMover) {
|
||||
// TODO
|
||||
} else {
|
||||
mover->Serialize(outBitStream, bIsInitialUpdate);
|
||||
void MovingPlatformComponent::Update(float deltaTime) {
|
||||
if (!m_Serialize) return;
|
||||
|
||||
// Track whether we were travelling before update for sound management
|
||||
bool wasTravelling = m_MoverSubComponent &&
|
||||
(m_MoverSubComponent->GetState() & PlatformState::Travelling);
|
||||
|
||||
bool dirty = false;
|
||||
|
||||
if (m_MoverSubComponent) {
|
||||
m_MoverSubComponent->Update(deltaTime, dirty);
|
||||
}
|
||||
|
||||
if (m_RotatorSubComponent) {
|
||||
m_RotatorSubComponent->Update(deltaTime, dirty);
|
||||
}
|
||||
|
||||
// Handle travel sound looping (matching client PlayTravelSound/StopTravelSound)
|
||||
if (m_MoverSubComponent && !m_PlatformSoundTravel.empty()) {
|
||||
bool isTravelling = m_MoverSubComponent->GetState() & PlatformState::Travelling;
|
||||
if (isTravelling && !wasTravelling) {
|
||||
// Started travelling — play looping travel sound
|
||||
GameMessages::SendPlayNDAudioEmitter(m_Parent, UNASSIGNED_SYSTEM_ADDRESS, m_PlatformSoundTravel);
|
||||
}
|
||||
// Note: the client stops the travel sound on arrival/stop via StopTravelSound.
|
||||
// SendPlayNDAudioEmitter doesn't support stopping, so the sound will naturally end
|
||||
// or be replaced by the arrive/stop sound.
|
||||
}
|
||||
|
||||
if (dirty) {
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,201 +185,66 @@ void MovingPlatformComponent::OnQuickBuildInitilized() {
|
||||
}
|
||||
|
||||
void MovingPlatformComponent::OnCompleteQuickBuild() {
|
||||
if (m_NoAutoStart)
|
||||
return;
|
||||
|
||||
if (m_NoAutoStart) return;
|
||||
StartPathing();
|
||||
}
|
||||
|
||||
void MovingPlatformComponent::SetMovementState(eMovementPlatformState value) {
|
||||
auto* subComponent = static_cast<MoverSubComponent*>(m_MoverSubComponent);
|
||||
|
||||
subComponent->mState = value;
|
||||
|
||||
void MovingPlatformComponent::SetMovementState(uint32_t state) {
|
||||
if (m_MoverSubComponent) m_MoverSubComponent->SetState(state);
|
||||
if (m_RotatorSubComponent) m_RotatorSubComponent->SetState(state);
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
}
|
||||
|
||||
void MovingPlatformComponent::GotoWaypoint(uint32_t index, bool stopAtWaypoint) {
|
||||
auto* subComponent = static_cast<MoverSubComponent*>(m_MoverSubComponent);
|
||||
|
||||
subComponent->mDesiredWaypointIndex = index;
|
||||
subComponent->mNextWaypointIndex = index;
|
||||
subComponent->mShouldStopAtDesiredWaypoint = stopAtWaypoint;
|
||||
|
||||
StartPathing();
|
||||
}
|
||||
|
||||
void MovingPlatformComponent::StartPathing() {
|
||||
//GameMessages::SendStartPathing(m_Parent);
|
||||
m_PathingStopped = false;
|
||||
|
||||
auto* subComponent = static_cast<MoverSubComponent*>(m_MoverSubComponent);
|
||||
|
||||
subComponent->mShouldStopAtDesiredWaypoint = true;
|
||||
subComponent->mState = eMovementPlatformState::Stationary;
|
||||
|
||||
NiPoint3 targetPosition;
|
||||
|
||||
if (m_Path != nullptr) {
|
||||
const auto& currentWaypoint = m_Path->pathWaypoints[subComponent->mCurrentWaypointIndex];
|
||||
const auto& nextWaypoint = m_Path->pathWaypoints[subComponent->mNextWaypointIndex];
|
||||
|
||||
subComponent->mPosition = currentWaypoint.position;
|
||||
subComponent->mSpeed = currentWaypoint.speed;
|
||||
subComponent->mWaitTime = currentWaypoint.movingPlatform.wait;
|
||||
|
||||
targetPosition = nextWaypoint.position;
|
||||
} else {
|
||||
subComponent->mPosition = m_Parent->GetPosition();
|
||||
subComponent->mSpeed = 1.0f;
|
||||
subComponent->mWaitTime = 2.0f;
|
||||
|
||||
targetPosition = m_Parent->GetPosition() + NiPoint3(0.0f, 10.0f, 0.0f);
|
||||
}
|
||||
|
||||
m_Parent->AddCallbackTimer(subComponent->mWaitTime, [this] {
|
||||
SetMovementState(eMovementPlatformState::Moving);
|
||||
});
|
||||
|
||||
const auto travelTime = Vector3::Distance(targetPosition, subComponent->mPosition) / subComponent->mSpeed + 1.5f;
|
||||
|
||||
const auto travelNext = subComponent->mWaitTime + travelTime;
|
||||
|
||||
m_Parent->AddCallbackTimer(travelTime, [subComponent, this] {
|
||||
this->m_Parent->GetScript()->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex);
|
||||
});
|
||||
|
||||
m_Parent->AddCallbackTimer(travelNext, [this] {
|
||||
ContinuePathing();
|
||||
});
|
||||
|
||||
//GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS);
|
||||
if (m_MoverSubComponent) m_MoverSubComponent->GotoWaypoint(index, stopAtWaypoint);
|
||||
if (m_RotatorSubComponent) m_RotatorSubComponent->GotoWaypoint(index, stopAtWaypoint);
|
||||
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
}
|
||||
|
||||
void MovingPlatformComponent::ContinuePathing() {
|
||||
auto* subComponent = static_cast<MoverSubComponent*>(m_MoverSubComponent);
|
||||
void MovingPlatformComponent::StartPathing() {
|
||||
m_PathingStopped = false;
|
||||
|
||||
subComponent->mState = eMovementPlatformState::Stationary;
|
||||
if (m_MoverSubComponent) m_MoverSubComponent->StartPathing();
|
||||
if (m_RotatorSubComponent) m_RotatorSubComponent->StartPathing();
|
||||
|
||||
subComponent->mCurrentWaypointIndex = subComponent->mNextWaypointIndex;
|
||||
|
||||
NiPoint3 targetPosition;
|
||||
uint32_t pathSize;
|
||||
PathBehavior behavior;
|
||||
|
||||
if (m_Path != nullptr) {
|
||||
const auto& currentWaypoint = m_Path->pathWaypoints[subComponent->mCurrentWaypointIndex];
|
||||
const auto& nextWaypoint = m_Path->pathWaypoints[subComponent->mNextWaypointIndex];
|
||||
|
||||
subComponent->mPosition = currentWaypoint.position;
|
||||
subComponent->mSpeed = currentWaypoint.speed;
|
||||
subComponent->mWaitTime = currentWaypoint.movingPlatform.wait; // + 2;
|
||||
|
||||
pathSize = m_Path->pathWaypoints.size() - 1;
|
||||
|
||||
behavior = static_cast<PathBehavior>(m_Path->pathBehavior);
|
||||
|
||||
targetPosition = nextWaypoint.position;
|
||||
} else {
|
||||
subComponent->mPosition = m_Parent->GetPosition();
|
||||
subComponent->mSpeed = 1.0f;
|
||||
subComponent->mWaitTime = 2.0f;
|
||||
|
||||
targetPosition = m_Parent->GetPosition() + NiPoint3(0.0f, 10.0f, 0.0f);
|
||||
|
||||
pathSize = 1;
|
||||
behavior = PathBehavior::Loop;
|
||||
if (m_MoverSubComponent) {
|
||||
GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS,
|
||||
m_MoverSubComponent->GetShouldStopAtDesiredWaypoint(),
|
||||
m_MoverSubComponent->GetCurrentWaypointIndex(),
|
||||
m_MoverSubComponent->GetDesiredWaypointIndex(),
|
||||
m_MoverSubComponent->GetNextWaypointIndex(),
|
||||
static_cast<eMovementPlatformState>(m_MoverSubComponent->GetSerializedState()),
|
||||
m_MoverSubComponent->GetInReverse(),
|
||||
m_MoverSubComponent->GetIdleTimeElapsed(),
|
||||
m_MoverSubComponent->GetMoveTimeElapsed(),
|
||||
m_MoverSubComponent->GetPercentBetweenPoints(),
|
||||
m_MoverSubComponent->GetPosition());
|
||||
}
|
||||
|
||||
if (m_Parent->GetLOT() == 9483) {
|
||||
behavior = PathBehavior::Bounce;
|
||||
} else {
|
||||
return;
|
||||
if (!m_PlatformSoundStart.empty()) {
|
||||
GameMessages::SendPlayNDAudioEmitter(m_Parent, UNASSIGNED_SYSTEM_ADDRESS, m_PlatformSoundStart);
|
||||
}
|
||||
|
||||
if (subComponent->mCurrentWaypointIndex >= pathSize) {
|
||||
subComponent->mCurrentWaypointIndex = pathSize;
|
||||
switch (behavior) {
|
||||
case PathBehavior::Once:
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
return;
|
||||
|
||||
case PathBehavior::Bounce:
|
||||
subComponent->mInReverse = true;
|
||||
break;
|
||||
|
||||
case PathBehavior::Loop:
|
||||
subComponent->mNextWaypointIndex = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (subComponent->mCurrentWaypointIndex == 0) {
|
||||
subComponent->mInReverse = false;
|
||||
}
|
||||
|
||||
if (subComponent->mInReverse) {
|
||||
subComponent->mNextWaypointIndex = subComponent->mCurrentWaypointIndex - 1;
|
||||
} else {
|
||||
subComponent->mNextWaypointIndex = subComponent->mCurrentWaypointIndex + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
subComponent->mNextWaypointIndex = 0;
|
||||
subComponent->mCurrentWaypointIndex = 1;
|
||||
*/
|
||||
|
||||
//GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
if (subComponent->mCurrentWaypointIndex == subComponent->mDesiredWaypointIndex) {
|
||||
// TODO: Send event?
|
||||
StopPathing();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_Parent->CancelCallbackTimers();
|
||||
|
||||
m_Parent->AddCallbackTimer(subComponent->mWaitTime, [this] {
|
||||
SetMovementState(eMovementPlatformState::Moving);
|
||||
});
|
||||
|
||||
auto travelTime = Vector3::Distance(targetPosition, subComponent->mPosition) / subComponent->mSpeed + 1.5;
|
||||
|
||||
if (m_Parent->GetLOT() == 9483) {
|
||||
travelTime += 20;
|
||||
}
|
||||
|
||||
const auto travelNext = subComponent->mWaitTime + travelTime;
|
||||
|
||||
m_Parent->AddCallbackTimer(travelTime, [subComponent, this] {
|
||||
this->m_Parent->GetScript()->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex);
|
||||
});
|
||||
|
||||
m_Parent->AddCallbackTimer(travelNext, [this] {
|
||||
ContinuePathing();
|
||||
});
|
||||
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
}
|
||||
|
||||
void MovingPlatformComponent::StopPathing() {
|
||||
//m_Parent->CancelCallbackTimers();
|
||||
|
||||
auto* subComponent = static_cast<MoverSubComponent*>(m_MoverSubComponent);
|
||||
|
||||
m_PathingStopped = true;
|
||||
|
||||
subComponent->mState = eMovementPlatformState::Stopped;
|
||||
subComponent->mDesiredWaypointIndex = -1;
|
||||
subComponent->mShouldStopAtDesiredWaypoint = false;
|
||||
if (m_MoverSubComponent) m_MoverSubComponent->StopPathing();
|
||||
if (m_RotatorSubComponent) m_RotatorSubComponent->StopPathing();
|
||||
|
||||
GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS,
|
||||
false, 0, -1, 0, eMovementPlatformState::Stopped);
|
||||
|
||||
if (!m_PlatformSoundStop.empty()) {
|
||||
GameMessages::SendPlayNDAudioEmitter(m_Parent, UNASSIGNED_SYSTEM_ADDRESS, m_PlatformSoundStop);
|
||||
}
|
||||
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
|
||||
//GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS);
|
||||
}
|
||||
|
||||
void MovingPlatformComponent::SetSerialized(bool value) {
|
||||
@@ -332,18 +260,18 @@ void MovingPlatformComponent::SetNoAutoStart(const bool value) {
|
||||
}
|
||||
|
||||
void MovingPlatformComponent::WarpToWaypoint(size_t index) {
|
||||
const auto& waypoint = m_Path->pathWaypoints[index];
|
||||
|
||||
m_Parent->SetPosition(waypoint.position);
|
||||
m_Parent->SetRotation(waypoint.rotation);
|
||||
|
||||
if (m_MoverSubComponent) m_MoverSubComponent->WarpToWaypoint(index);
|
||||
if (m_RotatorSubComponent) m_RotatorSubComponent->WarpToWaypoint(index);
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
}
|
||||
|
||||
size_t MovingPlatformComponent::GetLastWaypointIndex() const {
|
||||
return m_Path->pathWaypoints.size() - 1;
|
||||
if (m_MoverSubComponent) return m_MoverSubComponent->GetLastWaypointIndex();
|
||||
if (m_RotatorSubComponent) return m_RotatorSubComponent->GetLastWaypointIndex();
|
||||
return 0;
|
||||
}
|
||||
|
||||
MoverSubComponent* MovingPlatformComponent::GetMoverSubComponent() const {
|
||||
return static_cast<MoverSubComponent*>(m_MoverSubComponent);
|
||||
PlatformSubComponent* MovingPlatformComponent::GetMoverSubComponent() const {
|
||||
if (m_MoverSubComponent) return m_MoverSubComponent.get();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user