Merge remote-tracking branch 'upstream/main' into PetFixes

This commit is contained in:
jadebenn
2024-02-13 20:59:27 -06:00
309 changed files with 4031 additions and 4493 deletions

View File

@@ -10,7 +10,6 @@
#include "WorldPackets.h"
#include "EntityManager.h"
#include "ChatPackets.h"
#include "Player.h"
#include "BitStreamUtils.h"
#include "dServer.h"
#include "GeneralUtils.h"
@@ -30,40 +29,36 @@
#include "LeaderboardManager.h"
ActivityComponent::ActivityComponent(Entity* parent, int32_t activityID) : Component(parent) {
if (activityID > 0) m_ActivityID = activityID;
else m_ActivityID = parent->GetVar<int32_t>(u"activityID");
CDActivitiesTable* activitiesTable = CDClientManager::Instance().GetTable<CDActivitiesTable>();
std::vector<CDActivities> activities = activitiesTable->Query([this](CDActivities entry) {return (entry.ActivityID == m_ActivityID); });
/*
* This is precisely what the client does functionally
* Use the component id as the default activity id and load its data from the database
* if activityID is specified and if that column exists in the activities table, update the activity info with that data.
*/
for (CDActivities activity : activities) {
m_ActivityInfo = activity;
if (static_cast<Leaderboard::Type>(activity.leaderboardType) == Leaderboard::Type::Racing && Game::config->GetValue("solo_racing") == "1") {
m_ActivityInfo.minTeamSize = 1;
m_ActivityInfo.minTeams = 1;
}
if (m_ActivityInfo.instanceMapID == -1) {
const auto& transferOverride = parent->GetVarAsString(u"transferZoneID");
if (!transferOverride.empty()) {
GeneralUtils::TryParse(transferOverride, m_ActivityInfo.instanceMapID);
}
}
m_ActivityID = activityID;
LoadActivityData(activityID);
if (m_Parent->HasVar(u"activityID")) {
m_ActivityID = parent->GetVar<int32_t>(u"activityID");
LoadActivityData(m_ActivityID);
}
auto* destroyableComponent = m_Parent->GetComponent<DestroyableComponent>();
if (destroyableComponent) {
// check for LMIs and set the loot LMIs
CDActivityRewardsTable* activityRewardsTable = CDClientManager::Instance().GetTable<CDActivityRewardsTable>();
// First lookup the loot matrix id for this component id.
CDActivityRewardsTable* activityRewardsTable = CDClientManager::GetTable<CDActivityRewardsTable>();
std::vector<CDActivityRewards> activityRewards = activityRewardsTable->Query([=](CDActivityRewards entry) {return (entry.LootMatrixIndex == destroyableComponent->GetLootMatrixID()); });
uint32_t startingLMI = 0;
// If we have one, set the starting loot matrix id to that.
if (activityRewards.size() > 0) {
startingLMI = activityRewards[0].LootMatrixIndex;
}
if (startingLMI > 0) {
// now time for bodge :)
// We may have more than 1 loot matrix index to use depending ont the size of the team that is looting the activity.
// So this logic will get the rest of the loot matrix indices for this activity.
std::vector<CDActivityRewards> objectTemplateActivities = activityRewardsTable->Query([=](CDActivityRewards entry) {return (activityRewards[0].objectTemplate == entry.objectTemplate); });
for (const auto& item : objectTemplateActivities) {
@@ -74,6 +69,26 @@ ActivityComponent::ActivityComponent(Entity* parent, int32_t activityID) : Compo
}
}
}
void ActivityComponent::LoadActivityData(const int32_t activityId) {
CDActivitiesTable* activitiesTable = CDClientManager::GetTable<CDActivitiesTable>();
std::vector<CDActivities> activities = activitiesTable->Query([activityId](CDActivities entry) {return (entry.ActivityID == activityId); });
bool soloRacing = Game::config->GetValue("solo_racing") == "1";
for (CDActivities activity : activities) {
m_ActivityInfo = activity;
if (static_cast<Leaderboard::Type>(activity.leaderboardType) == Leaderboard::Type::Racing && soloRacing) {
m_ActivityInfo.minTeamSize = 1;
m_ActivityInfo.minTeams = 1;
}
if (m_ActivityInfo.instanceMapID == -1) {
const auto& transferOverride = m_Parent->GetVarAsString(u"transferZoneID");
if (!transferOverride.empty()) {
m_ActivityInfo.instanceMapID =
GeneralUtils::TryParse<uint32_t>(transferOverride).value_or(m_ActivityInfo.instanceMapID);
}
}
}
}
void ActivityComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
outBitStream->Write(m_DirtyActivityInfo);
@@ -92,7 +107,7 @@ void ActivityComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIniti
}
void ActivityComponent::ReloadConfig() {
CDActivitiesTable* activitiesTable = CDClientManager::Instance().GetTable<CDActivitiesTable>();
CDActivitiesTable* activitiesTable = CDClientManager::GetTable<CDActivitiesTable>();
std::vector<CDActivities> activities = activitiesTable->Query([this](CDActivities entry) {return (entry.ActivityID == m_ActivityID); });
for (auto activity : activities) {
auto mapID = m_ActivityInfo.instanceMapID;
@@ -531,14 +546,14 @@ void ActivityInstance::RewardParticipant(Entity* participant) {
}
// First, get the activity data
auto* activityRewardsTable = CDClientManager::Instance().GetTable<CDActivityRewardsTable>();
auto* activityRewardsTable = CDClientManager::GetTable<CDActivityRewardsTable>();
std::vector<CDActivityRewards> activityRewards = activityRewardsTable->Query([this](CDActivityRewards entry) { return (entry.objectTemplate == m_ActivityInfo.ActivityID); });
if (!activityRewards.empty()) {
uint32_t minCoins = 0;
uint32_t maxCoins = 0;
auto* currencyTableTable = CDClientManager::Instance().GetTable<CDCurrencyTableTable>();
auto* currencyTableTable = CDClientManager::GetTable<CDCurrencyTableTable>();
std::vector<CDCurrencyTable> currencyTable = currencyTableTable->Query([=](CDCurrencyTable entry) { return (entry.currencyIndex == activityRewards[0].CurrencyIndex && entry.npcminlevel == 1); });
if (!currencyTable.empty()) {

View File

@@ -152,6 +152,8 @@ class ActivityComponent : public Component {
public:
ActivityComponent(Entity* parent, int32_t activityID);
void LoadActivityData(const int32_t activityId);
void Update(float deltaTime) override;
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;

View File

@@ -25,6 +25,7 @@
#include "Metrics.hpp"
#include "CDComponentsRegistryTable.h"
#include "CDPhysicsComponentTable.h"
#include "dNavMesh.h"
BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id): Component(parent) {
m_Target = LWOOBJID_EMPTY;
@@ -106,10 +107,10 @@ BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id):
int32_t collisionGroup = (COLLISION_GROUP_DYNAMIC | COLLISION_GROUP_ENEMY);
CDComponentsRegistryTable* componentRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
CDComponentsRegistryTable* componentRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
auto componentID = componentRegistryTable->GetByIDAndType(parent->GetLOT(), eReplicaComponentType::CONTROLLABLE_PHYSICS);
CDPhysicsComponentTable* physicsComponentTable = CDClientManager::Instance().GetTable<CDPhysicsComponentTable>();
CDPhysicsComponentTable* physicsComponentTable = CDClientManager::GetTable<CDPhysicsComponentTable>();
if (physicsComponentTable != nullptr) {
auto* info = physicsComponentTable->GetByID(componentID);
@@ -128,17 +129,17 @@ BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id):
m_dpEntity->SetPosition(m_Parent->GetPosition());
m_dpEntityEnemy->SetPosition(m_Parent->GetPosition());
dpWorld::Instance().AddEntity(m_dpEntity);
dpWorld::Instance().AddEntity(m_dpEntityEnemy);
dpWorld::AddEntity(m_dpEntity);
dpWorld::AddEntity(m_dpEntityEnemy);
}
BaseCombatAIComponent::~BaseCombatAIComponent() {
if (m_dpEntity)
dpWorld::Instance().RemoveEntity(m_dpEntity);
dpWorld::RemoveEntity(m_dpEntity);
if (m_dpEntityEnemy)
dpWorld::Instance().RemoveEntity(m_dpEntityEnemy);
dpWorld::RemoveEntity(m_dpEntityEnemy);
}
void BaseCombatAIComponent::Update(const float deltaTime) {
@@ -184,7 +185,7 @@ void BaseCombatAIComponent::Update(const float deltaTime) {
bool stunnedThisFrame = m_Stunned;
CalculateCombat(deltaTime); // Putting this here for now
if (m_StartPosition == NiPoint3::ZERO) {
if (m_StartPosition == NiPoint3Constant::ZERO) {
m_StartPosition = m_Parent->GetPosition();
}
@@ -653,8 +654,8 @@ void BaseCombatAIComponent::Wander() {
auto destination = m_StartPosition + delta;
if (dpWorld::Instance().IsLoaded()) {
destination.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(destination);
if (dpWorld::IsLoaded()) {
destination.y = dpWorld::GetNavMesh()->GetHeightAtPoint(destination);
}
if (Vector3::DistanceSquared(destination, m_MovementAI->GetParent()->GetPosition()) < 2 * 2) {

View File

@@ -45,9 +45,9 @@ struct AiSkillEntry
/**
* Handles the AI of entities, making them wander, tether and attack their enemies
*/
class BaseCombatAIComponent : public Component {
class BaseCombatAIComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::BASE_COMBAT_AI;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::BASE_COMBAT_AI;
BaseCombatAIComponent(Entity* parentEntity, uint32_t id);
~BaseCombatAIComponent() override;

View File

@@ -10,9 +10,9 @@
/**
* Attached to bouncer entities, allowing other entities to bounce off of it
*/
class BouncerComponent : public Component {
class BouncerComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::BOUNCER;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::BOUNCER;
BouncerComponent(Entity* parentEntity);
~BouncerComponent() override;

View File

@@ -164,7 +164,7 @@ void BuffComponent::ApplyBuff(const int32_t id, const float duration, const LWOO
const auto& parameters = GetBuffParameters(id);
for (const auto& parameter : parameters) {
if (parameter.name == "overtime") {
auto* behaviorTemplateTable = CDClientManager::Instance().GetTable<CDSkillBehaviorTable>();
auto* behaviorTemplateTable = CDClientManager::GetTable<CDSkillBehaviorTable>();
behaviorID = behaviorTemplateTable->GetSkillByID(parameter.values[0]).behaviorID;
stacks = static_cast<int32_t>(parameter.values[1]);

View File

@@ -47,9 +47,9 @@ struct Buff {
/**
* Allows for the application of buffs to the parent entity, altering health, armor and imagination.
*/
class BuffComponent : public Component {
class BuffComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::BUFF;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::BUFF;
explicit BuffComponent(Entity* parent);

View File

@@ -56,7 +56,7 @@ void BuildBorderComponent::OnUse(Entity* originator) {
4,
0,
-1,
NiPoint3::ZERO,
NiPoint3Constant::ZERO,
0
);
} else {

View File

@@ -14,9 +14,9 @@
/**
* Component for the build border, allowing the user to start building when interacting with it
*/
class BuildBorderComponent : public Component {
class BuildBorderComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::BUILD_BORDER;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::BUILD_BORDER;
BuildBorderComponent(Entity* parent);
~BuildBorderComponent() override;

View File

@@ -10,6 +10,7 @@ set(DGAME_DCOMPONENTS_SOURCES
"ControllablePhysicsComponent.cpp"
"DestroyableComponent.cpp"
"DonationVendorComponent.cpp"
"GhostComponent.cpp"
"InventoryComponent.cpp"
"ItemComponent.cpp"
"LevelProgressionComponent.cpp"
@@ -26,7 +27,6 @@ set(DGAME_DCOMPONENTS_SOURCES
"PlayerForcedMovementComponent.cpp"
"PossessableComponent.cpp"
"PossessorComponent.cpp"
"PropertyComponent.cpp"
"PropertyEntranceComponent.cpp"
"PropertyManagementComponent.cpp"
"PropertyVendorComponent.cpp"

View File

@@ -20,9 +20,11 @@
#include "Database.h"
#include "CDRewardCodesTable.h"
#include "Mail.h"
#include "ZoneInstanceManager.h"
#include "WorldPackets.h"
#include <ctime>
CharacterComponent::CharacterComponent(Entity* parent, Character* character) : Component(parent) {
CharacterComponent::CharacterComponent(Entity* parent, Character* character, const SystemAddress& systemAddress) : Component(parent) {
m_Character = character;
m_IsRacing = false;
@@ -44,6 +46,7 @@ CharacterComponent::CharacterComponent(Entity* parent, Character* character) : C
m_CurrentActivity = eGameActivity::NONE;
m_CountryCode = 0;
m_LastUpdateTimestamp = std::time(nullptr);
m_SystemAddress = systemAddress;
}
bool CharacterComponent::LandingAnimDisabled(int zoneID) {
@@ -760,15 +763,15 @@ void CharacterComponent::UpdateClientMinimap(bool showFaction, std::string ventu
}
void CharacterComponent::AwardClaimCodes() {
if (!m_Parent) return;
auto* user = m_Parent->GetParentUser();
if (!m_Parent || !m_Parent->GetCharacter()) return;
auto* user = m_Parent->GetCharacter()->GetParentUser();
if (!user) return;
auto rewardCodes = Database::Get()->GetRewardCodesByAccountID(user->GetAccountID());
if (rewardCodes.empty()) return;
auto* cdrewardCodes = CDClientManager::Instance().GetTable<CDRewardCodesTable>();
for (auto const rewardCode: rewardCodes){
auto* cdrewardCodes = CDClientManager::GetTable<CDRewardCodesTable>();
for (auto const rewardCode : rewardCodes) {
LOG_DEBUG("Processing RewardCode %i", rewardCode);
const uint32_t rewardCodeIndex = rewardCode >> 6;
const uint32_t bitIndex = rewardCode % 64;
@@ -786,3 +789,49 @@ void CharacterComponent::AwardClaimCodes() {
Mail::SendMail(LWOOBJID_EMPTY, "%[MAIL_SYSTEM_NOTIFICATION]", m_Parent, subject.str(), body.str(), attachmentLOT, 1);
}
}
void CharacterComponent::SendToZone(LWOMAPID zoneId, LWOCLONEID cloneId) const {
const auto objid = m_Parent->GetObjectID();
ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, zoneId, cloneId, false, [objid](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) {
auto* entity = Game::entityManager->GetEntity(objid);
if (!entity) return;
const auto sysAddr = entity->GetSystemAddress();
auto* character = entity->GetCharacter();
auto* characterComponent = entity->GetComponent<CharacterComponent>();
if (character && characterComponent) {
character->SetZoneID(zoneID);
character->SetZoneInstance(zoneInstance);
character->SetZoneClone(zoneClone);
characterComponent->SetLastRocketConfig(u"");
character->SaveXMLToDatabase();
}
WorldPackets::SendTransferToWorld(sysAddr, serverIP, serverPort, mythranShift);
Game::entityManager->DestructEntity(entity);
});
}
const SystemAddress& CharacterComponent::GetSystemAddress() const {
return m_SystemAddress;
}
void CharacterComponent::SetRespawnPos(const NiPoint3& position) {
if (!m_Character) return;
m_respawnPos = position;
m_Character->SetRespawnPoint(Game::zoneManager->GetZone()->GetWorldID(), position);
}
void CharacterComponent::SetRespawnRot(const NiQuaternion& rotation) {
m_respawnRot = rotation;
}

View File

@@ -11,6 +11,7 @@
#include "tinyxml2.h"
#include "eReplicaComponentType.h"
#include <array>
#include "Loot.h"
enum class eGameActivity : uint32_t;
@@ -61,11 +62,11 @@ enum StatisticID {
/**
* Represents a character, including their rockets and stats
*/
class CharacterComponent : public Component {
class CharacterComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::CHARACTER;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::CHARACTER;
CharacterComponent(Entity* parent, Character* character);
CharacterComponent(Entity* parent, Character* character, const SystemAddress& systemAddress);
~CharacterComponent() override;
void LoadFromXml(tinyxml2::XMLDocument* doc) override;
@@ -281,6 +282,30 @@ public:
LWOOBJID GetCurrentInteracting() {return m_CurrentInteracting;};
/**
* Sends a player to another zone with an optional clone ID
*
* @param zoneId zoneID for the new instance.
* @param cloneId cloneID for the new instance.
*/
void SendToZone(LWOMAPID zoneId, LWOCLONEID cloneId = 0) const;
const SystemAddress& GetSystemAddress() const;
const NiPoint3& GetRespawnPosition() const { return m_respawnPos; };
void SetRespawnPos(const NiPoint3& position);
const NiQuaternion& GetRespawnRotation() const { return m_respawnRot; };
void SetRespawnRot(const NiQuaternion& rotation);
std::map<LWOOBJID, Loot::Info>& GetDroppedLoot() { return m_DroppedLoot; };
uint64_t GetDroppedCoins() const { return m_DroppedCoins; };
void SetDroppedCoins(const uint64_t value) { m_DroppedCoins = value; };
/**
* Character info regarding this character, including clothing styles, etc.
*/
@@ -571,6 +596,16 @@ private:
std::array<uint64_t, 4> m_ClaimCodes{};
void AwardClaimCodes();
SystemAddress m_SystemAddress;
NiPoint3 m_respawnPos;
NiQuaternion m_respawnRot;
std::map<LWOOBJID, Loot::Info> m_DroppedLoot;
uint64_t m_DroppedCoins = 0;
};
#endif // CHARACTERCOMPONENT_H

View File

@@ -4,9 +4,9 @@
#include "Component.h"
#include "eReplicaComponentType.h"
class CollectibleComponent : public Component {
class CollectibleComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::COLLECTIBLE;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::COLLECTIBLE;
CollectibleComponent(Entity* parentEntity, int32_t collectibleId) : Component(parentEntity), m_CollectibleId(collectibleId) {}
int16_t GetCollectibleId() const { return m_CollectibleId; }

View File

@@ -7,8 +7,7 @@ class Entity;
/**
* Component base class, provides methods for game loop updates, usage events and loading and saving to XML.
*/
class Component
{
class Component {
public:
Component(Entity* parent);
virtual ~Component();

View File

@@ -57,13 +57,13 @@ ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity) : Phy
float radius = 1.5f;
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), radius, false);
m_dpEntity->SetCollisionGroup(COLLISION_GROUP_DYNAMIC | COLLISION_GROUP_FRIENDLY);
dpWorld::Instance().AddEntity(m_dpEntity);
dpWorld::AddEntity(m_dpEntity);
}
}
ControllablePhysicsComponent::~ControllablePhysicsComponent() {
if (m_dpEntity) {
dpWorld::Instance().RemoveEntity(m_dpEntity);
dpWorld::RemoveEntity(m_dpEntity);
}
}

View File

@@ -21,7 +21,7 @@ enum class eStateChangeType : uint32_t;
*/
class ControllablePhysicsComponent : public PhysicsComponent {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::CONTROLLABLE_PHYSICS;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::CONTROLLABLE_PHYSICS;
ControllablePhysicsComponent(Entity* entity);
~ControllablePhysicsComponent() override;

View File

@@ -81,7 +81,7 @@ DestroyableComponent::~DestroyableComponent() {
}
void DestroyableComponent::Reinitialize(LOT templateID) {
CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
CDComponentsRegistryTable* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
int32_t buffComponentID = compRegistryTable->GetByIDAndType(templateID, eReplicaComponentType::BUFF);
int32_t collectibleComponentID = compRegistryTable->GetByIDAndType(templateID, eReplicaComponentType::COLLECTIBLE);
@@ -92,7 +92,7 @@ void DestroyableComponent::Reinitialize(LOT templateID) {
if (quickBuildComponentID > 0) componentID = quickBuildComponentID;
if (buffComponentID > 0) componentID = buffComponentID;
CDDestructibleComponentTable* destCompTable = CDClientManager::Instance().GetTable<CDDestructibleComponentTable>();
CDDestructibleComponentTable* destCompTable = CDClientManager::GetTable<CDDestructibleComponentTable>();
std::vector<CDDestructibleComponent> destCompData = destCompTable->Query([=](CDDestructibleComponent entry) { return (entry.id == componentID); });
if (componentID > 0) {
@@ -251,13 +251,14 @@ void DestroyableComponent::SetMaxHealth(float value, bool playAnim) {
if (playAnim) {
// Now update the player bar
if (!m_Parent->GetParentUser()) return;
auto* characterComponent = m_Parent->GetComponent<CharacterComponent>();
if (!characterComponent) return;
AMFArrayValue args;
args.Insert("amount", std::to_string(difference));
args.Insert("type", "health");
GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", args);
GameMessages::SendUIMessageServerToSingleClient(m_Parent, characterComponent->GetSystemAddress(), "MaxPlayerBarUpdate", args);
}
Game::entityManager->SerializeEntity(m_Parent);
@@ -292,13 +293,14 @@ void DestroyableComponent::SetMaxArmor(float value, bool playAnim) {
if (playAnim) {
// Now update the player bar
if (!m_Parent->GetParentUser()) return;
auto* characterComponent = m_Parent->GetComponent<CharacterComponent>();
if (!characterComponent) return;
AMFArrayValue args;
args.Insert("amount", std::to_string(value));
args.Insert("type", "armor");
GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", args);
GameMessages::SendUIMessageServerToSingleClient(m_Parent, characterComponent->GetSystemAddress(), "MaxPlayerBarUpdate", args);
}
Game::entityManager->SerializeEntity(m_Parent);
@@ -332,13 +334,14 @@ void DestroyableComponent::SetMaxImagination(float value, bool playAnim) {
if (playAnim) {
// Now update the player bar
if (!m_Parent->GetParentUser()) return;
auto* characterComponent = m_Parent->GetComponent<CharacterComponent>();
if (!characterComponent) return;
AMFArrayValue args;
args.Insert("amount", std::to_string(difference));
args.Insert("type", "imagination");
GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", args);
GameMessages::SendUIMessageServerToSingleClient(m_Parent, characterComponent->GetSystemAddress(), "MaxPlayerBarUpdate", args);
}
Game::entityManager->SerializeEntity(m_Parent);
}

View File

@@ -17,9 +17,9 @@ 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 : public Component {
class DestroyableComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::DESTROYABLE;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::DESTROYABLE;
DestroyableComponent(Entity* parentEntity);
~DestroyableComponent() override;

View File

@@ -8,7 +8,7 @@ class Entity;
class DonationVendorComponent final : public VendorComponent {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::DONATION_VENDOR;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::DONATION_VENDOR;
DonationVendorComponent(Entity* parent);
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
uint32_t GetActivityID() {return m_ActivityId;};

View File

@@ -0,0 +1,57 @@
#include "GhostComponent.h"
GhostComponent::GhostComponent(Entity* parent) : Component(parent) {
m_GhostReferencePoint = NiPoint3Constant::ZERO;
m_GhostOverridePoint = NiPoint3Constant::ZERO;
m_GhostOverride = false;
}
GhostComponent::~GhostComponent() {
for (auto& observedEntity : m_ObservedEntities) {
if (observedEntity == LWOOBJID_EMPTY) continue;
auto* entity = Game::entityManager->GetGhostCandidate(observedEntity);
if (!entity) continue;
entity->SetObservers(entity->GetObservers() - 1);
}
}
void GhostComponent::SetGhostReferencePoint(const NiPoint3& value) {
m_GhostReferencePoint = value;
}
void GhostComponent::SetGhostOverridePoint(const NiPoint3& value) {
m_GhostOverridePoint = value;
}
void GhostComponent::AddLimboConstruction(LWOOBJID objectId) {
m_LimboConstructions.insert(objectId);
}
void GhostComponent::RemoveLimboConstruction(LWOOBJID objectId) {
m_LimboConstructions.erase(objectId);
}
void GhostComponent::ConstructLimboEntities() {
for (const auto& objectId : m_LimboConstructions) {
auto* entity = Game::entityManager->GetEntity(objectId);
if (!entity) continue;
Game::entityManager->ConstructEntity(entity, m_Parent->GetSystemAddress());
}
m_LimboConstructions.clear();
}
void GhostComponent::ObserveEntity(LWOOBJID id) {
m_ObservedEntities.insert(id);
}
bool GhostComponent::IsObserved(LWOOBJID id) {
return m_ObservedEntities.contains(id);
}
void GhostComponent::GhostEntity(LWOOBJID id) {
m_ObservedEntities.erase(id);
}

View File

@@ -0,0 +1,54 @@
#ifndef __GHOSTCOMPONENT__H__
#define __GHOSTCOMPONENT__H__
#include "Component.h"
#include "eReplicaComponentType.h"
#include <unordered_set>
class NiPoint3;
class GhostComponent final : public Component {
public:
static inline const eReplicaComponentType ComponentType = eReplicaComponentType::GHOST;
GhostComponent(Entity* parent);
~GhostComponent() override;
void SetGhostOverride(bool value) { m_GhostOverride = value; };
const NiPoint3& GetGhostReferencePoint() const { return m_GhostOverride ? m_GhostOverridePoint : m_GhostReferencePoint; };
const NiPoint3& GetOriginGhostReferencePoint() const { return m_GhostReferencePoint; };
const NiPoint3& GetGhostOverridePoint() const { return m_GhostOverridePoint; };
bool GetGhostOverride() const { return m_GhostOverride; };
void SetGhostReferencePoint(const NiPoint3& value);
void SetGhostOverridePoint(const NiPoint3& value);
void AddLimboConstruction(const LWOOBJID objectId);
void RemoveLimboConstruction(const LWOOBJID objectId);
void ConstructLimboEntities();
void ObserveEntity(const LWOOBJID id);
bool IsObserved(const LWOOBJID id);
void GhostEntity(const LWOOBJID id);
private:
NiPoint3 m_GhostReferencePoint;
NiPoint3 m_GhostOverridePoint;
std::unordered_set<LWOOBJID> m_ObservedEntities;
std::unordered_set<LWOOBJID> m_LimboConstructions;
bool m_GhostOverride;
};
#endif //!__GHOSTCOMPONENT__H__

View File

@@ -2,8 +2,8 @@
#include "EntityManager.h"
HavokVehiclePhysicsComponent::HavokVehiclePhysicsComponent(Entity* parent) : PhysicsComponent(parent) {
m_Velocity = NiPoint3::ZERO;
m_AngularVelocity = NiPoint3::ZERO;
m_Velocity = NiPoint3Constant::ZERO;
m_AngularVelocity = NiPoint3Constant::ZERO;
m_IsOnGround = true;
m_IsOnRail = false;
m_DirtyPosition = true;

View File

@@ -4,38 +4,14 @@
#include "Entity.h"
#include "PhysicsComponent.h"
#include "eReplicaComponentType.h"
struct RemoteInputInfo {
RemoteInputInfo() {
m_RemoteInputX = 0;
m_RemoteInputY = 0;
m_IsPowersliding = false;
m_IsModified = false;
}
void operator=(const RemoteInputInfo& other) {
m_RemoteInputX = other.m_RemoteInputX;
m_RemoteInputY = other.m_RemoteInputY;
m_IsPowersliding = other.m_IsPowersliding;
m_IsModified = other.m_IsModified;
}
bool operator==(const RemoteInputInfo& other) {
return m_RemoteInputX == other.m_RemoteInputX && m_RemoteInputY == other.m_RemoteInputY && m_IsPowersliding == other.m_IsPowersliding && m_IsModified == other.m_IsModified;
}
float m_RemoteInputX;
float m_RemoteInputY;
bool m_IsPowersliding;
bool m_IsModified;
};
#include "PositionUpdate.h"
/**
* Physics component for vehicles.
*/
class HavokVehiclePhysicsComponent : public PhysicsComponent {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::HAVOK_VEHICLE_PHYSICS;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::HAVOK_VEHICLE_PHYSICS;
HavokVehiclePhysicsComponent(Entity* parentEntity);

View File

@@ -14,7 +14,6 @@
#include "Character.h"
#include "EntityManager.h"
#include "ItemSet.h"
#include "Player.h"
#include "PetComponent.h"
#include "PossessorComponent.h"
#include "PossessableComponent.h"
@@ -31,6 +30,7 @@
#include "eMissionTaskType.h"
#include "eStateChangeType.h"
#include "eUseItemResponse.h"
#include "Mail.h"
#include "CDComponentsRegistryTable.h"
#include "CDInventoryComponentTable.h"
@@ -55,10 +55,10 @@ InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* do
return;
}
auto* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
auto* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
const auto componentId = compRegistryTable->GetByIDAndType(lot, eReplicaComponentType::INVENTORY);
auto* inventoryComponentTable = CDClientManager::Instance().GetTable<CDInventoryComponentTable>();
auto* inventoryComponentTable = CDClientManager::GetTable<CDInventoryComponentTable>();
auto items = inventoryComponentTable->Query([=](const CDInventoryComponent entry) { return entry.id == componentId; });
auto slot = 0u;
@@ -264,17 +264,11 @@ void InventoryComponent::AddItem(
}
if (slot == -1) {
auto* player = dynamic_cast<Player*>(GetParent());
if (player == nullptr) {
return;
}
outOfSpace += size;
switch (sourceType) {
case 0:
player->SendMail(LWOOBJID_EMPTY, "Darkflame Universe", "Lost Reward", "You received an item and didn&apos;t have room for it.", lot, size);
Mail::SendMail(LWOOBJID_EMPTY, "Darkflame Universe", m_Parent, "Lost Reward", "You received an item and didn&apos;t have room for it.", lot, size);
break;
case 1:
@@ -915,11 +909,11 @@ void InventoryComponent::UnEquipItem(Item* item) {
void InventoryComponent::EquipScripts(Item* equippedItem) {
CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
CDComponentsRegistryTable* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
if (!compRegistryTable) return;
int32_t scriptComponentID = compRegistryTable->GetByIDAndType(equippedItem->GetLot(), eReplicaComponentType::SCRIPT, -1);
if (scriptComponentID > -1) {
CDScriptComponentTable* scriptCompTable = CDClientManager::Instance().GetTable<CDScriptComponentTable>();
CDScriptComponentTable* scriptCompTable = CDClientManager::GetTable<CDScriptComponentTable>();
CDScriptComponent scriptCompData = scriptCompTable->GetByID(scriptComponentID);
auto* itemScript = CppScripts::GetScript(m_Parent, scriptCompData.script_name);
if (!itemScript) {
@@ -930,11 +924,11 @@ void InventoryComponent::EquipScripts(Item* equippedItem) {
}
void InventoryComponent::UnequipScripts(Item* unequippedItem) {
CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
CDComponentsRegistryTable* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
if (!compRegistryTable) return;
int32_t scriptComponentID = compRegistryTable->GetByIDAndType(unequippedItem->GetLot(), eReplicaComponentType::SCRIPT, -1);
if (scriptComponentID > -1) {
CDScriptComponentTable* scriptCompTable = CDClientManager::Instance().GetTable<CDScriptComponentTable>();
CDScriptComponentTable* scriptCompTable = CDClientManager::GetTable<CDScriptComponentTable>();
CDScriptComponent scriptCompData = scriptCompTable->GetByID(scriptComponentID);
auto* itemScript = CppScripts::GetScript(m_Parent, scriptCompData.script_name);
if (!itemScript) {
@@ -1228,7 +1222,7 @@ void InventoryComponent::SpawnPet(Item* item) {
EntityInfo info{};
info.lot = item->GetLot();
info.pos = m_Parent->GetPosition();
info.rot = NiQuaternion::IDENTITY;
info.rot = NiQuaternionConstant::IDENTITY;
info.spawnerID = m_Parent->GetObjectID();
auto* pet = Game::entityManager->CreateEntity(info);
@@ -1286,7 +1280,7 @@ bool InventoryComponent::IsTransferInventory(eInventoryType type) {
}
uint32_t InventoryComponent::FindSkill(const LOT lot) {
auto* table = CDClientManager::Instance().GetTable<CDObjectSkillsTable>();
auto* table = CDClientManager::GetTable<CDObjectSkillsTable>();
const auto results = table->Query([=](const CDObjectSkills& entry) {
return entry.objectTemplate == static_cast<unsigned int>(lot);
@@ -1304,8 +1298,8 @@ uint32_t InventoryComponent::FindSkill(const LOT lot) {
std::vector<uint32_t> InventoryComponent::FindBuffs(Item* item, bool castOnEquip) const {
std::vector<uint32_t> buffs;
if (item == nullptr) return buffs;
auto* table = CDClientManager::Instance().GetTable<CDObjectSkillsTable>();
auto* behaviors = CDClientManager::Instance().GetTable<CDSkillBehaviorTable>();
auto* table = CDClientManager::GetTable<CDObjectSkillsTable>();
auto* behaviors = CDClientManager::GetTable<CDSkillBehaviorTable>();
const auto results = table->Query([=](const CDObjectSkills& entry) {
return entry.objectTemplate == static_cast<unsigned int>(item->GetLot());

View File

@@ -35,10 +35,9 @@ enum class eItemType : int32_t;
* of different types, each type representing a different group of items, see `eInventoryType` for a list of
* inventories.
*/
class InventoryComponent : public Component
{
class InventoryComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::INVENTORY;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::INVENTORY;
explicit InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document = nullptr);
void Update(float deltaTime) override;

View File

@@ -4,9 +4,9 @@
#include "Component.h"
#include "eReplicaComponentType.h"
class ItemComponent : public Component {
class ItemComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::ITEM;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::ITEM;
ItemComponent(Entity* entity) : Component(entity) {}

View File

@@ -11,10 +11,10 @@
* Component that handles the LOT that is shown in the LUP exhibit in the LUP world. Works by setting a timer and
* switching the LOTs around that we'd like to display.
*/
class LUPExhibitComponent : public Component
class LUPExhibitComponent final : public Component
{
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::LUP_EXHIBIT;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::LUP_EXHIBIT;
LUPExhibitComponent(Entity* parent) : Component(parent) {};
void Update(float deltaTime) override;

View File

@@ -44,7 +44,7 @@ void LevelProgressionComponent::Serialize(RakNet::BitStream* outBitStream, bool
}
void LevelProgressionComponent::HandleLevelUp() {
auto* rewardsTable = CDClientManager::Instance().GetTable<CDRewardsTable>();
auto* rewardsTable = CDClientManager::GetTable<CDRewardsTable>();
const auto& rewards = rewardsTable->GetByLevelID(m_Level);
bool rewardingItem = rewards.size() > 0;

View File

@@ -11,9 +11,9 @@
*
*/
class LevelProgressionComponent : public Component {
class LevelProgressionComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::LEVEL_PROGRESSION;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::LEVEL_PROGRESSION;
/**
* Constructor for this component

View File

@@ -6,7 +6,7 @@
class MiniGameControlComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MINI_GAME_CONTROL;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::MINI_GAME_CONTROL;
MiniGameControlComponent(Entity* parent) : Component(parent) {}
void Serialize(RakNet::BitStream* outBitStream, bool isConstruction);

View File

@@ -266,7 +266,7 @@ void MissionComponent::ForceProgressValue(uint32_t missionId, uint32_t taskType,
}
bool MissionComponent::GetMissionInfo(uint32_t missionId, CDMissions& result) {
auto* missionsTable = CDClientManager::Instance().GetTable<CDMissionsTable>();
auto* missionsTable = CDClientManager::GetTable<CDMissionsTable>();
const auto missions = missionsTable->Query([=](const CDMissions& entry) {
return entry.id == static_cast<int>(missionId);
@@ -320,8 +320,8 @@ const std::vector<uint32_t> MissionComponent::LookForAchievements(eMissionTaskTy
return acceptedAchievements;
#else
auto* missionTasksTable = CDClientManager::Instance().GetTable<CDMissionTasksTable>();
auto* missionsTable = CDClientManager::Instance().GetTable<CDMissionsTable>();
auto* missionTasksTable = CDClientManager::GetTable<CDMissionTasksTable>();
auto* missionsTable = CDClientManager::GetTable<CDMissionsTable>();
auto tasks = missionTasksTable->Query([=](const CDMissionTasks& entry) {
return entry.taskType == static_cast<unsigned>(type);
@@ -407,8 +407,8 @@ const std::vector<uint32_t>& MissionComponent::QueryAchievements(eMissionTaskTyp
}
// Find relevent tables
auto* missionTasksTable = CDClientManager::Instance().GetTable<CDMissionTasksTable>();
auto* missionsTable = CDClientManager::Instance().GetTable<CDMissionsTable>();
auto* missionTasksTable = CDClientManager::GetTable<CDMissionTasksTable>();
auto* missionsTable = CDClientManager::GetTable<CDMissionsTable>();
std::vector<uint32_t> result;

View File

@@ -24,10 +24,9 @@ class AchievementCacheKey;
* The mission inventory of an entity. Tracks mission state for each mission that can be accepted and allows for
* progression of each of the mission task types (see eMissionTaskType).
*/
class MissionComponent : public Component
{
class MissionComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MISSION;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::MISSION;
explicit MissionComponent(Entity* parent);
~MissionComponent() override;

View File

@@ -40,7 +40,7 @@ bool OfferedMission::GetAcceptsMission() const {
//------------------------ MissionOfferComponent below ------------------------
MissionOfferComponent::MissionOfferComponent(Entity* parent, const LOT parentLot) : Component(parent) {
auto* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
auto* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
auto value = compRegistryTable->GetByIDAndType(parentLot, eReplicaComponentType::MISSION_OFFER, -1);
@@ -48,7 +48,7 @@ MissionOfferComponent::MissionOfferComponent(Entity* parent, const LOT parentLot
const uint32_t componentId = value;
// Now lookup the missions in the MissionNPCComponent table
auto* missionNpcComponentTable = CDClientManager::Instance().GetTable<CDMissionNPCComponentTable>();
auto* missionNpcComponentTable = CDClientManager::GetTable<CDMissionNPCComponentTable>();
auto missions = missionNpcComponentTable->Query([=](const CDMissionNPCComponent& entry) {
return entry.id == static_cast<unsigned>(componentId);

View File

@@ -59,9 +59,9 @@ private:
/**
* Allows entities to offer missions to other entities, depending on their mission inventory progression.
*/
class MissionOfferComponent : public Component {
class MissionOfferComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MISSION_OFFER;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::MISSION_OFFER;
MissionOfferComponent(Entity* parent, LOT parentLot);

View File

@@ -22,9 +22,9 @@ class MoveToInventoryMessage;
/**
* Component that represents entities that are a model, e.g. collectible models and BBB models.
*/
class ModelComponent : public Component {
class ModelComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MODEL;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::MODEL;
ModelComponent(Entity* parent);

View File

@@ -10,9 +10,9 @@
* same as having said items in your inventory (the subkey for this component) this component is the one that
* renders the entity into the world.
*/
class ModuleAssemblyComponent : public Component {
class ModuleAssemblyComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MODULE_ASSEMBLY;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::MODULE_ASSEMBLY;
ModuleAssemblyComponent(Entity* parent);
~ModuleAssemblyComponent() override;

View File

@@ -16,6 +16,8 @@
#include "CDComponentsRegistryTable.h"
#include "CDPhysicsComponentTable.h"
#include "dNavMesh.h"
namespace {
/**
* Cache of all lots and their respective speeds
@@ -41,7 +43,7 @@ MovementAIComponent::MovementAIComponent(Entity* parent, MovementAIInfo info) :
m_NextWaypoint = m_Parent->GetPosition();
m_Acceleration = 0.4f;
m_PullingToPoint = false;
m_PullPoint = NiPoint3::ZERO;
m_PullPoint = NiPoint3Constant::ZERO;
m_HaltDistance = 0;
m_TimeToTravel = 0;
m_TimeTravelled = 0;
@@ -86,7 +88,7 @@ void MovementAIComponent::Update(const float deltaTime) {
SetPosition(source);
NiPoint3 velocity = NiPoint3::ZERO;
NiPoint3 velocity = NiPoint3Constant::ZERO;
if (m_Acceleration > 0 && m_BaseSpeed > 0 && AdvanceWaypointIndex()) // Do we have another waypoint to seek?
{
@@ -169,8 +171,8 @@ NiPoint3 MovementAIComponent::ApproximateLocation() const {
auto approximation = source + ((destination - source) * percentageToWaypoint);
if (dpWorld::Instance().IsLoaded()) {
approximation.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(approximation);
if (dpWorld::IsLoaded()) {
approximation.y = dpWorld::GetNavMesh()->GetHeightAtPoint(approximation);
}
return approximation;
@@ -181,8 +183,8 @@ bool MovementAIComponent::Warp(const NiPoint3& point) {
NiPoint3 destination = point;
if (dpWorld::Instance().IsLoaded()) {
destination.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(point);
if (dpWorld::IsLoaded()) {
destination.y = dpWorld::GetNavMesh()->GetHeightAtPoint(point);
if (std::abs(destination.y - point.y) > 3) {
return false;
@@ -201,7 +203,7 @@ void MovementAIComponent::Stop() {
SetPosition(ApproximateLocation());
SetVelocity(NiPoint3::ZERO);
SetVelocity(NiPoint3Constant::ZERO);
m_TimeToTravel = 0;
m_TimeTravelled = 0;
@@ -242,8 +244,8 @@ float MovementAIComponent::GetBaseSpeed(LOT lot) {
return it->second;
}
CDComponentsRegistryTable* componentRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
CDPhysicsComponentTable* physicsComponentTable = CDClientManager::Instance().GetTable<CDPhysicsComponentTable>();
CDComponentsRegistryTable* componentRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
CDPhysicsComponentTable* physicsComponentTable = CDClientManager::GetTable<CDPhysicsComponentTable>();
int32_t componentID;
CDPhysicsComponent* physicsComponent = nullptr;
@@ -302,8 +304,8 @@ void MovementAIComponent::SetDestination(const NiPoint3& destination) {
}
std::vector<NiPoint3> computedPath;
if (dpWorld::Instance().IsLoaded()) {
computedPath = dpWorld::Instance().GetNavMesh()->GetPath(m_Parent->GetPosition(), destination, m_Info.wanderSpeed);
if (dpWorld::IsLoaded()) {
computedPath = dpWorld::GetNavMesh()->GetPath(m_Parent->GetPosition(), destination, m_Info.wanderSpeed);
}
// Somehow failed
@@ -328,8 +330,8 @@ void MovementAIComponent::SetDestination(const NiPoint3& destination) {
// Simply path
for (auto& point : computedPath) {
if (dpWorld::Instance().IsLoaded()) {
point.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(point);
if (dpWorld::IsLoaded()) {
point.y = dpWorld::GetNavMesh()->GetHeightAtPoint(point);
}
m_InterpolatedWaypoints.push_back(point);

View File

@@ -55,9 +55,9 @@ struct MovementAIInfo {
* Component that handles the movement settings of an entity. Not to be confused with the BaseCombatAI component that
* actually handles attackig and following enemy entities.
*/
class MovementAIComponent : public Component {
class MovementAIComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MOVEMENT_AI;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::MOVEMENT_AI;
MovementAIComponent(Entity* parentEntity, MovementAIInfo info);

View File

@@ -104,9 +104,9 @@ public:
* 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 {
class MovingPlatformComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MOVING_PLATFORM;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::MOVING_PLATFORM;
MovingPlatformComponent(Entity* parent, const std::string& pathName);
~MovingPlatformComponent() override;

View File

@@ -8,9 +8,9 @@
* Component that handles the LUP/WBL rocket launchpad that can be interacted with to travel to WBL worlds.
*
*/
class MultiZoneEntranceComponent : public Component {
class MultiZoneEntranceComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::MULTI_ZONE_ENTRANCE;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::MULTI_ZONE_ENTRANCE;
/**
* Constructor for this component, builds the m_LUPWorlds vector

View File

@@ -34,6 +34,7 @@
#include "eObjectBits.h"
#include "eGameMasterLevel.h"
#include "eMissionState.h"
#include "dNavMesh.h"
std::unordered_map<LOT, PetComponent::PetPuzzleData> PetComponent::buildCache{};
std::unordered_map<LWOOBJID, LWOOBJID> PetComponent::currentActivities{};
@@ -73,8 +74,8 @@ std::map<LOT, int32_t> PetComponent::petFlags = {
{ 13067, 838 }, // Skeleton dragon
};
PetComponent::PetComponent(Entity* parentEntity, uint32_t componentId) : Component{ parentEntity },
m_PetInfo{ CDClientManager::Instance().GetTable<CDPetComponentTable>()->GetByID(componentId) } {
PetComponent::PetComponent(Entity* parentEntity, uint32_t componentId) : Component{ parentEntity } {
m_PetInfo = CDClientManager::GetTable<CDPetComponentTable>()->GetByID(componentId); // TODO: Make reference when safe
m_ComponentId = componentId;
m_Interaction = LWOOBJID_EMPTY;
m_InteractType = PetInteractType::none;
@@ -273,17 +274,17 @@ void PetComponent::OnUse(Entity* originator) {
NiPoint3 forward = NiQuaternion::LookAt(m_Parent->GetPosition(), originator->GetPosition()).GetForwardVector();
forward.y = 0;
if (dpWorld::Instance().IsLoaded()) {
if (dpWorld::IsLoaded()) {
NiPoint3 attempt = petPosition + forward * interactionDistance;
float y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(attempt);
float y = dpWorld::GetNavMesh()->GetHeightAtPoint(attempt);
while (std::abs(y - petPosition.y) > 4 && interactionDistance > 10) {
const NiPoint3 forward = m_Parent->GetRotation().GetForwardVector();
attempt = originatorPosition + forward * interactionDistance;
y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(attempt);
y = dpWorld::GetNavMesh()->GetHeightAtPoint(attempt);
interactionDistance -= 0.5f;
}
@@ -476,7 +477,7 @@ void PetComponent::NotifyTamingBuildSuccess(NiPoint3 position) {
EntityInfo info{};
info.lot = cached->second.puzzleModelLot;
info.pos = position;
info.rot = NiQuaternion::IDENTITY;
info.rot = NiQuaternionConstant::IDENTITY;
info.spawnerID = tamer->GetObjectID();
auto* modelEntity = Game::entityManager->CreateEntity(info);
@@ -531,9 +532,9 @@ void PetComponent::NotifyTamingBuildSuccess(NiPoint3 position) {
LWOOBJID_EMPTY,
false,
ePetTamingNotifyType::NAMINGPET,
NiPoint3::ZERO,
NiPoint3::ZERO,
NiQuaternion::IDENTITY,
NiPoint3Constant::ZERO,
NiPoint3Constant::ZERO,
NiQuaternionConstant::IDENTITY,
UNASSIGNED_SYSTEM_ADDRESS
);
@@ -608,9 +609,9 @@ void PetComponent::RequestSetPetName(std::u16string name) {
m_Tamer,
false,
ePetTamingNotifyType::SUCCESS,
NiPoint3::ZERO,
NiPoint3::ZERO,
NiQuaternion::IDENTITY,
NiPoint3Constant::ZERO,
NiPoint3Constant::ZERO,
NiQuaternionConstant::IDENTITY,
UNASSIGNED_SYSTEM_ADDRESS
);
@@ -649,9 +650,9 @@ void PetComponent::ClientExitTamingMinigame(bool voluntaryExit) {
m_Tamer,
false,
ePetTamingNotifyType::QUIT,
NiPoint3::ZERO,
NiPoint3::ZERO,
NiQuaternion::IDENTITY,
NiPoint3Constant::ZERO,
NiPoint3Constant::ZERO,
NiQuaternionConstant::IDENTITY,
UNASSIGNED_SYSTEM_ADDRESS
);
@@ -700,9 +701,9 @@ void PetComponent::ClientFailTamingMinigame() {
m_Tamer,
false,
ePetTamingNotifyType::FAILED,
NiPoint3::ZERO,
NiPoint3::ZERO,
NiQuaternion::IDENTITY,
NiPoint3Constant::ZERO,
NiPoint3Constant::ZERO,
NiQuaternionConstant::IDENTITY,
UNASSIGNED_SYSTEM_ADDRESS
);
@@ -746,8 +747,8 @@ void PetComponent::Wander() {
auto destination = m_StartPosition + delta;
if (dpWorld::Instance().IsLoaded()) {
destination.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(destination);
if (dpWorld::IsLoaded()) {
destination.y = dpWorld::GetNavMesh()->GetHeightAtPoint(destination);
}
if (Vector3::DistanceSquared(destination, m_MovementAI->GetParent()->GetPosition()) < 2 * 2) {
@@ -756,7 +757,7 @@ void PetComponent::Wander() {
return;
}
m_MovementAI->SetMaxSpeed(m_PetInfo.sprintSpeed); //info.wanderSpeed);
m_MovementAI->SetMaxSpeed(m_PetInfo.sprintSpeed);
m_MovementAI->SetDestination(destination);
@@ -1152,6 +1153,7 @@ void PetComponent::AddDrainImaginationTimer(Item* item, bool fromTaming) {
if (!fromTaming) playerDestroyableComponent->Imagine(-1);
// Set this to a variable so when this is called back from the player the timer doesn't fire off.
m_Parent->AddCallbackTimer(m_PetInfo.imaginationDrainRate, [playerDestroyableComponent, this, item]() {
m_Parent->AddCallbackTimer(m_PetInfo.imaginationDrainRate, [playerDestroyableComponent, this, item]() {
if (!playerDestroyableComponent) {
LOG("No petComponent and/or no playerDestroyableComponent");
@@ -1209,7 +1211,7 @@ void PetComponent::Release() {
item->SetCount(0, false, false);
}
void PetComponent::Command(const NiPoint3& position, const LWOOBJID& source, int32_t commandType, int32_t typeId, bool overrideObey) {
void PetComponent::Command(const NiPoint3& position, const LWOOBJID source, const int32_t commandType, const int32_t typeId, const bool overrideObey) {
auto* owner = GetOwner();
if (!owner) return;

View File

@@ -5,6 +5,7 @@
#include "MovementAIComponent.h"
#include "Component.h"
#include "Preconditions.h"
#include "ePetAbilityType.h"
#include "eReplicaComponentType.h"
#include "ePetAbilityType.h"
#include "CDPetComponentTable.h"
@@ -64,9 +65,10 @@ enum PetEmote : int32_t {
* Represents an entity that is a pet. This pet can be tamed and consequently follows the tamer around, allowing it
* to dig for treasure and activate pet bouncers.
*/
class PetComponent : public Component {
class PetComponent final : public Component
{
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PET;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::PET;
/**
* PetComponent constructor
@@ -252,7 +254,7 @@ public:
* @param typeId extra information about the command, e.g. the emote to play
* @param overrideObey unused
*/
void Command(const NiPoint3& position, const LWOOBJID& source, int32_t commandType, int32_t typeId, bool overrideObey);
void Command(const NiPoint3& position, const LWOOBJID source, const int32_t commandType, const int32_t typeId, const bool overrideObey);
/**
* Returns the ID of the owner of this pet (if any)
@@ -583,8 +585,9 @@ private:
/**
* Pet information loaded from the CDClientDatabase
* TODO: Switch to a reference when safe to do so
*/
CDPetComponent& m_PetInfo;
CDPetComponent m_PetInfo;
};
#endif // PETCOMPONENT_H
#endif // !PETCOMPONENT_H

View File

@@ -143,10 +143,10 @@ PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent) : PhysicsCompon
*/
if (!m_HasCreatedPhysics) {
CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
CDComponentsRegistryTable* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
auto componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), eReplicaComponentType::PHANTOM_PHYSICS);
CDPhysicsComponentTable* physComp = CDClientManager::Instance().GetTable<CDPhysicsComponentTable>();
CDPhysicsComponentTable* physComp = CDClientManager::GetTable<CDPhysicsComponentTable>();
if (physComp == nullptr) return;
@@ -156,89 +156,48 @@ PhantomPhysicsComponent::PhantomPhysicsComponent(Entity* parent) : PhysicsCompon
//temp test
if (info->physicsAsset == "miscellaneous\\misc_phys_10x1x5.hkx") {
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 10.0f, 5.0f, 1.0f);
m_dpEntity->SetScale(m_Scale);
m_dpEntity->SetRotation(m_Rotation);
m_dpEntity->SetPosition(m_Position);
dpWorld::Instance().AddEntity(m_dpEntity);
} else if (info->physicsAsset == "miscellaneous\\misc_phys_640x640.hkx") {
// Move this down by 13.521004 units so it is still effectively at the same height as before
m_Position = m_Position - NiPoint3::UNIT_Y * 13.521004f;
// TODO Fix physics simulation to do simulation at high velocities due to bullet through paper problem...
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 1638.4f, 13.521004f * 2.0f, 1638.4f);
m_dpEntity->SetScale(m_Scale);
m_dpEntity->SetRotation(m_Rotation);
m_dpEntity->SetPosition(m_Position);
dpWorld::Instance().AddEntity(m_dpEntity);
// Move this down by 13.521004 units so it is still effectively at the same height as before
m_Position = m_Position - NiPoint3Constant::UNIT_Y * 13.521004f;
} else if (info->physicsAsset == "env\\trigger_wall_tall.hkx") {
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 10.0f, 25.0f, 1.0f);
m_dpEntity->SetScale(m_Scale);
m_dpEntity->SetRotation(m_Rotation);
m_dpEntity->SetPosition(m_Position);
dpWorld::Instance().AddEntity(m_dpEntity);
} else if (info->physicsAsset == "env\\env_gen_placeholderphysics.hkx") {
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 20.0f, 20.0f, 20.0f);
m_dpEntity->SetScale(m_Scale);
m_dpEntity->SetRotation(m_Rotation);
m_dpEntity->SetPosition(m_Position);
dpWorld::Instance().AddEntity(m_dpEntity);
} else if (info->physicsAsset == "env\\POI_trigger_wall.hkx") {
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 1.0f, 12.5f, 20.0f); // Not sure what the real size is
m_dpEntity->SetScale(m_Scale);
m_dpEntity->SetRotation(m_Rotation);
m_dpEntity->SetPosition(m_Position);
dpWorld::Instance().AddEntity(m_dpEntity);
} else if (info->physicsAsset == "env\\NG_NinjaGo\\env_ng_gen_gate_chamber_puzzle_ceiling_tile_falling_phantom.hkx") {
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 18.0f, 5.0f, 15.0f);
m_dpEntity->SetScale(m_Scale);
m_dpEntity->SetRotation(m_Rotation);
m_dpEntity->SetPosition(m_Position + m_Rotation.GetForwardVector() * 7.5f);
dpWorld::Instance().AddEntity(m_dpEntity);
m_Position += m_Rotation.GetForwardVector() * 7.5f;
} else if (info->physicsAsset == "env\\NG_NinjaGo\\ng_flamejet_brick_phantom.HKX") {
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 1.0f, 1.0f, 12.0f);
m_dpEntity->SetScale(m_Scale);
m_dpEntity->SetRotation(m_Rotation);
m_dpEntity->SetPosition(m_Position + m_Rotation.GetForwardVector() * 6.0f);
dpWorld::Instance().AddEntity(m_dpEntity);
m_Position += m_Rotation.GetForwardVector() * 6.0f;
} else if (info->physicsAsset == "env\\Ring_Trigger.hkx") {
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 6.0f, 6.0f, 6.0f);
m_dpEntity->SetScale(m_Scale);
m_dpEntity->SetRotation(m_Rotation);
m_dpEntity->SetPosition(m_Position);
dpWorld::Instance().AddEntity(m_dpEntity);
} else if (info->physicsAsset == "env\\vfx_propertyImaginationBall.hkx") {
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 4.5f);
m_dpEntity->SetScale(m_Scale);
m_dpEntity->SetRotation(m_Rotation);
m_dpEntity->SetPosition(m_Position);
dpWorld::Instance().AddEntity(m_dpEntity);
} else if (info->physicsAsset == "env\\env_won_fv_gas-blocking-volume.hkx") {
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 390.496826f, 111.467964f, 600.821534f, true);
m_dpEntity->SetScale(m_Scale);
m_dpEntity->SetRotation(m_Rotation);
m_Position.y -= (111.467964f * m_Scale) / 2;
m_dpEntity->SetPosition(m_Position);
dpWorld::Instance().AddEntity(m_dpEntity);
} else {
//LOG("This one is supposed to have %s", info->physicsAsset.c_str());
// LOG_DEBUG("This one is supposed to have %s", info->physicsAsset.c_str());
//add fallback cube:
m_dpEntity = new dpEntity(m_Parent->GetObjectID(), 2.0f, 2.0f, 2.0f);
m_dpEntity->SetScale(m_Scale);
m_dpEntity->SetRotation(m_Rotation);
m_dpEntity->SetPosition(m_Position);
dpWorld::Instance().AddEntity(m_dpEntity);
}
m_dpEntity->SetScale(m_Scale);
m_dpEntity->SetRotation(m_Rotation);
m_dpEntity->SetPosition(m_Position);
dpWorld::AddEntity(m_dpEntity);
}
}
PhantomPhysicsComponent::~PhantomPhysicsComponent() {
if (m_dpEntity) {
dpWorld::Instance().RemoveEntity(m_dpEntity);
dpWorld::RemoveEntity(m_dpEntity);
}
}
@@ -260,10 +219,10 @@ void PhantomPhysicsComponent::CreatePhysics() {
y = m_Parent->GetVar<float>(u"primitiveModelValueY");
z = m_Parent->GetVar<float>(u"primitiveModelValueZ");
} else {
CDComponentsRegistryTable* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
CDComponentsRegistryTable* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
auto componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), eReplicaComponentType::PHANTOM_PHYSICS);
CDPhysicsComponentTable* physComp = CDClientManager::Instance().GetTable<CDPhysicsComponentTable>();
CDPhysicsComponentTable* physComp = CDClientManager::GetTable<CDPhysicsComponentTable>();
if (physComp == nullptr) return;
@@ -300,7 +259,7 @@ void PhantomPhysicsComponent::CreatePhysics() {
m_dpEntity->SetPosition({ m_Position.x, m_Position.y - (height / 2), m_Position.z });
dpWorld::Instance().AddEntity(m_dpEntity);
dpWorld::AddEntity(m_dpEntity);
m_HasCreatedPhysics = true;
}

View File

@@ -25,9 +25,9 @@ enum class ePhysicsEffectType : uint32_t ;
* trigger gameplay events, for example the bus in Avant Gardens that moves around when the player touches its physics
* body. Optionally this object can also have effects, like the fans in AG.
*/
class PhantomPhysicsComponent : public PhysicsComponent {
class PhantomPhysicsComponent final : public PhysicsComponent {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PHANTOM_PHYSICS;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::PHANTOM_PHYSICS;
PhantomPhysicsComponent(Entity* parent);
~PhantomPhysicsComponent() override;

View File

@@ -1,8 +1,8 @@
#include "PhysicsComponent.h"
PhysicsComponent::PhysicsComponent(Entity* parent) : Component(parent) {
m_Position = NiPoint3::ZERO;
m_Rotation = NiQuaternion::IDENTITY;
m_Position = NiPoint3Constant::ZERO;
m_Rotation = NiQuaternionConstant::IDENTITY;
m_DirtyPosition = false;
}

View File

@@ -8,9 +8,9 @@
* Component that handles player forced movement
*
*/
class PlayerForcedMovementComponent : public Component {
class PlayerForcedMovementComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PLAYER_FORCED_MOVEMENT;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::PLAYER_FORCED_MOVEMENT;
/**
* Constructor for this component

View File

@@ -12,9 +12,9 @@
* Represents an entity that can be controlled by some other entity, generally used by cars to indicate that some
* player is controlling it.
*/
class PossessableComponent : public Component {
class PossessableComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::POSSESSABLE;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::POSSESSABLE;
PossessableComponent(Entity* parentEntity, uint32_t componentId);

View File

@@ -16,9 +16,9 @@ enum class ePossessionType : uint8_t {
/**
* Represents an entity that can posess other entities. Generally used by players to drive a car.
*/
class PossessorComponent : public Component {
class PossessorComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::POSSESSOR;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::POSSESSOR;
PossessorComponent(Entity* parent);
~PossessorComponent() override;

View File

@@ -1,11 +0,0 @@
#include "PropertyComponent.h"
#include "GameMessages.h"
#include "dZoneManager.h"
PropertyComponent::PropertyComponent(Entity* parent) : Component(parent) {
m_PropertyName = parent->GetVar<std::string>(u"propertyName");
m_PropertyState = new PropertyState();
}
PropertyComponent::~PropertyComponent() = default;

View File

@@ -1,34 +1,22 @@
/*
* Darkflame Universe
* Copyright 2018
* Copyright 2024
*/
#ifndef PROPERTYCOMPONENT_H
#define PROPERTYCOMPONENT_H
#include "BitStream.h"
#include "Entity.h"
#include "Component.h"
#include "eReplicaComponentType.h"
struct PropertyState {
LWOOBJID ownerID;
LWOOBJID propertyID;
bool rented;
};
/**
* This component is unused and has no functionality
*/
class PropertyComponent : public Component {
class PropertyComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY;
explicit PropertyComponent(Entity* parentEntity);
~PropertyComponent() override;
[[nodiscard]] PropertyState* GetPropertyState() const { return m_PropertyState; };
private:
PropertyState* m_PropertyState;
std::string m_PropertyName;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY;
explicit PropertyComponent(Entity* const parentEntity) noexcept : Component{ parentEntity } {}
};
#endif // PROPERTYCOMPONENT_H
#endif // !PROPERTYCOMPONENT_H

View File

@@ -18,7 +18,7 @@
PropertyEntranceComponent::PropertyEntranceComponent(Entity* parent, uint32_t componentID) : Component(parent) {
this->propertyQueries = {};
auto table = CDClientManager::Instance().GetTable<CDPropertyEntranceComponentTable>();
auto table = CDClientManager::GetTable<CDPropertyEntranceComponentTable>();
const auto& entry = table->GetByID(componentID);
this->m_MapID = entry.mapID;

View File

@@ -11,10 +11,10 @@
/**
* Represents the launch pad that's used to select and browse properties
*/
class PropertyEntranceComponent : public Component {
class PropertyEntranceComponent final : public Component {
public:
explicit PropertyEntranceComponent(Entity* parent, uint32_t componentID);
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_ENTRANCE;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_ENTRANCE;
/**
* Handles an OnUse request for some other entity, rendering the property browse menu

View File

@@ -14,12 +14,13 @@
#include "Item.h"
#include "Database.h"
#include "ObjectIDManager.h"
#include "Player.h"
#include "RocketLaunchpadControlComponent.h"
#include "PropertyEntranceComponent.h"
#include "InventoryComponent.h"
#include "eMissionTaskType.h"
#include "eObjectBits.h"
#include "CharacterComponent.h"
#include "PlayerManager.h"
#include <vector>
#include "CppScripts.h"
@@ -175,8 +176,6 @@ bool PropertyManagementComponent::Claim(const LWOOBJID playerId) {
auto* entity = Game::entityManager->GetEntity(playerId);
auto* user = entity->GetParentUser();
auto character = entity->GetCharacter();
if (!character) return false;
@@ -226,7 +225,7 @@ void PropertyManagementComponent::OnStartBuilding() {
if (ownerEntity == nullptr) return;
const auto players = Player::GetAllPlayers();
const auto players = PlayerManager::GetAllPlayers();
LWOMAPID zoneId = 1100;
@@ -247,7 +246,8 @@ void PropertyManagementComponent::OnStartBuilding() {
for (auto* player : players) {
if (player == ownerEntity) continue;
player->SendToZone(zoneId);
auto* characterComponent = player->GetComponent<CharacterComponent>();
if (characterComponent) characterComponent->SendToZone(zoneId);
}
auto inventoryComponent = ownerEntity->GetComponent<InventoryComponent>();
@@ -294,7 +294,7 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N
const auto modelLOT = item->GetLot();
if (rotation != NiQuaternion::IDENTITY) {
if (rotation != NiQuaternionConstant::IDENTITY) {
rotation = { rotation.w, rotation.z, rotation.y, rotation.x };
}
@@ -478,7 +478,7 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet
GameMessages::SendGetModelsOnProperty(entity->GetObjectID(), GetModels(), UNASSIGNED_SYSTEM_ADDRESS);
GameMessages::SendPlaceModelResponse(entity->GetObjectID(), entity->GetSystemAddress(), NiPoint3::ZERO, LWOOBJID_EMPTY, 16, NiQuaternion::IDENTITY);
GameMessages::SendPlaceModelResponse(entity->GetObjectID(), entity->GetSystemAddress(), NiPoint3Constant::ZERO, LWOOBJID_EMPTY, 16, NiQuaternionConstant::IDENTITY);
if (spawner != nullptr) {
Game::zoneManager->RemoveSpawner(spawner->m_Info.spawnerID);
@@ -519,7 +519,7 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet
{
item->SetCount(item->GetCount() - 1);
LOG("BODGE TIME, YES IT GOES HERE");
LOG("DLU currently does not support breaking apart brick by brick models.");
break;
}
@@ -531,7 +531,7 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet
GameMessages::SendGetModelsOnProperty(entity->GetObjectID(), GetModels(), UNASSIGNED_SYSTEM_ADDRESS);
GameMessages::SendPlaceModelResponse(entity->GetObjectID(), entity->GetSystemAddress(), NiPoint3::ZERO, LWOOBJID_EMPTY, 16, NiQuaternion::IDENTITY);
GameMessages::SendPlaceModelResponse(entity->GetObjectID(), entity->GetSystemAddress(), NiPoint3Constant::ZERO, LWOOBJID_EMPTY, 16, NiQuaternionConstant::IDENTITY);
if (spawner != nullptr) {
Game::zoneManager->RemoveSpawner(spawner->m_Info.spawnerID);

View File

@@ -8,8 +8,7 @@
/**
* Information regarding which players may visit this property
*/
enum class PropertyPrivacyOption
{
enum class PropertyPrivacyOption {
/**
* Default, only you can visit your property
*/
@@ -29,10 +28,9 @@ enum class PropertyPrivacyOption
/**
* Main component that handles interactions with a property, generally the plaques you see on properties.
*/
class PropertyManagementComponent : public Component
{
class PropertyManagementComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_MANAGEMENT;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_MANAGEMENT;
PropertyManagementComponent(Entity* parent);
static PropertyManagementComponent* Instance();

View File

@@ -7,10 +7,9 @@
/**
* The property guard that stands on a property before it's claimed, allows entities to attempt claiming this property.
*/
class PropertyVendorComponent : public Component
{
class PropertyVendorComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_VENDOR;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::PROPERTY_VENDOR;
explicit PropertyVendorComponent(Entity* parent);
/**

View File

@@ -18,7 +18,7 @@ ProximityMonitorComponent::~ProximityMonitorComponent() {
for (const auto& en : m_ProximitiesData) {
if (!en.second) continue;
dpWorld::Instance().RemoveEntity(en.second);
dpWorld::RemoveEntity(en.second);
}
m_ProximitiesData.clear();
@@ -28,12 +28,12 @@ void ProximityMonitorComponent::SetProximityRadius(float proxRadius, const std::
dpEntity* en = new dpEntity(m_Parent->GetObjectID(), proxRadius);
en->SetPosition(m_Parent->GetPosition());
dpWorld::Instance().AddEntity(en);
dpWorld::AddEntity(en);
m_ProximitiesData.insert(std::make_pair(name, en));
}
void ProximityMonitorComponent::SetProximityRadius(dpEntity* entity, const std::string& name) {
dpWorld::Instance().AddEntity(entity);
dpWorld::AddEntity(entity);
entity->SetPosition(m_Parent->GetPosition());
m_ProximitiesData.insert(std::make_pair(name, entity));
}

View File

@@ -17,9 +17,9 @@
* Utility component for detecting how close entities are to named proximities for this entity. Allows you to store
* proximity checks for multiple ojects.
*/
class ProximityMonitorComponent : public Component {
class ProximityMonitorComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::PROXIMITY_MONITOR;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::PROXIMITY_MONITOR;
ProximityMonitorComponent(Entity* parentEntity, int smallRadius = -1, int largeRadius = -1);
~ProximityMonitorComponent() override;

View File

@@ -14,7 +14,6 @@
#include "eGameActivity.h"
#include "dServer.h"
#include "PacketUtils.h"
#include "Spawner.h"
#include "MovingPlatformComponent.h"
#include "Preconditions.h"
@@ -24,7 +23,7 @@
#include "CppScripts.h"
QuickBuildComponent::QuickBuildComponent(Entity* entity) : Component(entity) {
QuickBuildComponent::QuickBuildComponent(Entity* const entity) : Component{ entity } {
std::u16string checkPreconditions = entity->GetVar<std::u16string>(u"CheckPrecondition");
if (!checkPreconditions.empty()) {
@@ -34,10 +33,9 @@ QuickBuildComponent::QuickBuildComponent(Entity* entity) : Component(entity) {
// Should a setting that has the build activator position exist, fetch that setting here and parse it for position.
// It is assumed that the user who sets this setting uses the correct character delimiter (character 31 or in hex 0x1F)
auto positionAsVector = GeneralUtils::SplitString(m_Parent->GetVarAsString(u"rebuild_activators"), 0x1F);
if (positionAsVector.size() == 3 &&
GeneralUtils::TryParse(positionAsVector[0], m_ActivatorPosition.x) &&
GeneralUtils::TryParse(positionAsVector[1], m_ActivatorPosition.y) &&
GeneralUtils::TryParse(positionAsVector[2], m_ActivatorPosition.z)) {
const auto activatorPositionValid = GeneralUtils::TryParse<NiPoint3>(positionAsVector);
if (positionAsVector.size() == 3 && activatorPositionValid) {
m_ActivatorPosition = activatorPositionValid.value();
} else {
LOG("Failed to find activator position for lot %i. Defaulting to parents position.", m_Parent->GetLOT());
m_ActivatorPosition = m_Parent->GetPosition();
@@ -254,13 +252,13 @@ void QuickBuildComponent::OnUse(Entity* originator) {
}
void QuickBuildComponent::SpawnActivator() {
if (!m_SelfActivator || m_ActivatorPosition != NiPoint3::ZERO) {
if (!m_SelfActivator || m_ActivatorPosition != NiPoint3Constant::ZERO) {
if (!m_Activator) {
EntityInfo info;
info.lot = 6604;
info.spawnerID = m_Parent->GetObjectID();
info.pos = m_ActivatorPosition == NiPoint3::ZERO ? m_Parent->GetPosition() : m_ActivatorPosition;
info.pos = m_ActivatorPosition == NiPoint3Constant::ZERO ? m_Parent->GetPosition() : m_ActivatorPosition;
m_Activator = Game::entityManager->CreateEntity(info, nullptr, m_Parent);
if (m_Activator) {
@@ -285,73 +283,73 @@ void QuickBuildComponent::DespawnActivator() {
}
}
Entity* QuickBuildComponent::GetActivator() {
Entity* QuickBuildComponent::GetActivator() const {
return Game::entityManager->GetEntity(m_ActivatorId);
}
NiPoint3 QuickBuildComponent::GetActivatorPosition() {
NiPoint3 QuickBuildComponent::GetActivatorPosition() const noexcept {
return m_ActivatorPosition;
}
float QuickBuildComponent::GetResetTime() {
float QuickBuildComponent::GetResetTime() const noexcept {
return m_ResetTime;
}
float QuickBuildComponent::GetCompleteTime() {
float QuickBuildComponent::GetCompleteTime() const noexcept {
return m_CompleteTime;
}
int QuickBuildComponent::GetTakeImagination() {
int32_t QuickBuildComponent::GetTakeImagination() const noexcept {
return m_TakeImagination;
}
bool QuickBuildComponent::GetInterruptible() {
bool QuickBuildComponent::GetInterruptible() const noexcept {
return m_Interruptible;
}
bool QuickBuildComponent::GetSelfActivator() {
bool QuickBuildComponent::GetSelfActivator() const noexcept {
return m_SelfActivator;
}
std::vector<int> QuickBuildComponent::GetCustomModules() {
std::vector<int32_t> QuickBuildComponent::GetCustomModules() const noexcept {
return m_CustomModules;
}
int QuickBuildComponent::GetActivityId() {
int32_t QuickBuildComponent::GetActivityId() const noexcept {
return m_ActivityId;
}
int QuickBuildComponent::GetPostImaginationCost() {
int32_t QuickBuildComponent::GetPostImaginationCost() const noexcept {
return m_PostImaginationCost;
}
float QuickBuildComponent::GetTimeBeforeSmash() {
float QuickBuildComponent::GetTimeBeforeSmash() const noexcept {
return m_TimeBeforeSmash;
}
eQuickBuildState QuickBuildComponent::GetState() {
eQuickBuildState QuickBuildComponent::GetState() const noexcept {
return m_State;
}
Entity* QuickBuildComponent::GetBuilder() const {
auto* builder = Game::entityManager->GetEntity(m_Builder);
auto* const builder = Game::entityManager->GetEntity(m_Builder);
return builder;
}
bool QuickBuildComponent::GetRepositionPlayer() const {
bool QuickBuildComponent::GetRepositionPlayer() const noexcept {
return m_RepositionPlayer;
}
void QuickBuildComponent::SetActivatorPosition(NiPoint3 value) {
void QuickBuildComponent::SetActivatorPosition(const NiPoint3& value) noexcept {
m_ActivatorPosition = value;
}
void QuickBuildComponent::SetResetTime(float value) {
void QuickBuildComponent::SetResetTime(const float value) noexcept {
m_ResetTime = value;
}
void QuickBuildComponent::SetCompleteTime(float value) {
void QuickBuildComponent::SetCompleteTime(const float value) noexcept {
if (value < 0) {
m_CompleteTime = 4.5f;
} else {
@@ -359,31 +357,31 @@ void QuickBuildComponent::SetCompleteTime(float value) {
}
}
void QuickBuildComponent::SetTakeImagination(int value) {
void QuickBuildComponent::SetTakeImagination(const int32_t value) noexcept {
m_TakeImagination = value;
}
void QuickBuildComponent::SetInterruptible(bool value) {
void QuickBuildComponent::SetInterruptible(const bool value) noexcept {
m_Interruptible = value;
}
void QuickBuildComponent::SetSelfActivator(bool value) {
void QuickBuildComponent::SetSelfActivator(const bool value) noexcept {
m_SelfActivator = value;
}
void QuickBuildComponent::SetCustomModules(std::vector<int> value) {
void QuickBuildComponent::SetCustomModules(const std::vector<int32_t>& value) noexcept {
m_CustomModules = value;
}
void QuickBuildComponent::SetActivityId(int value) {
void QuickBuildComponent::SetActivityId(const int32_t value) noexcept {
m_ActivityId = value;
}
void QuickBuildComponent::SetPostImaginationCost(int value) {
void QuickBuildComponent::SetPostImaginationCost(const int32_t value) noexcept {
m_PostImaginationCost = value;
}
void QuickBuildComponent::SetTimeBeforeSmash(float value) {
void QuickBuildComponent::SetTimeBeforeSmash(const float value) noexcept {
if (value < 0) {
m_TimeBeforeSmash = 10.0f;
} else {
@@ -391,11 +389,11 @@ void QuickBuildComponent::SetTimeBeforeSmash(float value) {
}
}
void QuickBuildComponent::SetRepositionPlayer(bool value) {
void QuickBuildComponent::SetRepositionPlayer(const bool value) noexcept {
m_RepositionPlayer = value;
}
void QuickBuildComponent::StartQuickBuild(Entity* user) {
void QuickBuildComponent::StartQuickBuild(Entity* const user) {
if (m_State == eQuickBuildState::OPEN || m_State == eQuickBuildState::COMPLETED || m_State == eQuickBuildState::INCOMPLETE) {
m_Builder = user->GetObjectID();
@@ -428,10 +426,8 @@ void QuickBuildComponent::StartQuickBuild(Entity* user) {
}
}
void QuickBuildComponent::CompleteQuickBuild(Entity* user) {
if (user == nullptr) {
return;
}
void QuickBuildComponent::CompleteQuickBuild(Entity* const user) {
if (!user) return;
auto* characterComponent = user->GetComponent<CharacterComponent>();
if (characterComponent != nullptr) {
@@ -520,7 +516,7 @@ void QuickBuildComponent::CompleteQuickBuild(Entity* user) {
RenderComponent::PlayAnimation(user, u"rebuild-celebrate", 1.09f);
}
void QuickBuildComponent::ResetQuickBuild(bool failed) {
void QuickBuildComponent::ResetQuickBuild(const bool failed) {
Entity* builder = GetBuilder();
if (m_State == eQuickBuildState::BUILDING && builder) {
@@ -555,7 +551,7 @@ void QuickBuildComponent::ResetQuickBuild(bool failed) {
}
}
void QuickBuildComponent::CancelQuickBuild(Entity* entity, eQuickBuildFailReason failReason, bool skipChecks) {
void QuickBuildComponent::CancelQuickBuild(Entity* const entity, const eQuickBuildFailReason failReason, const bool skipChecks) {
if (m_State != eQuickBuildState::COMPLETED || skipChecks) {
m_Builder = LWOOBJID_EMPTY;
@@ -583,9 +579,7 @@ void QuickBuildComponent::CancelQuickBuild(Entity* entity, eQuickBuildFailReason
Game::entityManager->SerializeEntity(m_Parent);
}
if (entity == nullptr) {
return;
}
if (!entity) return;
CharacterComponent* characterComponent = entity->GetComponent<CharacterComponent>();
if (characterComponent) {

View File

@@ -20,11 +20,11 @@ enum class eQuickBuildFailReason : uint32_t;
* consists of an activator that shows a popup and then the actual entity that the bricks are built into. Note
* that quick builds are also scripted activities so this shared some logic with the ScriptedActivityComponent.
*/
class QuickBuildComponent : public Component {
class QuickBuildComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::QUICK_BUILD;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::QUICK_BUILD;
QuickBuildComponent(Entity* entity);
QuickBuildComponent(Entity* const entity);
~QuickBuildComponent() override;
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
@@ -50,148 +50,148 @@ public:
* Returns the entity that acts as the activator for this quickbuild
* @return the entity that acts as the activator for this quickbuild
*/
Entity* GetActivator();
[[nodiscard]] Entity* GetActivator() const;
/**
* Returns the spawn position of the activator for this quickbuild, if any
* @return the spawn position of the activator for this quickbuild, if any
*/
NiPoint3 GetActivatorPosition();
[[nodiscard]] NiPoint3 GetActivatorPosition() const noexcept;
/**
* Sets the spawn position for the activator of this quickbuild
* @param value the spawn position to set for the activator
*/
void SetActivatorPosition(NiPoint3 value);
void SetActivatorPosition(const NiPoint3& value) noexcept;
/**
* Returns the time it takes for the quickbuild to reset after being built
* @return the time it takes for the quickbuild to reset after being built
*/
float GetResetTime();
[[nodiscard]] float GetResetTime() const noexcept;
/**
* Sets the time it takes for the quickbuild to reset after being built
* @param value the reset time to set
*/
void SetResetTime(float value);
void SetResetTime(const float value) noexcept;
/**
* Returns the time it takes to complete the quickbuild
* @return the time it takes to complete the quickbuild
*/
float GetCompleteTime();
[[nodiscard]] float GetCompleteTime() const noexcept;
/**
* Sets the time it takes to complete the quickbuild
* @param value the completion time to set
*/
void SetCompleteTime(float value);
void SetCompleteTime(const float value) noexcept;
/**
* Returns the imagination that's taken when completing the quickbuild
* @return the imagination that's taken when completing the quickbuild
*/
int GetTakeImagination();
[[nodiscard]] int32_t GetTakeImagination() const noexcept;
/**
* Sets the imagination that's taken when completing the quickbuild
* @param value the imagination deduction to set
*/
void SetTakeImagination(int value);
void SetTakeImagination(const int32_t value) noexcept;
/**
* Returns if the quickbuild can be interrupted, currently unused
* @return if the quickbuild can be interrupted
*/
bool GetInterruptible();
[[nodiscard]] bool GetInterruptible() const noexcept;
/**
* Sets whether or not the quickbuild can be interrupted, currently unused
* @param value true if the quickbuild may be interrupted, false otherwise
*/
void SetInterruptible(bool value);
void SetInterruptible(const bool value) noexcept;
/**
* Returns whether or not this entity contains a built-in activator
* @return whether or not this entity contains a built-in activator
*/
bool GetSelfActivator();
[[nodiscard]] bool GetSelfActivator() const noexcept;
/**
* Sets whether or not this entity contains a built-in activator. If set to false this will spawn activators on
* each new quickbuild.
* @param value whether or not this entity contains a built-in activator
*/
void SetSelfActivator(bool value);
void SetSelfActivator(const bool value) noexcept;
/**
* Currently unused
*/
std::vector<int> GetCustomModules();
[[nodiscard]] std::vector<int32_t> GetCustomModules() const noexcept;
/**
* Currently unused
*/
void SetCustomModules(std::vector<int> value);
void SetCustomModules(const std::vector<int32_t>& value) noexcept;
/**
* Returns the activity ID for participating in this quickbuild
* @return the activity ID for participating in this quickbuild
*/
int GetActivityId();
[[nodiscard]] int32_t GetActivityId() const noexcept;
/**
* Sets the activity ID for participating in this quickbuild
* @param value the activity ID to set
*/
void SetActivityId(int value);
void SetActivityId(const int32_t value) noexcept;
/**
* Currently unused
*/
int GetPostImaginationCost();
[[nodiscard]] int32_t GetPostImaginationCost() const noexcept;
/**
* Currently unused
*/
void SetPostImaginationCost(int value);
void SetPostImaginationCost(const int32_t value) noexcept;
/**
* Returns the time it takes for an incomplete quickbuild to be smashed automatically
* @return the time it takes for an incomplete quickbuild to be smashed automatically
*/
float GetTimeBeforeSmash();
[[nodiscard]] float GetTimeBeforeSmash() const noexcept;
/**
* Sets the time it takes for an incomplete quickbuild to be smashed automatically
* @param value the time to set
*/
void SetTimeBeforeSmash(float value);
void SetTimeBeforeSmash(const float value) noexcept;
/**
* Returns the current quickbuild state
* @return the current quickbuild state
*/
eQuickBuildState GetState();
[[nodiscard]] eQuickBuildState GetState() const noexcept;
/**
* Returns the player that is currently building this quickbuild
* @return the player that is currently building this quickbuild
*/
Entity* GetBuilder() const;
[[nodiscard]] Entity* GetBuilder() const;
/**
* Returns whether or not the player is repositioned when initiating the quickbuild
* @return whether or not the player is repositioned when initiating the quickbuild
*/
bool GetRepositionPlayer() const;
[[nodiscard]] bool GetRepositionPlayer() const noexcept;
/**
* Sets whether or not the player is repositioned when initiating the quickbuild
* @param value whether or not the player is repositioned when initiating the quickbuild
*/
void SetRepositionPlayer(bool value);
void SetRepositionPlayer(const bool value) noexcept;
/**
* Adds a callback that is called when the quickbuild is completed
@@ -209,7 +209,7 @@ public:
* Resets the quickbuild
* @param failed whether or not the player failed to complete the quickbuild, triggers an extra animation
*/
void ResetQuickBuild(bool failed);
void ResetQuickBuild(const bool failed);
/**
* Cancels the quickbuild if it wasn't completed
@@ -217,7 +217,7 @@ public:
* @param failReason the reason the quickbuild was cancelled
* @param skipChecks whether or not to skip the check for the quickbuild not being completed
*/
void CancelQuickBuild(Entity* builder, eQuickBuildFailReason failReason, bool skipChecks = false);
void CancelQuickBuild(Entity* const builder, const eQuickBuildFailReason failReason, const bool skipChecks = false);
private:
/**
* Whether or not the quickbuild state has been changed since we last serialized it.
@@ -242,7 +242,7 @@ private:
/**
* The position that the quickbuild activator is spawned at
*/
NiPoint3 m_ActivatorPosition = NiPoint3::ZERO;
NiPoint3 m_ActivatorPosition = NiPoint3Constant::ZERO;
/**
* The entity that represents the quickbuild activator
@@ -287,7 +287,7 @@ private:
/**
* The imagination that's deducted when completing the quickbuild
*/
int m_TakeImagination = 0;
int32_t m_TakeImagination = 0;
/**
* Currently unused
@@ -302,17 +302,17 @@ private:
/**
* Currently unused
*/
std::vector<int> m_CustomModules{};
std::vector<int32_t> m_CustomModules{};
/**
* The activity ID that players partake in when doing this quickbuild
*/
int m_ActivityId = 0;
int32_t m_ActivityId = 0;
/**
* Currently unused
*/
int m_PostImaginationCost = 0;
int32_t m_PostImaginationCost = 0;
/**
* The time it takes for the quickbuild to reset when it's not completed yet
@@ -327,7 +327,7 @@ private:
/**
* The amount of imagination that was drained when building this quickbuild
*/
int m_DrainedImagination = 0;
int32_t m_DrainedImagination = 0;
/**
* Whether to reposition the player or not when building
@@ -337,7 +337,7 @@ private:
/**
* Currently unused
*/
float m_SoftTimer = 0;
int32_t m_SoftTimer = 0;
/**
* The ID of the entity that's currently building the quickbuild
@@ -353,13 +353,13 @@ private:
* Starts the quickbuild for a certain entity
* @param user the entity to start the quickbuild
*/
void StartQuickBuild(Entity* user);
void StartQuickBuild(Entity* const user);
/**
* Completes the quickbuild for an entity, dropping loot and despawning the activator
* @param user the entity that completed the quickbuild
*/
void CompleteQuickBuild(Entity* user);
void CompleteQuickBuild(Entity* const user);
};
#endif // QUICKBUILDCOMPONENT_H

View File

@@ -12,7 +12,6 @@
#include "Item.h"
#include "MissionComponent.h"
#include "ModuleAssemblyComponent.h"
#include "Player.h"
#include "PossessableComponent.h"
#include "PossessorComponent.h"
#include "eRacingTaskParam.h"
@@ -54,7 +53,7 @@ RacingControlComponent::RacingControlComponent(Entity* parent)
if (Game::zoneManager->CheckIfAccessibleZone((worldID / 10) * 10)) m_MainWorld = (worldID / 10) * 10;
m_ActivityID = 42;
CDActivitiesTable* activitiesTable = CDClientManager::Instance().GetTable<CDActivitiesTable>();
CDActivitiesTable* activitiesTable = CDClientManager::GetTable<CDActivitiesTable>();
std::vector<CDActivities> activities = activitiesTable->Query([=](CDActivities entry) {return (entry.instanceMapID == worldID); });
for (CDActivities activity : activities) m_ActivityID = activity.ActivityID;
}
@@ -71,10 +70,8 @@ void RacingControlComponent::OnPlayerLoaded(Entity* player) {
// If the race has already started, send the player back to the main world.
if (m_Loaded || !vehicle) {
auto* playerInstance = dynamic_cast<Player*>(player);
if (playerInstance) {
playerInstance->SendToZone(m_MainWorld);
}
auto* characterComponent = player->GetComponent<CharacterComponent>();
if (characterComponent) characterComponent->SendToZone(m_MainWorld);
return;
}
@@ -105,10 +102,11 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player,
if (item == nullptr) {
LOG("Failed to find item");
auto* playerInstance = dynamic_cast<Player*>(player);
if (playerInstance) {
auto* characterComponent = player->GetComponent<CharacterComponent>();
if (characterComponent) {
m_LoadedPlayers--;
playerInstance->SendToZone(m_MainWorld);
characterComponent->SendToZone(m_MainWorld);
}
return;
@@ -120,8 +118,8 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player,
GeneralUtils::UTF16ToWTF8(m_PathName));
auto spawnPointEntities = Game::entityManager->GetEntitiesByLOT(4843);
auto startPosition = NiPoint3::ZERO;
auto startRotation = NiQuaternion::IDENTITY;
auto startPosition = NiPoint3Constant::ZERO;
auto startRotation = NiQuaternionConstant::IDENTITY;
const std::string placementAsString = std::to_string(positionNumber);
for (auto entity : spawnPointEntities) {
if (!entity) continue;
@@ -427,9 +425,9 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, int32_t bu
m_Parent->GetObjectID(), 3, 0, LWOOBJID_EMPTY, u"",
player->GetObjectID(), UNASSIGNED_SYSTEM_ADDRESS);
auto* playerInstance = dynamic_cast<Player*>(player);
auto* characterComponent = player->GetComponent<CharacterComponent>();
playerInstance->SendToZone(m_MainWorld);
if (characterComponent) characterComponent->SendToZone(m_MainWorld);
vehicle->Kill();
}
@@ -561,9 +559,9 @@ void RacingControlComponent::Update(float deltaTime) {
continue;
}
auto* playerInstance = dynamic_cast<Player*>(playerEntity);
auto* characterComponent = playerEntity->GetComponent<CharacterComponent>();
playerInstance->SendToZone(m_MainWorld);
if (characterComponent) characterComponent->SendToZone(m_MainWorld);
}
m_LobbyPlayers.clear();
@@ -623,9 +621,9 @@ void RacingControlComponent::Update(float deltaTime) {
continue;
}
auto* playerInstance = dynamic_cast<Player*>(playerEntity);
auto* characterComponent = playerEntity->GetComponent<CharacterComponent>();
playerInstance->SendToZone(m_MainWorld);
if (characterComponent) characterComponent->SendToZone(m_MainWorld);
}
return;
@@ -819,7 +817,7 @@ void RacingControlComponent::Update(float deltaTime) {
// Some offset up to make they don't fall through the terrain on a
// respawn, seems to fix itself to the track anyhow
player.respawnPosition = position + NiPoint3::UNIT_Y * 5;
player.respawnPosition = position + NiPoint3Constant::UNIT_Y * 5;
player.respawnRotation = vehicle->GetRotation();
player.respawnIndex = respawnIndex;

View File

@@ -103,9 +103,9 @@ struct RacingPlayerInfo {
/**
* Component that's attached to a manager entity in each race zone that loads player vehicles, keep scores, etc.
*/
class RacingControlComponent : public Component {
class RacingControlComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::RACING_CONTROL;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::RACING_CONTROL;
RacingControlComponent(Entity* parentEntity);
~RacingControlComponent();

View File

@@ -8,7 +8,7 @@ class Entity;
class RacingSoundTriggerComponent : public SoundTriggerComponent {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::RACING_SOUND_TRIGGER;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::RACING_SOUND_TRIGGER;
RacingSoundTriggerComponent(Entity* parent) : SoundTriggerComponent(parent){};
};

View File

@@ -6,7 +6,7 @@
class RacingStatsComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::RACING_STATS;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::RACING_STATS;
RacingStatsComponent(Entity* parent) : Component(parent) {}
};

View File

@@ -13,7 +13,7 @@
RailActivatorComponent::RailActivatorComponent(Entity* parent, int32_t componentID) : Component(parent) {
m_ComponentID = componentID;
const auto tableData = CDClientManager::Instance().GetTable<CDRailActivatorComponentTable>()->GetEntryByID(componentID);;
const auto tableData = CDClientManager::GetTable<CDRailActivatorComponentTable>()->GetEntryByID(componentID);;
m_Path = parent->GetVar<std::u16string>(u"rail_path");
m_PathDirection = parent->GetVar<bool>(u"rail_path_direction");

View File

@@ -15,7 +15,7 @@ public:
explicit RailActivatorComponent(Entity* parent, int32_t componentID);
~RailActivatorComponent() override;
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::RAIL_ACTIVATOR;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::RAIL_ACTIVATOR;
/**
* Handles the OnUse event from some entity, initiates the rail movement

View File

@@ -1,11 +1,12 @@
#include "RenderComponent.h"
#include <algorithm>
#include <sstream>
#include <string>
#include <utility>
#include <iomanip>
#include "Entity.h"
#include "PacketUtils.h"
#include "CDClientManager.h"
#include "GameMessages.h"
@@ -15,8 +16,7 @@
std::unordered_map<int32_t, float> RenderComponent::m_DurationCache{};
RenderComponent::RenderComponent(Entity* parent, int32_t componentId): Component(parent) {
m_Effects = std::vector<Effect*>();
RenderComponent::RenderComponent(Entity* const parentEntity, const int32_t componentId) : Component{ parentEntity } {
m_LastAnimationName = "";
if (componentId == -1) return;
@@ -27,116 +27,69 @@ RenderComponent::RenderComponent(Entity* parent, int32_t componentId): Component
if (!result.eof()) {
auto animationGroupIDs = std::string(result.getStringField("animationGroupIDs", ""));
if (!animationGroupIDs.empty()) {
auto* animationsTable = CDClientManager::Instance().GetTable<CDAnimationsTable>();
auto* animationsTable = CDClientManager::GetTable<CDAnimationsTable>();
auto groupIdsSplit = GeneralUtils::SplitString(animationGroupIDs, ',');
for (auto& groupId : groupIdsSplit) {
int32_t groupIdInt;
if (!GeneralUtils::TryParse(groupId, groupIdInt)) {
const auto groupIdInt = GeneralUtils::TryParse<int32_t>(groupId);
if (!groupIdInt) {
LOG("bad animation group Id %s", groupId.c_str());
continue;
}
m_animationGroupIds.push_back(groupIdInt);
animationsTable->CacheAnimationGroup(groupIdInt);
m_animationGroupIds.push_back(groupIdInt.value());
animationsTable->CacheAnimationGroup(groupIdInt.value());
}
}
}
result.finalize();
}
RenderComponent::~RenderComponent() {
for (Effect* eff : m_Effects) {
if (eff) {
delete eff;
eff = nullptr;
}
}
m_Effects.clear();
}
void RenderComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
if (!bIsInitialUpdate) return;
outBitStream->Write<uint32_t>(m_Effects.size());
for (Effect* eff : m_Effects) {
// we still need to write 0 as the size for name if it is a nullptr
if (!eff) {
outBitStream->Write<uint8_t>(0);
continue;
}
outBitStream->Write<uint8_t>(eff->name.size());
for (auto& eff : m_Effects) {
outBitStream->Write<uint8_t>(eff.name.size());
// if there is no name, then we don't write anything else
if (eff->name.empty()) continue;
if (eff.name.empty()) continue;
for (const auto& value : eff->name) outBitStream->Write<uint8_t>(value);
for (const auto& value : eff.name) outBitStream->Write<uint8_t>(value);
outBitStream->Write(eff->effectID);
outBitStream->Write(eff.effectID);
outBitStream->Write<uint8_t>(eff->type.size());
for (const auto& value : eff->type) outBitStream->Write<uint16_t>(value);
outBitStream->Write<uint8_t>(eff.type.size());
for (const auto& value : eff.type) outBitStream->Write<uint16_t>(value);
outBitStream->Write<float_t>(eff->priority);
outBitStream->Write<int64_t>(eff->secondary);
outBitStream->Write<float_t>(eff.priority);
outBitStream->Write<int64_t>(eff.secondary);
}
}
Effect* RenderComponent::AddEffect(const int32_t effectId, const std::string& name, const std::u16string& type, const float priority) {
auto* eff = new Effect();
eff->effectID = effectId;
eff->name = name;
eff->type = type;
eff->priority = priority;
m_Effects.push_back(eff);
return eff;
Effect& RenderComponent::AddEffect(const int32_t effectId, const std::string& name, const std::u16string& type, const float priority) {
return m_Effects.emplace_back(effectId, name, type, priority);
}
void RenderComponent::RemoveEffect(const std::string& name) {
uint32_t index = -1;
if (m_Effects.empty()) return;
for (auto i = 0u; i < m_Effects.size(); ++i) {
auto* eff = m_Effects[i];
const auto effectToRemove = std::ranges::find_if(m_Effects, [&name](auto&& effect) { return effect.name == name; });
if (effectToRemove == m_Effects.end()) return; // Return early if effect is not present
if (eff->name == name) {
index = i;
delete eff;
break;
}
}
if (index == -1) {
return;
}
m_Effects.erase(m_Effects.begin() + index);
const auto lastEffect = m_Effects.rbegin();
*effectToRemove = std::move(*lastEffect); // Move-overwrite
m_Effects.pop_back();
}
void RenderComponent::Update(const float deltaTime) {
std::vector<Effect*> dead;
void RenderComponent::Update(const float deltaTime) {
for (auto& effect : m_Effects) {
if (effect.time == 0) continue; // Skip persistent effects
for (auto* effect : m_Effects) {
if (effect->time == 0) {
continue; // Skip persistent effects
}
const auto result = effect.time - deltaTime;
if (result <= 0) continue;
const auto result = effect->time - deltaTime;
if (result <= 0) {
dead.push_back(effect);
continue;
}
effect->time = result;
}
for (auto* effect : dead) {
// StopEffect(effect->name);
effect.time = result;
}
}
@@ -145,12 +98,12 @@ void RenderComponent::PlayEffect(const int32_t effectId, const std::u16string& e
GameMessages::SendPlayFXEffect(m_Parent, effectId, effectType, name, secondary, priority, scale, serialize);
auto* effect = AddEffect(effectId, name, effectType, priority);
auto& effect = AddEffect(effectId, name, effectType, priority);
const auto& pair = m_DurationCache.find(effectId);
if (pair != m_DurationCache.end()) {
effect->time = pair->second;
effect.time = pair->second;
return;
}
@@ -169,16 +122,16 @@ void RenderComponent::PlayEffect(const int32_t effectId, const std::u16string& e
m_DurationCache[effectId] = 0;
effect->time = 0; // Persistent effect
effect.time = 0; // Persistent effect
return;
}
effect->time = static_cast<float>(result.getFloatField(0));
effect.time = static_cast<float>(result.getFloatField(0));
result.finalize();
m_DurationCache[effectId] = effect->time;
m_DurationCache[effectId] = effect.time;
}
void RenderComponent::StopEffect(const std::string& name, const bool killImmediate) {
@@ -187,11 +140,6 @@ void RenderComponent::StopEffect(const std::string& name, const bool killImmedia
RemoveEffect(name);
}
std::vector<Effect*>& RenderComponent::GetEffects() {
return m_Effects;
}
float RenderComponent::PlayAnimation(Entity* self, const std::u16string& animation, float priority, float scale) {
if (!self) return 0.0f;
return RenderComponent::PlayAnimation(self, GeneralUtils::UTF16ToWTF8(animation), priority, scale);
@@ -219,13 +167,12 @@ float RenderComponent::DoAnimation(Entity* self, const std::string& animation, b
auto* renderComponent = self->GetComponent<RenderComponent>();
if (!renderComponent) return returnlength;
auto* animationsTable = CDClientManager::Instance().GetTable<CDAnimationsTable>();
auto* animationsTable = CDClientManager::GetTable<CDAnimationsTable>();
for (auto& groupId : renderComponent->m_animationGroupIds) {
auto animationGroup = animationsTable->GetAnimation(animation, renderComponent->GetLastAnimationName(), groupId);
if (animationGroup.FoundData()) {
auto data = animationGroup.Data();
renderComponent->SetLastAnimationName(data.animation_name);
returnlength = data.animation_length;
if (animationGroup) {
renderComponent->SetLastAnimationName(animationGroup->animation_name);
returnlength = animationGroup->animation_length;
}
}
if (sendAnimation) GameMessages::SendPlayAnimation(self, GeneralUtils::ASCIIToUTF16(animation), priority, scale);

View File

@@ -17,7 +17,12 @@ class Entity;
* here.
*/
struct Effect {
Effect() { priority = 1.0f; }
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 } {
}
/**
* The ID of the effect
@@ -54,12 +59,11 @@ struct Effect {
* Determines that a component should be visibly rendered into the world, most entities have this. This component
* also handles effects that play for entities.
*/
class RenderComponent : public Component {
class RenderComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::RENDER;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::RENDER;
RenderComponent(Entity* entity, int32_t componentId = -1);
~RenderComponent() override;
RenderComponent(Entity* const parentEntity, const int32_t componentId = -1);
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
void Update(float deltaTime) override;
@@ -72,7 +76,7 @@ public:
* @param priority the priority of the effect
* @return if successful, the effect that was created
*/
Effect* AddEffect(int32_t effectId, const std::string& name, const std::u16string& type, const float priority);
[[maybe_unused]] Effect& AddEffect(const int32_t effectId, const std::string& name, const std::u16string& type, const float priority);
/**
* Removes an effect for this entity
@@ -99,12 +103,6 @@ public:
*/
void StopEffect(const std::string& name, bool killImmediate = true);
/**
* Returns the list of currently active effects
* @return
*/
std::vector<Effect*>& GetEffects();
/**
* 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
@@ -125,10 +123,10 @@ public:
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);
static float GetAnimationTime(Entity* self, const std::string& animation);
static float GetAnimationTime(Entity* self, const std::u16string& animation);
[[nodiscard]] static float GetAnimationTime(Entity* self, const std::string& animation);
[[nodiscard]] static float GetAnimationTime(Entity* self, const std::u16string& animation);
const std::string& GetLastAnimationName() const { return m_LastAnimationName; };
[[nodiscard]] const std::string& GetLastAnimationName() const { return m_LastAnimationName; };
void SetLastAnimationName(const std::string& name) { m_LastAnimationName = name; };
private:
@@ -136,7 +134,7 @@ private:
/**
* List of currently active effects
*/
std::vector<Effect*> m_Effects;
std::vector<Effect> m_Effects;
std::vector<int32_t> m_animationGroupIds;

View File

@@ -19,7 +19,7 @@
*/
class RigidbodyPhantomPhysicsComponent : public PhysicsComponent {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::RIGID_BODY_PHANTOM_PHYSICS;
RigidbodyPhantomPhysicsComponent(Entity* parent);

View File

@@ -16,9 +16,9 @@ class PreconditionExpression;
/**
* Component that handles rocket launchpads that can be interacted with to travel to other worlds.
*/
class RocketLaunchpadControlComponent : public Component {
class RocketLaunchpadControlComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::ROCKET_LAUNCH;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::ROCKET_LAUNCH;
RocketLaunchpadControlComponent(Entity* parent, int rocketId);
~RocketLaunchpadControlComponent() override;

View File

@@ -6,9 +6,9 @@
class Entity;
class ScriptedActivityComponent : public ActivityComponent {
class ScriptedActivityComponent final : public ActivityComponent {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::SCRIPTED_ACTIVITY;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::SCRIPTED_ACTIVITY;
ScriptedActivityComponent(Entity* parent, int activityID) : ActivityComponent(parent, activityID){};
};

View File

@@ -71,9 +71,9 @@ struct StaticShootingGalleryParams {
* A very ancient component that was used to guide shooting galleries, it's still kind of used but a lot of logic is
* also in the related scripts.
*/
class ShootingGalleryComponent : public Component {
class ShootingGalleryComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::SHOOTING_GALLERY;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::SHOOTING_GALLERY;
explicit ShootingGalleryComponent(Entity* parent);
~ShootingGalleryComponent();

View File

@@ -28,7 +28,7 @@ enum class eClimbableType : int32_t {
*/
class SimplePhysicsComponent : public PhysicsComponent {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::SIMPLE_PHYSICS;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::SIMPLE_PHYSICS;
SimplePhysicsComponent(Entity* parent, uint32_t componentID);
~SimplePhysicsComponent() override;
@@ -87,12 +87,12 @@ private:
/**
* The current velocity of the entity
*/
NiPoint3 m_Velocity = NiPoint3::ZERO;
NiPoint3 m_Velocity = NiPoint3Constant::ZERO;
/**
* The current angular velocity of the entity
*/
NiPoint3 m_AngularVelocity = NiPoint3::ZERO;
NiPoint3 m_AngularVelocity = NiPoint3Constant::ZERO;
/**
* Whether or not the velocity has changed

View File

@@ -234,7 +234,7 @@ bool SkillComponent::CastSkill(const uint32_t skillId, LWOOBJID target, const LW
// if it's not in the cache look it up and cache it
if (pair == m_skillBehaviorCache.end()) {
auto skillTable = CDClientManager::Instance().GetTable<CDSkillBehaviorTable>();
auto skillTable = CDClientManager::GetTable<CDSkillBehaviorTable>();
behaviorId = skillTable->GetSkillByID(skillId).behaviorID;
m_skillBehaviorCache.insert_or_assign(skillId, behaviorId);
} else {

View File

@@ -1,6 +1,6 @@
/*
* Darkflame Universe
* Copyright 2018
* Copyright 2024
*/
#ifndef SKILLCOMPONENT_H
@@ -55,11 +55,11 @@ struct SkillExecutionResult {
*
* Skills are a built up by a tree of behaviors. See dGame/dBehaviors/ for a list of behaviors.
*
* This system is very conveluted and still has a lot of unknowns.
* This system is very convoluted and still has a lot of unknowns.
*/
class SkillComponent : public Component {
class SkillComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::SKILL;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::SKILL;
explicit SkillComponent(Entity* parent);
~SkillComponent() override;

View File

@@ -1,4 +1,5 @@
#pragma once
#include "dCommonVars.h"
#include "Entity.h"
#include "GUID.h"
@@ -43,7 +44,7 @@ struct GUIDResults{
void Serialize(RakNet::BitStream* outBitStream);
};
struct MixerProgram{
struct MixerProgram {
std::string name;
uint32_t result;
@@ -58,7 +59,7 @@ struct MixerProgram{
class SoundTriggerComponent : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::SOUND_TRIGGER;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::SOUND_TRIGGER;
explicit SoundTriggerComponent(Entity* parent);
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
void ActivateMusicCue(const std::string& name, float bordemTime = -1.0);
@@ -66,11 +67,11 @@ public:
private:
std::vector<MusicCue> m_MusicCues = {};
std::vector<MusicParameter> m_MusicParameters = {};
std::vector<GUIDResults> m_2DAmbientSounds = {};
std::vector<GUIDResults> m_3DAmbientSounds = {};
std::vector<MixerProgram> m_MixerPrograms = {};
std::vector<MusicCue> m_MusicCues;
std::vector<MusicParameter> m_MusicParameters;
std::vector<GUIDResults> m_2DAmbientSounds;
std::vector<GUIDResults> m_3DAmbientSounds;
std::vector<MixerProgram> m_MixerPrograms;
bool m_Dirty = false;
};

View File

@@ -14,9 +14,9 @@
/**
* A component for switches in game, including pet triggered switches.
*/
class SwitchComponent : public Component {
class SwitchComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::SWITCH;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::SWITCH;
SwitchComponent(Entity* parent);
~SwitchComponent() override;

View File

@@ -9,10 +9,10 @@
#include "ControllablePhysicsComponent.h"
#include "MissionComponent.h"
#include "PhantomPhysicsComponent.h"
#include "Player.h"
#include "QuickBuildComponent.h"
#include "SkillComponent.h"
#include "eEndBehavior.h"
#include "PlayerManager.h"
TriggerComponent::TriggerComponent(Entity* parent, const std::string triggerInfo): Component(parent) {
@@ -21,10 +21,8 @@ TriggerComponent::TriggerComponent(Entity* parent, const std::string triggerInfo
std::vector<std::string> tokens = GeneralUtils::SplitString(triggerInfo, ':');
uint32_t sceneID;
GeneralUtils::TryParse<uint32_t>(tokens.at(0), sceneID);
uint32_t triggerID;
GeneralUtils::TryParse<uint32_t>(tokens.at(1), triggerID);
const auto sceneID = GeneralUtils::TryParse<uint32_t>(tokens.at(0)).value_or(0);
const auto triggerID = GeneralUtils::TryParse<uint32_t>(tokens.at(1)).value_or(0);
m_Trigger = Game::zoneManager->GetZone()->GetTrigger(sceneID, triggerID);
@@ -175,7 +173,7 @@ std::vector<Entity*> TriggerComponent::GatherTargets(LUTriggers::Command* comman
}
} else if (command->target == "objGroup") entities = Game::entityManager->GetEntitiesInGroup(command->targetName);
else if (command->target == "allPlayers") {
for (auto* player : Player::GetAllPlayers()) {
for (auto* player : PlayerManager::GetAllPlayers()) {
entities.push_back(player);
}
} else if (command->target == "allNPCs") { /*UNUSED*/ }
@@ -190,9 +188,8 @@ void TriggerComponent::HandleFireEvent(Entity* targetEntity, std::string args) {
}
void TriggerComponent::HandleDestroyObject(Entity* targetEntity, std::string args){
uint32_t killType;
GeneralUtils::TryParse<uint32_t>(args, killType);
targetEntity->Smash(m_Parent->GetObjectID(), static_cast<eKillType>(killType));
const eKillType killType = GeneralUtils::TryParse<eKillType>(args).value_or(eKillType::VIOLENT);
targetEntity->Smash(m_Parent->GetObjectID(), killType);
}
void TriggerComponent::HandleToggleTrigger(Entity* targetEntity, std::string args){
@@ -216,9 +213,8 @@ void TriggerComponent::HandleResetRebuild(Entity* targetEntity, std::string args
void TriggerComponent::HandleMoveObject(Entity* targetEntity, std::vector<std::string> argArray){
if (argArray.size() <= 2) return;
auto position = targetEntity->GetPosition();
NiPoint3 offset = NiPoint3::ZERO;
GeneralUtils::TryParse(argArray.at(0), argArray.at(1), argArray.at(2), offset);
NiPoint3 position = targetEntity->GetPosition();
const NiPoint3 offset = GeneralUtils::TryParse<NiPoint3>(argArray).value_or(NiPoint3Constant::ZERO);
position += offset;
targetEntity->SetPosition(position);
@@ -227,8 +223,7 @@ void TriggerComponent::HandleMoveObject(Entity* targetEntity, std::vector<std::s
void TriggerComponent::HandleRotateObject(Entity* targetEntity, std::vector<std::string> argArray){
if (argArray.size() <= 2) return;
NiPoint3 vector = NiPoint3::ZERO;
GeneralUtils::TryParse(argArray.at(0), argArray.at(1), argArray.at(2), vector);
const NiPoint3 vector = GeneralUtils::TryParse<NiPoint3>(argArray).value_or(NiPoint3Constant::ZERO);
NiQuaternion rotation = NiQuaternion::FromEulerAngles(vector);
targetEntity->SetRotation(rotation);
@@ -245,8 +240,7 @@ void TriggerComponent::HandlePushObject(Entity* targetEntity, std::vector<std::s
phantomPhysicsComponent->SetPhysicsEffectActive(true);
phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::PUSH);
phantomPhysicsComponent->SetDirectionalMultiplier(1);
NiPoint3 direction = NiPoint3::ZERO;
GeneralUtils::TryParse(argArray.at(0), argArray.at(1), argArray.at(2), direction);
const NiPoint3 direction = GeneralUtils::TryParse<NiPoint3>(argArray).value_or(NiPoint3Constant::ZERO);
phantomPhysicsComponent->SetDirection(direction);
Game::entityManager->SerializeEntity(m_Parent);
@@ -259,8 +253,8 @@ void TriggerComponent::HandleRepelObject(Entity* targetEntity, std::string args)
LOG_DEBUG("Phantom Physics component not found!");
return;
}
float forceMultiplier;
GeneralUtils::TryParse<float>(args, forceMultiplier);
const float forceMultiplier = GeneralUtils::TryParse<float>(args).value_or(1.0f);
phantomPhysicsComponent->SetPhysicsEffectActive(true);
phantomPhysicsComponent->SetEffectType(ePhysicsEffectType::REPULSE);
phantomPhysicsComponent->SetDirectionalMultiplier(forceMultiplier);
@@ -279,11 +273,10 @@ void TriggerComponent::HandleRepelObject(Entity* targetEntity, std::string args)
void TriggerComponent::HandleSetTimer(Entity* targetEntity, std::vector<std::string> argArray){
if (argArray.size() != 2) {
LOG_DEBUG("Not ehought variables!");
LOG_DEBUG("Not enough variables!");
return;
}
float time = 0.0;
GeneralUtils::TryParse<float>(argArray.at(1), time);
const float time = GeneralUtils::TryParse<float>(argArray.at(1)).value_or(0.0f);
m_Parent->AddTimer(argArray.at(0), time);
}
@@ -299,7 +292,7 @@ void TriggerComponent::HandlePlayCinematic(Entity* targetEntity, std::vector<std
bool hidePlayer = false;
if (argArray.size() >= 2) {
GeneralUtils::TryParse<float>(argArray.at(1), leadIn);
leadIn = GeneralUtils::TryParse<float>(argArray.at(1)).value_or(leadIn);
if (argArray.size() >= 3 && argArray.at(2) == "wait") {
wait = eEndBehavior::WAIT;
if (argArray.size() >= 4 && argArray.at(3) == "unlock") {
@@ -344,12 +337,16 @@ void TriggerComponent::HandleUpdateMission(Entity* targetEntity, std::vector<std
void TriggerComponent::HandlePlayEffect(Entity* targetEntity, std::vector<std::string> argArray) {
if (argArray.size() < 3) return;
int32_t effectID = 0;
if (!GeneralUtils::TryParse<int32_t>(argArray.at(1), effectID)) return;
const auto effectID = GeneralUtils::TryParse<int32_t>(argArray.at(1));
if (!effectID) return;
std::u16string effectType = GeneralUtils::UTF8ToUTF16(argArray.at(2));
float priority = 1;
if (argArray.size() == 4) GeneralUtils::TryParse<float>(argArray.at(3), priority);
GameMessages::SendPlayFXEffect(targetEntity, effectID, effectType, argArray.at(0), LWOOBJID_EMPTY, priority);
if (argArray.size() == 4) {
priority = GeneralUtils::TryParse<float>(argArray.at(3)).value_or(priority);
}
GameMessages::SendPlayFXEffect(targetEntity, effectID.value(), effectType, argArray.at(0), LWOOBJID_EMPTY, priority);
}
void TriggerComponent::HandleCastSkill(Entity* targetEntity, std::string args){
@@ -358,8 +355,7 @@ void TriggerComponent::HandleCastSkill(Entity* targetEntity, std::string args){
LOG_DEBUG("Skill component not found!");
return;
}
uint32_t skillId;
GeneralUtils::TryParse<uint32_t>(args, skillId);
const uint32_t skillId = GeneralUtils::TryParse<uint32_t>(args).value_or(0);
skillComponent->CastSkill(skillId, targetEntity->GetObjectID());
}
@@ -381,17 +377,16 @@ void TriggerComponent::HandleSetPhysicsVolumeEffect(Entity* targetEntity, std::v
phantomPhysicsComponent->SetEffectType(effectType);
phantomPhysicsComponent->SetDirectionalMultiplier(std::stof(argArray.at(1)));
if (argArray.size() > 4) {
NiPoint3 direction = NiPoint3::ZERO;
GeneralUtils::TryParse(argArray.at(2), argArray.at(3), argArray.at(4), direction);
const NiPoint3 direction =
GeneralUtils::TryParse<NiPoint3>(argArray.at(2), argArray.at(3), argArray.at(4)).value_or(NiPoint3Constant::ZERO);
phantomPhysicsComponent->SetDirection(direction);
}
if (argArray.size() > 5) {
uint32_t min;
GeneralUtils::TryParse<uint32_t>(argArray.at(6), min);
const uint32_t min = GeneralUtils::TryParse<uint32_t>(argArray.at(6)).value_or(0);
phantomPhysicsComponent->SetMin(min);
uint32_t max;
GeneralUtils::TryParse<uint32_t>(argArray.at(7), max);
const uint32_t max = GeneralUtils::TryParse<uint32_t>(argArray.at(7)).value_or(0);
phantomPhysicsComponent->SetMax(max);
}

View File

@@ -5,9 +5,9 @@
#include "LUTriggers.h"
#include "eReplicaComponentType.h"
class TriggerComponent : public Component {
class TriggerComponent final : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::TRIGGER;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::TRIGGER;
explicit TriggerComponent(Entity* parent, const std::string triggerInfo);

View File

@@ -41,14 +41,14 @@ void VendorComponent::RefreshInventory(bool isCreation) {
return;
}
auto* lootMatrixTable = CDClientManager::Instance().GetTable<CDLootMatrixTable>();
auto* lootMatrixTable = CDClientManager::GetTable<CDLootMatrixTable>();
const auto& lootMatrices = lootMatrixTable->GetMatrix(m_LootMatrixID);
if (lootMatrices.empty()) return;
auto* lootTableTable = CDClientManager::Instance().GetTable<CDLootTableTable>();
auto* itemComponentTable = CDClientManager::Instance().GetTable<CDItemComponentTable>();
auto* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
auto* lootTableTable = CDClientManager::GetTable<CDLootTableTable>();
auto* itemComponentTable = CDClientManager::GetTable<CDItemComponentTable>();
auto* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
for (const auto& lootMatrix : lootMatrices) {
auto vendorItems = lootTableTable->GetTable(lootMatrix.LootTableIndex);
@@ -101,10 +101,10 @@ void VendorComponent::RefreshInventory(bool isCreation) {
}
void VendorComponent::SetupConstants() {
auto* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
auto* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
int componentID = compRegistryTable->GetByIDAndType(m_Parent->GetLOT(), eReplicaComponentType::VENDOR);
auto* vendorComponentTable = CDClientManager::Instance().GetTable<CDVendorComponentTable>();
auto* vendorComponentTable = CDClientManager::GetTable<CDVendorComponentTable>();
std::vector<CDVendorComponent> vendorComps = vendorComponentTable->Query([=](CDVendorComponent entry) { return (entry.id == componentID); });
if (vendorComps.empty()) return;
auto vendorData = vendorComps.at(0);

View File

@@ -20,7 +20,7 @@ struct SoldItem {
class VendorComponent : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::VENDOR;
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::VENDOR;
VendorComponent(Entity* parent);
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;