mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-03-07 00:59:48 +00:00
Merge branch 'main' into chatpacketwhowhere
This commit is contained in:
81
dGame/dComponents/AchievementVendorComponent.cpp
Normal file
81
dGame/dComponents/AchievementVendorComponent.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
#include "AchievementVendorComponent.h"
|
||||
#include "MissionComponent.h"
|
||||
#include "InventoryComponent.h"
|
||||
#include "eMissionState.h"
|
||||
#include "CDComponentsRegistryTable.h"
|
||||
#include "CDItemComponentTable.h"
|
||||
#include "eVendorTransactionResult.h"
|
||||
#include "CheatDetection.h"
|
||||
#include "UserManager.h"
|
||||
#include "CDMissionsTable.h"
|
||||
|
||||
AchievementVendorComponent::AchievementVendorComponent(Entity* parent) : VendorComponent(parent) {
|
||||
RefreshInventory(true);
|
||||
};
|
||||
|
||||
bool AchievementVendorComponent::SellsItem(Entity* buyer, const LOT lot) {
|
||||
auto* missionComponent = buyer->GetComponent<MissionComponent>();
|
||||
if (!missionComponent) return false;
|
||||
|
||||
if (m_PlayerPurchasableItems[buyer->GetObjectID()].contains(lot)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
CDMissionsTable* missionsTable = CDClientManager::GetTable<CDMissionsTable>();
|
||||
const auto missions = missionsTable->GetMissionsForReward(lot);
|
||||
for (const auto mission : missions) {
|
||||
if (missionComponent->GetMissionState(mission) == eMissionState::COMPLETE) {
|
||||
m_PlayerPurchasableItems[buyer->GetObjectID()].insert(lot);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AchievementVendorComponent::Buy(Entity* buyer, LOT lot, uint32_t count) {
|
||||
// get the item Comp from the item LOT
|
||||
CDComponentsRegistryTable* compRegistryTable = CDClientManager::GetTable<CDComponentsRegistryTable>();
|
||||
CDItemComponentTable* itemComponentTable = CDClientManager::GetTable<CDItemComponentTable>();
|
||||
int itemCompID = compRegistryTable->GetByIDAndType(lot, eReplicaComponentType::ITEM);
|
||||
CDItemComponent itemComp = itemComponentTable->GetItemComponentByID(itemCompID);
|
||||
uint32_t costLOT = itemComp.commendationLOT;
|
||||
|
||||
if (costLOT == -1 || !SellsItem(buyer, lot)) {
|
||||
auto* user = UserManager::Instance()->GetUser(buyer->GetSystemAddress());
|
||||
CheatDetection::ReportCheat(user, buyer->GetSystemAddress(), "Attempted to buy item %i from achievement vendor %i that is not purchasable", lot, m_Parent->GetLOT());
|
||||
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
auto* inventoryComponent = buyer->GetComponent<InventoryComponent>();
|
||||
if (!inventoryComponent) {
|
||||
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (costLOT == 13763) { // Faction Token Proxy
|
||||
auto* missionComponent = buyer->GetComponent<MissionComponent>();
|
||||
if (!missionComponent) return;
|
||||
|
||||
if (missionComponent->GetMissionState(545) == eMissionState::COMPLETE) costLOT = 8318; // "Assembly Token"
|
||||
if (missionComponent->GetMissionState(556) == eMissionState::COMPLETE) costLOT = 8321; // "Venture League Token"
|
||||
if (missionComponent->GetMissionState(567) == eMissionState::COMPLETE) costLOT = 8319; // "Sentinels Token"
|
||||
if (missionComponent->GetMissionState(578) == eMissionState::COMPLETE) costLOT = 8320; // "Paradox Token"
|
||||
}
|
||||
|
||||
const uint32_t altCurrencyCost = itemComp.commendationCost * count;
|
||||
if (inventoryComponent->GetLotCount(costLOT) < altCurrencyCost) {
|
||||
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
inventoryComponent->RemoveItem(costLOT, altCurrencyCost);
|
||||
inventoryComponent->AddItem(lot, count, eLootSourceType::VENDOR);
|
||||
GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_SUCCESS);
|
||||
|
||||
}
|
||||
|
||||
void AchievementVendorComponent::RefreshInventory(bool isCreation) {
|
||||
SetHasStandardCostItems(true);
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
}
|
||||
25
dGame/dComponents/AchievementVendorComponent.h
Normal file
25
dGame/dComponents/AchievementVendorComponent.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef __ACHIEVEMENTVENDORCOMPONENT__H__
|
||||
#define __ACHIEVEMENTVENDORCOMPONENT__H__
|
||||
|
||||
#include "VendorComponent.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
class Entity;
|
||||
|
||||
class AchievementVendorComponent final : public VendorComponent {
|
||||
public:
|
||||
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::ACHIEVEMENT_VENDOR;
|
||||
AchievementVendorComponent(Entity* parent);
|
||||
|
||||
void RefreshInventory(bool isCreation = false) override;
|
||||
bool SellsItem(Entity* buyer, const LOT lot);
|
||||
void Buy(Entity* buyer, LOT lot, uint32_t count);
|
||||
|
||||
private:
|
||||
std::map<LWOOBJID,std::set<LOT>> m_PlayerPurchasableItems;
|
||||
};
|
||||
|
||||
|
||||
#endif //!__ACHIEVEMENTVENDORCOMPONENT__H__
|
||||
@@ -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"
|
||||
@@ -46,7 +45,7 @@ ActivityComponent::ActivityComponent(Entity* parent, int32_t activityID) : Compo
|
||||
|
||||
if (destroyableComponent) {
|
||||
// First lookup the loot matrix id for this component id.
|
||||
CDActivityRewardsTable* activityRewardsTable = CDClientManager::Instance().GetTable<CDActivityRewardsTable>();
|
||||
CDActivityRewardsTable* activityRewardsTable = CDClientManager::GetTable<CDActivityRewardsTable>();
|
||||
std::vector<CDActivityRewards> activityRewards = activityRewardsTable->Query([=](CDActivityRewards entry) {return (entry.LootMatrixIndex == destroyableComponent->GetLootMatrixID()); });
|
||||
|
||||
uint32_t startingLMI = 0;
|
||||
@@ -70,7 +69,7 @@ ActivityComponent::ActivityComponent(Entity* parent, int32_t activityID) : Compo
|
||||
}
|
||||
}
|
||||
void ActivityComponent::LoadActivityData(const int32_t activityId) {
|
||||
CDActivitiesTable* activitiesTable = CDClientManager::Instance().GetTable<CDActivitiesTable>();
|
||||
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";
|
||||
@@ -83,21 +82,22 @@ void ActivityComponent::LoadActivityData(const int32_t activityId) {
|
||||
if (m_ActivityInfo.instanceMapID == -1) {
|
||||
const auto& transferOverride = m_Parent->GetVarAsString(u"transferZoneID");
|
||||
if (!transferOverride.empty()) {
|
||||
GeneralUtils::TryParse(transferOverride, m_ActivityInfo.instanceMapID);
|
||||
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);
|
||||
void ActivityComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream.Write(m_DirtyActivityInfo);
|
||||
if (m_DirtyActivityInfo) {
|
||||
outBitStream->Write<uint32_t>(m_ActivityPlayers.size());
|
||||
outBitStream.Write<uint32_t>(m_ActivityPlayers.size());
|
||||
if (!m_ActivityPlayers.empty()) {
|
||||
for (const auto& activityPlayer : m_ActivityPlayers) {
|
||||
outBitStream->Write<LWOOBJID>(activityPlayer->playerID);
|
||||
outBitStream.Write<LWOOBJID>(activityPlayer->playerID);
|
||||
for (const auto& activityValue : activityPlayer->values) {
|
||||
outBitStream->Write<float_t>(activityValue);
|
||||
outBitStream.Write<float_t>(activityValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,7 +106,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;
|
||||
@@ -545,14 +545,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()) {
|
||||
|
||||
@@ -155,7 +155,7 @@ public:
|
||||
void LoadActivityData(const int32_t activityId);
|
||||
|
||||
void Update(float deltaTime) override;
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
/**
|
||||
* Makes some entity join the minigame, if it's a lobbied one, the entity will be placed in the lobby
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -519,11 +520,11 @@ bool BaseCombatAIComponent::IsMech() {
|
||||
}
|
||||
|
||||
|
||||
void BaseCombatAIComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream->Write(m_DirtyStateOrTarget || bIsInitialUpdate);
|
||||
void BaseCombatAIComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream.Write(m_DirtyStateOrTarget || bIsInitialUpdate);
|
||||
if (m_DirtyStateOrTarget || bIsInitialUpdate) {
|
||||
outBitStream->Write(m_State);
|
||||
outBitStream->Write(m_Target);
|
||||
outBitStream.Write(m_State);
|
||||
outBitStream.Write(m_Target);
|
||||
m_DirtyStateOrTarget = false;
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -45,15 +45,15 @@ 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;
|
||||
|
||||
void Update(float deltaTime) override;
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
/**
|
||||
* Get the current behavioral state of the enemy
|
||||
|
||||
@@ -22,10 +22,10 @@ BouncerComponent::BouncerComponent(Entity* parent) : Component(parent) {
|
||||
BouncerComponent::~BouncerComponent() {
|
||||
}
|
||||
|
||||
void BouncerComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream->Write(m_PetEnabled);
|
||||
void BouncerComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream.Write(m_PetEnabled);
|
||||
if (m_PetEnabled) {
|
||||
outBitStream->Write(m_PetBouncerEnabled);
|
||||
outBitStream.Write(m_PetBouncerEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
Entity* GetParentEntity() const;
|
||||
|
||||
|
||||
@@ -32,24 +32,24 @@ BuffComponent::BuffComponent(Entity* parent) : Component(parent) {
|
||||
BuffComponent::~BuffComponent() {
|
||||
}
|
||||
|
||||
void BuffComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
void BuffComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
if (!bIsInitialUpdate) return;
|
||||
outBitStream->Write(!m_Buffs.empty());
|
||||
outBitStream.Write(!m_Buffs.empty());
|
||||
if (!m_Buffs.empty()) {
|
||||
outBitStream->Write<uint32_t>(m_Buffs.size());
|
||||
outBitStream.Write<uint32_t>(m_Buffs.size());
|
||||
|
||||
for (const auto& [id, buff] : m_Buffs) {
|
||||
outBitStream->Write<uint32_t>(id);
|
||||
outBitStream->Write(buff.time != 0.0f);
|
||||
if (buff.time != 0.0f) outBitStream->Write<uint32_t>(buff.time * 1000.0f);
|
||||
outBitStream->Write(buff.cancelOnDeath);
|
||||
outBitStream->Write(buff.cancelOnZone);
|
||||
outBitStream->Write(buff.cancelOnDamaged);
|
||||
outBitStream->Write(buff.cancelOnRemoveBuff);
|
||||
outBitStream->Write(buff.cancelOnUi);
|
||||
outBitStream->Write(buff.cancelOnLogout);
|
||||
outBitStream->Write(buff.cancelOnUnequip);
|
||||
outBitStream->Write0(); // Cancel on Damage Absorb Ran Out. Generally false from what I can tell
|
||||
outBitStream.Write<uint32_t>(id);
|
||||
outBitStream.Write(buff.time != 0.0f);
|
||||
if (buff.time != 0.0f) outBitStream.Write<uint32_t>(buff.time * 1000.0f);
|
||||
outBitStream.Write(buff.cancelOnDeath);
|
||||
outBitStream.Write(buff.cancelOnZone);
|
||||
outBitStream.Write(buff.cancelOnDamaged);
|
||||
outBitStream.Write(buff.cancelOnRemoveBuff);
|
||||
outBitStream.Write(buff.cancelOnUi);
|
||||
outBitStream.Write(buff.cancelOnLogout);
|
||||
outBitStream.Write(buff.cancelOnUnequip);
|
||||
outBitStream.Write0(); // Cancel on Damage Absorb Ran Out. Generally false from what I can tell
|
||||
|
||||
auto* team = TeamManager::Instance()->GetTeam(buff.source);
|
||||
bool addedByTeammate = false;
|
||||
@@ -57,15 +57,15 @@ void BuffComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUp
|
||||
addedByTeammate = std::count(team->members.begin(), team->members.end(), m_Parent->GetObjectID()) > 0;
|
||||
}
|
||||
|
||||
outBitStream->Write(addedByTeammate); // Added by teammate. If source is in the same team as the target, this is true. Otherwise, false.
|
||||
outBitStream->Write(buff.applyOnTeammates);
|
||||
if (addedByTeammate) outBitStream->Write(buff.source);
|
||||
outBitStream.Write(addedByTeammate); // Added by teammate. If source is in the same team as the target, this is true. Otherwise, false.
|
||||
outBitStream.Write(buff.applyOnTeammates);
|
||||
if (addedByTeammate) outBitStream.Write(buff.source);
|
||||
|
||||
outBitStream->Write<uint32_t>(buff.refCount);
|
||||
outBitStream.Write<uint32_t>(buff.refCount);
|
||||
}
|
||||
}
|
||||
|
||||
outBitStream->Write0(); // something to do with immunity buffs?
|
||||
outBitStream.Write0(); // something to do with immunity buffs?
|
||||
}
|
||||
|
||||
void BuffComponent::Update(float deltaTime) {
|
||||
@@ -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]);
|
||||
@@ -208,9 +208,8 @@ void BuffComponent::ApplyBuff(const int32_t id, const float duration, const LWOO
|
||||
void BuffComponent::RemoveBuff(int32_t id, bool fromUnEquip, bool removeImmunity, bool ignoreRefCount) {
|
||||
const auto& iter = m_Buffs.find(id);
|
||||
|
||||
if (iter == m_Buffs.end()) {
|
||||
return;
|
||||
}
|
||||
// If the buff is already scheduled to be removed, don't do it again
|
||||
if (iter == m_Buffs.end() || m_BuffsToRemove.contains(id)) return;
|
||||
|
||||
if (!ignoreRefCount && !iter->second.cancelOnRemoveBuff) {
|
||||
iter->second.refCount--;
|
||||
@@ -222,7 +221,7 @@ void BuffComponent::RemoveBuff(int32_t id, bool fromUnEquip, bool removeImmunity
|
||||
|
||||
GameMessages::SendRemoveBuff(m_Parent, fromUnEquip, removeImmunity, id);
|
||||
|
||||
m_BuffsToRemove.push_back(id);
|
||||
m_BuffsToRemove.insert(id);
|
||||
|
||||
RemoveBuffEffect(id);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
|
||||
void UpdateXml(tinyxml2::XMLDocument* doc) override;
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
void Update(float deltaTime) override;
|
||||
|
||||
@@ -141,7 +141,7 @@ private:
|
||||
std::map<int32_t, Buff> m_Buffs;
|
||||
|
||||
// Buffs to remove at the end of the update frame.
|
||||
std::vector<int32_t> m_BuffsToRemove;
|
||||
std::set<int32_t> m_BuffsToRemove;
|
||||
|
||||
/**
|
||||
* Parameters (=effects) for each buff
|
||||
|
||||
@@ -56,7 +56,7 @@ void BuildBorderComponent::OnUse(Entity* originator) {
|
||||
4,
|
||||
0,
|
||||
-1,
|
||||
NiPoint3::ZERO,
|
||||
NiPoint3Constant::ZERO,
|
||||
0
|
||||
);
|
||||
} else {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
set(DGAME_DCOMPONENTS_SOURCES
|
||||
"AchievementVendorComponent.cpp"
|
||||
"ActivityComponent.cpp"
|
||||
"BaseCombatAIComponent.cpp"
|
||||
"BouncerComponent.cpp"
|
||||
@@ -27,7 +28,6 @@ set(DGAME_DCOMPONENTS_SOURCES
|
||||
"PlayerForcedMovementComponent.cpp"
|
||||
"PossessableComponent.cpp"
|
||||
"PossessorComponent.cpp"
|
||||
"PropertyComponent.cpp"
|
||||
"PropertyEntranceComponent.cpp"
|
||||
"PropertyManagementComponent.cpp"
|
||||
"PropertyVendorComponent.cpp"
|
||||
@@ -48,11 +48,35 @@ set(DGAME_DCOMPONENTS_SOURCES
|
||||
"HavokVehiclePhysicsComponent.cpp"
|
||||
"VendorComponent.cpp"
|
||||
"MiniGameControlComponent.cpp"
|
||||
"ScriptComponent.cpp"
|
||||
)
|
||||
|
||||
add_library(dComponents STATIC ${DGAME_DCOMPONENTS_SOURCES})
|
||||
target_include_directories(dComponents PRIVATE ${PROJECT_SOURCE_DIR}/dScripts/02_server/Map/General) # PetDigServer.h
|
||||
add_library(dComponents OBJECT ${DGAME_DCOMPONENTS_SOURCES})
|
||||
target_include_directories(dComponents PUBLIC "."
|
||||
"${PROJECT_SOURCE_DIR}/dGame/dPropertyBehaviors" # via ModelComponent.h
|
||||
"${PROJECT_SOURCE_DIR}/dGame/dPropertyBehaviors/ControlBehaviorMessages"
|
||||
"${PROJECT_SOURCE_DIR}/dGame/dMission" # via MissionComponent.h
|
||||
"${PROJECT_SOURCE_DIR}/dGame/dBehaviors" # via InventoryComponent.h
|
||||
"${PROJECT_SOURCE_DIR}/dGame/dInventory" # via InventoryComponent.h
|
||||
PRIVATE
|
||||
"${PROJECT_SOURCE_DIR}/dCommon"
|
||||
"${PROJECT_SOURCE_DIR}/dCommon/dEnums"
|
||||
"${PROJECT_SOURCE_DIR}/dDatabase/CDClientDatabase"
|
||||
"${PROJECT_SOURCE_DIR}/dDatabase/CDClientDatabase/CDClientTables"
|
||||
"${PROJECT_SOURCE_DIR}/dDatabase/GameDatabase"
|
||||
"${PROJECT_SOURCE_DIR}/dDatabase/GameDatabase/ITables"
|
||||
"${PROJECT_SOURCE_DIR}/thirdparty/mariadb-connector-cpp/include"
|
||||
# dPhysics (via dpWorld.h)
|
||||
"${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Recast/Include"
|
||||
"${PROJECT_SOURCE_DIR}/thirdparty/recastnavigation/Detour/Include"
|
||||
|
||||
"${PROJECT_SOURCE_DIR}/dScripts/02_server/Map/General" # PetDigServer.h
|
||||
"${PROJECT_SOURCE_DIR}/dGame/dGameMessages" # direct
|
||||
"${PROJECT_SOURCE_DIR}/dGame/dUtilities" # direct Loot.h
|
||||
"${PROJECT_SOURCE_DIR}/dGame/dEntity" # via dZoneManager/Spawner.h
|
||||
"${PROJECT_SOURCE_DIR}/dZoneManager" # via BouncerComponent.cpp, ActivityComponent.cpp
|
||||
"${PROJECT_SOURCE_DIR}/dChatFilter" # via PetComponent.cpp
|
||||
)
|
||||
target_precompile_headers(dComponents REUSE_FROM dGameBase)
|
||||
target_link_libraries(dComponents
|
||||
PUBLIC dPhysics dDatabase
|
||||
INTERFACE dUtilities dCommon dBehaviors dChatFilter dMission dInventory)
|
||||
|
||||
target_link_libraries(dComponents INTERFACE dBehaviors)
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#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;
|
||||
@@ -46,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) {
|
||||
@@ -77,94 +78,94 @@ bool CharacterComponent::LandingAnimDisabled(int zoneID) {
|
||||
CharacterComponent::~CharacterComponent() {
|
||||
}
|
||||
|
||||
void CharacterComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
void CharacterComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
|
||||
if (bIsInitialUpdate) {
|
||||
outBitStream->Write(m_ClaimCodes[0] != 0);
|
||||
if (m_ClaimCodes[0] != 0) outBitStream->Write(m_ClaimCodes[0]);
|
||||
outBitStream->Write(m_ClaimCodes[1] != 0);
|
||||
if (m_ClaimCodes[1] != 0) outBitStream->Write(m_ClaimCodes[1]);
|
||||
outBitStream->Write(m_ClaimCodes[2] != 0);
|
||||
if (m_ClaimCodes[2] != 0) outBitStream->Write(m_ClaimCodes[2]);
|
||||
outBitStream->Write(m_ClaimCodes[3] != 0);
|
||||
if (m_ClaimCodes[3] != 0) outBitStream->Write(m_ClaimCodes[3]);
|
||||
outBitStream.Write(m_ClaimCodes[0] != 0);
|
||||
if (m_ClaimCodes[0] != 0) outBitStream.Write(m_ClaimCodes[0]);
|
||||
outBitStream.Write(m_ClaimCodes[1] != 0);
|
||||
if (m_ClaimCodes[1] != 0) outBitStream.Write(m_ClaimCodes[1]);
|
||||
outBitStream.Write(m_ClaimCodes[2] != 0);
|
||||
if (m_ClaimCodes[2] != 0) outBitStream.Write(m_ClaimCodes[2]);
|
||||
outBitStream.Write(m_ClaimCodes[3] != 0);
|
||||
if (m_ClaimCodes[3] != 0) outBitStream.Write(m_ClaimCodes[3]);
|
||||
|
||||
outBitStream->Write(m_Character->GetHairColor());
|
||||
outBitStream->Write(m_Character->GetHairStyle());
|
||||
outBitStream->Write<uint32_t>(0); //Default "head"
|
||||
outBitStream->Write(m_Character->GetShirtColor());
|
||||
outBitStream->Write(m_Character->GetPantsColor());
|
||||
outBitStream->Write(m_Character->GetShirtStyle());
|
||||
outBitStream->Write<uint32_t>(0); //Default "head color"
|
||||
outBitStream->Write(m_Character->GetEyebrows());
|
||||
outBitStream->Write(m_Character->GetEyes());
|
||||
outBitStream->Write(m_Character->GetMouth());
|
||||
outBitStream->Write<uint64_t>(0); //AccountID, trying out if 0 works.
|
||||
outBitStream->Write(m_Character->GetLastLogin()); //Last login
|
||||
outBitStream->Write<uint64_t>(0); //"prop mod last display time"
|
||||
outBitStream->Write<uint64_t>(m_Uscore); //u-score
|
||||
outBitStream->Write0(); //Not free-to-play (disabled in DLU)
|
||||
outBitStream.Write(m_Character->GetHairColor());
|
||||
outBitStream.Write(m_Character->GetHairStyle());
|
||||
outBitStream.Write<uint32_t>(0); //Default "head"
|
||||
outBitStream.Write(m_Character->GetShirtColor());
|
||||
outBitStream.Write(m_Character->GetPantsColor());
|
||||
outBitStream.Write(m_Character->GetShirtStyle());
|
||||
outBitStream.Write<uint32_t>(0); //Default "head color"
|
||||
outBitStream.Write(m_Character->GetEyebrows());
|
||||
outBitStream.Write(m_Character->GetEyes());
|
||||
outBitStream.Write(m_Character->GetMouth());
|
||||
outBitStream.Write<uint64_t>(0); //AccountID, trying out if 0 works.
|
||||
outBitStream.Write(m_Character->GetLastLogin()); //Last login
|
||||
outBitStream.Write<uint64_t>(0); //"prop mod last display time"
|
||||
outBitStream.Write<uint64_t>(m_Uscore); //u-score
|
||||
outBitStream.Write0(); //Not free-to-play (disabled in DLU)
|
||||
|
||||
//Stats:
|
||||
outBitStream->Write(m_CurrencyCollected);
|
||||
outBitStream->Write(m_BricksCollected);
|
||||
outBitStream->Write(m_SmashablesSmashed);
|
||||
outBitStream->Write(m_QuickBuildsCompleted);
|
||||
outBitStream->Write(m_EnemiesSmashed);
|
||||
outBitStream->Write(m_RocketsUsed);
|
||||
outBitStream->Write(m_MissionsCompleted);
|
||||
outBitStream->Write(m_PetsTamed);
|
||||
outBitStream->Write(m_ImaginationPowerUpsCollected);
|
||||
outBitStream->Write(m_LifePowerUpsCollected);
|
||||
outBitStream->Write(m_ArmorPowerUpsCollected);
|
||||
outBitStream->Write(m_MetersTraveled);
|
||||
outBitStream->Write(m_TimesSmashed);
|
||||
outBitStream->Write(m_TotalDamageTaken);
|
||||
outBitStream->Write(m_TotalDamageHealed);
|
||||
outBitStream->Write(m_TotalArmorRepaired);
|
||||
outBitStream->Write(m_TotalImaginationRestored);
|
||||
outBitStream->Write(m_TotalImaginationUsed);
|
||||
outBitStream->Write(m_DistanceDriven);
|
||||
outBitStream->Write(m_TimeAirborneInCar);
|
||||
outBitStream->Write(m_RacingImaginationPowerUpsCollected);
|
||||
outBitStream->Write(m_RacingImaginationCratesSmashed);
|
||||
outBitStream->Write(m_RacingCarBoostsActivated);
|
||||
outBitStream->Write(m_RacingTimesWrecked);
|
||||
outBitStream->Write(m_RacingSmashablesSmashed);
|
||||
outBitStream->Write(m_RacesFinished);
|
||||
outBitStream->Write(m_FirstPlaceRaceFinishes);
|
||||
outBitStream.Write(m_CurrencyCollected);
|
||||
outBitStream.Write(m_BricksCollected);
|
||||
outBitStream.Write(m_SmashablesSmashed);
|
||||
outBitStream.Write(m_QuickBuildsCompleted);
|
||||
outBitStream.Write(m_EnemiesSmashed);
|
||||
outBitStream.Write(m_RocketsUsed);
|
||||
outBitStream.Write(m_MissionsCompleted);
|
||||
outBitStream.Write(m_PetsTamed);
|
||||
outBitStream.Write(m_ImaginationPowerUpsCollected);
|
||||
outBitStream.Write(m_LifePowerUpsCollected);
|
||||
outBitStream.Write(m_ArmorPowerUpsCollected);
|
||||
outBitStream.Write(m_MetersTraveled);
|
||||
outBitStream.Write(m_TimesSmashed);
|
||||
outBitStream.Write(m_TotalDamageTaken);
|
||||
outBitStream.Write(m_TotalDamageHealed);
|
||||
outBitStream.Write(m_TotalArmorRepaired);
|
||||
outBitStream.Write(m_TotalImaginationRestored);
|
||||
outBitStream.Write(m_TotalImaginationUsed);
|
||||
outBitStream.Write(m_DistanceDriven);
|
||||
outBitStream.Write(m_TimeAirborneInCar);
|
||||
outBitStream.Write(m_RacingImaginationPowerUpsCollected);
|
||||
outBitStream.Write(m_RacingImaginationCratesSmashed);
|
||||
outBitStream.Write(m_RacingCarBoostsActivated);
|
||||
outBitStream.Write(m_RacingTimesWrecked);
|
||||
outBitStream.Write(m_RacingSmashablesSmashed);
|
||||
outBitStream.Write(m_RacesFinished);
|
||||
outBitStream.Write(m_FirstPlaceRaceFinishes);
|
||||
|
||||
outBitStream->Write0();
|
||||
outBitStream->Write(m_IsLanding);
|
||||
outBitStream.Write0();
|
||||
outBitStream.Write(m_IsLanding);
|
||||
if (m_IsLanding) {
|
||||
outBitStream->Write<uint16_t>(m_LastRocketConfig.size());
|
||||
outBitStream.Write<uint16_t>(m_LastRocketConfig.size());
|
||||
for (uint16_t character : m_LastRocketConfig) {
|
||||
outBitStream->Write(character);
|
||||
outBitStream.Write(character);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
outBitStream->Write(m_DirtyGMInfo);
|
||||
outBitStream.Write(m_DirtyGMInfo);
|
||||
if (m_DirtyGMInfo) {
|
||||
outBitStream->Write(m_PvpEnabled);
|
||||
outBitStream->Write(m_IsGM);
|
||||
outBitStream->Write(m_GMLevel);
|
||||
outBitStream->Write(m_EditorEnabled);
|
||||
outBitStream->Write(m_EditorLevel);
|
||||
outBitStream.Write(m_PvpEnabled);
|
||||
outBitStream.Write(m_IsGM);
|
||||
outBitStream.Write(m_GMLevel);
|
||||
outBitStream.Write(m_EditorEnabled);
|
||||
outBitStream.Write(m_EditorLevel);
|
||||
}
|
||||
|
||||
outBitStream->Write(m_DirtyCurrentActivity);
|
||||
if (m_DirtyCurrentActivity) outBitStream->Write(m_CurrentActivity);
|
||||
outBitStream.Write(m_DirtyCurrentActivity);
|
||||
if (m_DirtyCurrentActivity) outBitStream.Write(m_CurrentActivity);
|
||||
|
||||
outBitStream->Write(m_DirtySocialInfo);
|
||||
outBitStream.Write(m_DirtySocialInfo);
|
||||
if (m_DirtySocialInfo) {
|
||||
outBitStream->Write(m_GuildID);
|
||||
outBitStream->Write<unsigned char>(m_GuildName.size());
|
||||
outBitStream.Write(m_GuildID);
|
||||
outBitStream.Write<unsigned char>(m_GuildName.size());
|
||||
if (!m_GuildName.empty())
|
||||
outBitStream->WriteBits(reinterpret_cast<const unsigned char*>(m_GuildName.c_str()), static_cast<unsigned char>(m_GuildName.size()) * sizeof(wchar_t) * 8);
|
||||
outBitStream.WriteBits(reinterpret_cast<const unsigned char*>(m_GuildName.c_str()), static_cast<unsigned char>(m_GuildName.size()) * sizeof(wchar_t) * 8);
|
||||
|
||||
outBitStream->Write(m_IsLEGOClubMember);
|
||||
outBitStream->Write(m_CountryCode);
|
||||
outBitStream.Write(m_IsLEGOClubMember);
|
||||
outBitStream.Write(m_CountryCode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -762,14 +763,14 @@ 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>();
|
||||
auto* cdrewardCodes = CDClientManager::GetTable<CDRewardCodesTable>();
|
||||
for (auto const rewardCode : rewardCodes) {
|
||||
LOG_DEBUG("Processing RewardCode %i", rewardCode);
|
||||
const uint32_t rewardCodeIndex = rewardCode >> 6;
|
||||
@@ -817,3 +818,20 @@ void CharacterComponent::SendToZone(LWOMAPID zoneId, LWOCLONEID cloneId) const {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -5,15 +5,17 @@
|
||||
#include "RakNetTypes.h"
|
||||
#include "Character.h"
|
||||
#include "Component.h"
|
||||
#include "Item.h"
|
||||
#include <string>
|
||||
#include "CDMissionsTable.h"
|
||||
#include "tinyxml2.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
#include <array>
|
||||
#include "Loot.h"
|
||||
|
||||
enum class eGameActivity : uint32_t;
|
||||
|
||||
class Item;
|
||||
|
||||
/**
|
||||
* The statistics that can be achieved per zone
|
||||
*/
|
||||
@@ -61,17 +63,17 @@ 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;
|
||||
void UpdateXml(tinyxml2::XMLDocument* doc) override;
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
/**
|
||||
* Updates the rocket configuration using a LOT string separated by commas
|
||||
@@ -289,6 +291,22 @@ public:
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
@@ -579,6 +597,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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "CollectibleComponent.h"
|
||||
|
||||
void CollectibleComponent::Serialize(RakNet::BitStream* outBitStream, bool isConstruction) {
|
||||
outBitStream->Write(GetCollectibleId());
|
||||
void CollectibleComponent::Serialize(RakNet::BitStream& outBitStream, bool isConstruction) {
|
||||
outBitStream.Write(GetCollectibleId());
|
||||
}
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
#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; }
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool isConstruction) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool isConstruction) override;
|
||||
private:
|
||||
int16_t m_CollectibleId = 0;
|
||||
};
|
||||
|
||||
@@ -29,6 +29,6 @@ void Component::LoadFromXml(tinyxml2::XMLDocument* doc) {
|
||||
|
||||
}
|
||||
|
||||
void Component::Serialize(RakNet::BitStream* outBitStream, bool isConstruction) {
|
||||
void Component::Serialize(RakNet::BitStream& outBitStream, bool isConstruction) {
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
@@ -43,7 +42,7 @@ public:
|
||||
*/
|
||||
virtual void LoadFromXml(tinyxml2::XMLDocument* doc);
|
||||
|
||||
virtual void Serialize(RakNet::BitStream* outBitStream, bool isConstruction);
|
||||
virtual void Serialize(RakNet::BitStream& outBitStream, bool isConstruction);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
@@ -21,14 +21,11 @@ ControllablePhysicsComponent::ControllablePhysicsComponent(Entity* entity) : Phy
|
||||
m_InJetpackMode = false;
|
||||
m_IsOnGround = true;
|
||||
m_IsOnRail = false;
|
||||
m_DirtyVelocity = true;
|
||||
m_DirtyAngularVelocity = true;
|
||||
m_dpEntity = nullptr;
|
||||
m_Static = false;
|
||||
m_SpeedMultiplier = 1;
|
||||
m_GravityScale = 1;
|
||||
m_DirtyCheats = false;
|
||||
m_IgnoreMultipliers = false;
|
||||
|
||||
m_DirtyEquippedItemInfo = true;
|
||||
m_PickupRadius = 0.0f;
|
||||
@@ -57,13 +54,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,90 +68,93 @@ void ControllablePhysicsComponent::Update(float deltaTime) {
|
||||
|
||||
}
|
||||
|
||||
void ControllablePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
void ControllablePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
//If this is a creation, then we assume the position is dirty, even when it isn't.
|
||||
//This is because new clients will still need to receive the position.
|
||||
//if (bIsInitialUpdate) m_DirtyPosition = true;
|
||||
|
||||
if (bIsInitialUpdate) {
|
||||
outBitStream->Write(m_InJetpackMode);
|
||||
outBitStream.Write(m_InJetpackMode);
|
||||
if (m_InJetpackMode) {
|
||||
outBitStream->Write(m_JetpackEffectID);
|
||||
outBitStream->Write(m_JetpackFlying);
|
||||
outBitStream->Write(m_JetpackBypassChecks);
|
||||
outBitStream.Write(m_JetpackEffectID);
|
||||
outBitStream.Write(m_JetpackFlying);
|
||||
outBitStream.Write(m_JetpackBypassChecks);
|
||||
}
|
||||
|
||||
outBitStream->Write1(); // always write these on construction
|
||||
outBitStream->Write(m_ImmuneToStunMoveCount);
|
||||
outBitStream->Write(m_ImmuneToStunJumpCount);
|
||||
outBitStream->Write(m_ImmuneToStunTurnCount);
|
||||
outBitStream->Write(m_ImmuneToStunAttackCount);
|
||||
outBitStream->Write(m_ImmuneToStunUseItemCount);
|
||||
outBitStream->Write(m_ImmuneToStunEquipCount);
|
||||
outBitStream->Write(m_ImmuneToStunInteractCount);
|
||||
outBitStream.Write1(); // always write these on construction
|
||||
outBitStream.Write(m_ImmuneToStunMoveCount);
|
||||
outBitStream.Write(m_ImmuneToStunJumpCount);
|
||||
outBitStream.Write(m_ImmuneToStunTurnCount);
|
||||
outBitStream.Write(m_ImmuneToStunAttackCount);
|
||||
outBitStream.Write(m_ImmuneToStunUseItemCount);
|
||||
outBitStream.Write(m_ImmuneToStunEquipCount);
|
||||
outBitStream.Write(m_ImmuneToStunInteractCount);
|
||||
}
|
||||
|
||||
if (m_IgnoreMultipliers) m_DirtyCheats = false;
|
||||
outBitStream.Write(m_DirtyCheats || bIsInitialUpdate);
|
||||
if (m_DirtyCheats || bIsInitialUpdate) {
|
||||
outBitStream.Write(m_GravityScale);
|
||||
outBitStream.Write(m_SpeedMultiplier);
|
||||
|
||||
outBitStream->Write(m_DirtyCheats);
|
||||
if (m_DirtyCheats) {
|
||||
outBitStream->Write(m_GravityScale);
|
||||
outBitStream->Write(m_SpeedMultiplier);
|
||||
|
||||
m_DirtyCheats = false;
|
||||
if (!bIsInitialUpdate) m_DirtyCheats = false;
|
||||
}
|
||||
|
||||
outBitStream->Write(m_DirtyEquippedItemInfo);
|
||||
if (m_DirtyEquippedItemInfo) {
|
||||
outBitStream->Write(m_PickupRadius);
|
||||
outBitStream->Write(m_InJetpackMode);
|
||||
m_DirtyEquippedItemInfo = false;
|
||||
outBitStream.Write(m_DirtyEquippedItemInfo || bIsInitialUpdate);
|
||||
if (m_DirtyEquippedItemInfo || bIsInitialUpdate) {
|
||||
outBitStream.Write(m_PickupRadius);
|
||||
outBitStream.Write(m_InJetpackMode);
|
||||
|
||||
if (!bIsInitialUpdate) m_DirtyEquippedItemInfo = false;
|
||||
}
|
||||
|
||||
outBitStream->Write(m_DirtyBubble);
|
||||
if (m_DirtyBubble) {
|
||||
outBitStream->Write(m_IsInBubble);
|
||||
outBitStream.Write(m_DirtyBubble || bIsInitialUpdate);
|
||||
if (m_DirtyBubble || bIsInitialUpdate) {
|
||||
outBitStream.Write(m_IsInBubble);
|
||||
if (m_IsInBubble) {
|
||||
outBitStream->Write(m_BubbleType);
|
||||
outBitStream->Write(m_SpecialAnims);
|
||||
outBitStream.Write(m_BubbleType);
|
||||
outBitStream.Write(m_SpecialAnims);
|
||||
}
|
||||
m_DirtyBubble = false;
|
||||
|
||||
if (!bIsInitialUpdate) m_DirtyBubble = false;
|
||||
}
|
||||
|
||||
outBitStream->Write(m_DirtyPosition || bIsInitialUpdate);
|
||||
outBitStream.Write(m_DirtyPosition || bIsInitialUpdate);
|
||||
if (m_DirtyPosition || bIsInitialUpdate) {
|
||||
outBitStream->Write(m_Position.x);
|
||||
outBitStream->Write(m_Position.y);
|
||||
outBitStream->Write(m_Position.z);
|
||||
outBitStream.Write(m_Position.x);
|
||||
outBitStream.Write(m_Position.y);
|
||||
outBitStream.Write(m_Position.z);
|
||||
|
||||
outBitStream->Write(m_Rotation.x);
|
||||
outBitStream->Write(m_Rotation.y);
|
||||
outBitStream->Write(m_Rotation.z);
|
||||
outBitStream->Write(m_Rotation.w);
|
||||
outBitStream.Write(m_Rotation.x);
|
||||
outBitStream.Write(m_Rotation.y);
|
||||
outBitStream.Write(m_Rotation.z);
|
||||
outBitStream.Write(m_Rotation.w);
|
||||
|
||||
outBitStream->Write(m_IsOnGround);
|
||||
outBitStream->Write(m_IsOnRail);
|
||||
outBitStream.Write(m_IsOnGround);
|
||||
outBitStream.Write(m_IsOnRail);
|
||||
|
||||
outBitStream->Write(m_DirtyVelocity);
|
||||
if (m_DirtyVelocity) {
|
||||
outBitStream->Write(m_Velocity.x);
|
||||
outBitStream->Write(m_Velocity.y);
|
||||
outBitStream->Write(m_Velocity.z);
|
||||
bool isNotZero = m_Velocity != NiPoint3Constant::ZERO;
|
||||
outBitStream.Write(isNotZero);
|
||||
if (isNotZero) {
|
||||
outBitStream.Write(m_Velocity.x);
|
||||
outBitStream.Write(m_Velocity.y);
|
||||
outBitStream.Write(m_Velocity.z);
|
||||
}
|
||||
|
||||
outBitStream->Write(m_DirtyAngularVelocity);
|
||||
if (m_DirtyAngularVelocity) {
|
||||
outBitStream->Write(m_AngularVelocity.x);
|
||||
outBitStream->Write(m_AngularVelocity.y);
|
||||
outBitStream->Write(m_AngularVelocity.z);
|
||||
isNotZero = m_AngularVelocity != NiPoint3Constant::ZERO;
|
||||
outBitStream.Write(isNotZero);
|
||||
if (isNotZero) {
|
||||
outBitStream.Write(m_AngularVelocity.x);
|
||||
outBitStream.Write(m_AngularVelocity.y);
|
||||
outBitStream.Write(m_AngularVelocity.z);
|
||||
}
|
||||
|
||||
outBitStream->Write0();
|
||||
}
|
||||
outBitStream.Write0(); // local_space_info, always zero for now.
|
||||
|
||||
if (!bIsInitialUpdate) {
|
||||
outBitStream->Write(m_IsTeleporting);
|
||||
m_IsTeleporting = false;
|
||||
if (!bIsInitialUpdate) {
|
||||
m_DirtyPosition = false;
|
||||
outBitStream.Write(m_IsTeleporting);
|
||||
m_IsTeleporting = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,33 +211,29 @@ void ControllablePhysicsComponent::SetRotation(const NiQuaternion& rot) {
|
||||
}
|
||||
|
||||
void ControllablePhysicsComponent::SetVelocity(const NiPoint3& vel) {
|
||||
if (m_Static) {
|
||||
return;
|
||||
}
|
||||
if (m_Static || m_Velocity == vel) return;
|
||||
|
||||
m_Velocity = vel;
|
||||
m_DirtyPosition = true;
|
||||
m_DirtyVelocity = true;
|
||||
|
||||
if (m_dpEntity) m_dpEntity->SetVelocity(vel);
|
||||
}
|
||||
|
||||
void ControllablePhysicsComponent::SetAngularVelocity(const NiPoint3& vel) {
|
||||
if (m_Static) {
|
||||
return;
|
||||
}
|
||||
if (m_Static || m_AngularVelocity == vel) return;
|
||||
|
||||
m_AngularVelocity = vel;
|
||||
m_DirtyPosition = true;
|
||||
m_DirtyAngularVelocity = true;
|
||||
}
|
||||
|
||||
void ControllablePhysicsComponent::SetIsOnGround(bool val) {
|
||||
if (m_IsOnGround == val) return;
|
||||
m_DirtyPosition = true;
|
||||
m_IsOnGround = val;
|
||||
}
|
||||
|
||||
void ControllablePhysicsComponent::SetIsOnRail(bool val) {
|
||||
if (m_IsOnRail == val) return;
|
||||
m_DirtyPosition = true;
|
||||
m_IsOnRail = val;
|
||||
}
|
||||
@@ -245,15 +241,6 @@ void ControllablePhysicsComponent::SetIsOnRail(bool val) {
|
||||
void ControllablePhysicsComponent::SetDirtyPosition(bool val) {
|
||||
m_DirtyPosition = val;
|
||||
}
|
||||
|
||||
void ControllablePhysicsComponent::SetDirtyVelocity(bool val) {
|
||||
m_DirtyVelocity = val;
|
||||
}
|
||||
|
||||
void ControllablePhysicsComponent::SetDirtyAngularVelocity(bool val) {
|
||||
m_DirtyAngularVelocity = val;
|
||||
}
|
||||
|
||||
void ControllablePhysicsComponent::AddPickupRadiusScale(float value) {
|
||||
m_ActivePickupRadiusScales.push_back(value);
|
||||
if (value > m_PickupRadius) {
|
||||
@@ -309,7 +296,7 @@ void ControllablePhysicsComponent::RemoveSpeedboost(float value) {
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
}
|
||||
|
||||
void ControllablePhysicsComponent::ActivateBubbleBuff(eBubbleType bubbleType, bool specialAnims){
|
||||
void ControllablePhysicsComponent::ActivateBubbleBuff(eBubbleType bubbleType, bool specialAnims) {
|
||||
if (m_IsInBubble) {
|
||||
LOG("Already in bubble");
|
||||
return;
|
||||
@@ -321,7 +308,7 @@ void ControllablePhysicsComponent::ActivateBubbleBuff(eBubbleType bubbleType, bo
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
}
|
||||
|
||||
void ControllablePhysicsComponent::DeactivateBubbleBuff(){
|
||||
void ControllablePhysicsComponent::DeactivateBubbleBuff() {
|
||||
m_DirtyBubble = true;
|
||||
m_IsInBubble = false;
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
@@ -336,9 +323,9 @@ void ControllablePhysicsComponent::SetStunImmunity(
|
||||
const bool bImmuneToStunJump,
|
||||
const bool bImmuneToStunMove,
|
||||
const bool bImmuneToStunTurn,
|
||||
const bool bImmuneToStunUseItem){
|
||||
const bool bImmuneToStunUseItem) {
|
||||
|
||||
if (state == eStateChangeType::POP){
|
||||
if (state == eStateChangeType::POP) {
|
||||
if (bImmuneToStunAttack && m_ImmuneToStunAttackCount > 0) m_ImmuneToStunAttackCount -= 1;
|
||||
if (bImmuneToStunEquip && m_ImmuneToStunEquipCount > 0) m_ImmuneToStunEquipCount -= 1;
|
||||
if (bImmuneToStunInteract && m_ImmuneToStunInteractCount > 0) m_ImmuneToStunInteractCount -= 1;
|
||||
|
||||
@@ -21,13 +21,13 @@ 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;
|
||||
|
||||
void Update(float deltaTime) override;
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
void LoadFromXml(tinyxml2::XMLDocument* doc) override;
|
||||
void UpdateXml(tinyxml2::XMLDocument* doc) override;
|
||||
|
||||
@@ -104,18 +104,6 @@ public:
|
||||
*/
|
||||
void SetDirtyPosition(bool val);
|
||||
|
||||
/**
|
||||
* Mark the velocity as dirty, forcing a serializtion update next tick
|
||||
* @param val whether or not the velocity is dirty
|
||||
*/
|
||||
void SetDirtyVelocity(bool val);
|
||||
|
||||
/**
|
||||
* Mark the angular velocity as dirty, forcing a serialization update next tick
|
||||
* @param val whether or not the angular velocity is dirty
|
||||
*/
|
||||
void SetDirtyAngularVelocity(bool val);
|
||||
|
||||
/**
|
||||
* Sets whether or not the entity is currently wearing a jetpack
|
||||
* @param val whether or not the entity is currently wearing a jetpack
|
||||
@@ -186,18 +174,6 @@ public:
|
||||
*/
|
||||
const float GetGravityScale() const { return m_GravityScale; }
|
||||
|
||||
/**
|
||||
* Sets the ignore multipliers value, allowing you to skip the serialization of speed and gravity multipliers
|
||||
* @param value whether or not to ignore multipliers
|
||||
*/
|
||||
void SetIgnoreMultipliers(bool value) { m_IgnoreMultipliers = value; }
|
||||
|
||||
/**
|
||||
* Returns the current ignore multipliers value
|
||||
* @return the current ignore multipliers value
|
||||
*/
|
||||
const bool GetIgnoreMultipliers() const { return m_IgnoreMultipliers; }
|
||||
|
||||
/**
|
||||
* Can make an entity static, making it unable to move around
|
||||
* @param value whether or not the entity is static
|
||||
@@ -310,21 +286,11 @@ private:
|
||||
*/
|
||||
dpEntity* m_dpEntity;
|
||||
|
||||
/**
|
||||
* Whether or not the velocity is dirty, forcing a serialization of the velocity
|
||||
*/
|
||||
bool m_DirtyVelocity;
|
||||
|
||||
/**
|
||||
* The current velocity of the entity
|
||||
*/
|
||||
NiPoint3 m_Velocity;
|
||||
|
||||
/**
|
||||
* Whether or not the angular velocity is dirty, forcing a serialization
|
||||
*/
|
||||
bool m_DirtyAngularVelocity;
|
||||
|
||||
/**
|
||||
* The current angular velocity of the entity
|
||||
*/
|
||||
@@ -375,11 +341,6 @@ private:
|
||||
*/
|
||||
bool m_DirtyCheats;
|
||||
|
||||
/**
|
||||
* Makes it so that the speed multiplier and gravity scale are no longer serialized if false
|
||||
*/
|
||||
bool m_IgnoreMultipliers;
|
||||
|
||||
/**
|
||||
* Whether this entity is static, making it unable to move
|
||||
*/
|
||||
|
||||
@@ -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) {
|
||||
@@ -122,61 +122,61 @@ void DestroyableComponent::Reinitialize(LOT templateID) {
|
||||
}
|
||||
}
|
||||
|
||||
void DestroyableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
void DestroyableComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
if (bIsInitialUpdate) {
|
||||
outBitStream->Write1(); // always write these on construction
|
||||
outBitStream->Write(m_ImmuneToBasicAttackCount);
|
||||
outBitStream->Write(m_ImmuneToDamageOverTimeCount);
|
||||
outBitStream->Write(m_ImmuneToKnockbackCount);
|
||||
outBitStream->Write(m_ImmuneToInterruptCount);
|
||||
outBitStream->Write(m_ImmuneToSpeedCount);
|
||||
outBitStream->Write(m_ImmuneToImaginationGainCount);
|
||||
outBitStream->Write(m_ImmuneToImaginationLossCount);
|
||||
outBitStream->Write(m_ImmuneToQuickbuildInterruptCount);
|
||||
outBitStream->Write(m_ImmuneToPullToPointCount);
|
||||
outBitStream.Write1(); // always write these on construction
|
||||
outBitStream.Write(m_ImmuneToBasicAttackCount);
|
||||
outBitStream.Write(m_ImmuneToDamageOverTimeCount);
|
||||
outBitStream.Write(m_ImmuneToKnockbackCount);
|
||||
outBitStream.Write(m_ImmuneToInterruptCount);
|
||||
outBitStream.Write(m_ImmuneToSpeedCount);
|
||||
outBitStream.Write(m_ImmuneToImaginationGainCount);
|
||||
outBitStream.Write(m_ImmuneToImaginationLossCount);
|
||||
outBitStream.Write(m_ImmuneToQuickbuildInterruptCount);
|
||||
outBitStream.Write(m_ImmuneToPullToPointCount);
|
||||
}
|
||||
|
||||
outBitStream->Write(m_DirtyHealth || bIsInitialUpdate);
|
||||
outBitStream.Write(m_DirtyHealth || bIsInitialUpdate);
|
||||
if (m_DirtyHealth || bIsInitialUpdate) {
|
||||
outBitStream->Write(m_iHealth);
|
||||
outBitStream->Write(m_fMaxHealth);
|
||||
outBitStream->Write(m_iArmor);
|
||||
outBitStream->Write(m_fMaxArmor);
|
||||
outBitStream->Write(m_iImagination);
|
||||
outBitStream->Write(m_fMaxImagination);
|
||||
outBitStream.Write(m_iHealth);
|
||||
outBitStream.Write(m_fMaxHealth);
|
||||
outBitStream.Write(m_iArmor);
|
||||
outBitStream.Write(m_fMaxArmor);
|
||||
outBitStream.Write(m_iImagination);
|
||||
outBitStream.Write(m_fMaxImagination);
|
||||
|
||||
outBitStream->Write(m_DamageToAbsorb);
|
||||
outBitStream->Write(IsImmune());
|
||||
outBitStream->Write(m_IsGMImmune);
|
||||
outBitStream->Write(m_IsShielded);
|
||||
outBitStream.Write(m_DamageToAbsorb);
|
||||
outBitStream.Write(IsImmune());
|
||||
outBitStream.Write(m_IsGMImmune);
|
||||
outBitStream.Write(m_IsShielded);
|
||||
|
||||
outBitStream->Write(m_fMaxHealth);
|
||||
outBitStream->Write(m_fMaxArmor);
|
||||
outBitStream->Write(m_fMaxImagination);
|
||||
outBitStream.Write(m_fMaxHealth);
|
||||
outBitStream.Write(m_fMaxArmor);
|
||||
outBitStream.Write(m_fMaxImagination);
|
||||
|
||||
outBitStream->Write<uint32_t>(m_FactionIDs.size());
|
||||
outBitStream.Write<uint32_t>(m_FactionIDs.size());
|
||||
for (size_t i = 0; i < m_FactionIDs.size(); ++i) {
|
||||
outBitStream->Write(m_FactionIDs[i]);
|
||||
outBitStream.Write(m_FactionIDs[i]);
|
||||
}
|
||||
|
||||
outBitStream->Write(m_IsSmashable);
|
||||
outBitStream.Write(m_IsSmashable);
|
||||
|
||||
if (bIsInitialUpdate) {
|
||||
outBitStream->Write(m_IsDead);
|
||||
outBitStream->Write(m_IsSmashed);
|
||||
outBitStream.Write(m_IsDead);
|
||||
outBitStream.Write(m_IsSmashed);
|
||||
|
||||
if (m_IsSmashable) {
|
||||
outBitStream->Write(m_IsModuleAssembly);
|
||||
outBitStream->Write(m_ExplodeFactor != 1.0f);
|
||||
if (m_ExplodeFactor != 1.0f) outBitStream->Write(m_ExplodeFactor);
|
||||
outBitStream.Write(m_IsModuleAssembly);
|
||||
outBitStream.Write(m_ExplodeFactor != 1.0f);
|
||||
if (m_ExplodeFactor != 1.0f) outBitStream.Write(m_ExplodeFactor);
|
||||
}
|
||||
}
|
||||
m_DirtyHealth = false;
|
||||
}
|
||||
|
||||
outBitStream->Write(m_DirtyThreatList || bIsInitialUpdate);
|
||||
outBitStream.Write(m_DirtyThreatList || bIsInitialUpdate);
|
||||
if (m_DirtyThreatList || bIsInitialUpdate) {
|
||||
outBitStream->Write(m_HasThreats);
|
||||
outBitStream.Write(m_HasThreats);
|
||||
m_DirtyThreatList = false;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -782,16 +785,12 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType
|
||||
}
|
||||
|
||||
Entity* zoneControl = Game::entityManager->GetZoneControlEntity();
|
||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) {
|
||||
script->OnPlayerDied(zoneControl, m_Parent);
|
||||
}
|
||||
if (zoneControl) zoneControl->GetScript()->OnPlayerDied(zoneControl, m_Parent);
|
||||
|
||||
std::vector<Entity*> scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY);
|
||||
for (Entity* scriptEntity : scriptedActs) {
|
||||
if (scriptEntity->GetObjectID() != zoneControl->GetObjectID()) { // Don't want to trigger twice on instance worlds
|
||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(scriptEntity)) {
|
||||
script->OnPlayerDied(scriptEntity, m_Parent);
|
||||
}
|
||||
scriptEntity->GetScript()->OnPlayerDied(scriptEntity, m_Parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,15 +17,15 @@ 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;
|
||||
|
||||
void Update(float deltaTime) override;
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
void LoadFromXml(tinyxml2::XMLDocument* doc) override;
|
||||
void UpdateXml(tinyxml2::XMLDocument* doc) override;
|
||||
|
||||
|
||||
@@ -36,13 +36,13 @@ void DonationVendorComponent::SubmitDonation(uint32_t count) {
|
||||
m_DirtyDonationVendor = true;
|
||||
}
|
||||
|
||||
void DonationVendorComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
void DonationVendorComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
VendorComponent::Serialize(outBitStream, bIsInitialUpdate);
|
||||
outBitStream->Write(bIsInitialUpdate || m_DirtyDonationVendor);
|
||||
outBitStream.Write(bIsInitialUpdate || m_DirtyDonationVendor);
|
||||
if (bIsInitialUpdate || m_DirtyDonationVendor) {
|
||||
outBitStream->Write(m_PercentComplete);
|
||||
outBitStream->Write(m_TotalDonated);
|
||||
outBitStream->Write(m_TotalRemaining);
|
||||
outBitStream.Write(m_PercentComplete);
|
||||
outBitStream.Write(m_TotalDonated);
|
||||
outBitStream.Write(m_TotalRemaining);
|
||||
if (!bIsInitialUpdate) m_DirtyDonationVendor = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ 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;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
uint32_t GetActivityID() {return m_ActivityId;};
|
||||
void SubmitDonation(uint32_t count);
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#include "GhostComponent.h"
|
||||
|
||||
GhostComponent::GhostComponent(Entity* parent) : Component(parent) {
|
||||
m_GhostReferencePoint = NiPoint3::ZERO;
|
||||
m_GhostOverridePoint = NiPoint3::ZERO;
|
||||
m_GhostReferencePoint = NiPoint3Constant::ZERO;
|
||||
m_GhostOverridePoint = NiPoint3Constant::ZERO;
|
||||
m_GhostOverride = false;
|
||||
}
|
||||
|
||||
GhostComponent::~GhostComponent() {
|
||||
for (auto& observedEntity : m_ObservedEntities) {
|
||||
if (observedEntity == 0) continue;
|
||||
if (observedEntity == LWOOBJID_EMPTY) continue;
|
||||
|
||||
auto* entity = Game::entityManager->GetGhostCandidate(observedEntity);
|
||||
if (!entity) continue;
|
||||
@@ -44,14 +44,14 @@ void GhostComponent::ConstructLimboEntities() {
|
||||
m_LimboConstructions.clear();
|
||||
}
|
||||
|
||||
void GhostComponent::ObserveEntity(int32_t id) {
|
||||
void GhostComponent::ObserveEntity(LWOOBJID id) {
|
||||
m_ObservedEntities.insert(id);
|
||||
}
|
||||
|
||||
bool GhostComponent::IsObserved(int32_t id) {
|
||||
bool GhostComponent::IsObserved(LWOOBJID id) {
|
||||
return m_ObservedEntities.contains(id);
|
||||
}
|
||||
|
||||
void GhostComponent::GhostEntity(int32_t id) {
|
||||
void GhostComponent::GhostEntity(LWOOBJID id) {
|
||||
m_ObservedEntities.erase(id);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
class NiPoint3;
|
||||
|
||||
class GhostComponent : public Component {
|
||||
class GhostComponent final : public Component {
|
||||
public:
|
||||
static inline const eReplicaComponentType ComponentType = eReplicaComponentType::GHOST;
|
||||
GhostComponent(Entity* parent);
|
||||
@@ -33,18 +33,18 @@ public:
|
||||
|
||||
void ConstructLimboEntities();
|
||||
|
||||
void ObserveEntity(const int32_t id);
|
||||
void ObserveEntity(const LWOOBJID id);
|
||||
|
||||
bool IsObserved(const int32_t id);
|
||||
bool IsObserved(const LWOOBJID id);
|
||||
|
||||
void GhostEntity(const int32_t id);
|
||||
void GhostEntity(const LWOOBJID id);
|
||||
|
||||
private:
|
||||
NiPoint3 m_GhostReferencePoint;
|
||||
|
||||
NiPoint3 m_GhostOverridePoint;
|
||||
|
||||
std::unordered_set<int32_t> m_ObservedEntities;
|
||||
std::unordered_set<LWOOBJID> m_ObservedEntities;
|
||||
|
||||
std::unordered_set<LWOOBJID> m_LimboConstructions;
|
||||
|
||||
|
||||
@@ -2,13 +2,11 @@
|
||||
#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;
|
||||
m_DirtyVelocity = true;
|
||||
m_DirtyAngularVelocity = true;
|
||||
m_EndBehavior = GeneralUtils::GenerateRandomNumber<uint32_t>(0, 7);
|
||||
}
|
||||
|
||||
@@ -37,85 +35,66 @@ void HavokVehiclePhysicsComponent::SetIsOnRail(bool val) {
|
||||
}
|
||||
|
||||
void HavokVehiclePhysicsComponent::SetRemoteInputInfo(const RemoteInputInfo& remoteInputInfo) {
|
||||
if (m_RemoteInputInfo == remoteInputInfo) return;
|
||||
if (remoteInputInfo == m_RemoteInputInfo) return;
|
||||
this->m_RemoteInputInfo = remoteInputInfo;
|
||||
m_DirtyRemoteInput = true;
|
||||
m_DirtyPosition = true;
|
||||
}
|
||||
|
||||
void HavokVehiclePhysicsComponent::SetDirtyVelocity(bool val) {
|
||||
m_DirtyVelocity = val;
|
||||
}
|
||||
|
||||
void HavokVehiclePhysicsComponent::SetDirtyAngularVelocity(bool val) {
|
||||
m_DirtyAngularVelocity = val;
|
||||
}
|
||||
|
||||
void HavokVehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream->Write(bIsInitialUpdate || m_DirtyPosition);
|
||||
void HavokVehiclePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream.Write(bIsInitialUpdate || m_DirtyPosition);
|
||||
|
||||
if (bIsInitialUpdate || m_DirtyPosition) {
|
||||
m_DirtyPosition = false;
|
||||
outBitStream->Write(m_Position.x);
|
||||
outBitStream->Write(m_Position.y);
|
||||
outBitStream->Write(m_Position.z);
|
||||
outBitStream.Write(m_Position.x);
|
||||
outBitStream.Write(m_Position.y);
|
||||
outBitStream.Write(m_Position.z);
|
||||
|
||||
outBitStream->Write(m_Rotation.x);
|
||||
outBitStream->Write(m_Rotation.y);
|
||||
outBitStream->Write(m_Rotation.z);
|
||||
outBitStream->Write(m_Rotation.w);
|
||||
outBitStream.Write(m_Rotation.x);
|
||||
outBitStream.Write(m_Rotation.y);
|
||||
outBitStream.Write(m_Rotation.z);
|
||||
outBitStream.Write(m_Rotation.w);
|
||||
|
||||
outBitStream->Write(m_IsOnGround);
|
||||
outBitStream->Write(m_IsOnRail);
|
||||
outBitStream.Write(m_IsOnGround);
|
||||
outBitStream.Write(m_IsOnRail);
|
||||
|
||||
outBitStream->Write(bIsInitialUpdate || m_DirtyVelocity);
|
||||
|
||||
if (bIsInitialUpdate || m_DirtyVelocity) {
|
||||
outBitStream->Write(m_Velocity.x);
|
||||
outBitStream->Write(m_Velocity.y);
|
||||
outBitStream->Write(m_Velocity.z);
|
||||
m_DirtyVelocity = false;
|
||||
bool isNotZero = m_Velocity != NiPoint3Constant::ZERO;
|
||||
outBitStream.Write(isNotZero);
|
||||
if (isNotZero) {
|
||||
outBitStream.Write(m_Velocity.x);
|
||||
outBitStream.Write(m_Velocity.y);
|
||||
outBitStream.Write(m_Velocity.z);
|
||||
}
|
||||
|
||||
outBitStream->Write(bIsInitialUpdate || m_DirtyAngularVelocity);
|
||||
|
||||
if (bIsInitialUpdate || m_DirtyAngularVelocity) {
|
||||
outBitStream->Write(m_AngularVelocity.x);
|
||||
outBitStream->Write(m_AngularVelocity.y);
|
||||
outBitStream->Write(m_AngularVelocity.z);
|
||||
m_DirtyAngularVelocity = false;
|
||||
isNotZero = m_AngularVelocity != NiPoint3Constant::ZERO;
|
||||
outBitStream.Write(isNotZero);
|
||||
if (isNotZero) {
|
||||
outBitStream.Write(m_AngularVelocity.x);
|
||||
outBitStream.Write(m_AngularVelocity.y);
|
||||
outBitStream.Write(m_AngularVelocity.z);
|
||||
}
|
||||
|
||||
outBitStream->Write0(); // local_space_info. TODO: Implement this
|
||||
outBitStream.Write0(); // local_space_info. TODO: Implement this
|
||||
|
||||
outBitStream->Write(m_DirtyRemoteInput || bIsInitialUpdate); // remote_input_info
|
||||
if (m_DirtyRemoteInput || bIsInitialUpdate) {
|
||||
outBitStream->Write(m_RemoteInputInfo.m_RemoteInputX);
|
||||
outBitStream->Write(m_RemoteInputInfo.m_RemoteInputY);
|
||||
outBitStream->Write(m_RemoteInputInfo.m_IsPowersliding);
|
||||
outBitStream->Write(m_RemoteInputInfo.m_IsModified);
|
||||
m_DirtyRemoteInput = false;
|
||||
}
|
||||
// This structure only has this bool flag set to false if a ptr to the peVehicle is null, which we don't have
|
||||
// therefore, this will always be 1, even if all the values in the structure are 0.
|
||||
outBitStream.Write1(); // has remote_input_info
|
||||
outBitStream.Write(m_RemoteInputInfo.m_RemoteInputX);
|
||||
outBitStream.Write(m_RemoteInputInfo.m_RemoteInputY);
|
||||
outBitStream.Write(m_RemoteInputInfo.m_IsPowersliding);
|
||||
outBitStream.Write(m_RemoteInputInfo.m_IsModified);
|
||||
|
||||
outBitStream->Write(125.0f); // remote_input_ping TODO: Figure out how this should be calculated as it seems to be constant through the whole race.
|
||||
|
||||
outBitStream.Write(125.0f); // remote_input_ping TODO: Figure out how this should be calculated as it seems to be constant through the whole race.
|
||||
|
||||
if (!bIsInitialUpdate) {
|
||||
outBitStream->Write0();
|
||||
outBitStream.Write0();
|
||||
}
|
||||
}
|
||||
|
||||
if (bIsInitialUpdate) {
|
||||
outBitStream->Write<uint8_t>(m_EndBehavior);
|
||||
outBitStream->Write1(); // is input locked?
|
||||
outBitStream.Write<uint8_t>(m_EndBehavior);
|
||||
outBitStream.Write1(); // is input locked?
|
||||
}
|
||||
|
||||
outBitStream->Write0();
|
||||
}
|
||||
|
||||
void HavokVehiclePhysicsComponent::Update(float deltaTime) {
|
||||
if (m_SoftUpdate > 5) {
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
m_SoftUpdate = 0;
|
||||
} else {
|
||||
m_SoftUpdate += deltaTime;
|
||||
}
|
||||
outBitStream.Write0();
|
||||
}
|
||||
|
||||
@@ -11,13 +11,11 @@
|
||||
*/
|
||||
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);
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
void Update(float deltaTime) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
/**
|
||||
* Sets the velocity
|
||||
@@ -67,22 +65,16 @@ public:
|
||||
*/
|
||||
const bool GetIsOnRail() const { return m_IsOnRail; }
|
||||
|
||||
void SetDirtyPosition(bool val);
|
||||
void SetDirtyVelocity(bool val);
|
||||
void SetDirtyAngularVelocity(bool val);
|
||||
void SetRemoteInputInfo(const RemoteInputInfo&);
|
||||
|
||||
private:
|
||||
bool m_DirtyVelocity;
|
||||
NiPoint3 m_Velocity;
|
||||
|
||||
bool m_DirtyAngularVelocity;
|
||||
NiPoint3 m_AngularVelocity;
|
||||
|
||||
bool m_IsOnGround;
|
||||
bool m_IsOnRail;
|
||||
|
||||
float m_SoftUpdate = 0;
|
||||
uint32_t m_EndBehavior;
|
||||
RemoteInputInfo m_RemoteInputInfo;
|
||||
bool m_DirtyRemoteInput;
|
||||
};
|
||||
|
||||
@@ -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"
|
||||
@@ -56,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;
|
||||
@@ -695,11 +694,11 @@ void InventoryComponent::UpdateXml(tinyxml2::XMLDocument* document) {
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryComponent::Serialize(RakNet::BitStream* outBitStream, const bool bIsInitialUpdate) {
|
||||
void InventoryComponent::Serialize(RakNet::BitStream& outBitStream, const bool bIsInitialUpdate) {
|
||||
if (bIsInitialUpdate || m_Dirty) {
|
||||
outBitStream->Write(true);
|
||||
outBitStream.Write(true);
|
||||
|
||||
outBitStream->Write<uint32_t>(m_Equipped.size());
|
||||
outBitStream.Write<uint32_t>(m_Equipped.size());
|
||||
|
||||
for (const auto& pair : m_Equipped) {
|
||||
const auto item = pair.second;
|
||||
@@ -708,21 +707,21 @@ void InventoryComponent::Serialize(RakNet::BitStream* outBitStream, const bool b
|
||||
AddItemSkills(item.lot);
|
||||
}
|
||||
|
||||
outBitStream->Write(item.id);
|
||||
outBitStream->Write(item.lot);
|
||||
outBitStream.Write(item.id);
|
||||
outBitStream.Write(item.lot);
|
||||
|
||||
outBitStream->Write0();
|
||||
outBitStream.Write0();
|
||||
|
||||
outBitStream->Write(item.count > 0);
|
||||
if (item.count > 0) outBitStream->Write(item.count);
|
||||
outBitStream.Write(item.count > 0);
|
||||
if (item.count > 0) outBitStream.Write(item.count);
|
||||
|
||||
outBitStream->Write(item.slot != 0);
|
||||
if (item.slot != 0) outBitStream->Write<uint16_t>(item.slot);
|
||||
outBitStream.Write(item.slot != 0);
|
||||
if (item.slot != 0) outBitStream.Write<uint16_t>(item.slot);
|
||||
|
||||
outBitStream->Write0();
|
||||
outBitStream.Write0();
|
||||
|
||||
bool flag = !item.config.empty();
|
||||
outBitStream->Write(flag);
|
||||
outBitStream.Write(flag);
|
||||
if (flag) {
|
||||
RakNet::BitStream ldfStream;
|
||||
ldfStream.Write<int32_t>(item.config.size()); // Key count
|
||||
@@ -731,26 +730,26 @@ void InventoryComponent::Serialize(RakNet::BitStream* outBitStream, const bool b
|
||||
std::string newRocketStr = data->GetValueAsString() + ";";
|
||||
GeneralUtils::ReplaceInString(newRocketStr, "+", ";");
|
||||
LDFData<std::u16string>* ldf_data = new LDFData<std::u16string>(u"assemblyPartLOTs", GeneralUtils::ASCIIToUTF16(newRocketStr));
|
||||
ldf_data->WriteToPacket(&ldfStream);
|
||||
ldf_data->WriteToPacket(ldfStream);
|
||||
delete ldf_data;
|
||||
} else {
|
||||
data->WriteToPacket(&ldfStream);
|
||||
data->WriteToPacket(ldfStream);
|
||||
}
|
||||
}
|
||||
outBitStream->Write(ldfStream.GetNumberOfBytesUsed() + 1);
|
||||
outBitStream->Write<uint8_t>(0); // Don't compress
|
||||
outBitStream->Write(ldfStream);
|
||||
outBitStream.Write(ldfStream.GetNumberOfBytesUsed() + 1);
|
||||
outBitStream.Write<uint8_t>(0); // Don't compress
|
||||
outBitStream.Write(ldfStream);
|
||||
}
|
||||
|
||||
outBitStream->Write1();
|
||||
outBitStream.Write1();
|
||||
}
|
||||
|
||||
m_Dirty = false;
|
||||
} else {
|
||||
outBitStream->Write(false);
|
||||
outBitStream.Write(false);
|
||||
}
|
||||
|
||||
outBitStream->Write(false);
|
||||
outBitStream.Write(false);
|
||||
}
|
||||
|
||||
void InventoryComponent::Update(float deltaTime) {
|
||||
@@ -910,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) {
|
||||
@@ -925,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) {
|
||||
@@ -1223,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);
|
||||
@@ -1281,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);
|
||||
@@ -1299,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());
|
||||
|
||||
@@ -35,14 +35,13 @@ 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;
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
void LoadXml(tinyxml2::XMLDocument* document);
|
||||
void UpdateXml(tinyxml2::XMLDocument* document) override;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "ItemComponent.h"
|
||||
|
||||
void ItemComponent::Serialize(RakNet::BitStream* outBitStream, bool isConstruction) {
|
||||
outBitStream->Write0();
|
||||
void ItemComponent::Serialize(RakNet::BitStream& outBitStream, bool isConstruction) {
|
||||
outBitStream.Write0();
|
||||
}
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
#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) {}
|
||||
|
||||
void Serialize(RakNet::BitStream* bitStream, bool isConstruction) override;
|
||||
void Serialize(RakNet::BitStream& bitStream, bool isConstruction) override;
|
||||
};
|
||||
|
||||
#endif //!__ITEMCOMPONENT__H__
|
||||
|
||||
@@ -15,10 +15,10 @@ void LUPExhibitComponent::NextLUPExhibit() {
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
}
|
||||
|
||||
void LUPExhibitComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream->Write(m_DirtyLUPExhibit);
|
||||
void LUPExhibitComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream.Write(m_DirtyLUPExhibit);
|
||||
if (m_DirtyLUPExhibit) {
|
||||
outBitStream->Write(m_LUPExhibits[m_LUPExhibitIndex % m_LUPExhibits.size()]);
|
||||
outBitStream.Write(m_LUPExhibits[m_LUPExhibitIndex % m_LUPExhibits.size()]);
|
||||
if (!bIsInitialUpdate) m_DirtyLUPExhibit = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
* 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;
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
void NextLUPExhibit();
|
||||
private:
|
||||
float m_UpdateTimer = 0.0f;
|
||||
|
||||
@@ -37,14 +37,14 @@ void LevelProgressionComponent::LoadFromXml(tinyxml2::XMLDocument* doc) {
|
||||
m_CharacterVersion = static_cast<eCharacterVersion>(characterVersion);
|
||||
}
|
||||
|
||||
void LevelProgressionComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream->Write(bIsInitialUpdate || m_DirtyLevelInfo);
|
||||
if (bIsInitialUpdate || m_DirtyLevelInfo) outBitStream->Write(m_Level);
|
||||
void LevelProgressionComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream.Write(bIsInitialUpdate || m_DirtyLevelInfo);
|
||||
if (bIsInitialUpdate || m_DirtyLevelInfo) outBitStream.Write(m_Level);
|
||||
m_DirtyLevelInfo = false;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -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
|
||||
@@ -21,7 +21,7 @@ public:
|
||||
*/
|
||||
LevelProgressionComponent(Entity* parent);
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
/**
|
||||
* Save data from this componennt to character XML
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "MiniGameControlComponent.h"
|
||||
|
||||
void MiniGameControlComponent::Serialize(RakNet::BitStream* outBitStream, bool isConstruction) {
|
||||
outBitStream->Write<uint32_t>(0x40000000);
|
||||
void MiniGameControlComponent::Serialize(RakNet::BitStream& outBitStream, bool isConstruction) {
|
||||
outBitStream.Write<uint32_t>(0x40000000);
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
|
||||
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);
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool isConstruction);
|
||||
};
|
||||
|
||||
#endif //!__MINIGAMECONTROLCOMPONENT__H__
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "MinigameComponent.h"
|
||||
|
||||
void MinigameComponent::Serialize(RakNet::BitStream* outBitStream, bool isConstruction) {
|
||||
outBitStream->Write<uint32_t>(0x40000000);
|
||||
void MinigameComponent::Serialize(RakNet::BitStream& outBitStream, bool isConstruction) {
|
||||
outBitStream.Write<uint32_t>(0x40000000);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -24,14 +24,13 @@ 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;
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags);
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate, unsigned int& flags);
|
||||
void LoadFromXml(tinyxml2::XMLDocument* doc) override;
|
||||
void UpdateXml(tinyxml2::XMLDocument* doc) override;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -14,26 +14,26 @@ ModelComponent::ModelComponent(Entity* parent) : Component(parent) {
|
||||
m_userModelID = m_Parent->GetVarAs<LWOOBJID>(u"userModelID");
|
||||
}
|
||||
|
||||
void ModelComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
void ModelComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
// ItemComponent Serialization. Pets do not get this serialization.
|
||||
if (!m_Parent->HasComponent(eReplicaComponentType::PET)) {
|
||||
outBitStream->Write1();
|
||||
outBitStream->Write<LWOOBJID>(m_userModelID != LWOOBJID_EMPTY ? m_userModelID : m_Parent->GetObjectID());
|
||||
outBitStream->Write<int>(0);
|
||||
outBitStream->Write0();
|
||||
outBitStream.Write1();
|
||||
outBitStream.Write<LWOOBJID>(m_userModelID != LWOOBJID_EMPTY ? m_userModelID : m_Parent->GetObjectID());
|
||||
outBitStream.Write<int>(0);
|
||||
outBitStream.Write0();
|
||||
}
|
||||
|
||||
//actual model component:
|
||||
outBitStream->Write1(); // Yes we are writing model info
|
||||
outBitStream->Write0(); // Is pickable
|
||||
outBitStream->Write<uint32_t>(2); // Physics type
|
||||
outBitStream->Write(m_OriginalPosition); // Original position
|
||||
outBitStream->Write(m_OriginalRotation); // Original rotation
|
||||
outBitStream.Write1(); // Yes we are writing model info
|
||||
outBitStream.Write0(); // Is pickable
|
||||
outBitStream.Write<uint32_t>(2); // Physics type
|
||||
outBitStream.Write(m_OriginalPosition); // Original position
|
||||
outBitStream.Write(m_OriginalRotation); // Original rotation
|
||||
|
||||
outBitStream->Write1(); // We are writing behavior info
|
||||
outBitStream->Write<uint32_t>(0); // Number of behaviors
|
||||
outBitStream->Write1(); // Is this model paused
|
||||
if (bIsInitialUpdate) outBitStream->Write0(); // We are not writing model editing info
|
||||
outBitStream.Write1(); // We are writing behavior info
|
||||
outBitStream.Write<uint32_t>(0); // Number of behaviors
|
||||
outBitStream.Write1(); // Is this model paused
|
||||
if (bIsInitialUpdate) outBitStream.Write0(); // We are not writing model editing info
|
||||
}
|
||||
|
||||
void ModelComponent::UpdatePendingBehaviorId(const int32_t newId) {
|
||||
|
||||
@@ -22,13 +22,13 @@ 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);
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
/**
|
||||
* Returns the original position of the model
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
* @param args the arguments of the message to be deserialized
|
||||
*/
|
||||
template<typename Msg>
|
||||
void HandleControlBehaviorsMsg(AMFArrayValue* args) {
|
||||
void HandleControlBehaviorsMsg(const AMFArrayValue& args) {
|
||||
static_assert(std::is_base_of_v<BehaviorMessageBase, Msg>, "Msg must be a BehaviorMessageBase");
|
||||
Msg msg(args);
|
||||
for (auto& behavior : m_Behaviors) {
|
||||
|
||||
@@ -46,20 +46,20 @@ const std::u16string& ModuleAssemblyComponent::GetAssemblyPartsLOTs() const {
|
||||
return m_AssemblyPartsLOTs;
|
||||
}
|
||||
|
||||
void ModuleAssemblyComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
void ModuleAssemblyComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
if (bIsInitialUpdate) {
|
||||
outBitStream->Write1();
|
||||
outBitStream.Write1();
|
||||
|
||||
outBitStream->Write(m_SubKey != LWOOBJID_EMPTY);
|
||||
outBitStream.Write(m_SubKey != LWOOBJID_EMPTY);
|
||||
if (m_SubKey != LWOOBJID_EMPTY) {
|
||||
outBitStream->Write(m_SubKey);
|
||||
outBitStream.Write(m_SubKey);
|
||||
}
|
||||
|
||||
outBitStream->Write(m_UseOptionalParts);
|
||||
outBitStream.Write(m_UseOptionalParts);
|
||||
|
||||
outBitStream->Write<uint16_t>(m_AssemblyPartsLOTs.size());
|
||||
outBitStream.Write<uint16_t>(m_AssemblyPartsLOTs.size());
|
||||
for (char16_t character : m_AssemblyPartsLOTs) {
|
||||
outBitStream->Write(character);
|
||||
outBitStream.Write(character);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
* 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;
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
void Update(float deltaTime) override;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -32,25 +32,25 @@ MoverSubComponent::MoverSubComponent(const NiPoint3& startPos) {
|
||||
|
||||
MoverSubComponent::~MoverSubComponent() = default;
|
||||
|
||||
void MoverSubComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream->Write<bool>(true);
|
||||
void MoverSubComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream.Write<bool>(true);
|
||||
|
||||
outBitStream->Write(mState);
|
||||
outBitStream->Write<int32_t>(mDesiredWaypointIndex);
|
||||
outBitStream->Write(mShouldStopAtDesiredWaypoint);
|
||||
outBitStream->Write(mInReverse);
|
||||
outBitStream.Write(mState);
|
||||
outBitStream.Write<int32_t>(mDesiredWaypointIndex);
|
||||
outBitStream.Write(mShouldStopAtDesiredWaypoint);
|
||||
outBitStream.Write(mInReverse);
|
||||
|
||||
outBitStream->Write<float_t>(mPercentBetweenPoints);
|
||||
outBitStream.Write<float_t>(mPercentBetweenPoints);
|
||||
|
||||
outBitStream->Write<float_t>(mPosition.x);
|
||||
outBitStream->Write<float_t>(mPosition.y);
|
||||
outBitStream->Write<float_t>(mPosition.z);
|
||||
outBitStream.Write<float_t>(mPosition.x);
|
||||
outBitStream.Write<float_t>(mPosition.y);
|
||||
outBitStream.Write<float_t>(mPosition.z);
|
||||
|
||||
outBitStream->Write<uint32_t>(mCurrentWaypointIndex);
|
||||
outBitStream->Write<uint32_t>(mNextWaypointIndex);
|
||||
outBitStream.Write<uint32_t>(mCurrentWaypointIndex);
|
||||
outBitStream.Write<uint32_t>(mNextWaypointIndex);
|
||||
|
||||
outBitStream->Write<float_t>(mIdleTimeElapsed);
|
||||
outBitStream->Write<float_t>(0.0f); // Move time elapsed
|
||||
outBitStream.Write<float_t>(mIdleTimeElapsed);
|
||||
outBitStream.Write<float_t>(0.0f); // Move time elapsed
|
||||
}
|
||||
|
||||
//------------- MovingPlatformComponent below --------------
|
||||
@@ -71,43 +71,43 @@ MovingPlatformComponent::~MovingPlatformComponent() {
|
||||
delete static_cast<MoverSubComponent*>(m_MoverSubComponent);
|
||||
}
|
||||
|
||||
void MovingPlatformComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
void MovingPlatformComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
// Here we don't serialize the moving platform to let the client simulate the movement
|
||||
|
||||
if (!m_Serialize) {
|
||||
outBitStream->Write<bool>(false);
|
||||
outBitStream->Write<bool>(false);
|
||||
outBitStream.Write<bool>(false);
|
||||
outBitStream.Write<bool>(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
outBitStream->Write<bool>(true);
|
||||
outBitStream.Write<bool>(true);
|
||||
|
||||
auto hasPath = !m_PathingStopped && !m_PathName.empty();
|
||||
outBitStream->Write(hasPath);
|
||||
outBitStream.Write(hasPath);
|
||||
|
||||
if (hasPath) {
|
||||
// Is on rail
|
||||
outBitStream->Write1();
|
||||
outBitStream.Write1();
|
||||
|
||||
outBitStream->Write<uint16_t>(m_PathName.size());
|
||||
outBitStream.Write<uint16_t>(m_PathName.size());
|
||||
for (const auto& c : m_PathName) {
|
||||
outBitStream->Write<uint16_t>(c);
|
||||
outBitStream.Write<uint16_t>(c);
|
||||
}
|
||||
|
||||
// Starting point
|
||||
outBitStream->Write<uint32_t>(0);
|
||||
outBitStream.Write<uint32_t>(0);
|
||||
|
||||
// Reverse
|
||||
outBitStream->Write<bool>(false);
|
||||
outBitStream.Write<bool>(false);
|
||||
}
|
||||
|
||||
const auto hasPlatform = m_MoverSubComponent != nullptr;
|
||||
outBitStream->Write<bool>(hasPlatform);
|
||||
outBitStream.Write<bool>(hasPlatform);
|
||||
|
||||
if (hasPlatform) {
|
||||
auto* mover = static_cast<MoverSubComponent*>(m_MoverSubComponent);
|
||||
outBitStream->Write(m_MoverSubComponentType);
|
||||
outBitStream.Write(m_MoverSubComponentType);
|
||||
|
||||
if (m_MoverSubComponentType == eMoverSubComponentType::simpleMover) {
|
||||
// TODO
|
||||
@@ -162,7 +162,7 @@ void MovingPlatformComponent::StartPathing() {
|
||||
const auto& nextWaypoint = m_Path->pathWaypoints[subComponent->mNextWaypointIndex];
|
||||
|
||||
subComponent->mPosition = currentWaypoint.position;
|
||||
subComponent->mSpeed = currentWaypoint.movingPlatform.speed;
|
||||
subComponent->mSpeed = currentWaypoint.speed;
|
||||
subComponent->mWaitTime = currentWaypoint.movingPlatform.wait;
|
||||
|
||||
targetPosition = nextWaypoint.position;
|
||||
@@ -183,9 +183,7 @@ void MovingPlatformComponent::StartPathing() {
|
||||
const auto travelNext = subComponent->mWaitTime + travelTime;
|
||||
|
||||
m_Parent->AddCallbackTimer(travelTime, [subComponent, this] {
|
||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) {
|
||||
script->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex);
|
||||
}
|
||||
this->m_Parent->GetScript()->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex);
|
||||
});
|
||||
|
||||
m_Parent->AddCallbackTimer(travelNext, [this] {
|
||||
@@ -213,7 +211,7 @@ void MovingPlatformComponent::ContinuePathing() {
|
||||
const auto& nextWaypoint = m_Path->pathWaypoints[subComponent->mNextWaypointIndex];
|
||||
|
||||
subComponent->mPosition = currentWaypoint.position;
|
||||
subComponent->mSpeed = currentWaypoint.movingPlatform.speed;
|
||||
subComponent->mSpeed = currentWaypoint.speed;
|
||||
subComponent->mWaitTime = currentWaypoint.movingPlatform.wait; // + 2;
|
||||
|
||||
pathSize = m_Path->pathWaypoints.size() - 1;
|
||||
@@ -295,9 +293,7 @@ void MovingPlatformComponent::ContinuePathing() {
|
||||
const auto travelNext = subComponent->mWaitTime + travelTime;
|
||||
|
||||
m_Parent->AddCallbackTimer(travelTime, [subComponent, this] {
|
||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) {
|
||||
script->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex);
|
||||
}
|
||||
this->m_Parent->GetScript()->OnWaypointReached(m_Parent, subComponent->mNextWaypointIndex);
|
||||
});
|
||||
|
||||
m_Parent->AddCallbackTimer(travelNext, [this] {
|
||||
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
MoverSubComponent(const NiPoint3& startPos);
|
||||
~MoverSubComponent();
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate);
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate);
|
||||
|
||||
/**
|
||||
* The state the platform is currently in
|
||||
@@ -104,14 +104,14 @@ 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;
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
/**
|
||||
* Stops all pathing, called when an entity starts a quick build associated with this platform
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -30,6 +30,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{};
|
||||
@@ -70,7 +71,7 @@ std::map<LOT, int32_t> PetComponent::petFlags = {
|
||||
};
|
||||
|
||||
PetComponent::PetComponent(Entity* parentEntity, uint32_t componentId) : Component{ parentEntity } {
|
||||
m_PetInfo = CDClientManager::Instance().GetTable<CDPetComponentTable>()->GetByID(componentId); // TODO: Make reference when safe
|
||||
m_PetInfo = CDClientManager::GetTable<CDPetComponentTable>()->GetByID(componentId); // TODO: Make reference when safe
|
||||
m_ComponentId = componentId;
|
||||
|
||||
m_Interaction = LWOOBJID_EMPTY;
|
||||
@@ -83,7 +84,7 @@ PetComponent::PetComponent(Entity* parentEntity, uint32_t componentId) : Compone
|
||||
m_DatabaseId = LWOOBJID_EMPTY;
|
||||
m_Status = 67108866; // Tamable
|
||||
m_Ability = ePetAbilityType::Invalid;
|
||||
m_StartPosition = NiPoint3::ZERO;
|
||||
m_StartPosition = NiPoint3Constant::ZERO;
|
||||
m_MovementAI = nullptr;
|
||||
m_TresureTime = 0;
|
||||
m_Preconditions = nullptr;
|
||||
@@ -95,42 +96,42 @@ PetComponent::PetComponent(Entity* parentEntity, uint32_t componentId) : Compone
|
||||
}
|
||||
}
|
||||
|
||||
void PetComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
void PetComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
const bool tamed = m_Owner != LWOOBJID_EMPTY;
|
||||
|
||||
outBitStream->Write1(); // Always serialize as dirty for now
|
||||
outBitStream.Write1(); // Always serialize as dirty for now
|
||||
|
||||
outBitStream->Write<uint32_t>(m_Status);
|
||||
outBitStream->Write(tamed ? m_Ability : ePetAbilityType::Invalid); // Something with the overhead icon?
|
||||
outBitStream.Write<uint32_t>(m_Status);
|
||||
outBitStream.Write(tamed ? m_Ability : ePetAbilityType::Invalid); // Something with the overhead icon?
|
||||
|
||||
const bool interacting = m_Interaction != LWOOBJID_EMPTY;
|
||||
|
||||
outBitStream->Write(interacting);
|
||||
outBitStream.Write(interacting);
|
||||
if (interacting) {
|
||||
outBitStream->Write(m_Interaction);
|
||||
outBitStream.Write(m_Interaction);
|
||||
}
|
||||
|
||||
outBitStream->Write(tamed);
|
||||
outBitStream.Write(tamed);
|
||||
if (tamed) {
|
||||
outBitStream->Write(m_Owner);
|
||||
outBitStream.Write(m_Owner);
|
||||
}
|
||||
|
||||
if (bIsInitialUpdate) {
|
||||
outBitStream->Write(tamed);
|
||||
outBitStream.Write(tamed);
|
||||
if (tamed) {
|
||||
outBitStream->Write(m_ModerationStatus);
|
||||
outBitStream.Write(m_ModerationStatus);
|
||||
|
||||
const auto nameData = GeneralUtils::UTF8ToUTF16(m_Name);
|
||||
const auto ownerNameData = GeneralUtils::UTF8ToUTF16(m_OwnerName);
|
||||
|
||||
outBitStream->Write<uint8_t>(nameData.size());
|
||||
outBitStream.Write<uint8_t>(nameData.size());
|
||||
for (const auto c : nameData) {
|
||||
outBitStream->Write(c);
|
||||
outBitStream.Write(c);
|
||||
}
|
||||
|
||||
outBitStream->Write<uint8_t>(ownerNameData.size());
|
||||
outBitStream.Write<uint8_t>(ownerNameData.size());
|
||||
for (const auto c : ownerNameData) {
|
||||
outBitStream->Write(c);
|
||||
outBitStream.Write(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -250,17 +251,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;
|
||||
}
|
||||
@@ -305,13 +306,11 @@ void PetComponent::OnUse(Entity* originator) {
|
||||
currentActivities.insert_or_assign(m_Tamer, m_Parent->GetObjectID());
|
||||
|
||||
// Notify the start of a pet taming minigame
|
||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) {
|
||||
script->OnNotifyPetTamingMinigame(m_Parent, originator, ePetTamingNotifyType::BEGIN);
|
||||
}
|
||||
m_Parent->GetScript()->OnNotifyPetTamingMinigame(m_Parent, originator, ePetTamingNotifyType::BEGIN);
|
||||
}
|
||||
|
||||
void PetComponent::Update(float deltaTime) {
|
||||
if (m_StartPosition == NiPoint3::ZERO) {
|
||||
if (m_StartPosition == NiPoint3Constant::ZERO) {
|
||||
m_StartPosition = m_Parent->GetPosition();
|
||||
}
|
||||
|
||||
@@ -446,7 +445,7 @@ void PetComponent::Update(float deltaTime) {
|
||||
if (distance < 5 * 5) {
|
||||
m_Interaction = closestTresure->GetObjectID();
|
||||
|
||||
Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, 202, true);
|
||||
Command(NiPoint3Constant::ZERO, LWOOBJID_EMPTY, 1, 202, true);
|
||||
|
||||
m_TresureTime = 2;
|
||||
} else if (distance < 10 * 10) {
|
||||
@@ -530,7 +529,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);
|
||||
@@ -590,9 +589,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
|
||||
);
|
||||
|
||||
@@ -670,9 +669,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
|
||||
);
|
||||
|
||||
@@ -689,9 +688,7 @@ void PetComponent::RequestSetPetName(std::u16string name) {
|
||||
m_Tamer = LWOOBJID_EMPTY;
|
||||
|
||||
// Notify the end of a pet taming minigame
|
||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) {
|
||||
script->OnNotifyPetTamingMinigame(m_Parent, tamer, ePetTamingNotifyType::SUCCESS);
|
||||
}
|
||||
m_Parent->GetScript()->OnNotifyPetTamingMinigame(m_Parent, tamer, ePetTamingNotifyType::SUCCESS);
|
||||
}
|
||||
|
||||
void PetComponent::ClientExitTamingMinigame(bool voluntaryExit) {
|
||||
@@ -711,9 +708,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
|
||||
);
|
||||
|
||||
@@ -730,9 +727,7 @@ void PetComponent::ClientExitTamingMinigame(bool voluntaryExit) {
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
|
||||
// Notify the end of a pet taming minigame
|
||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) {
|
||||
script->OnNotifyPetTamingMinigame(m_Parent, tamer, ePetTamingNotifyType::QUIT);
|
||||
}
|
||||
m_Parent->GetScript()->OnNotifyPetTamingMinigame(m_Parent, tamer, ePetTamingNotifyType::QUIT);
|
||||
}
|
||||
|
||||
void PetComponent::StartTimer() {
|
||||
@@ -762,9 +757,9 @@ void PetComponent::ClientFailTamingMinigame() {
|
||||
m_Tamer,
|
||||
false,
|
||||
ePetTamingNotifyType::FAILED,
|
||||
NiPoint3::ZERO,
|
||||
NiPoint3::ZERO,
|
||||
NiQuaternion::IDENTITY,
|
||||
NiPoint3Constant::ZERO,
|
||||
NiPoint3Constant::ZERO,
|
||||
NiQuaternionConstant::IDENTITY,
|
||||
UNASSIGNED_SYSTEM_ADDRESS
|
||||
);
|
||||
|
||||
@@ -781,9 +776,7 @@ void PetComponent::ClientFailTamingMinigame() {
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
|
||||
// Notify the end of a pet taming minigame
|
||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) {
|
||||
script->OnNotifyPetTamingMinigame(m_Parent, tamer, ePetTamingNotifyType::FAILED);
|
||||
}
|
||||
m_Parent->GetScript()->OnNotifyPetTamingMinigame(m_Parent, tamer, ePetTamingNotifyType::FAILED);
|
||||
}
|
||||
|
||||
void PetComponent::Wander() {
|
||||
@@ -812,8 +805,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) {
|
||||
|
||||
@@ -13,15 +13,15 @@
|
||||
* 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;
|
||||
|
||||
explicit PetComponent(Entity* parentEntity, uint32_t componentId);
|
||||
~PetComponent() override;
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
void Update(float deltaTime) override;
|
||||
|
||||
/**
|
||||
@@ -353,7 +353,6 @@ private:
|
||||
|
||||
/**
|
||||
* Pet information loaded from the CDClientDatabase
|
||||
* TODO: Switch to a reference when safe to do so
|
||||
*/
|
||||
CDPetComponent m_PetInfo;
|
||||
};
|
||||
|
||||
@@ -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,35 +259,35 @@ 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;
|
||||
}
|
||||
|
||||
void PhantomPhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
void PhantomPhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
PhysicsComponent::Serialize(outBitStream, bIsInitialUpdate);
|
||||
|
||||
outBitStream->Write(m_EffectInfoDirty || bIsInitialUpdate);
|
||||
outBitStream.Write(m_EffectInfoDirty || bIsInitialUpdate);
|
||||
if (m_EffectInfoDirty || bIsInitialUpdate) {
|
||||
outBitStream->Write(m_IsPhysicsEffectActive);
|
||||
outBitStream.Write(m_IsPhysicsEffectActive);
|
||||
|
||||
if (m_IsPhysicsEffectActive) {
|
||||
outBitStream->Write(m_EffectType);
|
||||
outBitStream->Write(m_DirectionalMultiplier);
|
||||
outBitStream.Write(m_EffectType);
|
||||
outBitStream.Write(m_DirectionalMultiplier);
|
||||
|
||||
// forgive me father for i have sinned
|
||||
outBitStream->Write0();
|
||||
//outBitStream->Write(m_MinMax);
|
||||
outBitStream.Write0();
|
||||
//outBitStream.Write(m_MinMax);
|
||||
//if (m_MinMax) {
|
||||
//outBitStream->Write(m_Min);
|
||||
//outBitStream->Write(m_Max);
|
||||
//outBitStream.Write(m_Min);
|
||||
//outBitStream.Write(m_Max);
|
||||
//}
|
||||
|
||||
outBitStream->Write(m_IsDirectional);
|
||||
outBitStream.Write(m_IsDirectional);
|
||||
if (m_IsDirectional) {
|
||||
outBitStream->Write(m_Direction.x);
|
||||
outBitStream->Write(m_Direction.y);
|
||||
outBitStream->Write(m_Direction.z);
|
||||
outBitStream.Write(m_Direction.x);
|
||||
outBitStream.Write(m_Direction.y);
|
||||
outBitStream.Write(m_Direction.z);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,14 +25,14 @@ 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;
|
||||
void Update(float deltaTime) override;
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
/**
|
||||
* Creates the physics shape for this entity based on LDF data
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
void PhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream->Write(bIsInitialUpdate || m_DirtyPosition);
|
||||
void PhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream.Write(bIsInitialUpdate || m_DirtyPosition);
|
||||
if (bIsInitialUpdate || m_DirtyPosition) {
|
||||
outBitStream->Write(m_Position.x);
|
||||
outBitStream->Write(m_Position.y);
|
||||
outBitStream->Write(m_Position.z);
|
||||
outBitStream->Write(m_Rotation.x);
|
||||
outBitStream->Write(m_Rotation.y);
|
||||
outBitStream->Write(m_Rotation.z);
|
||||
outBitStream->Write(m_Rotation.w);
|
||||
outBitStream.Write(m_Position.x);
|
||||
outBitStream.Write(m_Position.y);
|
||||
outBitStream.Write(m_Position.z);
|
||||
outBitStream.Write(m_Rotation.x);
|
||||
outBitStream.Write(m_Rotation.y);
|
||||
outBitStream.Write(m_Rotation.z);
|
||||
outBitStream.Write(m_Rotation.w);
|
||||
if (!bIsInitialUpdate) m_DirtyPosition = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ public:
|
||||
PhysicsComponent(Entity* parent);
|
||||
virtual ~PhysicsComponent() = default;
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
const NiPoint3& GetPosition() const { return m_Position; }
|
||||
virtual void SetPosition(const NiPoint3& pos) { if (m_Position == pos) return; m_Position = pos; m_DirtyPosition = true; }
|
||||
|
||||
@@ -6,11 +6,11 @@ PlayerForcedMovementComponent::PlayerForcedMovementComponent(Entity* parent) : C
|
||||
|
||||
PlayerForcedMovementComponent::~PlayerForcedMovementComponent() {}
|
||||
|
||||
void PlayerForcedMovementComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream->Write(m_DirtyInfo || bIsInitialUpdate);
|
||||
void PlayerForcedMovementComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream.Write(m_DirtyInfo || bIsInitialUpdate);
|
||||
if (m_DirtyInfo || bIsInitialUpdate) {
|
||||
outBitStream->Write(m_PlayerOnRail);
|
||||
outBitStream->Write(m_ShowBillboard);
|
||||
outBitStream.Write(m_PlayerOnRail);
|
||||
outBitStream.Write(m_ShowBillboard);
|
||||
}
|
||||
m_DirtyInfo = false;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
PlayerForcedMovementComponent(Entity* parent);
|
||||
~PlayerForcedMovementComponent() override;
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
/**
|
||||
* @brief Set the Player On Rail object
|
||||
|
||||
@@ -27,17 +27,17 @@ PossessableComponent::PossessableComponent(Entity* parent, uint32_t componentId)
|
||||
result.finalize();
|
||||
}
|
||||
|
||||
void PossessableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream->Write(m_DirtyPossessable || bIsInitialUpdate);
|
||||
void PossessableComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream.Write(m_DirtyPossessable || bIsInitialUpdate);
|
||||
if (m_DirtyPossessable || bIsInitialUpdate) {
|
||||
m_DirtyPossessable = false; // reset flag
|
||||
outBitStream->Write(m_Possessor != LWOOBJID_EMPTY);
|
||||
if (m_Possessor != LWOOBJID_EMPTY) outBitStream->Write(m_Possessor);
|
||||
outBitStream.Write(m_Possessor != LWOOBJID_EMPTY);
|
||||
if (m_Possessor != LWOOBJID_EMPTY) outBitStream.Write(m_Possessor);
|
||||
|
||||
outBitStream->Write(m_AnimationFlag != eAnimationFlags::IDLE_NONE);
|
||||
if (m_AnimationFlag != eAnimationFlags::IDLE_NONE) outBitStream->Write(m_AnimationFlag);
|
||||
outBitStream.Write(m_AnimationFlag != eAnimationFlags::IDLE_NONE);
|
||||
if (m_AnimationFlag != eAnimationFlags::IDLE_NONE) outBitStream.Write(m_AnimationFlag);
|
||||
|
||||
outBitStream->Write(m_ImmediatelyDepossess);
|
||||
outBitStream.Write(m_ImmediatelyDepossess);
|
||||
m_ImmediatelyDepossess = false; // reset flag
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
* 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);
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
/**
|
||||
* @brief mounts the Entity
|
||||
|
||||
@@ -26,15 +26,15 @@ PossessorComponent::~PossessorComponent() {
|
||||
}
|
||||
}
|
||||
|
||||
void PossessorComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream->Write(m_DirtyPossesor || bIsInitialUpdate);
|
||||
void PossessorComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream.Write(m_DirtyPossesor || bIsInitialUpdate);
|
||||
if (m_DirtyPossesor || bIsInitialUpdate) {
|
||||
m_DirtyPossesor = false;
|
||||
outBitStream->Write(m_Possessable != LWOOBJID_EMPTY);
|
||||
outBitStream.Write(m_Possessable != LWOOBJID_EMPTY);
|
||||
if (m_Possessable != LWOOBJID_EMPTY) {
|
||||
outBitStream->Write(m_Possessable);
|
||||
outBitStream.Write(m_Possessable);
|
||||
}
|
||||
outBitStream->Write(m_PossessableType);
|
||||
outBitStream.Write(m_PossessableType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,14 +16,14 @@ 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;
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
/**
|
||||
* @brief Mounts the entity
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "Item.h"
|
||||
#include "Database.h"
|
||||
#include "ObjectIDManager.h"
|
||||
#include "Player.h"
|
||||
#include "RocketLaunchpadControlComponent.h"
|
||||
#include "PropertyEntranceComponent.h"
|
||||
#include "InventoryComponent.h"
|
||||
@@ -177,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;
|
||||
|
||||
@@ -217,9 +214,7 @@ bool PropertyManagementComponent::Claim(const LWOOBJID playerId) {
|
||||
Database::Get()->InsertNewProperty(info, templateId, worldId);
|
||||
|
||||
auto* zoneControlObject = Game::zoneManager->GetZoneControlObject();
|
||||
for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControlObject)) {
|
||||
script->OnZonePropertyRented(zoneControlObject, entity);
|
||||
}
|
||||
if (zoneControlObject) zoneControlObject->GetScript()->OnZonePropertyRented(zoneControlObject, entity);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -297,7 +292,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 };
|
||||
}
|
||||
|
||||
@@ -481,7 +476,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);
|
||||
@@ -534,7 +529,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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
/**
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -23,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()) {
|
||||
@@ -33,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();
|
||||
@@ -56,55 +55,55 @@ QuickBuildComponent::~QuickBuildComponent() {
|
||||
DespawnActivator();
|
||||
}
|
||||
|
||||
void QuickBuildComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
void QuickBuildComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
if (m_Parent->GetComponent(eReplicaComponentType::DESTROYABLE) == nullptr) {
|
||||
if (bIsInitialUpdate) {
|
||||
outBitStream->Write(false);
|
||||
outBitStream.Write(false);
|
||||
}
|
||||
|
||||
outBitStream->Write(false);
|
||||
outBitStream.Write(false);
|
||||
|
||||
outBitStream->Write(false);
|
||||
outBitStream.Write(false);
|
||||
}
|
||||
// If build state is completed and we've already serialized once in the completed state,
|
||||
// don't serializing this component anymore as this will cause the build to jump again.
|
||||
// If state changes, serialization will begin again.
|
||||
if (!m_StateDirty && m_State == eQuickBuildState::COMPLETED) {
|
||||
outBitStream->Write0();
|
||||
outBitStream->Write0();
|
||||
outBitStream.Write0();
|
||||
outBitStream.Write0();
|
||||
return;
|
||||
}
|
||||
// BEGIN Scripted Activity
|
||||
outBitStream->Write1();
|
||||
outBitStream.Write1();
|
||||
|
||||
Entity* builder = GetBuilder();
|
||||
|
||||
if (builder) {
|
||||
outBitStream->Write<uint32_t>(1);
|
||||
outBitStream->Write(builder->GetObjectID());
|
||||
outBitStream.Write<uint32_t>(1);
|
||||
outBitStream.Write(builder->GetObjectID());
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
outBitStream->Write(0.0f);
|
||||
outBitStream.Write(0.0f);
|
||||
}
|
||||
} else {
|
||||
outBitStream->Write<uint32_t>(0);
|
||||
outBitStream.Write<uint32_t>(0);
|
||||
}
|
||||
// END Scripted Activity
|
||||
|
||||
outBitStream->Write1();
|
||||
outBitStream.Write1();
|
||||
|
||||
outBitStream->Write(m_State);
|
||||
outBitStream.Write(m_State);
|
||||
|
||||
outBitStream->Write(m_ShowResetEffect);
|
||||
outBitStream->Write(m_Activator != nullptr);
|
||||
outBitStream.Write(m_ShowResetEffect);
|
||||
outBitStream.Write(m_Activator != nullptr);
|
||||
|
||||
outBitStream->Write(m_Timer);
|
||||
outBitStream->Write(m_TimerIncomplete);
|
||||
outBitStream.Write(m_Timer);
|
||||
outBitStream.Write(m_TimerIncomplete);
|
||||
|
||||
if (bIsInitialUpdate) {
|
||||
outBitStream->Write(false);
|
||||
outBitStream->Write(m_ActivatorPosition);
|
||||
outBitStream->Write(m_RepositionPlayer);
|
||||
outBitStream.Write(false);
|
||||
outBitStream.Write(m_ActivatorPosition);
|
||||
outBitStream.Write(m_RepositionPlayer);
|
||||
}
|
||||
m_StateDirty = false;
|
||||
}
|
||||
@@ -253,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) {
|
||||
@@ -284,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 {
|
||||
@@ -358,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 {
|
||||
@@ -390,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();
|
||||
|
||||
@@ -415,22 +414,18 @@ void QuickBuildComponent::StartQuickBuild(Entity* user) {
|
||||
movingPlatform->OnQuickBuildInitilized();
|
||||
}
|
||||
|
||||
for (auto* script : CppScripts::GetEntityScripts(m_Parent)) {
|
||||
script->OnQuickBuildStart(m_Parent, user);
|
||||
}
|
||||
auto* script = m_Parent->GetScript();
|
||||
script->OnQuickBuildStart(m_Parent, user);
|
||||
|
||||
// Notify scripts and possible subscribers
|
||||
for (auto* script : CppScripts::GetEntityScripts(m_Parent))
|
||||
script->OnQuickBuildNotifyState(m_Parent, m_State);
|
||||
script->OnQuickBuildNotifyState(m_Parent, m_State);
|
||||
for (const auto& cb : m_QuickBuildStateCallbacks)
|
||||
cb(m_State);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -488,10 +483,9 @@ void QuickBuildComponent::CompleteQuickBuild(Entity* user) {
|
||||
}
|
||||
|
||||
// Notify scripts
|
||||
for (auto* script : CppScripts::GetEntityScripts(m_Parent)) {
|
||||
script->OnQuickBuildComplete(m_Parent, user);
|
||||
script->OnQuickBuildNotifyState(m_Parent, m_State);
|
||||
}
|
||||
auto* script = m_Parent->GetScript();
|
||||
script->OnQuickBuildComplete(m_Parent, user);
|
||||
script->OnQuickBuildNotifyState(m_Parent, m_State);
|
||||
|
||||
// Notify subscribers
|
||||
for (const auto& callback : m_QuickBuildStateCallbacks)
|
||||
@@ -519,7 +513,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) {
|
||||
@@ -542,8 +536,7 @@ void QuickBuildComponent::ResetQuickBuild(bool failed) {
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
|
||||
// Notify scripts and possible subscribers
|
||||
for (auto* script : CppScripts::GetEntityScripts(m_Parent))
|
||||
script->OnQuickBuildNotifyState(m_Parent, m_State);
|
||||
m_Parent->GetScript()->OnQuickBuildNotifyState(m_Parent, m_State);
|
||||
for (const auto& cb : m_QuickBuildStateCallbacks)
|
||||
cb(m_State);
|
||||
|
||||
@@ -554,7 +547,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;
|
||||
@@ -574,17 +567,14 @@ void QuickBuildComponent::CancelQuickBuild(Entity* entity, eQuickBuildFailReason
|
||||
m_StateDirty = true;
|
||||
|
||||
// Notify scripts and possible subscribers
|
||||
for (auto* script : CppScripts::GetEntityScripts(m_Parent))
|
||||
script->OnQuickBuildNotifyState(m_Parent, m_State);
|
||||
m_Parent->GetScript()->OnQuickBuildNotifyState(m_Parent, m_State);
|
||||
for (const auto& cb : m_QuickBuildStateCallbacks)
|
||||
cb(m_State);
|
||||
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
}
|
||||
|
||||
if (entity == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (!entity) return;
|
||||
|
||||
CharacterComponent* characterComponent = entity->GetComponent<CharacterComponent>();
|
||||
if (characterComponent) {
|
||||
|
||||
@@ -20,14 +20,14 @@ 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;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
void Update(float deltaTime) 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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -119,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;
|
||||
@@ -434,83 +433,83 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, int32_t bu
|
||||
}
|
||||
}
|
||||
|
||||
void RacingControlComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
void RacingControlComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
// BEGIN Scripted Activity
|
||||
outBitStream->Write1();
|
||||
outBitStream.Write1();
|
||||
|
||||
outBitStream->Write<uint32_t>(m_RacingPlayers.size());
|
||||
outBitStream.Write<uint32_t>(m_RacingPlayers.size());
|
||||
for (const auto& player : m_RacingPlayers) {
|
||||
outBitStream->Write(player.playerID);
|
||||
outBitStream.Write(player.playerID);
|
||||
|
||||
outBitStream->Write(player.data[0]);
|
||||
if (player.finished != 0) outBitStream->Write<float>(player.raceTime);
|
||||
else outBitStream->Write(player.data[1]);
|
||||
if (player.finished != 0) outBitStream->Write<float>(player.bestLapTime);
|
||||
else outBitStream->Write(player.data[2]);
|
||||
if (player.finished == 1) outBitStream->Write<float>(1.0f);
|
||||
else outBitStream->Write(player.data[3]);
|
||||
outBitStream->Write(player.data[4]);
|
||||
outBitStream->Write(player.data[5]);
|
||||
outBitStream->Write(player.data[6]);
|
||||
outBitStream->Write(player.data[7]);
|
||||
outBitStream->Write(player.data[8]);
|
||||
outBitStream->Write(player.data[9]);
|
||||
outBitStream.Write(player.data[0]);
|
||||
if (player.finished != 0) outBitStream.Write<float>(player.raceTime);
|
||||
else outBitStream.Write(player.data[1]);
|
||||
if (player.finished != 0) outBitStream.Write<float>(player.bestLapTime);
|
||||
else outBitStream.Write(player.data[2]);
|
||||
if (player.finished == 1) outBitStream.Write<float>(1.0f);
|
||||
else outBitStream.Write(player.data[3]);
|
||||
outBitStream.Write(player.data[4]);
|
||||
outBitStream.Write(player.data[5]);
|
||||
outBitStream.Write(player.data[6]);
|
||||
outBitStream.Write(player.data[7]);
|
||||
outBitStream.Write(player.data[8]);
|
||||
outBitStream.Write(player.data[9]);
|
||||
}
|
||||
|
||||
// END Scripted Activity
|
||||
|
||||
outBitStream->Write1();
|
||||
outBitStream->Write<uint16_t>(m_RacingPlayers.size());
|
||||
outBitStream.Write1();
|
||||
outBitStream.Write<uint16_t>(m_RacingPlayers.size());
|
||||
|
||||
outBitStream->Write(!m_AllPlayersReady);
|
||||
outBitStream.Write(!m_AllPlayersReady);
|
||||
if (!m_AllPlayersReady) {
|
||||
int32_t numReady = 0;
|
||||
for (const auto& player : m_RacingPlayers) {
|
||||
outBitStream->Write1(); // Has more player data
|
||||
outBitStream->Write(player.playerID);
|
||||
outBitStream->Write(player.vehicleID);
|
||||
outBitStream->Write(player.playerIndex);
|
||||
outBitStream->Write(player.playerLoaded);
|
||||
outBitStream.Write1(); // Has more player data
|
||||
outBitStream.Write(player.playerID);
|
||||
outBitStream.Write(player.vehicleID);
|
||||
outBitStream.Write(player.playerIndex);
|
||||
outBitStream.Write(player.playerLoaded);
|
||||
if (player.playerLoaded) numReady++;
|
||||
}
|
||||
|
||||
outBitStream->Write0(); // No more data
|
||||
outBitStream.Write0(); // No more data
|
||||
if (numReady == m_RacingPlayers.size()) m_AllPlayersReady = true;
|
||||
}
|
||||
|
||||
outBitStream->Write(!m_RacingPlayers.empty());
|
||||
outBitStream.Write(!m_RacingPlayers.empty());
|
||||
if (!m_RacingPlayers.empty()) {
|
||||
for (const auto& player : m_RacingPlayers) {
|
||||
if (player.finished == 0) continue;
|
||||
outBitStream->Write1(); // Has more date
|
||||
outBitStream.Write1(); // Has more date
|
||||
|
||||
outBitStream->Write(player.playerID);
|
||||
outBitStream->Write(player.finished);
|
||||
outBitStream.Write(player.playerID);
|
||||
outBitStream.Write(player.finished);
|
||||
}
|
||||
|
||||
outBitStream->Write0(); // No more data
|
||||
outBitStream.Write0(); // No more data
|
||||
}
|
||||
|
||||
outBitStream->Write(bIsInitialUpdate);
|
||||
outBitStream.Write(bIsInitialUpdate);
|
||||
if (bIsInitialUpdate) {
|
||||
outBitStream->Write(m_RemainingLaps);
|
||||
outBitStream->Write<uint16_t>(m_PathName.size());
|
||||
outBitStream.Write(m_RemainingLaps);
|
||||
outBitStream.Write<uint16_t>(m_PathName.size());
|
||||
for (const auto character : m_PathName) {
|
||||
outBitStream->Write(character);
|
||||
outBitStream.Write(character);
|
||||
}
|
||||
}
|
||||
|
||||
outBitStream->Write(!m_RacingPlayers.empty());
|
||||
outBitStream.Write(!m_RacingPlayers.empty());
|
||||
if (!m_RacingPlayers.empty()) {
|
||||
for (const auto& player : m_RacingPlayers) {
|
||||
if (player.finished == 0) continue;
|
||||
outBitStream->Write1(); // Has more data
|
||||
outBitStream->Write(player.playerID);
|
||||
outBitStream->Write<float>(player.bestLapTime);
|
||||
outBitStream->Write<float>(player.raceTime);
|
||||
outBitStream.Write1(); // Has more data
|
||||
outBitStream.Write(player.playerID);
|
||||
outBitStream.Write<float>(player.bestLapTime);
|
||||
outBitStream.Write<float>(player.raceTime);
|
||||
}
|
||||
|
||||
outBitStream->Write0(); // No more data
|
||||
outBitStream.Write0(); // No more data
|
||||
}
|
||||
}
|
||||
|
||||
@@ -818,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;
|
||||
|
||||
|
||||
@@ -103,14 +103,14 @@ 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();
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
void Update(float deltaTime) override;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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){};
|
||||
};
|
||||
|
||||
|
||||
@@ -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) {}
|
||||
};
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#include "RenderComponent.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <iomanip>
|
||||
|
||||
#include "Entity.h"
|
||||
@@ -14,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;
|
||||
|
||||
@@ -26,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) {
|
||||
void RenderComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
if (!bIsInitialUpdate) return;
|
||||
|
||||
outBitStream->Write<uint32_t>(m_Effects.size());
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,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;
|
||||
}
|
||||
@@ -168,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) {
|
||||
@@ -186,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);
|
||||
@@ -218,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);
|
||||
|
||||
@@ -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,14 +59,13 @@ 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 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;
|
||||
|
||||
|
||||
@@ -11,6 +11,6 @@ RigidbodyPhantomPhysicsComponent::RigidbodyPhantomPhysicsComponent(Entity* paren
|
||||
m_Rotation = m_Parent->GetDefaultRotation();
|
||||
}
|
||||
|
||||
void RigidbodyPhantomPhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
void RigidbodyPhantomPhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
PhysicsComponent::Serialize(outBitStream, bIsInitialUpdate);
|
||||
}
|
||||
|
||||
@@ -19,11 +19,11 @@
|
||||
*/
|
||||
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);
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
};
|
||||
|
||||
#endif // __RIGIDBODYPHANTOMPHYSICS_H__
|
||||
|
||||
@@ -139,7 +139,7 @@ void RocketLaunchpadControlComponent::TellMasterToPrepZone(int zoneID) {
|
||||
CBITSTREAM;
|
||||
BitStreamUtils::WriteHeader(bitStream, eConnectionType::MASTER, eMasterMessageType::PREP_ZONE);
|
||||
bitStream.Write(zoneID);
|
||||
Game::server->SendToMaster(&bitStream);
|
||||
Game::server->SendToMaster(bitStream);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
52
dGame/dComponents/ScriptComponent.cpp
Normal file
52
dGame/dComponents/ScriptComponent.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Darkflame Universe
|
||||
* Copyright 2018
|
||||
*/
|
||||
|
||||
#include "Entity.h"
|
||||
#include "ScriptComponent.h"
|
||||
|
||||
ScriptComponent::ScriptComponent(Entity* parent, std::string scriptName, bool serialized, bool client) : Component(parent) {
|
||||
m_Serialized = serialized;
|
||||
m_Client = client;
|
||||
|
||||
SetScript(scriptName);
|
||||
}
|
||||
|
||||
ScriptComponent::~ScriptComponent() {
|
||||
|
||||
}
|
||||
|
||||
void ScriptComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
if (bIsInitialUpdate) {
|
||||
const auto& networkSettings = m_Parent->GetNetworkSettings();
|
||||
auto hasNetworkSettings = !networkSettings.empty();
|
||||
outBitStream.Write(hasNetworkSettings);
|
||||
|
||||
if (hasNetworkSettings) {
|
||||
|
||||
// First write the most inner LDF data
|
||||
RakNet::BitStream ldfData;
|
||||
ldfData.Write<uint8_t>(0);
|
||||
ldfData.Write<uint32_t>(networkSettings.size());
|
||||
|
||||
for (auto* networkSetting : networkSettings) {
|
||||
networkSetting->WriteToPacket(ldfData);
|
||||
}
|
||||
|
||||
// Finally write everything to the stream
|
||||
outBitStream.Write<uint32_t>(ldfData.GetNumberOfBytesUsed());
|
||||
outBitStream.Write(ldfData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CppScripts::Script* const ScriptComponent::GetScript() {
|
||||
return m_Script;
|
||||
}
|
||||
|
||||
void ScriptComponent::SetScript(const std::string& scriptName) {
|
||||
// Scripts are managed by the CppScripts class and are effecitvely singletons
|
||||
// and they may also be used by other script components so DON'T delete them.
|
||||
m_Script = CppScripts::GetScript(m_Parent, scriptName);
|
||||
}
|
||||
65
dGame/dComponents/ScriptComponent.h
Normal file
65
dGame/dComponents/ScriptComponent.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Darkflame Universe
|
||||
* Copyright 2018
|
||||
*/
|
||||
|
||||
#ifndef SCRIPTCOMPONENT_H
|
||||
#define SCRIPTCOMPONENT_H
|
||||
|
||||
#include "CppScripts.h"
|
||||
#include "Component.h"
|
||||
#include <string>
|
||||
#include "eReplicaComponentType.h"
|
||||
|
||||
class Entity;
|
||||
|
||||
/**
|
||||
* Handles the loading and execution of server side scripts on entities, scripts were originally written in Lua,
|
||||
* here they're written in C++
|
||||
*/
|
||||
class ScriptComponent final : public Component {
|
||||
public:
|
||||
static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::SCRIPT;
|
||||
|
||||
ScriptComponent(Entity* parent, std::string scriptName, bool serialized, bool client = false);
|
||||
~ScriptComponent() override;
|
||||
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
/**
|
||||
* Returns the script that's attached to this entity
|
||||
* @return the script that's attached to this entity
|
||||
*/
|
||||
CppScripts::Script* const GetScript();
|
||||
|
||||
/**
|
||||
* Sets whether the entity should be serialized, unused
|
||||
* @param var whether the entity should be serialized
|
||||
*/
|
||||
void SetSerialized(const bool var) { m_Serialized = var; }
|
||||
|
||||
/**
|
||||
* Sets the script using a path by looking through dScripts for a script that matches
|
||||
* @param scriptName the name of the script to find
|
||||
*/
|
||||
void SetScript(const std::string& scriptName);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* The script attached to this entity
|
||||
*/
|
||||
CppScripts::Script* m_Script;
|
||||
|
||||
/**
|
||||
* Whether or not the comp should be serialized, unused
|
||||
*/
|
||||
bool m_Serialized;
|
||||
|
||||
/**
|
||||
* Whether or not this script is a client script
|
||||
*/
|
||||
bool m_Client;
|
||||
};
|
||||
|
||||
#endif // SCRIPTCOMPONENT_H
|
||||
@@ -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){};
|
||||
};
|
||||
|
||||
|
||||
@@ -17,50 +17,50 @@ void ShootingGalleryComponent::SetDynamicParams(const DynamicShootingGalleryPara
|
||||
Game::entityManager->SerializeEntity(m_Parent);
|
||||
}
|
||||
|
||||
void ShootingGalleryComponent::Serialize(RakNet::BitStream* outBitStream, bool isInitialUpdate) {
|
||||
void ShootingGalleryComponent::Serialize(RakNet::BitStream& outBitStream, bool isInitialUpdate) {
|
||||
// Start ScriptedActivityComponent
|
||||
outBitStream->Write<bool>(true);
|
||||
outBitStream.Write<bool>(true);
|
||||
if (m_CurrentPlayerID == LWOOBJID_EMPTY) {
|
||||
outBitStream->Write<uint32_t>(0);
|
||||
outBitStream.Write<uint32_t>(0);
|
||||
} else {
|
||||
outBitStream->Write<uint32_t>(1);
|
||||
outBitStream->Write<LWOOBJID>(m_CurrentPlayerID);
|
||||
outBitStream.Write<uint32_t>(1);
|
||||
outBitStream.Write<LWOOBJID>(m_CurrentPlayerID);
|
||||
for (size_t i = 0; i < 10; i++) {
|
||||
outBitStream->Write<float_t>(0.0f);
|
||||
outBitStream.Write<float_t>(0.0f);
|
||||
}
|
||||
|
||||
}
|
||||
// End ScriptedActivityComponent
|
||||
|
||||
if (isInitialUpdate) {
|
||||
outBitStream->Write<float_t>(m_StaticParams.cameraPosition.GetX());
|
||||
outBitStream->Write<float_t>(m_StaticParams.cameraPosition.GetY());
|
||||
outBitStream->Write<float_t>(m_StaticParams.cameraPosition.GetZ());
|
||||
outBitStream.Write<float_t>(m_StaticParams.cameraPosition.GetX());
|
||||
outBitStream.Write<float_t>(m_StaticParams.cameraPosition.GetY());
|
||||
outBitStream.Write<float_t>(m_StaticParams.cameraPosition.GetZ());
|
||||
|
||||
outBitStream->Write<float_t>(m_StaticParams.cameraLookatPosition.GetX());
|
||||
outBitStream->Write<float_t>(m_StaticParams.cameraLookatPosition.GetY());
|
||||
outBitStream->Write<float_t>(m_StaticParams.cameraLookatPosition.GetZ());
|
||||
outBitStream.Write<float_t>(m_StaticParams.cameraLookatPosition.GetX());
|
||||
outBitStream.Write<float_t>(m_StaticParams.cameraLookatPosition.GetY());
|
||||
outBitStream.Write<float_t>(m_StaticParams.cameraLookatPosition.GetZ());
|
||||
}
|
||||
|
||||
outBitStream->Write<bool>(m_Dirty || isInitialUpdate);
|
||||
outBitStream.Write<bool>(m_Dirty || isInitialUpdate);
|
||||
if (m_Dirty || isInitialUpdate) {
|
||||
outBitStream->Write<double_t>(m_DynamicParams.cannonVelocity);
|
||||
outBitStream->Write<double_t>(m_DynamicParams.cannonRefireRate);
|
||||
outBitStream->Write<double_t>(m_DynamicParams.cannonMinDistance);
|
||||
outBitStream.Write<double_t>(m_DynamicParams.cannonVelocity);
|
||||
outBitStream.Write<double_t>(m_DynamicParams.cannonRefireRate);
|
||||
outBitStream.Write<double_t>(m_DynamicParams.cannonMinDistance);
|
||||
|
||||
outBitStream->Write<float_t>(m_DynamicParams.cameraBarrelOffset.GetX());
|
||||
outBitStream->Write<float_t>(m_DynamicParams.cameraBarrelOffset.GetY());
|
||||
outBitStream->Write<float_t>(m_DynamicParams.cameraBarrelOffset.GetZ());
|
||||
outBitStream.Write<float_t>(m_DynamicParams.cameraBarrelOffset.GetX());
|
||||
outBitStream.Write<float_t>(m_DynamicParams.cameraBarrelOffset.GetY());
|
||||
outBitStream.Write<float_t>(m_DynamicParams.cameraBarrelOffset.GetZ());
|
||||
|
||||
outBitStream->Write<float_t>(m_DynamicParams.cannonAngle);
|
||||
outBitStream.Write<float_t>(m_DynamicParams.cannonAngle);
|
||||
|
||||
outBitStream->Write<float_t>(m_DynamicParams.facing.GetX());
|
||||
outBitStream->Write<float_t>(m_DynamicParams.facing.GetY());
|
||||
outBitStream->Write<float_t>(m_DynamicParams.facing.GetZ());
|
||||
outBitStream.Write<float_t>(m_DynamicParams.facing.GetX());
|
||||
outBitStream.Write<float_t>(m_DynamicParams.facing.GetY());
|
||||
outBitStream.Write<float_t>(m_DynamicParams.facing.GetZ());
|
||||
|
||||
outBitStream->Write<LWOOBJID>(m_CurrentPlayerID);
|
||||
outBitStream->Write<float_t>(m_DynamicParams.cannonTimeout);
|
||||
outBitStream->Write<float_t>(m_DynamicParams.cannonFOV);
|
||||
outBitStream.Write<LWOOBJID>(m_CurrentPlayerID);
|
||||
outBitStream.Write<float_t>(m_DynamicParams.cannonTimeout);
|
||||
outBitStream.Write<float_t>(m_DynamicParams.cannonFOV);
|
||||
if (!isInitialUpdate) m_Dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,13 +71,13 @@ 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();
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool isInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool isInitialUpdate) override;
|
||||
|
||||
/**
|
||||
* Returns the static params for the shooting gallery
|
||||
|
||||
@@ -32,26 +32,26 @@ SimplePhysicsComponent::SimplePhysicsComponent(Entity* parent, uint32_t componen
|
||||
SimplePhysicsComponent::~SimplePhysicsComponent() {
|
||||
}
|
||||
|
||||
void SimplePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
void SimplePhysicsComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
if (bIsInitialUpdate) {
|
||||
outBitStream->Write(m_ClimbableType != eClimbableType::CLIMBABLE_TYPE_NOT);
|
||||
outBitStream->Write(m_ClimbableType);
|
||||
outBitStream.Write(m_ClimbableType != eClimbableType::CLIMBABLE_TYPE_NOT);
|
||||
outBitStream.Write(m_ClimbableType);
|
||||
}
|
||||
|
||||
outBitStream->Write(m_DirtyVelocity || bIsInitialUpdate);
|
||||
outBitStream.Write(m_DirtyVelocity || bIsInitialUpdate);
|
||||
if (m_DirtyVelocity || bIsInitialUpdate) {
|
||||
outBitStream->Write(m_Velocity);
|
||||
outBitStream->Write(m_AngularVelocity);
|
||||
outBitStream.Write(m_Velocity);
|
||||
outBitStream.Write(m_AngularVelocity);
|
||||
|
||||
m_DirtyVelocity = false;
|
||||
}
|
||||
|
||||
// Physics motion state
|
||||
if (m_PhysicsMotionState != 0) {
|
||||
outBitStream->Write1();
|
||||
outBitStream->Write<uint32_t>(m_PhysicsMotionState);
|
||||
outBitStream.Write1();
|
||||
outBitStream.Write<uint32_t>(m_PhysicsMotionState);
|
||||
} else {
|
||||
outBitStream->Write0();
|
||||
outBitStream.Write0();
|
||||
}
|
||||
PhysicsComponent::Serialize(outBitStream, bIsInitialUpdate);
|
||||
}
|
||||
|
||||
@@ -28,12 +28,12 @@ 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;
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
/**
|
||||
* Returns the velocity of this entity
|
||||
@@ -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
|
||||
|
||||
@@ -31,7 +31,7 @@ ProjectileSyncEntry::ProjectileSyncEntry() {
|
||||
|
||||
std::unordered_map<uint32_t, uint32_t> SkillComponent::m_skillBehaviorCache = {};
|
||||
|
||||
bool SkillComponent::CastPlayerSkill(const uint32_t behaviorId, const uint32_t skillUid, RakNet::BitStream* bitStream, const LWOOBJID target, uint32_t skillID) {
|
||||
bool SkillComponent::CastPlayerSkill(const uint32_t behaviorId, const uint32_t skillUid, RakNet::BitStream& bitStream, const LWOOBJID target, uint32_t skillID) {
|
||||
auto* context = new BehaviorContext(this->m_Parent->GetObjectID());
|
||||
|
||||
context->caster = m_Parent->GetObjectID();
|
||||
@@ -51,7 +51,7 @@ bool SkillComponent::CastPlayerSkill(const uint32_t behaviorId, const uint32_t s
|
||||
return !context->failed;
|
||||
}
|
||||
|
||||
void SkillComponent::SyncPlayerSkill(const uint32_t skillUid, const uint32_t syncId, RakNet::BitStream* bitStream) {
|
||||
void SkillComponent::SyncPlayerSkill(const uint32_t skillUid, const uint32_t syncId, RakNet::BitStream& bitStream) {
|
||||
const auto index = this->m_managedBehaviors.find(skillUid);
|
||||
|
||||
if (index == this->m_managedBehaviors.end()) {
|
||||
@@ -66,7 +66,7 @@ void SkillComponent::SyncPlayerSkill(const uint32_t skillUid, const uint32_t syn
|
||||
}
|
||||
|
||||
|
||||
void SkillComponent::SyncPlayerProjectile(const LWOOBJID projectileId, RakNet::BitStream* bitStream, const LWOOBJID target) {
|
||||
void SkillComponent::SyncPlayerProjectile(const LWOOBJID projectileId, RakNet::BitStream& bitStream, const LWOOBJID target) {
|
||||
auto index = -1;
|
||||
|
||||
for (auto i = 0u; i < this->m_managedProjectiles.size(); ++i) {
|
||||
@@ -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 {
|
||||
@@ -252,7 +252,7 @@ bool SkillComponent::CastSkill(const uint32_t skillId, LWOOBJID target, const LW
|
||||
|
||||
|
||||
SkillExecutionResult SkillComponent::CalculateBehavior(const uint32_t skillId, const uint32_t behaviorId, const LWOOBJID target, const bool ignoreTarget, const bool clientInitalized, const LWOOBJID originatorOverride) {
|
||||
auto* bitStream = new RakNet::BitStream();
|
||||
RakNet::BitStream bitStream{};
|
||||
|
||||
auto* behavior = Behavior::CreateBehavior(behaviorId);
|
||||
|
||||
@@ -268,12 +268,9 @@ SkillExecutionResult SkillComponent::CalculateBehavior(const uint32_t skillId, c
|
||||
|
||||
behavior->Calculate(context, bitStream, { target, 0 });
|
||||
|
||||
for (auto* script : CppScripts::GetEntityScripts(m_Parent)) {
|
||||
script->OnSkillCast(m_Parent, skillId);
|
||||
}
|
||||
m_Parent->GetScript()->OnSkillCast(m_Parent, skillId);
|
||||
|
||||
if (!context->foundTarget) {
|
||||
delete bitStream;
|
||||
delete context;
|
||||
|
||||
// Invalid attack
|
||||
@@ -299,22 +296,20 @@ SkillExecutionResult SkillComponent::CalculateBehavior(const uint32_t skillId, c
|
||||
}
|
||||
//start.optionalTargetID = target;
|
||||
|
||||
start.sBitStream.assign(reinterpret_cast<char*>(bitStream->GetData()), bitStream->GetNumberOfBytesUsed());
|
||||
start.sBitStream.assign(reinterpret_cast<char*>(bitStream.GetData()), bitStream.GetNumberOfBytesUsed());
|
||||
|
||||
// Write message
|
||||
RakNet::BitStream message;
|
||||
|
||||
BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, eClientMessageType::GAME_MSG);
|
||||
message.Write(this->m_Parent->GetObjectID());
|
||||
start.Serialize(&message);
|
||||
start.Serialize(message);
|
||||
|
||||
Game::server->Send(&message, UNASSIGNED_SYSTEM_ADDRESS, true);
|
||||
Game::server->Send(message, UNASSIGNED_SYSTEM_ADDRESS, true);
|
||||
}
|
||||
|
||||
context->ExecuteUpdates();
|
||||
|
||||
delete bitStream;
|
||||
|
||||
// Valid attack
|
||||
return { true, context->skillTime };
|
||||
}
|
||||
@@ -424,13 +419,13 @@ void SkillComponent::SyncProjectileCalculation(const ProjectileSyncEntry& entry)
|
||||
|
||||
auto* behavior = Behavior::CreateBehavior(behaviorId);
|
||||
|
||||
auto* bitStream = new RakNet::BitStream();
|
||||
RakNet::BitStream bitStream{};
|
||||
|
||||
behavior->Calculate(entry.context, bitStream, entry.branchContext);
|
||||
|
||||
DoClientProjectileImpact projectileImpact;
|
||||
|
||||
projectileImpact.sBitStream.assign(reinterpret_cast<char*>(bitStream->GetData()), bitStream->GetNumberOfBytesUsed());
|
||||
projectileImpact.sBitStream.assign(reinterpret_cast<char*>(bitStream.GetData()), bitStream.GetNumberOfBytesUsed());
|
||||
projectileImpact.i64OwnerID = this->m_Parent->GetObjectID();
|
||||
projectileImpact.i64OrgID = entry.id;
|
||||
projectileImpact.i64TargetID = entry.branchContext.target;
|
||||
@@ -439,42 +434,34 @@ void SkillComponent::SyncProjectileCalculation(const ProjectileSyncEntry& entry)
|
||||
|
||||
BitStreamUtils::WriteHeader(message, eConnectionType::CLIENT, eClientMessageType::GAME_MSG);
|
||||
message.Write(this->m_Parent->GetObjectID());
|
||||
projectileImpact.Serialize(&message);
|
||||
projectileImpact.Serialize(message);
|
||||
|
||||
Game::server->Send(&message, UNASSIGNED_SYSTEM_ADDRESS, true);
|
||||
Game::server->Send(message, UNASSIGNED_SYSTEM_ADDRESS, true);
|
||||
|
||||
entry.context->ExecuteUpdates();
|
||||
|
||||
delete bitStream;
|
||||
}
|
||||
|
||||
void SkillComponent::HandleUnmanaged(const uint32_t behaviorId, const LWOOBJID target, LWOOBJID source) {
|
||||
auto* context = new BehaviorContext(source);
|
||||
BehaviorContext context{ source };
|
||||
|
||||
context->unmanaged = true;
|
||||
context->caster = target;
|
||||
context.unmanaged = true;
|
||||
context.caster = target;
|
||||
|
||||
auto* behavior = Behavior::CreateBehavior(behaviorId);
|
||||
|
||||
auto* bitStream = new RakNet::BitStream();
|
||||
RakNet::BitStream bitStream{};
|
||||
|
||||
behavior->Handle(context, bitStream, { target });
|
||||
|
||||
delete bitStream;
|
||||
|
||||
delete context;
|
||||
behavior->Handle(&context, bitStream, { target });
|
||||
}
|
||||
|
||||
void SkillComponent::HandleUnCast(const uint32_t behaviorId, const LWOOBJID target) {
|
||||
auto* context = new BehaviorContext(target);
|
||||
BehaviorContext context{ target };
|
||||
|
||||
context->caster = target;
|
||||
context.caster = target;
|
||||
|
||||
auto* behavior = Behavior::CreateBehavior(behaviorId);
|
||||
|
||||
behavior->UnCast(context, { target });
|
||||
|
||||
delete context;
|
||||
behavior->UnCast(&context, { target });
|
||||
}
|
||||
|
||||
SkillComponent::SkillComponent(Entity* parent): Component(parent) {
|
||||
@@ -485,8 +472,8 @@ SkillComponent::~SkillComponent() {
|
||||
Reset();
|
||||
}
|
||||
|
||||
void SkillComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
if (bIsInitialUpdate) outBitStream->Write0();
|
||||
void SkillComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
if (bIsInitialUpdate) outBitStream.Write0();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Darkflame Universe
|
||||
* Copyright 2018
|
||||
* Copyright 2024
|
||||
*/
|
||||
|
||||
#ifndef SKILLCOMPONENT_H
|
||||
@@ -55,16 +55,16 @@ 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;
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) override;
|
||||
void Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
|
||||
/**
|
||||
* Computes skill updates. Invokes CalculateUpdate.
|
||||
@@ -93,7 +93,7 @@ public:
|
||||
* @param bitStream the bitSteam given by the client to determine the behavior path
|
||||
* @param target the explicit target of the skill
|
||||
*/
|
||||
bool CastPlayerSkill(uint32_t behaviorId, uint32_t skillUid, RakNet::BitStream* bitStream, LWOOBJID target, uint32_t skillID = 0);
|
||||
bool CastPlayerSkill(uint32_t behaviorId, uint32_t skillUid, RakNet::BitStream& bitStream, LWOOBJID target, uint32_t skillID = 0);
|
||||
|
||||
/**
|
||||
* Continues a player skill. Should only be called when the server receives a sync message from the client.
|
||||
@@ -101,7 +101,7 @@ public:
|
||||
* @param syncId the unique sync ID of the skill given by the client
|
||||
* @param bitStream the bitSteam given by the client to determine the behavior path
|
||||
*/
|
||||
void SyncPlayerSkill(uint32_t skillUid, uint32_t syncId, RakNet::BitStream* bitStream);
|
||||
void SyncPlayerSkill(uint32_t skillUid, uint32_t syncId, RakNet::BitStream& bitStream);
|
||||
|
||||
/**
|
||||
* Continues a player projectile calculation. Should only be called when the server receives a projectile sync message from the client.
|
||||
@@ -109,7 +109,7 @@ public:
|
||||
* @param bitStream the bitSteam given by the client to determine the behavior path
|
||||
* @param target the explicit target of the target
|
||||
*/
|
||||
void SyncPlayerProjectile(LWOOBJID projectileId, RakNet::BitStream* bitStream, LWOOBJID target);
|
||||
void SyncPlayerProjectile(LWOOBJID projectileId, RakNet::BitStream& bitStream, LWOOBJID target);
|
||||
|
||||
/**
|
||||
* Registers a player projectile. Should only be called when the server is computing a player projectile.
|
||||
|
||||
@@ -2,28 +2,28 @@
|
||||
#include "Game.h"
|
||||
#include "Logger.h"
|
||||
|
||||
void MusicCue::Serialize(RakNet::BitStream* outBitStream){
|
||||
outBitStream->Write<uint8_t>(name.size());
|
||||
outBitStream->Write(name.c_str(), name.size());
|
||||
outBitStream->Write(result);
|
||||
outBitStream->Write(boredomTime);
|
||||
void MusicCue::Serialize(RakNet::BitStream& outBitStream){
|
||||
outBitStream.Write<uint8_t>(name.size());
|
||||
outBitStream.Write(name.c_str(), name.size());
|
||||
outBitStream.Write(result);
|
||||
outBitStream.Write(boredomTime);
|
||||
}
|
||||
|
||||
void MusicParameter::Serialize(RakNet::BitStream* outBitStream){
|
||||
outBitStream->Write<uint8_t>(name.size());
|
||||
outBitStream->Write(name.c_str(), name.size());
|
||||
outBitStream->Write(value);
|
||||
void MusicParameter::Serialize(RakNet::BitStream& outBitStream){
|
||||
outBitStream.Write<uint8_t>(name.size());
|
||||
outBitStream.Write(name.c_str(), name.size());
|
||||
outBitStream.Write(value);
|
||||
}
|
||||
|
||||
void GUIDResults::Serialize(RakNet::BitStream* outBitStream){
|
||||
void GUIDResults::Serialize(RakNet::BitStream& outBitStream){
|
||||
guid.Serialize(outBitStream);
|
||||
outBitStream->Write(result);
|
||||
outBitStream.Write(result);
|
||||
}
|
||||
|
||||
void MixerProgram::Serialize(RakNet::BitStream* outBitStream){
|
||||
outBitStream->Write<uint8_t>(name.size());
|
||||
outBitStream->Write(name.c_str(), name.size());
|
||||
outBitStream->Write(result);
|
||||
void MixerProgram::Serialize(RakNet::BitStream& outBitStream){
|
||||
outBitStream.Write<uint8_t>(name.size());
|
||||
outBitStream.Write(name.c_str(), name.size());
|
||||
outBitStream.Write(result);
|
||||
}
|
||||
SoundTriggerComponent::SoundTriggerComponent(Entity* parent) : Component(parent) {
|
||||
|
||||
@@ -55,30 +55,30 @@ SoundTriggerComponent::SoundTriggerComponent(Entity* parent) : Component(parent)
|
||||
if (!mixerName.empty()) this->m_MixerPrograms.push_back(MixerProgram(mixerName));
|
||||
}
|
||||
|
||||
void SoundTriggerComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream->Write(this->m_Dirty || bIsInitialUpdate);
|
||||
void SoundTriggerComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream.Write(this->m_Dirty || bIsInitialUpdate);
|
||||
if (this->m_Dirty || bIsInitialUpdate) {
|
||||
outBitStream->Write<uint8_t>(this->m_MusicCues.size());
|
||||
outBitStream.Write<uint8_t>(this->m_MusicCues.size());
|
||||
for (auto& musicCue : this->m_MusicCues) {
|
||||
musicCue.Serialize(outBitStream);
|
||||
}
|
||||
|
||||
outBitStream->Write<uint8_t>(this->m_MusicParameters.size());
|
||||
outBitStream.Write<uint8_t>(this->m_MusicParameters.size());
|
||||
for (auto& musicParam : this->m_MusicParameters) {
|
||||
musicParam.Serialize(outBitStream);
|
||||
}
|
||||
|
||||
outBitStream->Write<uint8_t>(this->m_2DAmbientSounds.size());
|
||||
outBitStream.Write<uint8_t>(this->m_2DAmbientSounds.size());
|
||||
for (auto twoDAmbientSound : this->m_2DAmbientSounds) {
|
||||
twoDAmbientSound.Serialize(outBitStream);
|
||||
}
|
||||
|
||||
outBitStream->Write<uint8_t>(this->m_3DAmbientSounds.size());
|
||||
outBitStream.Write<uint8_t>(this->m_3DAmbientSounds.size());
|
||||
for (auto threeDAmbientSound : this->m_3DAmbientSounds) {
|
||||
threeDAmbientSound.Serialize(outBitStream);
|
||||
}
|
||||
|
||||
outBitStream->Write<uint8_t>(this->m_MixerPrograms.size());
|
||||
outBitStream.Write<uint8_t>(this->m_MixerPrograms.size());
|
||||
for (auto& mixerProgram : this->m_MixerPrograms) {
|
||||
mixerProgram.Serialize(outBitStream);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "dCommonVars.h"
|
||||
#include "Entity.h"
|
||||
#include "GUID.h"
|
||||
@@ -16,7 +17,7 @@ struct MusicCue {
|
||||
this->boredomTime = boredomTime;
|
||||
};
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream);
|
||||
void Serialize(RakNet::BitStream& outBitStream);
|
||||
};
|
||||
|
||||
struct MusicParameter {
|
||||
@@ -28,7 +29,7 @@ struct MusicParameter {
|
||||
this->value = value;
|
||||
}
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream);
|
||||
void Serialize(RakNet::BitStream& outBitStream);
|
||||
};
|
||||
|
||||
struct GUIDResults{
|
||||
@@ -40,10 +41,10 @@ struct GUIDResults{
|
||||
this->result = result;
|
||||
}
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream);
|
||||
void Serialize(RakNet::BitStream& outBitStream);
|
||||
};
|
||||
|
||||
struct MixerProgram{
|
||||
struct MixerProgram {
|
||||
std::string name;
|
||||
uint32_t result;
|
||||
|
||||
@@ -52,25 +53,25 @@ struct MixerProgram{
|
||||
this->result = result;
|
||||
}
|
||||
|
||||
void Serialize(RakNet::BitStream* outBitStream);
|
||||
void Serialize(RakNet::BitStream& outBitStream);
|
||||
};
|
||||
|
||||
|
||||
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 Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) override;
|
||||
void ActivateMusicCue(const std::string& name, float bordemTime = -1.0);
|
||||
void DeactivateMusicCue(const std::string& name);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -21,8 +21,8 @@ SwitchComponent::~SwitchComponent() {
|
||||
}
|
||||
}
|
||||
|
||||
void SwitchComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream->Write(m_Active);
|
||||
void SwitchComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
outBitStream.Write(m_Active);
|
||||
}
|
||||
|
||||
void SwitchComponent::SetActive(bool active) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user