2021-12-05 17:54:36 +00:00
|
|
|
#ifndef RENDERCOMPONENT_H
|
|
|
|
#define RENDERCOMPONENT_H
|
|
|
|
|
2024-01-05 12:33:52 +00:00
|
|
|
#include "BitStream.h"
|
2021-12-05 17:54:36 +00:00
|
|
|
#include <vector>
|
|
|
|
#include <string>
|
|
|
|
#include <unordered_map>
|
|
|
|
|
2023-05-13 22:22:00 +00:00
|
|
|
#include "Amf3.h"
|
2021-12-05 17:54:36 +00:00
|
|
|
#include "Component.h"
|
2023-03-04 07:16:37 +00:00
|
|
|
#include "eReplicaComponentType.h"
|
2021-12-05 17:54:36 +00:00
|
|
|
|
|
|
|
class Entity;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* An effect that plays for an entity. This might seem a bit abstract so digging through the CDClient is recommended
|
|
|
|
* here.
|
|
|
|
*/
|
|
|
|
struct Effect {
|
2024-01-31 14:38:38 +00:00
|
|
|
explicit Effect(const int32_t effectID, const std::string& name, const std::u16string& type, const float priority = 1.0f) noexcept
|
|
|
|
: effectID{ effectID }
|
|
|
|
, name{ name }
|
|
|
|
, type{ type }
|
|
|
|
, priority{ priority } {
|
|
|
|
}
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* The ID of the effect
|
|
|
|
*/
|
|
|
|
int32_t effectID = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The name of the effect
|
|
|
|
*/
|
|
|
|
std::string name = "";
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The type of the effect
|
|
|
|
*/
|
|
|
|
std::u16string type = u"";
|
|
|
|
|
|
|
|
/**
|
2023-10-09 20:20:56 +00:00
|
|
|
* The importantness of the effect
|
2022-07-28 13:39:57 +00:00
|
|
|
*/
|
2023-10-09 20:20:56 +00:00
|
|
|
float priority = 1.0f;
|
2022-07-28 13:39:57 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Some related entity that casted the effect
|
|
|
|
*/
|
|
|
|
uint64_t secondary = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The time that this effect plays for
|
|
|
|
*/
|
|
|
|
float time = 0;
|
2021-12-05 17:54:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Determines that a component should be visibly rendered into the world, most entities have this. This component
|
|
|
|
* also handles effects that play for entities.
|
|
|
|
*/
|
2024-01-24 05:13:23 +00:00
|
|
|
class RenderComponent final : public Component {
|
2021-12-05 17:54:36 +00:00
|
|
|
public:
|
2024-01-24 05:13:23 +00:00
|
|
|
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::RENDER;
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2024-01-31 14:38:38 +00:00
|
|
|
RenderComponent(Entity* const parentEntity, const int32_t componentId = -1);
|
2022-07-28 13:39:57 +00:00
|
|
|
|
2024-02-27 07:25:44 +00:00
|
|
|
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
2022-07-28 13:39:57 +00:00
|
|
|
void Update(float deltaTime) override;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds an effect to this entity, if successful the effect is returned
|
|
|
|
* @param effectId the ID of the effect
|
|
|
|
* @param name the name of the effect
|
|
|
|
* @param type the type of the effect
|
2023-10-09 20:20:56 +00:00
|
|
|
* @param priority the priority of the effect
|
2022-07-28 13:39:57 +00:00
|
|
|
* @return if successful, the effect that was created
|
|
|
|
*/
|
2024-01-31 14:38:38 +00:00
|
|
|
[[maybe_unused]] Effect& AddEffect(const int32_t effectId, const std::string& name, const std::u16string& type, const float priority);
|
2022-07-28 13:39:57 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Removes an effect for this entity
|
|
|
|
* @param name the name of the effect to remove
|
|
|
|
*/
|
|
|
|
void RemoveEffect(const std::string& name);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Plays an effect, removes any effects under this name and plays the one according to these params
|
|
|
|
* @param effectId the ID of the effect
|
|
|
|
* @param effectType the type of the effect
|
|
|
|
* @param name the name of the effect
|
|
|
|
* @param secondary some entity that cast the effect
|
|
|
|
* @param priority effect priority (determines if the client will play it over other effects)
|
|
|
|
* @param scale effect scale
|
|
|
|
* @param serialize whether to serialize the change or not
|
|
|
|
*/
|
|
|
|
void PlayEffect(int32_t effectId, const std::u16string& effectType, const std::string& name, LWOOBJID secondary = LWOOBJID_EMPTY, float priority = 1, float scale = 1, bool serialize = true);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Removes and stops the effect for a certain name
|
|
|
|
* @param name name of the effect to stop
|
|
|
|
* @param killImmediate whether ot not to immediately stop playing the effect or phase it out
|
|
|
|
*/
|
|
|
|
void StopEffect(const std::string& name, bool killImmediate = true);
|
|
|
|
|
2023-03-26 10:09:04 +00:00
|
|
|
/**
|
|
|
|
* Verifies that an animation can be played on this entity by checking
|
|
|
|
* if it has the animation assigned to its group. If it does, the animation is echo'd
|
|
|
|
* down to all clients to be played and the duration of the played animation is returned.
|
|
|
|
* If the animation did not exist or the function was called in an invalid state, 0 is returned.
|
2023-10-09 20:20:56 +00:00
|
|
|
*
|
2023-03-26 10:09:04 +00:00
|
|
|
* The logic here matches the exact client logic.
|
2023-10-09 20:20:56 +00:00
|
|
|
*
|
2023-03-26 10:09:04 +00:00
|
|
|
* @param self The entity that wants to play an animation
|
|
|
|
* @param animation The animation_type (animationID in the client) to be played.
|
|
|
|
* @param sendAnimation Whether or not to echo the animation down to all clients.
|
|
|
|
* @param priority The priority of the animation. Only used if sendAnimation is true.
|
|
|
|
* @param scale The scale of the animation. Only used if sendAnimation is true.
|
2023-10-09 20:20:56 +00:00
|
|
|
*
|
2023-03-26 10:09:04 +00:00
|
|
|
* @return The duration of the animation that was played.
|
|
|
|
*/
|
2023-03-20 13:10:52 +00:00
|
|
|
static float DoAnimation(Entity* self, const std::string& animation, bool sendAnimation, float priority = 0.0f, float scale = 1.0f);
|
|
|
|
|
|
|
|
static float PlayAnimation(Entity* self, const std::u16string& animation, float priority = 0.0f, float scale = 1.0f);
|
|
|
|
static float PlayAnimation(Entity* self, const std::string& animation, float priority = 0.0f, float scale = 1.0f);
|
2024-01-31 14:38:38 +00:00
|
|
|
[[nodiscard]] static float GetAnimationTime(Entity* self, const std::string& animation);
|
|
|
|
[[nodiscard]] static float GetAnimationTime(Entity* self, const std::u16string& animation);
|
2023-03-20 13:10:52 +00:00
|
|
|
|
2024-01-31 14:38:38 +00:00
|
|
|
[[nodiscard]] const std::string& GetLastAnimationName() const { return m_LastAnimationName; };
|
2023-03-20 13:10:52 +00:00
|
|
|
void SetLastAnimationName(const std::string& name) { m_LastAnimationName = name; };
|
|
|
|
|
2021-12-05 17:54:36 +00:00
|
|
|
private:
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* List of currently active effects
|
|
|
|
*/
|
2024-01-31 14:38:38 +00:00
|
|
|
std::vector<Effect> m_Effects;
|
2021-12-05 17:54:36 +00:00
|
|
|
|
2023-03-20 13:10:52 +00:00
|
|
|
std::vector<int32_t> m_animationGroupIds;
|
|
|
|
|
|
|
|
// The last animationName that was played
|
|
|
|
std::string m_LastAnimationName;
|
|
|
|
|
2022-07-28 13:39:57 +00:00
|
|
|
/**
|
|
|
|
* Cache of queries that look for the length of each effect, indexed by effect ID
|
|
|
|
*/
|
|
|
|
static std::unordered_map<int32_t, float> m_DurationCache;
|
2023-10-29 16:37:26 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Cache for animation groups, indexed by the component ID
|
|
|
|
*/
|
|
|
|
static std::unordered_map<int32_t, std::vector<int32_t>> m_AnimationGroupCache;
|
2021-12-05 17:54:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // RENDERCOMPONENT_H
|