2021-12-05 17:54:36 +00:00
|
|
|
/*
|
|
|
|
* Darkflame Universe
|
|
|
|
* Copyright 2019
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef MOVINGPLATFORMCOMPONENT_H
|
|
|
|
#define MOVINGPLATFORMCOMPONENT_H
|
|
|
|
|
|
|
|
#include "NiPoint3.h"
|
2023-07-31 09:13:19 +00:00
|
|
|
#include <memory>
|
2021-12-05 17:54:36 +00:00
|
|
|
#include <string>
|
2023-07-31 09:13:19 +00:00
|
|
|
#include <vector>
|
2021-12-05 17:54:36 +00:00
|
|
|
|
|
|
|
#include "dCommonVars.h"
|
|
|
|
#include "Component.h"
|
2023-01-07 05:17:05 +00:00
|
|
|
#include "eMovementPlatformState.h"
|
2023-03-04 07:16:37 +00:00
|
|
|
#include "eReplicaComponentType.h"
|
2023-01-07 05:17:05 +00:00
|
|
|
|
|
|
|
class Path;
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2023-07-31 09:13:19 +00:00
|
|
|
/**
|
|
|
|
* Different types of available platforms
|
|
|
|
*/
|
2021-12-05 17:54:36 +00:00
|
|
|
enum class eMoverSubComponentType : uint32_t {
|
2023-07-31 09:13:19 +00:00
|
|
|
None = 0,
|
|
|
|
Mover = 4,
|
|
|
|
SimpleMover = 5,
|
|
|
|
Rotator = 6
|
2021-12-05 17:54:36 +00:00
|
|
|
};
|
|
|
|
|
2023-07-31 09:13:19 +00:00
|
|
|
class PlatformSubComponent {
|
2021-12-05 17:54:36 +00:00
|
|
|
public:
|
2023-07-31 09:13:19 +00:00
|
|
|
PlatformSubComponent();
|
|
|
|
virtual ~PlatformSubComponent() = default;
|
|
|
|
virtual void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate);
|
|
|
|
virtual eMoverSubComponentType GetPlatformType() { return eMoverSubComponentType::None; };
|
|
|
|
bool GetIsDirty() const { return m_IsDirty; }
|
|
|
|
protected:
|
|
|
|
|
|
|
|
#ifdef _MOVING_PLATFORM_TEST
|
|
|
|
public:
|
|
|
|
#endif
|
2021-12-05 17:54:36 +00:00
|
|
|
/**
|
|
|
|
* The state the platform is currently in
|
|
|
|
*/
|
2023-07-31 09:13:19 +00:00
|
|
|
eMovementPlatformState m_State = eMovementPlatformState::Stopped | eMovementPlatformState::ReachedDesiredWaypoint;
|
|
|
|
int32_t m_DesiredWaypointIndex = 0;
|
|
|
|
float m_PercentBetweenPoints = 0;
|
|
|
|
NiPoint3 m_Position;
|
|
|
|
uint32_t m_CurrentWaypointIndex;
|
|
|
|
uint32_t m_NextWaypointIndex;
|
|
|
|
float m_IdleTimeElapsed = 0;
|
|
|
|
float m_Speed = 0;
|
|
|
|
float m_WaitTime = 0;
|
|
|
|
float m_MoveTimeElapsed = 0;
|
|
|
|
bool m_IsDirty = false;
|
|
|
|
bool m_InReverse = false;
|
|
|
|
bool m_ShouldStopAtDesiredWaypoint = false;
|
|
|
|
};
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2023-07-31 09:13:19 +00:00
|
|
|
class MoverPlatformSubComponent : public PlatformSubComponent {
|
|
|
|
public:
|
|
|
|
MoverPlatformSubComponent() : PlatformSubComponent() {};
|
|
|
|
~MoverPlatformSubComponent() override = default;
|
|
|
|
eMoverSubComponentType GetPlatformType() override { return eMoverSubComponentType::Mover; }
|
|
|
|
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override { PlatformSubComponent::Serialize(outBitStream, bIsInitialUpdate); };
|
|
|
|
};
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2023-07-31 09:13:19 +00:00
|
|
|
class RotatorPlatformSubComponent : public PlatformSubComponent {
|
|
|
|
public:
|
|
|
|
RotatorPlatformSubComponent() : PlatformSubComponent() {};
|
|
|
|
~RotatorPlatformSubComponent() override = default;
|
|
|
|
eMoverSubComponentType GetPlatformType() override { return eMoverSubComponentType::Rotator; }
|
|
|
|
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override { PlatformSubComponent::Serialize(outBitStream, bIsInitialUpdate); };
|
2021-12-05 17:54:36 +00:00
|
|
|
};
|
|
|
|
|
2023-07-31 09:13:19 +00:00
|
|
|
// Only moves. Has NO path.
|
|
|
|
class SimpleMoverPlatformSubComponent : public PlatformSubComponent {
|
|
|
|
public:
|
|
|
|
SimpleMoverPlatformSubComponent() : PlatformSubComponent() {};
|
|
|
|
~SimpleMoverPlatformSubComponent() override = default;
|
|
|
|
eMoverSubComponentType GetPlatformType() override { return eMoverSubComponentType::SimpleMover; }
|
|
|
|
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override { PlatformSubComponent::Serialize(outBitStream, bIsInitialUpdate); };
|
|
|
|
};
|
2021-12-05 17:54:36 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Represents entities that may be moving platforms, indicating how they should move through the world.
|
|
|
|
* NOTE: the logic in this component hardly does anything, apparently the client can figure most of this stuff out
|
|
|
|
* if you just serialize it correctly, resulting in smoother results anyway. Don't be surprised if the exposed APIs
|
|
|
|
* don't at all do what you expect them to as we don't instruct the client of changes made here.
|
|
|
|
* ^^^ Trivia: This made the red blocks platform and property platforms a pain to implement.
|
|
|
|
*/
|
|
|
|
class MovingPlatformComponent : public Component {
|
|
|
|
public:
|
2023-03-04 07:16:37 +00:00
|
|
|
static const eReplicaComponentType ComponentType = eReplicaComponentType::MOVING_PLATFORM;
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
MovingPlatformComponent(Entity* parent, const std::string& pathName);
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags);
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
/**
|
|
|
|
* Stops all pathing, called when an entity starts a quick build associated with this platform
|
|
|
|
*/
|
|
|
|
void OnRebuildInitilized();
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
/**
|
|
|
|
* Starts the pathing, called when an entity completed a quick build associated with this platform
|
|
|
|
*/
|
|
|
|
void OnCompleteRebuild();
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
/**
|
|
|
|
* Updates the movement state for the moving platform
|
|
|
|
* @param value the movement state to set
|
|
|
|
*/
|
2023-01-07 05:17:05 +00:00
|
|
|
void SetMovementState(eMovementPlatformState value);
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
/**
|
|
|
|
* Instructs the moving platform to go to some waypoint
|
|
|
|
* @param index the index of the waypoint
|
|
|
|
* @param stopAtWaypoint determines if the platform should stop at the waypoint
|
|
|
|
*/
|
|
|
|
void GotoWaypoint(uint32_t index, bool stopAtWaypoint = true);
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
/**
|
|
|
|
* Starts the pathing of this platform, setting appropriate waypoints and speeds
|
|
|
|
*/
|
|
|
|
void StartPathing();
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
/**
|
|
|
|
* Continues the path of the platform, after it's been stopped
|
|
|
|
*/
|
|
|
|
void ContinuePathing();
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
/**
|
|
|
|
* Stops the platform from moving, waiting for it to be activated again.
|
|
|
|
*/
|
|
|
|
void StopPathing();
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
/**
|
|
|
|
* Determines if the entity should be serialized on the next update
|
|
|
|
* @param value whether to serialize the entity or not
|
|
|
|
*/
|
|
|
|
void SetSerialized(bool value);
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
/**
|
|
|
|
* Returns if this platform will start automatically after spawn
|
|
|
|
* @return if this platform will start automatically after spawn
|
|
|
|
*/
|
|
|
|
bool GetNoAutoStart() const;
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
/**
|
|
|
|
* Sets the auto start value for this platform
|
|
|
|
* @param value the auto start value to set
|
|
|
|
*/
|
|
|
|
void SetNoAutoStart(bool value);
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
/**
|
|
|
|
* Warps the platform to a waypoint index, skipping its current path
|
|
|
|
* @param index the index to go to
|
|
|
|
*/
|
|
|
|
void WarpToWaypoint(size_t index);
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
/**
|
|
|
|
* Returns the waypoint this platform was previously at
|
|
|
|
* @return the waypoint this platform was previously at
|
|
|
|
*/
|
|
|
|
size_t GetLastWaypointIndex() const;
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2023-07-31 09:13:19 +00:00
|
|
|
#ifdef _MOVING_PLATFORM_TEST
|
2021-12-05 17:54:36 +00:00
|
|
|
/**
|
2023-07-31 09:13:19 +00:00
|
|
|
* Only used for testing. Do not call in production code. Let the constructor take care of this.
|
|
|
|
*
|
|
|
|
* @param platformSubComponent
|
2021-12-05 17:54:36 +00:00
|
|
|
*/
|
2023-07-31 09:13:19 +00:00
|
|
|
void _AddPlatformSubComponent(std::unique_ptr<PlatformSubComponent> platformSubComponent) {
|
|
|
|
m_Platforms.push_back(std::move(platformSubComponent));
|
|
|
|
}
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2023-07-31 09:13:19 +00:00
|
|
|
void _SetPath(const std::u16string& path) {
|
|
|
|
m_PathName = path;
|
|
|
|
m_DirtyPathInfo = true;
|
|
|
|
}
|
|
|
|
#endif
|
2021-12-05 17:54:36 +00:00
|
|
|
private:
|
|
|
|
/**
|
|
|
|
* The name of the path this platform is currently on
|
|
|
|
*/
|
|
|
|
std::u16string m_PathName;
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
/**
|
|
|
|
* Whether the platform has stopped pathing
|
|
|
|
*/
|
|
|
|
bool m_PathingStopped = false;
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
/**
|
|
|
|
* The mover sub component that belongs to this platform
|
|
|
|
*/
|
2023-07-31 09:13:19 +00:00
|
|
|
std::vector<std::unique_ptr<PlatformSubComponent>> m_Platforms;
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
/**
|
|
|
|
* Whether the platform shouldn't auto start
|
|
|
|
*/
|
|
|
|
bool m_NoAutoStart;
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
/**
|
|
|
|
* Whether to serialize the entity on the next update
|
|
|
|
*/
|
|
|
|
bool m_Serialize = false;
|
2023-07-31 09:13:19 +00:00
|
|
|
|
|
|
|
bool m_DirtyPathInfo = false;
|
2021-12-05 17:54:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // MOVINGPLATFORMCOMPONENT_H
|