mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-11-09 01:38:20 +00:00
28ce8ac54d
resolves a memory leak in BrickDatabase, adds stability to character save doc. Tested that saving manually via force-save, logout and /crash all saved my position and my removed banana as expected. The doc was always deleted on character destruction and on any updates, so this is just a semantic change (and now we no longer have new'd tinyxml2::documents on the heap)
627 lines
19 KiB
C++
627 lines
19 KiB
C++
#ifndef DESTROYABLECOMPONENT_H
|
|
#define DESTROYABLECOMPONENT_H
|
|
|
|
#include "RakNetTypes.h"
|
|
#include <vector>
|
|
#include "tinyxml2.h"
|
|
#include "Entity.h"
|
|
#include "Component.h"
|
|
#include "eReplicaComponentType.h"
|
|
|
|
namespace CppScripts {
|
|
class Script;
|
|
}; //! namespace CppScripts
|
|
enum class eStateChangeType : uint32_t;
|
|
|
|
/**
|
|
* Represents the stats of an entity, for example its health, imagination and armor. Also handles factions, which
|
|
* indicate which enemies this entity has.
|
|
*/
|
|
class DestroyableComponent final : public Component {
|
|
public:
|
|
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::DESTROYABLE;
|
|
|
|
DestroyableComponent(Entity* parentEntity);
|
|
~DestroyableComponent() override;
|
|
|
|
void Update(float deltaTime) override;
|
|
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
|
void LoadFromXml(const tinyxml2::XMLDocument& doc) override;
|
|
void UpdateXml(tinyxml2::XMLDocument& doc) override;
|
|
|
|
/**
|
|
* Initializes the component using a different LOT
|
|
* @param templateID the ID to use for initialization
|
|
*/
|
|
void Reinitialize(LOT templateID);
|
|
|
|
/**
|
|
* Sets the health of this entity. Makes sure this is serialized on the next tick and if this is a character its
|
|
* stats will also update.
|
|
* @param value the new health value
|
|
*/
|
|
void SetHealth(int32_t value);
|
|
|
|
/**
|
|
* Heals the entity by some delta amount
|
|
* @param health the delta amount to heal
|
|
*/
|
|
void Heal(uint32_t health);
|
|
|
|
/**
|
|
* Returns the current health of this entity
|
|
* @return the current health of this entity
|
|
*/
|
|
int32_t GetHealth() const { return m_iHealth; }
|
|
|
|
/**
|
|
* Updates the max health this entity has (e.g. what it can heal to), and optionally displays a UI animation indicating that
|
|
* @param value the max health value to set
|
|
* @param playAnim whether or not to play a UI animation indicating the change in max health
|
|
*/
|
|
void SetMaxHealth(float value, bool playAnim = false);
|
|
|
|
/**
|
|
* Returns the curent max health of this entity
|
|
* @return the current max health of this entity
|
|
*/
|
|
float GetMaxHealth() const { return m_fMaxHealth; }
|
|
|
|
/**
|
|
* Sets the armor for this entity. This also makes sure this change is serialized and if this is a character it also
|
|
* updates their stats.
|
|
* @param value the armor value to set
|
|
*/
|
|
void SetArmor(int32_t value);
|
|
|
|
/**
|
|
* Repairs armor of this entity, updating it by a delta amount
|
|
* @param armor the amount of armor to repair
|
|
*/
|
|
void Repair(uint32_t armor);
|
|
|
|
/**
|
|
* Returns the current armor value for the entity
|
|
* @return the current armor value for the entity
|
|
*/
|
|
int32_t GetArmor() const { return m_iArmor; }
|
|
|
|
/**
|
|
* Updates the max armor this entity has (e.g. what it can heal to), and optionally displays a UI animation indicating that
|
|
* @param value the max armor value to set
|
|
* @param playAnim whether or not to play a UI animation indicating the change in max armor
|
|
*/
|
|
void SetMaxArmor(float value, bool playAnim = false);
|
|
|
|
/**
|
|
* Returns the current maximum armor this entity can have
|
|
* @return the current maximum armor this entity can have
|
|
*/
|
|
float GetMaxArmor() const { return m_fMaxArmor; }
|
|
|
|
/**
|
|
* Sets the imagination value for this entity. Ensures that the change is serialized and if this is a character
|
|
* their stats will be updated. Can also trigger the assembly passive ability to restore on 0 imag.
|
|
* @param value
|
|
*/
|
|
void SetImagination(int32_t value);
|
|
|
|
/**
|
|
* Updates the imagination of this entity by a delta amount
|
|
* @param deltaImagination the imagination to update
|
|
*/
|
|
void Imagine(int32_t deltaImagination);
|
|
|
|
/**
|
|
* Returns the current imagination value of this entity
|
|
* @return the current imagination value of this entity
|
|
*/
|
|
int32_t GetImagination() const { return m_iImagination; }
|
|
|
|
/**
|
|
* Updates the max imagination this entity has (e.g. what it can heal to), and optionally displays a UI animation indicating that
|
|
* @param value the max imagination value to set
|
|
* @param playAnim whether or not to play a UI animation indicating the change in max imagination
|
|
*/
|
|
void SetMaxImagination(float value, bool playAnim = false);
|
|
|
|
/**
|
|
* Returns the current max imagination value
|
|
* @return the current max imagination value
|
|
*/
|
|
float GetMaxImagination() const { return m_fMaxImagination; }
|
|
|
|
/**
|
|
* Sets the damage this entity can absorb before getting hurt, also serializes this change.
|
|
* @param value the damage to absorb
|
|
*/
|
|
void SetDamageToAbsorb(int32_t value);
|
|
|
|
/**
|
|
* Returns the current damage to absorb
|
|
* @return the current damage to absorb
|
|
*/
|
|
int32_t GetDamageToAbsorb() const { return m_DamageToAbsorb; }
|
|
|
|
/**
|
|
* Sets the reduced damage value for each attack for this entity, also serializes that change.
|
|
* @param value the damage to reduce for each attack
|
|
*/
|
|
void SetDamageReduction(int32_t value);
|
|
|
|
/**
|
|
* Returns the current damage reduction value
|
|
* @return the current damage reduction value
|
|
*/
|
|
int32_t GetDamageReduction() const { return m_DamageReduction; }
|
|
|
|
/**
|
|
* Sets whether or not this entity is immune to attacks
|
|
* @param value whether or not this entity is immune to attacks
|
|
*/
|
|
void SetIsImmune(bool value);
|
|
|
|
/**
|
|
* Returns whether or not this entity is immune to attacks
|
|
* @return whether or not this entity is immune to attacks
|
|
*/
|
|
bool IsImmune() const;
|
|
|
|
/**
|
|
* @return whether this entity is currently immune to attacks due to a damage cooldown period
|
|
*/
|
|
bool IsCooldownImmune() const;
|
|
|
|
/**
|
|
* Sets if this entity has GM immunity, making it not killable
|
|
* @param value the GM immunity of this entity
|
|
*/
|
|
void SetIsGMImmune(bool value);
|
|
|
|
/**
|
|
* Returns whether or not this entity has GM immunity
|
|
* @return whether or not this entity has GM immunity
|
|
*/
|
|
bool GetIsGMImmune() const { return m_IsGMImmune; }
|
|
|
|
/**
|
|
* Sets whether or not this entity is shielded for a certain amount of damage
|
|
* @param value whether or not this entity is shielded for a certain amount of damage
|
|
*/
|
|
void SetIsShielded(bool value);
|
|
|
|
/**
|
|
* Returns if this entity is currently shielded from damage
|
|
* @return if this entity is currently shielded from damage
|
|
*/
|
|
bool GetIsShielded() const { return m_IsShielded; }
|
|
|
|
/**
|
|
* Adds a faction to the faction list of this entity, potentially making more factions friendly. Fetches the info
|
|
* from the CDClient.
|
|
* @param factionID the faction ID to add
|
|
* @param ignoreChecks whether or not to allow factionID -1
|
|
*/
|
|
void AddFaction(int32_t factionID, bool ignoreChecks = false);
|
|
|
|
/**
|
|
* Adds a faction ID to the enemy list
|
|
* @param factionID the faction ID to make an enemy
|
|
*/
|
|
void AddEnemyFaction(int32_t factionID);
|
|
|
|
/**
|
|
* Sets whether or not this entity can be smashed, does not indicate the smashable glow, which is indicated by
|
|
* faction ids
|
|
* @param value whether or not this entity is smashable
|
|
*/
|
|
void SetIsSmashable(bool value);
|
|
|
|
/**
|
|
* Returns whether or not this entity is smashable
|
|
* @return whether or not this entity is smashable
|
|
*/
|
|
bool GetIsSmashable() const { return m_IsSmashable; }
|
|
|
|
/**
|
|
* Returns the current is-dead value, this is mostly unused
|
|
* @return the current is-dead value, this is mostly unused
|
|
*/
|
|
bool GetIsDead() const { return m_IsDead; }
|
|
|
|
/**
|
|
* Returns the current is-smashed value, this is mostly unused
|
|
* @return the current is-smashed value, this is mostly unused
|
|
*/
|
|
bool GetIsSmashed() const { return m_IsSmashed; }
|
|
|
|
/**
|
|
* Sets whether or not this entity has bricks flying out when smashed
|
|
* @param value whether or not this entity has bricks flying out when smashed
|
|
*/
|
|
void SetHasBricks(bool value);
|
|
|
|
/**
|
|
* Returns whether or not this entity has bricks flying out when smashed
|
|
* @return whether or not this entity has bricks flying out when smashed
|
|
*/
|
|
bool GetHasBricks() const { return m_IsModuleAssembly; }
|
|
|
|
/**
|
|
* Sets the multiplier for the explosion that's visible when the bricks fly out when this entity is smashed
|
|
* @param value the multiplier for the explosion that's visible when the bricks fly out when this entity is smashed
|
|
*/
|
|
void SetExplodeFactor(float value) { m_ExplodeFactor = value; };
|
|
|
|
/**
|
|
* Returns the current multiplier for explosions
|
|
* @return the current multiplier for explosions
|
|
*/
|
|
float GetExplodeFactor() const { return m_ExplodeFactor; }
|
|
|
|
/**
|
|
* Sets the amount of attacks this entity can block before being able to be damaged again, useful for example for
|
|
* shields.
|
|
* @param value the amount of attacks this entity can block before being able to be damaged again
|
|
*/
|
|
void SetAttacksToBlock(uint32_t value);
|
|
|
|
/**
|
|
* Returns the current amount of attacks this entity can block
|
|
* @return the current amount of attacks this entity can block
|
|
*/
|
|
uint32_t GetAttacksToBlock() const { return m_AttacksToBlock; }
|
|
|
|
/**
|
|
* Sets whether or not this enemy currently has threats, NOTE: only here for serialization, has no use internally
|
|
* @param value whether or not this enemy currently has threats
|
|
*/
|
|
void SetHasThreats(bool value);
|
|
|
|
/**
|
|
* Returns whether or not this entity currently has threats, NOTE: unused internally
|
|
* @return whether or not this entity currently has threats
|
|
*/
|
|
bool GetHasThreats() const { return m_HasThreats; }
|
|
|
|
/**
|
|
* Returns whether or not this entity is knockback immune, based on whether it's quickbuilding or has assembly gear
|
|
* @return whether or not this entity is knockback immune
|
|
*/
|
|
bool IsKnockbackImmune() const;
|
|
|
|
/**
|
|
* Sets the faction ID of this entity, overriding all previously set entries
|
|
* @param factionID the faction ID to set
|
|
*/
|
|
void SetFaction(int32_t factionID, bool ignoreChecks = false);
|
|
|
|
/**
|
|
* Returns whether or not the provided entity is an enemy of this entity
|
|
* @param other the entity to check
|
|
* @return whether the provided entity is an enemy of this entity or not
|
|
*/
|
|
bool IsEnemy(const Entity* other) const;
|
|
|
|
/**
|
|
* Returns whether or not the provided entity is a friend of this entity
|
|
* @param other the entity to check
|
|
* @return whether or not the provided entity is a friend of this entity
|
|
*/
|
|
bool IsFriend(const Entity* other) const;
|
|
|
|
/**
|
|
* Returns all the faction IDs that this entity considers a friend
|
|
* @return all the faction IDs that this entity considers a friend
|
|
*/
|
|
const std::vector<int32_t>& GetFactionIDs() const { return m_FactionIDs; }
|
|
|
|
/**
|
|
* Returns all the faction IDs that this entity considers an enemy
|
|
* @return all the faction IDs that this entity considers an enemy
|
|
*/
|
|
const std::vector<int32_t>& GetEnemyFactionsIDs() const { return m_EnemyFactionIDs; }
|
|
|
|
/**
|
|
* Returns whether the provided faction is a friendly faction
|
|
* @param factionID the faction ID to check
|
|
* @return whether the provided faction is a friendly faction
|
|
*/
|
|
bool HasFaction(int32_t factionID) const;
|
|
|
|
/**
|
|
* Sets the minimum amount of coins this entity drops when smashed
|
|
* @param minCoins the minimum amount of coins this entity drops when smashed
|
|
*/
|
|
void SetMinCoins(uint32_t minCoins) { m_MinCoins = minCoins; }
|
|
|
|
/**
|
|
* Returns the minimum amount of coins this entity drops when smashed
|
|
* @return the minimum amount of coins this entity drops when smashed
|
|
*/
|
|
uint32_t GetMinCoins() const { return m_MinCoins; }
|
|
|
|
/**
|
|
* Sets the maximum amount of coins this entity drops when smashed
|
|
* @param maxCoins the maximum amount of coins this entity drops when smashed
|
|
*/
|
|
void SetMaxCoins(uint32_t maxCoins) { m_MaxCoins = maxCoins; }
|
|
|
|
/**
|
|
* Returns the maximum amount of coins this entity drops when smashed
|
|
* @return the maximum amount of coins this entity drops when smashed
|
|
*/
|
|
uint32_t GetMaxCoins() const { return m_MaxCoins; }
|
|
|
|
/**
|
|
* Sets the loot matrix ID that will be used to determine what items to drop when this entity is smashed
|
|
* @param lootMatrixID the loot matrix ID to set
|
|
*/
|
|
void SetLootMatrixID(uint32_t lootMatrixID) { m_LootMatrixID = lootMatrixID; }
|
|
|
|
/**
|
|
* Returns the current loot matrix ID that will be used to determine loot drops when this entity is smashed
|
|
* @return the current loot matrix ID
|
|
*/
|
|
uint32_t GetLootMatrixID() const { return m_LootMatrixID; }
|
|
|
|
/**
|
|
* Returns the ID of the entity that killed this entity, if any
|
|
* @return the ID of the entity that killed this entity, if any
|
|
*/
|
|
LWOOBJID GetKillerID() const;
|
|
|
|
/**
|
|
* Returns the entity that killed this entity, if any
|
|
* @return the entity that killed this entity, if any
|
|
*/
|
|
Entity* GetKiller() const;
|
|
|
|
/**
|
|
* Attempt to damage this entity, handles everything from health and armor to absorption, immunity and callbacks.
|
|
* @param damage the damage to attempt to apply
|
|
* @param source the attacker that caused this damage
|
|
* @param skillID the skill that damaged this entity
|
|
* @param echo whether or not to serialize the damage
|
|
*/
|
|
void Damage(uint32_t damage, LWOOBJID source, uint32_t skillID = 0, bool echo = true);
|
|
|
|
/**
|
|
* Smashes this entity, notifying all clients
|
|
* @param source the source that smashed this entity
|
|
* @param skillID the skill that killed this entity
|
|
* @param killType the way this entity was killed, determines if a client animation is played
|
|
* @param deathType the animation to play when killed
|
|
*/
|
|
void Smash(LWOOBJID source, eKillType killType = eKillType::VIOLENT, const std::u16string& deathType = u"", uint32_t skillID = 0);
|
|
|
|
/**
|
|
* Push or Pop a layer of status immunity to this entity
|
|
*/
|
|
void SetStatusImmunity(
|
|
const eStateChangeType state,
|
|
const bool bImmuneToBasicAttack = false,
|
|
const bool bImmuneToDamageOverTime = false,
|
|
const bool bImmuneToKnockback = false,
|
|
const bool bImmuneToInterrupt = false,
|
|
const bool bImmuneToSpeed = false,
|
|
const bool bImmuneToImaginationGain = false,
|
|
const bool bImmuneToImaginationLoss = false,
|
|
const bool bImmuneToQuickbuildInterrupt = false,
|
|
const bool bImmuneToPullToPoint = false
|
|
);
|
|
|
|
// Getters for status immunities
|
|
const bool GetImmuneToBasicAttack() { return m_ImmuneToBasicAttackCount > 0; };
|
|
const bool GetImmuneToDamageOverTime() { return m_ImmuneToDamageOverTimeCount > 0; };
|
|
const bool GetImmuneToKnockback() { return m_ImmuneToKnockbackCount > 0; };
|
|
const bool GetImmuneToInterrupt() { return m_ImmuneToInterruptCount > 0; };
|
|
const bool GetImmuneToSpeed() { return m_ImmuneToSpeedCount > 0; };
|
|
const bool GetImmuneToImaginationGain() { return m_ImmuneToImaginationGainCount > 0; };
|
|
const bool GetImmuneToImaginationLoss() { return m_ImmuneToImaginationLossCount > 0; };
|
|
const bool GetImmuneToQuickbuildInterrupt() { return m_ImmuneToQuickbuildInterruptCount > 0; };
|
|
const bool GetImmuneToPullToPoint() { return m_ImmuneToPullToPointCount > 0; };
|
|
|
|
// Damage cooldown setters/getters
|
|
void SetDamageCooldownTimer(float value) { m_DamageCooldownTimer = value; }
|
|
float GetDamageCooldownTimer() { return m_DamageCooldownTimer; }
|
|
|
|
// Death behavior setters/getters
|
|
void SetDeathBehavior(int32_t value) { m_DeathBehavior = value; }
|
|
int32_t GetDeathBehavior() const { return m_DeathBehavior; }
|
|
|
|
/**
|
|
* Utility to reset all stats to the default stats based on items and completed missions
|
|
*/
|
|
void FixStats();
|
|
|
|
/**
|
|
* Adds a callback that is called when this entity is hit by some other entity
|
|
* @param callback the callback to add
|
|
*/
|
|
void AddOnHitCallback(const std::function<void(Entity*)>& callback);
|
|
|
|
/**
|
|
* Pushes a faction back to the list of factions.
|
|
* @param value Faction to add to list.
|
|
*
|
|
* This method should only be used for testing. Use AddFaction(int32_t, bool) for adding a faction properly.
|
|
*/
|
|
void AddFactionNoLookup(int32_t faction) { m_FactionIDs.push_back(faction); };
|
|
|
|
/**
|
|
* Notify subscribed scripts of Damage actions.
|
|
*
|
|
* @param attacker The attacking Entity
|
|
* @param damage The amount of damage that was done
|
|
*/
|
|
void NotifySubscribers(Entity* attacker, uint32_t damage);
|
|
|
|
void Subscribe(LWOOBJID scriptObjId, CppScripts::Script* scriptToAdd);
|
|
void Unsubscribe(LWOOBJID scriptObjId);
|
|
|
|
// handle hardcode mode drops
|
|
void DoHardcoreModeDrops(const LWOOBJID source);
|
|
|
|
private:
|
|
/**
|
|
* Whether or not the health should be serialized
|
|
*/
|
|
bool m_DirtyHealth;
|
|
|
|
/**
|
|
* The health of the entity
|
|
*/
|
|
int32_t m_iHealth;
|
|
|
|
/**
|
|
* The max health of the entity
|
|
*/
|
|
float m_fMaxHealth;
|
|
|
|
/**
|
|
* The armor of the entity
|
|
*/
|
|
int32_t m_iArmor;
|
|
|
|
/**
|
|
* The max armor of the entity
|
|
*/
|
|
float m_fMaxArmor;
|
|
|
|
/**
|
|
* The imagination of the entity
|
|
*/
|
|
int32_t m_iImagination;
|
|
|
|
/**
|
|
* The max imagination of the entity
|
|
*/
|
|
float m_fMaxImagination;
|
|
|
|
/**
|
|
* The damage this entity can absord before being able to be damaged again
|
|
*/
|
|
int32_t m_DamageToAbsorb;
|
|
|
|
/**
|
|
* Whether this entity currently has GM immunity, making it unsmashable
|
|
*/
|
|
bool m_IsGMImmune;
|
|
|
|
/**
|
|
* Whether this entity is currently shielded from other attacks
|
|
*/
|
|
bool m_IsShielded;
|
|
|
|
/**
|
|
* The number of attacks this entity can block before being able to be attacked again
|
|
*/
|
|
uint32_t m_AttacksToBlock;
|
|
|
|
/**
|
|
* The amount of damage that should be reduced from every attack
|
|
*/
|
|
int32_t m_DamageReduction;
|
|
|
|
/**
|
|
* The faction IDs this entity considers friendly
|
|
*/
|
|
std::vector<int32_t> m_FactionIDs;
|
|
|
|
/**
|
|
* The faction IDs this entity considers hostile
|
|
*/
|
|
std::vector<int32_t> m_EnemyFactionIDs;
|
|
|
|
/**
|
|
* Whether this entity is smasahble, mostly unused
|
|
*/
|
|
bool m_IsSmashable;
|
|
|
|
/**
|
|
* Whether this entity is dead. Unused, here for serialization
|
|
*/
|
|
bool m_IsDead;
|
|
|
|
/**
|
|
* Whether this entity is smashed. Unused, here for serialization
|
|
*/
|
|
bool m_IsSmashed;
|
|
|
|
/**
|
|
* Whether this entity has bricks flying out when smashed (causes the client to look up the files)
|
|
*/
|
|
bool m_IsModuleAssembly;
|
|
|
|
/**
|
|
* The rate at which bricks fly out when smashed
|
|
*/
|
|
float m_ExplodeFactor;
|
|
|
|
/**
|
|
* Whether the list of potential enemies has changed
|
|
*/
|
|
bool m_DirtyThreatList;
|
|
|
|
/**
|
|
* Whether the entity has threats. Unused: here for serialization
|
|
*/
|
|
bool m_HasThreats;
|
|
|
|
/**
|
|
* The loot matrix that will be used to drop items when the entity is smashed
|
|
*/
|
|
uint32_t m_LootMatrixID;
|
|
|
|
/**
|
|
* The min amount of coins that will drop when this entity is smashed
|
|
*/
|
|
uint32_t m_MinCoins;
|
|
|
|
/**
|
|
* The max amount of coins that will drop when this entity is smashed
|
|
*/
|
|
uint32_t m_MaxCoins;
|
|
|
|
/**
|
|
* The ID of the entity that smashed this entity, if any
|
|
*/
|
|
LWOOBJID m_KillerID;
|
|
|
|
/**
|
|
* The list of callbacks that will be called when this entity gets hit
|
|
*/
|
|
std::vector<std::function<void(Entity*)>> m_OnHitCallbacks;
|
|
|
|
/**
|
|
* The list of scripts subscribed to this components actions
|
|
*/
|
|
std::map<LWOOBJID, CppScripts::Script*> m_SubscribedScripts;
|
|
|
|
/**
|
|
* status immunity counters
|
|
*/
|
|
uint32_t m_ImmuneToBasicAttackCount;
|
|
uint32_t m_ImmuneToDamageOverTimeCount;
|
|
uint32_t m_ImmuneToKnockbackCount;
|
|
uint32_t m_ImmuneToInterruptCount;
|
|
uint32_t m_ImmuneToSpeedCount;
|
|
uint32_t m_ImmuneToImaginationGainCount;
|
|
uint32_t m_ImmuneToImaginationLossCount;
|
|
uint32_t m_ImmuneToQuickbuildInterruptCount;
|
|
uint32_t m_ImmuneToPullToPointCount;
|
|
|
|
/**
|
|
* Death behavior type. If 0, the client plays a death animation as opposed to a smash animation.
|
|
*/
|
|
int32_t m_DeathBehavior;
|
|
|
|
/**
|
|
* Damage immunity cooldown timer. Set to a value that then counts down to create a damage cooldown for players
|
|
*/
|
|
float m_DamageCooldownTimer;
|
|
};
|
|
|
|
#endif // DESTROYABLECOMPONENT_H
|