Compare commits

..

1 Commits

Author SHA1 Message Date
David Markowitz
4353f37d00 Remove unused problematic code 2023-06-15 20:50:40 -07:00
265 changed files with 3333 additions and 5469 deletions

View File

@@ -14,4 +14,4 @@ EXTERNAL_IP=localhost
MARIADB_USER=darkflame
MARIADB_PASSWORD=SECRET_VALUE_CHANGE_ME
MARIADB_ROOT_PASSWORD=SECRET_VALUE_CHANGE_ME
MARIADB_DATABASE=darkflame
MARIADB_DATABASE=darkflame

View File

@@ -97,56 +97,15 @@ make_directory(${CMAKE_BINARY_DIR}/logs)
# Copy resource files on first build
set(RESOURCE_FILES "sharedconfig.ini" "authconfig.ini" "chatconfig.ini" "worldconfig.ini" "masterconfig.ini" "blacklist.dcf")
message(STATUS "Checking resource file integrity")
foreach (resource_file ${RESOURCE_FILES})
set(file_size 0)
if (EXISTS ${PROJECT_BINARY_DIR}/${resource_file})
file(SIZE ${PROJECT_BINARY_DIR}/${resource_file} file_size)
endif()
if (${file_size} EQUAL 0)
foreach(resource_file ${RESOURCE_FILES})
if (NOT EXISTS ${PROJECT_BINARY_DIR}/${resource_file})
configure_file(
${CMAKE_SOURCE_DIR}/resources/${resource_file} ${PROJECT_BINARY_DIR}/${resource_file}
COPYONLY
)
message(STATUS "Moved " ${resource_file} " to project binary directory")
elseif (resource_file MATCHES ".ini")
message(STATUS "Checking " ${resource_file} " for missing config options")
file(READ ${PROJECT_BINARY_DIR}/${resource_file} current_file_contents)
string(REPLACE "\\\n" "" current_file_contents ${current_file_contents})
string(REPLACE "\n" ";" current_file_contents ${current_file_contents})
set(parsed_current_file_contents "")
# Remove comment lines so they do not interfere with the variable parsing
foreach (line ${current_file_contents})
string(FIND ${line} "#" is_comment)
if (NOT ${is_comment} EQUAL 0)
string(APPEND parsed_current_file_contents ${line})
endif()
endforeach()
file(READ ${CMAKE_SOURCE_DIR}/resources/${resource_file} depot_file_contents)
string(REPLACE "\\\n" "" depot_file_contents ${depot_file_contents})
string(REPLACE "\n" ";" depot_file_contents ${depot_file_contents})
set(line_to_add "")
foreach (line ${depot_file_contents})
string(FIND ${line} "#" is_comment)
if (NOT ${is_comment} EQUAL 0)
string(REPLACE "=" ";" line_split ${line})
list(GET line_split 0 variable_name)
if (NOT ${parsed_current_file_contents} MATCHES ${variable_name})
message(STATUS "Adding missing config option " ${variable_name} " to " ${resource_file})
set(line_to_add ${line_to_add} ${line})
foreach (line_to_append ${line_to_add})
file(APPEND ${PROJECT_BINARY_DIR}/${resource_file} "\n" ${line_to_append})
endforeach()
file(APPEND ${PROJECT_BINARY_DIR}/${resource_file} "\n")
endif()
set(line_to_add "")
else()
set(line_to_add ${line_to_add} ${line})
endif()
endforeach()
message("Moved ${resource_file} to project binary directory")
endif()
endforeach()
message(STATUS "Resource file integrity check complete")
# Copy navmesh data on first build and extract it
if (NOT EXISTS ${PROJECT_BINARY_DIR}/navmeshes/)

View File

@@ -1,8 +1,12 @@
PROJECT_VERSION_MAJOR=1
PROJECT_VERSION_MINOR=0
PROJECT_VERSION_PATCH=1
PROJECT_VERSION_PATCH=4
# LICENSE
LICENSE=AGPL-3.0
# The network version.
# 171023 - Darkflame Universe client
# 171022 - Unmodded client
NET_VERSION=171022
# Debugging
# Set __dynamic to 1 to enable the -rdynamic flag for the linker, yielding some symbols in crashlogs.
__dynamic=1

View File

@@ -179,7 +179,7 @@ If you would like to build the server faster, append `-j<number>` where number i
### Notes
Depending on your operating system, you may need to adjust some pre-processor defines in [CMakeVariables.txt](./CMakeVariables.txt) before building:
* If you are on MacOS, ensure OPENSSL_ROOT_DIR is pointing to the openssl root directory.
* If you are using a Darkflame Universe client, ensure `client_net_version` in `build/sharedconfig.ini` is changed to 171023.
* If you are using a Darkflame Universe client, ensure NET_VERSION is changed to 171023.
## Configuring your server
This server has a few steps that need to be taken to configure the server for your use case.
@@ -338,7 +338,7 @@ This is a Work in Progress, but below are some quick links to documentaion for s
## Former Contributors
* TheMachine
* Matthew
* [Raine](https://github.com/uwainium)
* [Raine](https://github.com/Rainebannister)
* Bricknave
## Special Thanks

View File

@@ -29,7 +29,6 @@ namespace Game {
dServer* server = nullptr;
dConfig* config = nullptr;
bool shouldShutdown = false;
std::mt19937 randomEngine;
}
dLogger* SetupLogger();
@@ -84,8 +83,6 @@ int main(int argc, char** argv) {
delete res;
delete stmt;
Game::randomEngine = std::mt19937(time(0));
//It's safe to pass 'localhost' here, as the IP is only used as the external IP.
uint32_t maxClients = 50;
uint32_t ourPort = 1001; //LU client is hardcoded to use this for auth port, so I'm making it the default.

View File

@@ -33,7 +33,6 @@ namespace Game {
dChatFilter* chatFilter = nullptr;
AssetManager* assetManager = nullptr;
bool shouldShutdown = false;
std::mt19937 randomEngine;
}
@@ -115,8 +114,6 @@ int main(int argc, char** argv) {
Game::server = new dServer(Game::config->GetValue("external_ip"), ourPort, 0, maxClients, false, true, Game::logger, masterIP, masterPort, ServerType::Chat, Game::config, &Game::shouldShutdown);
Game::chatFilter = new dChatFilter(Game::assetManager->GetResPath().string() + "/chatplus_en_us", bool(std::stoi(Game::config->GetValue("dont_generate_dcf"))));
Game::randomEngine = std::mt19937(time(0));
//Run it until server gets a kill message from Master:
auto t = std::chrono::high_resolution_clock::now();

View File

@@ -10,8 +10,6 @@ class dConfig;
class RakPeerInterface;
class AssetManager;
struct SystemAddress;
class EntityManager;
class dZoneManager;
namespace Game {
extern dLogger* logger;
@@ -24,6 +22,4 @@ namespace Game {
extern AssetManager* assetManager;
extern SystemAddress chatSysAddr;
extern bool shouldShutdown;
extern EntityManager* entityManager;
extern dZoneManager* zoneManager;
}

View File

@@ -111,6 +111,29 @@ namespace GeneralUtils {
*/
bool CheckBit(int64_t value, uint32_t index);
// MARK: Random Number Generation
//! Generates a random number
/*!
\param min The minimum the generate from
\param max The maximum to generate to
*/
template <typename T>
inline T GenerateRandomNumber(std::size_t min, std::size_t max) {
// Make sure it is a numeric type
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
if constexpr (std::is_integral_v<T>) { // constexpr only necessary on first statement
std::uniform_int_distribution<T> distribution(min, max);
return distribution(Game::randomEngine);
} else if (std::is_floating_point_v<T>) {
std::uniform_real_distribution<T> distribution(min, max);
return distribution(Game::randomEngine);
}
return T();
}
bool ReplaceInString(std::string& str, const std::string& from, const std::string& to);
std::u16string ReadWString(RakNet::BitStream* inStream);
@@ -200,42 +223,4 @@ namespace GeneralUtils {
std::hash<T> h;
s ^= h(v) + 0x9e3779b9 + (s << 6) + (s >> 2);
}
// MARK: Random Number Generation
//! Generates a random number
/*!
\param min The minimum the generate from
\param max The maximum to generate to
*/
template <typename T>
inline T GenerateRandomNumber(std::size_t min, std::size_t max) {
// Make sure it is a numeric type
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
if constexpr (std::is_integral_v<T>) { // constexpr only necessary on first statement
std::uniform_int_distribution<T> distribution(min, max);
return distribution(Game::randomEngine);
} else if (std::is_floating_point_v<T>) {
std::uniform_real_distribution<T> distribution(min, max);
return distribution(Game::randomEngine);
}
return T();
}
// on Windows we need to undef these or else they conflict with our numeric limits calls
// DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS
#ifdef _WIN32
#undef min
#undef max
#endif
template <typename T>
inline T GenerateRandomNumber() {
// Make sure it is a numeric type
static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
return GenerateRandomNumber<T>(std::numeric_limits<T>::min(), std::numeric_limits<T>::max());
}
}

View File

@@ -129,13 +129,11 @@ NiPoint3 NiPoint3::operator+(const NiPoint3& point) const {
}
//! Operator for addition of vectors
NiPoint3& NiPoint3::operator+=(const NiPoint3& point) {
this->x += point.x;
this->y += point.y;
this->z += point.z;
return *this;
NiPoint3 NiPoint3::operator+=(const NiPoint3& point) const {
return NiPoint3(this->x + point.x, this->y + point.y, this->z + point.z);
}
//! Operator for subtraction of vectors
NiPoint3 NiPoint3::operator-(const NiPoint3& point) const {
return NiPoint3(this->x - point.x, this->y - point.y, this->z - point.z);

View File

@@ -136,7 +136,7 @@ public:
NiPoint3 operator+(const NiPoint3& point) const;
//! Operator for addition of vectors
NiPoint3& operator+=(const NiPoint3& point);
NiPoint3 operator+=(const NiPoint3& point) const;
//! Operator for subtraction of vectors
NiPoint3 operator-(const NiPoint3& point) const;

File diff suppressed because it is too large Load Diff

View File

@@ -1,30 +1,26 @@
#include "CDBehaviorParameterTable.h"
#include "GeneralUtils.h"
uint64_t GetHash(const uint32_t behaviorID, const uint32_t parameterID) {
uint64_t hash = behaviorID;
hash <<= 31U;
hash |= parameterID;
return hash;
}
CDBehaviorParameterTable::CDBehaviorParameterTable() {
CDBehaviorParameterTable::CDBehaviorParameterTable(void) {
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorParameter");
uint32_t uniqueParameterId = 0;
uint64_t hash = 0;
while (!tableData.eof()) {
uint32_t behaviorID = tableData.getIntField("behaviorID", -1);
CDBehaviorParameter entry;
entry.behaviorID = tableData.getIntField("behaviorID", -1);
auto candidateStringToAdd = std::string(tableData.getStringField("parameterID", ""));
auto parameter = m_ParametersList.find(candidateStringToAdd);
uint32_t parameterId;
if (parameter != m_ParametersList.end()) {
parameterId = parameter->second;
entry.parameterID = parameter;
} else {
parameterId = m_ParametersList.insert(std::make_pair(candidateStringToAdd, m_ParametersList.size())).first->second;
entry.parameterID = m_ParametersList.insert(std::make_pair(candidateStringToAdd, uniqueParameterId)).first;
uniqueParameterId++;
}
uint64_t hash = GetHash(behaviorID, parameterId);
float value = tableData.getFloatField("value", -1.0f);
hash = entry.behaviorID;
hash = (hash << 31U) | entry.parameterID->second;
entry.value = tableData.getFloatField("value", -1.0f);
m_Entries.insert(std::make_pair(hash, value));
m_Entries.insert(std::make_pair(hash, entry));
tableData.nextRow();
}
@@ -34,22 +30,27 @@ CDBehaviorParameterTable::CDBehaviorParameterTable() {
float CDBehaviorParameterTable::GetValue(const uint32_t behaviorID, const std::string& name, const float defaultValue) {
auto parameterID = this->m_ParametersList.find(name);
if (parameterID == this->m_ParametersList.end()) return defaultValue;
auto hash = GetHash(behaviorID, parameterID->second);
uint64_t hash = behaviorID;
hash = (hash << 31U) | parameterID->second;
// Search for specific parameter
auto it = m_Entries.find(hash);
return it != m_Entries.end() ? it->second : defaultValue;
const auto& it = m_Entries.find(hash);
return it != m_Entries.end() ? it->second.value : defaultValue;
}
std::map<std::string, float> CDBehaviorParameterTable::GetParametersByBehaviorID(uint32_t behaviorID) {
uint64_t hashBase = behaviorID;
std::map<std::string, float> returnInfo;
for (auto& [parameterString, parameterId] : m_ParametersList) {
uint64_t hash = GetHash(hashBase, parameterId);
uint64_t hash;
for (auto& parameterCandidate : m_ParametersList) {
hash = (hashBase << 31U) | parameterCandidate.second;
auto infoCandidate = m_Entries.find(hash);
if (infoCandidate != m_Entries.end()) {
returnInfo.insert(std::make_pair(parameterString, infoCandidate->second));
returnInfo.insert(std::make_pair(infoCandidate->second.parameterID->first, infoCandidate->second.value));
}
}
return returnInfo;
}

View File

@@ -5,15 +5,18 @@
#include <unordered_map>
#include <unordered_set>
struct CDBehaviorParameter {
unsigned int behaviorID; //!< The Behavior ID
std::unordered_map<std::string, uint32_t>::iterator parameterID; //!< The Parameter ID
float value; //!< The value of the behavior template
};
class CDBehaviorParameterTable : public CDTable<CDBehaviorParameterTable> {
private:
typedef uint64_t BehaviorParameterHash;
typedef float BehaviorParameterValue;
std::unordered_map<BehaviorParameterHash, BehaviorParameterValue> m_Entries;
std::unordered_map<uint64_t, CDBehaviorParameter> m_Entries;
std::unordered_map<std::string, uint32_t> m_ParametersList;
public:
CDBehaviorParameterTable();
float GetValue(const uint32_t behaviorID, const std::string& name, const float defaultValue = 0);
std::map<std::string, float> GetParametersByBehaviorID(uint32_t behaviorID);

View File

@@ -22,7 +22,7 @@ CDVendorComponentTable::CDVendorComponentTable(void) {
while (!tableData.eof()) {
CDVendorComponent entry;
entry.id = tableData.getIntField("id", -1);
entry.buyScalar = tableData.getFloatField("buyScalar", 0.0f);
entry.buyScalar = tableData.getFloatField("buyScalar", -1.0f);
entry.sellScalar = tableData.getFloatField("sellScalar", -1.0f);
entry.refreshTimeSeconds = tableData.getFloatField("refreshTimeSeconds", -1.0f);
entry.LootMatrixIndex = tableData.getIntField("LootMatrixIndex", -1);

View File

@@ -241,7 +241,7 @@ void Character::DoQuickXMLDataParse() {
//To try and fix the AG landing into:
if (m_ZoneID == 1000 && Game::server->GetZoneID() == 1100) {
//sneakily insert our position:
auto pos = Game::zoneManager->GetZone()->GetSpawnPos();
auto pos = dZoneManager::Instance()->GetZone()->GetSpawnPos();
character->SetAttribute("lzx", pos.x);
character->SetAttribute("lzy", pos.y);
character->SetAttribute("lzz", pos.z);
@@ -290,13 +290,13 @@ void Character::DoQuickXMLDataParse() {
void Character::UnlockEmote(int emoteID) {
m_UnlockedEmotes.push_back(emoteID);
GameMessages::SendSetEmoteLockState(Game::entityManager->GetEntity(m_ObjectID), false, emoteID);
GameMessages::SendSetEmoteLockState(EntityManager::Instance()->GetEntity(m_ObjectID), false, emoteID);
}
void Character::SetBuildMode(bool buildMode) {
m_BuildMode = buildMode;
auto* controller = Game::zoneManager->GetZoneControlObject();
auto* controller = dZoneManager::Instance()->GetZoneControlObject();
controller->OnFireEventServerSide(m_OurEntity, buildMode ? "OnBuildModeEnter" : "OnBuildModeLeave");
}
@@ -312,7 +312,7 @@ void Character::SaveXMLToDatabase() {
character->SetAttribute("gm", static_cast<uint32_t>(m_GMLevel));
character->SetAttribute("cc", m_Coins);
auto zoneInfo = Game::zoneManager->GetZone()->GetZoneID();
auto zoneInfo = dZoneManager::Instance()->GetZone()->GetZoneID();
// lzid garbage, binary concat of zoneID, zoneInstance and zoneClone
if (zoneInfo.GetMapID() != 0 && zoneInfo.GetCloneID() == 0) {
uint64_t lzidConcat = zoneInfo.GetCloneID();
@@ -418,13 +418,13 @@ void Character::WriteToDatabase() {
delete printer;
}
void Character::SetPlayerFlag(const uint32_t flagId, const bool value) {
void Character::SetPlayerFlag(const int32_t flagId, const bool value) {
// If the flag is already set, we don't have to recalculate it
if (GetPlayerFlag(flagId) == value) return;
if (value) {
// Update the mission component:
auto* player = Game::entityManager->GetEntity(m_ObjectID);
auto* player = EntityManager::Instance()->GetEntity(m_ObjectID);
if (player != nullptr) {
auto* missionComponent = player->GetComponent<MissionComponent>();
@@ -465,7 +465,7 @@ void Character::SetPlayerFlag(const uint32_t flagId, const bool value) {
GameMessages::SendNotifyClientFlagChange(m_ObjectID, flagId, value, m_ParentUser->GetSystemAddress());
}
bool Character::GetPlayerFlag(const uint32_t flagId) const {
bool Character::GetPlayerFlag(const int32_t flagId) const {
// Calculate the index first
const auto flagIndex = uint32_t(std::floor(flagId / 64));
@@ -602,7 +602,7 @@ void Character::SetCoins(int64_t newCoins, eLootSourceType lootSource) {
m_Coins = newCoins;
GameMessages::SendSetCurrency(Game::entityManager->GetEntity(m_ObjectID), m_Coins, 0, 0, 0, 0, true, lootSource);
GameMessages::SendSetCurrency(EntityManager::Instance()->GetEntity(m_ObjectID), m_Coins, 0, 0, 0, 0, true, lootSource);
}
bool Character::HasBeenToWorld(LWOMAPID mapID) const {

View File

@@ -415,14 +415,14 @@ public:
* @param flagId the ID of the flag to set
* @param value the value to set for the flag
*/
void SetPlayerFlag(uint32_t flagId, bool value);
void SetPlayerFlag(int32_t flagId, bool value);
/**
* Gets the value for a certain character flag
* @param flagId the ID of the flag to get a value for
* @return the value of the flag given the ID (the default is false, obviously)
*/
bool GetPlayerFlag(uint32_t flagId) const;
bool GetPlayerFlag(int32_t flagId) const;
/**
* Notifies the character that they're now muted

View File

@@ -51,7 +51,6 @@
#include "BuildBorderComponent.h"
#include "MovementAIComponent.h"
#include "VendorComponent.h"
#include "DonationVendorComponent.h"
#include "RocketLaunchpadControlComponent.h"
#include "PropertyComponent.h"
#include "BaseCombatAIComponent.h"
@@ -71,7 +70,6 @@
#include "ShootingGalleryComponent.h"
#include "RailActivatorComponent.h"
#include "LUPExhibitComponent.h"
#include "RacingSoundTriggerComponent.h"
#include "TriggerComponent.h"
#include "eGameMasterLevel.h"
#include "eReplicaComponentType.h"
@@ -265,17 +263,17 @@ void Entity::Initialize() {
NiQuaternion rot;
const auto& targetSceneName = m_Character->GetTargetScene();
auto* targetScene = Game::entityManager->GetSpawnPointEntity(targetSceneName);
auto* targetScene = EntityManager::Instance()->GetSpawnPointEntity(targetSceneName);
if (m_Character->HasBeenToWorld(mapID) && targetSceneName.empty()) {
pos = m_Character->GetRespawnPoint(mapID);
rot = Game::zoneManager->GetZone()->GetSpawnRot();
rot = dZoneManager::Instance()->GetZone()->GetSpawnRot();
} else if (targetScene != nullptr) {
pos = targetScene->GetPosition();
rot = targetScene->GetRotation();
} else {
pos = Game::zoneManager->GetZone()->GetSpawnPos();
rot = Game::zoneManager->GetZone()->GetSpawnRot();
pos = dZoneManager::Instance()->GetZone()->GetSpawnPos();
rot = dZoneManager::Instance()->GetZone()->GetSpawnRot();
}
controllablePhysics->SetPosition(pos);
@@ -319,9 +317,6 @@ void Entity::Initialize() {
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::SOUND_TRIGGER, -1) != -1) {
auto* comp = new SoundTriggerComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::SOUND_TRIGGER, comp));
} else if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::RACING_SOUND_TRIGGER, -1) != -1) {
auto* comp = new RacingSoundTriggerComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::RACING_SOUND_TRIGGER, comp));
}
//Also check for the collectible id:
@@ -510,7 +505,7 @@ void Entity::Initialize() {
// ZoneControl script
if (m_TemplateID == 2365) {
CDZoneTableTable* zoneTable = CDClientManager::Instance().GetTable<CDZoneTableTable>();
const auto zoneID = Game::zoneManager->GetZoneID();
const auto zoneID = dZoneManager::Instance()->GetZoneID();
const CDZoneTable* zoneData = zoneTable->Query(zoneID.GetMapID());
if (zoneData != nullptr) {
@@ -583,9 +578,6 @@ void Entity::Initialize() {
if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::VENDOR) > 0)) {
VendorComponent* comp = new VendorComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::VENDOR, comp));
} else if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::DONATION_VENDOR, -1) != -1)) {
DonationVendorComponent* comp = new DonationVendorComponent(this);
m_Components.insert(std::make_pair(eReplicaComponentType::DONATION_VENDOR, comp));
}
if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY_VENDOR, -1) != -1) {
@@ -699,7 +691,7 @@ void Entity::Initialize() {
}
std::string pathName = GetVarAsString(u"attached_path");
const Path* path = Game::zoneManager->GetZone()->GetPath(pathName);
const Path* path = dZoneManager::Instance()->GetZone()->GetPath(pathName);
//Check to see if we have an attached path and add the appropiate component to handle it:
if (path){
@@ -743,7 +735,7 @@ void Entity::Initialize() {
}
});
if (!m_Character && Game::entityManager->GetGhostingEnabled()) {
if (!m_Character && EntityManager::Instance()->GetGhostingEnabled()) {
// Don't ghost what is likely large scene elements
if (HasComponent(eReplicaComponentType::SIMPLE_PHYSICS) && HasComponent(eReplicaComponentType::RENDER) && (m_Components.size() == 2 || (HasComponent(eReplicaComponentType::TRIGGER) && m_Components.size() == 3))) {
goto no_ghosting;
@@ -1064,11 +1056,6 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType
soundTriggerComponent->Serialize(outBitStream, bIsInitialUpdate, flags);
}
RacingSoundTriggerComponent* racingSoundTriggerComponent;
if (TryGetComponent(eReplicaComponentType::RACING_SOUND_TRIGGER, racingSoundTriggerComponent)) {
racingSoundTriggerComponent->Serialize(outBitStream, bIsInitialUpdate, flags);
}
BuffComponent* buffComponent;
if (TryGetComponent(eReplicaComponentType::BUFF, buffComponent)) {
buffComponent->Serialize(outBitStream, bIsInitialUpdate, flags);
@@ -1173,11 +1160,6 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType
vendorComponent->Serialize(outBitStream, bIsInitialUpdate, flags);
}
DonationVendorComponent* donationVendorComponent;
if (TryGetComponent(eReplicaComponentType::DONATION_VENDOR, donationVendorComponent)) {
donationVendorComponent->Serialize(outBitStream, bIsInitialUpdate, flags);
}
BouncerComponent* bouncerComponent;
if (TryGetComponent(eReplicaComponentType::BOUNCER, bouncerComponent)) {
bouncerComponent->Serialize(outBitStream, bIsInitialUpdate, flags);
@@ -1302,12 +1284,12 @@ void Entity::Update(const float deltaTime) {
}
if (m_ShouldDestroyAfterUpdate) {
Game::entityManager->DestroyEntity(this->GetObjectID());
EntityManager::Instance()->DestroyEntity(this->GetObjectID());
}
}
void Entity::OnCollisionProximity(LWOOBJID otherEntity, const std::string& proxName, const std::string& status) {
Entity* other = Game::entityManager->GetEntity(otherEntity);
Entity* other = EntityManager::Instance()->GetEntity(otherEntity);
if (!other) return;
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) {
@@ -1321,7 +1303,7 @@ void Entity::OnCollisionProximity(LWOOBJID otherEntity, const std::string& proxN
}
void Entity::OnCollisionPhantom(const LWOOBJID otherEntity) {
auto* other = Game::entityManager->GetEntity(otherEntity);
auto* other = EntityManager::Instance()->GetEntity(otherEntity);
if (!other) return;
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) {
@@ -1368,7 +1350,7 @@ void Entity::OnCollisionPhantom(const LWOOBJID otherEntity) {
}
void Entity::OnCollisionLeavePhantom(const LWOOBJID otherEntity) {
auto* other = Game::entityManager->GetEntity(otherEntity);
auto* other = EntityManager::Instance()->GetEntity(otherEntity);
if (!other) return;
for (CppScripts::Script* script : CppScripts::GetEntityScripts(this)) {
@@ -1522,13 +1504,13 @@ void Entity::Smash(const LWOOBJID source, const eKillType killType, const std::u
auto* destroyableComponent = GetComponent<DestroyableComponent>();
if (destroyableComponent == nullptr) {
Kill(Game::entityManager->GetEntity(source));
Kill(EntityManager::Instance()->GetEntity(source));
return;
}
auto* possessorComponent = GetComponent<PossessorComponent>();
if (possessorComponent) {
if (possessorComponent->GetPossessable() != LWOOBJID_EMPTY) {
auto* mount = Game::entityManager->GetEntity(possessorComponent->GetPossessable());
auto* mount = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable());
if (mount) possessorComponent->Dismount(mount, true);
}
}
@@ -1556,20 +1538,20 @@ void Entity::Kill(Entity* murderer) {
}
if (!IsPlayer()) {
Game::entityManager->DestroyEntity(this);
EntityManager::Instance()->DestroyEntity(this);
}
const auto& grpNameQBShowBricks = GetVar<std::string>(u"grpNameQBShowBricks");
if (!grpNameQBShowBricks.empty()) {
auto spawners = Game::zoneManager->GetSpawnersByName(grpNameQBShowBricks);
auto spawners = dZoneManager::Instance()->GetSpawnersByName(grpNameQBShowBricks);
Spawner* spawner = nullptr;
if (!spawners.empty()) {
spawner = spawners[0];
} else {
spawners = Game::zoneManager->GetSpawnersInGroup(grpNameQBShowBricks);
spawners = dZoneManager::Instance()->GetSpawnersInGroup(grpNameQBShowBricks);
if (!spawners.empty()) {
spawner = spawners[0];
@@ -1737,7 +1719,7 @@ void Entity::CancelCallbackTimers() {
void Entity::ScheduleKillAfterUpdate(Entity* murderer) {
//if (m_Info.spawner) m_Info.spawner->ScheduleKill(this);
Game::entityManager->ScheduleForKill(this);
EntityManager::Instance()->ScheduleForKill(this);
if (murderer) m_ScheduleKiller = murderer;
}
@@ -1781,7 +1763,7 @@ void Entity::TriggerEvent(eTriggerEventType event, Entity* optionalTarget) {
Entity* Entity::GetOwner() const {
if (m_OwnerOverride != LWOOBJID_EMPTY) {
auto* other = Game::entityManager->GetEntity(m_OwnerOverride);
auto* other = EntityManager::Instance()->GetEntity(m_OwnerOverride);
if (other != nullptr) {
return other->GetOwner();
@@ -1925,7 +1907,7 @@ void Entity::SetPosition(NiPoint3 position) {
vehicel->SetPosition(position);
}
Game::entityManager->SerializeEntity(this);
EntityManager::Instance()->SerializeEntity(this);
}
void Entity::SetRotation(NiQuaternion rotation) {
@@ -1953,7 +1935,7 @@ void Entity::SetRotation(NiQuaternion rotation) {
vehicel->SetRotation(rotation);
}
Game::entityManager->SerializeEntity(this);
EntityManager::Instance()->SerializeEntity(this);
}
bool Entity::GetBoolean(const std::u16string& name) const {
@@ -2005,7 +1987,7 @@ std::vector<LWOOBJID>& Entity::GetTargetsInPhantom() {
for (auto i = 0u; i < m_TargetsInPhantom.size(); ++i) {
const auto id = m_TargetsInPhantom.at(i);
auto* entity = Game::entityManager->GetEntity(id);
auto* entity = EntityManager::Instance()->GetEntity(id);
if (entity == nullptr) {
continue;

View File

@@ -85,7 +85,6 @@ public:
bool GetPlayerReadyForUpdates() const { return m_PlayerIsReadyForUpdates; }
bool GetIsGhostingCandidate() const;
void SetIsGhostingCandidate(bool value) { m_IsGhostingCandidate = value; };
int8_t GetObservers() const;

View File

@@ -25,6 +25,8 @@
#include "eReplicaComponentType.h"
#include "eReplicaPacketType.h"
EntityManager* EntityManager::m_Address = nullptr;
// Configure which zones have ghosting disabled, mostly small worlds.
std::vector<LWOMAPID> EntityManager::m_GhostingExcludedZones = {
// Small zones
@@ -60,7 +62,7 @@ void EntityManager::Initialize() {
m_GhostingEnabled = std::find(
m_GhostingExcludedZones.begin(),
m_GhostingExcludedZones.end(),
Game::zoneManager->GetZoneID().GetMapID()
dZoneManager::Instance()->GetZoneID().GetMapID()
) == m_GhostingExcludedZones.end();
// grab hardcore mode settings and load them with sane defaults
@@ -75,7 +77,10 @@ void EntityManager::Initialize() {
// If cloneID is not zero, then hardcore mode is disabled
// aka minigames and props
if (Game::zoneManager->GetZoneID().GetCloneID() != 0) m_HardcoreMode = false;
if (dZoneManager::Instance()->GetZoneID().GetCloneID() != 0) m_HardcoreMode = false;
}
EntityManager::~EntityManager() {
}
Entity* EntityManager::CreateEntity(EntityInfo info, User* user, Entity* parentEntity, const bool controller, const LWOOBJID explicitId) {

View File

@@ -1,13 +1,12 @@
#ifndef ENTITYMANAGER_H
#define ENTITYMANAGER_H
#include "dCommonVars.h"
#include <map>
#include <stack>
#include <vector>
#include <unordered_map>
#include "dCommonVars.h"
class Entity;
class EntityInfo;
class Player;
@@ -18,8 +17,19 @@ struct SystemAddress;
class EntityManager {
public:
static EntityManager* Instance() {
if (!m_Address) {
m_Address = new EntityManager();
m_Address->Initialize();
}
return m_Address;
}
void Initialize();
~EntityManager();
void UpdateEntities(float deltaTime);
Entity* CreateEntity(EntityInfo info, User* user = nullptr, Entity* parentEntity = nullptr, bool controller = false, LWOOBJID explicitId = LWOOBJID_EMPTY);
void DestroyEntity(const LWOOBJID& objectID);
@@ -79,6 +89,7 @@ private:
void KillEntities();
void DeleteEntities();
static EntityManager* m_Address; //For singleton method
static std::vector<LWOMAPID> m_GhostingExcludedZones;
static std::vector<LOT> m_GhostingExcludedLOTs;

View File

@@ -1,8 +1,5 @@
#include "LeaderboardManager.h"
#include <sstream>
#include <utility>
#include "Database.h"
#include "EntityManager.h"
#include "Character.h"
@@ -13,400 +10,461 @@
#include "CDClientManager.h"
#include "GeneralUtils.h"
#include "Entity.h"
#include "LDFFormat.h"
#include "DluAssert.h"
#include "CDActivitiesTable.h"
#include "Metrics.hpp"
namespace LeaderboardManager {
std::map<GameID, Leaderboard::Type> leaderboardCache;
}
Leaderboard::Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, LWOOBJID relatedPlayer, const Leaderboard::Type leaderboardType) {
Leaderboard::Leaderboard(uint32_t gameID, uint32_t infoType, bool weekly, std::vector<LeaderboardEntry> entries,
LWOOBJID relatedPlayer, LeaderboardType leaderboardType) {
this->relatedPlayer = relatedPlayer;
this->gameID = gameID;
this->weekly = weekly;
this->infoType = infoType;
this->entries = std::move(entries);
this->leaderboardType = leaderboardType;
this->relatedPlayer = relatedPlayer;
}
Leaderboard::~Leaderboard() {
Clear();
}
std::u16string Leaderboard::ToString() const {
std::string leaderboard;
void Leaderboard::Clear() {
for (auto& entry : entries) for (auto ldfData : entry) delete ldfData;
}
leaderboard += "ADO.Result=7:1\n";
leaderboard += "Result.Count=1:1\n";
leaderboard += "Result[0].Index=0:RowNumber\n";
leaderboard += "Result[0].RowCount=1:" + std::to_string(entries.size()) + "\n";
inline void WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, LDFBaseData* data) {
leaderboard << "\nResult[0].Row[" << index << "]." << data->GetString();
}
auto index = 0;
for (const auto& entry : entries) {
leaderboard += "Result[0].Row[" + std::to_string(index) + "].LastPlayed=8:" + std::to_string(entry.lastPlayed) + "\n";
leaderboard += "Result[0].Row[" + std::to_string(index) + "].CharacterID=8:" + std::to_string(entry.playerID) + "\n";
leaderboard += "Result[0].Row[" + std::to_string(index) + "].NumPlayed=1:1\n";
leaderboard += "Result[0].Row[" + std::to_string(index) + "].RowNumber=8:" + std::to_string(entry.placement) + "\n";
leaderboard += "Result[0].Row[" + std::to_string(index) + "].Time=1:" + std::to_string(entry.time) + "\n";
void Leaderboard::Serialize(RakNet::BitStream* bitStream) const {
bitStream->Write(gameID);
bitStream->Write(infoType);
std::ostringstream leaderboard;
leaderboard << "ADO.Result=7:1"; // Unused in 1.10.64, but is in captures
leaderboard << "\nResult.Count=1:1"; // number of results, always 1
if (!this->entries.empty()) leaderboard << "\nResult[0].Index=0:RowNumber"; // "Primary key". Live doesn't include this if there are no entries.
leaderboard << "\nResult[0].RowCount=1:" << entries.size();
int32_t rowNumber = 0;
for (auto& entry : entries) {
for (auto* data : entry) {
WriteLeaderboardRow(leaderboard, rowNumber, data);
// Only these minigames have a points system
if (leaderboardType == Survival || leaderboardType == ShootingGallery) {
leaderboard += "Result[0].Row[" + std::to_string(index) + "].Points=1:" + std::to_string(entry.score) + "\n";
} else if (leaderboardType == SurvivalNS) {
leaderboard += "Result[0].Row[" + std::to_string(index) + "].Wave=1:" + std::to_string(entry.score) + "\n";
}
rowNumber++;
leaderboard += "Result[0].Row[" + std::to_string(index) + "].name=0:" + entry.playerName + "\n";
index++;
}
// Serialize the thing to a BitStream
uint32_t leaderboardSize = leaderboard.tellp();
bitStream->Write<uint32_t>(leaderboardSize);
// Doing this all in 1 call so there is no possbility of a dangling pointer.
bitStream->WriteAlignedBytes(reinterpret_cast<const unsigned char*>(GeneralUtils::ASCIIToUTF16(leaderboard.str()).c_str()), leaderboardSize * sizeof(char16_t));
if (leaderboardSize > 0) bitStream->Write<uint16_t>(0);
bitStream->Write0();
bitStream->Write0();
return GeneralUtils::UTF8ToUTF16(leaderboard);
}
void Leaderboard::QueryToLdf(std::unique_ptr<sql::ResultSet>& rows) {
Clear();
if (rows->rowsCount() == 0) return;
this->entries.reserve(rows->rowsCount());
while (rows->next()) {
constexpr int32_t MAX_NUM_DATA_PER_ROW = 9;
this->entries.push_back(std::vector<LDFBaseData*>());
auto& entry = this->entries.back();
entry.reserve(MAX_NUM_DATA_PER_ROW);
entry.push_back(new LDFData<uint64_t>(u"CharacterID", rows->getInt("character_id")));
entry.push_back(new LDFData<uint64_t>(u"LastPlayed", rows->getUInt64("lastPlayed")));
entry.push_back(new LDFData<int32_t>(u"NumPlayed", rows->getInt("timesPlayed")));
entry.push_back(new LDFData<std::u16string>(u"name", GeneralUtils::ASCIIToUTF16(rows->getString("name").c_str())));
entry.push_back(new LDFData<uint64_t>(u"RowNumber", rows->getInt("ranking")));
switch (leaderboardType) {
case Type::ShootingGallery:
entry.push_back(new LDFData<int32_t>(u"Score", rows->getInt("primaryScore")));
// Score:1
entry.push_back(new LDFData<int32_t>(u"Streak", rows->getInt("secondaryScore")));
// Streak:1
entry.push_back(new LDFData<float>(u"HitPercentage", (rows->getInt("tertiaryScore") / 100.0f)));
// HitPercentage:3 between 0 and 1
break;
case Type::Racing:
entry.push_back(new LDFData<float>(u"BestTime", rows->getDouble("primaryScore")));
// BestLapTime:3
entry.push_back(new LDFData<float>(u"BestLapTime", rows->getDouble("secondaryScore")));
// BestTime:3
entry.push_back(new LDFData<int32_t>(u"License", 1));
// License:1 - 1 if player has completed mission 637 and 0 otherwise
entry.push_back(new LDFData<int32_t>(u"NumWins", rows->getInt("numWins")));
// NumWins:1
break;
case Type::UnusedLeaderboard4:
entry.push_back(new LDFData<int32_t>(u"Points", rows->getInt("primaryScore")));
// Points:1
break;
case Type::MonumentRace:
entry.push_back(new LDFData<int32_t>(u"Time", rows->getInt("primaryScore")));
// Time:1(?)
break;
case Type::FootRace:
entry.push_back(new LDFData<int32_t>(u"Time", rows->getInt("primaryScore")));
// Time:1
break;
case Type::Survival:
entry.push_back(new LDFData<int32_t>(u"Points", rows->getInt("primaryScore")));
// Points:1
entry.push_back(new LDFData<int32_t>(u"Time", rows->getInt("secondaryScore")));
// Time:1
break;
case Type::SurvivalNS:
entry.push_back(new LDFData<int32_t>(u"Wave", rows->getInt("primaryScore")));
// Wave:1
entry.push_back(new LDFData<int32_t>(u"Time", rows->getInt("secondaryScore")));
// Time:1
break;
case Type::Donations:
entry.push_back(new LDFData<int32_t>(u"Score", rows->getInt("primaryScore")));
// Score:1
break;
case Type::None:
// This type is included here simply to resolve a compiler warning on mac about unused enum types
break;
default:
break;
}
}
std::vector<LeaderboardEntry> Leaderboard::GetEntries() {
return entries;
}
const std::string_view Leaderboard::GetOrdering(Leaderboard::Type leaderboardType) {
// Use a switch case and return desc for all 3 columns if higher is better and asc if lower is better
switch (leaderboardType) {
case Type::Racing:
case Type::MonumentRace:
return "primaryScore ASC, secondaryScore ASC, tertiaryScore ASC";
case Type::Survival:
return Game::config->GetValue("classic_survival_scoring") == "1" ?
"secondaryScore DESC, primaryScore DESC, tertiaryScore DESC" :
"primaryScore DESC, secondaryScore DESC, tertiaryScore DESC";
case Type::SurvivalNS:
return "primaryScore DESC, secondaryScore ASC, tertiaryScore DESC";
case Type::ShootingGallery:
case Type::FootRace:
case Type::UnusedLeaderboard4:
case Type::Donations:
case Type::None:
default:
return "primaryScore DESC, secondaryScore DESC, tertiaryScore DESC";
}
uint32_t Leaderboard::GetGameID() const {
return gameID;
}
void Leaderboard::SetupLeaderboard(bool weekly, uint32_t resultStart, uint32_t resultEnd) {
resultStart++;
resultEnd++;
// We need everything except 1 column so i'm selecting * from leaderboard
const std::string queryBase =
R"QUERY(
WITH leaderboardsRanked AS (
SELECT leaderboard.*, charinfo.name,
RANK() OVER
(
ORDER BY %s, UNIX_TIMESTAMP(last_played) ASC, id DESC
) AS ranking
FROM leaderboard JOIN charinfo on charinfo.id = leaderboard.character_id
WHERE game_id = ? %s
),
myStanding AS (
SELECT
ranking as myRank
FROM leaderboardsRanked
WHERE id = ?
),
lowestRanking AS (
SELECT MAX(ranking) AS lowestRank
FROM leaderboardsRanked
)
SELECT leaderboardsRanked.*, character_id, UNIX_TIMESTAMP(last_played) as lastPlayed, leaderboardsRanked.name, leaderboardsRanked.ranking FROM leaderboardsRanked, myStanding, lowestRanking
WHERE leaderboardsRanked.ranking
BETWEEN
LEAST(GREATEST(CAST(myRank AS SIGNED) - 5, %i), lowestRanking.lowestRank - 9)
AND
LEAST(GREATEST(myRank + 5, %i), lowestRanking.lowestRank)
ORDER BY ranking ASC;
)QUERY";
std::string friendsFilter =
R"QUERY(
AND (
character_id IN (
SELECT fr.requested_player FROM (
SELECT CASE
WHEN player_id = ? THEN friend_id
WHEN friend_id = ? THEN player_id
END AS requested_player
FROM friends
) AS fr
JOIN charinfo AS ci
ON ci.id = fr.requested_player
WHERE fr.requested_player IS NOT NULL
)
OR character_id = ?
)
)QUERY";
std::string weeklyFilter = " AND UNIX_TIMESTAMP(last_played) BETWEEN UNIX_TIMESTAMP(date_sub(now(),INTERVAL 1 WEEK)) AND UNIX_TIMESTAMP(now()) ";
std::string filter;
// Setup our filter based on the query type
if (this->infoType == InfoType::Friends) filter += friendsFilter;
if (this->weekly) filter += weeklyFilter;
const auto orderBase = GetOrdering(this->leaderboardType);
// For top query, we want to just rank all scores, but for all others we need the scores around a specific player
std::string baseLookup;
if (this->infoType == InfoType::Top) {
baseLookup = "SELECT id, last_played FROM leaderboard WHERE game_id = ? " + (this->weekly ? weeklyFilter : std::string("")) + " ORDER BY ";
baseLookup += orderBase.data();
} else {
baseLookup = "SELECT id, last_played FROM leaderboard WHERE game_id = ? " + (this->weekly ? weeklyFilter : std::string("")) + " AND character_id = ";
baseLookup += std::to_string(static_cast<uint32_t>(this->relatedPlayer));
}
baseLookup += " LIMIT 1";
Game::logger->LogDebug("LeaderboardManager", "query is %s", baseLookup.c_str());
std::unique_ptr<sql::PreparedStatement> baseQuery(Database::CreatePreppedStmt(baseLookup));
baseQuery->setInt(1, this->gameID);
std::unique_ptr<sql::ResultSet> baseResult(baseQuery->executeQuery());
if (!baseResult->next()) return; // In this case, there are no entries in the leaderboard for this game.
uint32_t relatedPlayerLeaderboardId = baseResult->getInt("id");
// Create and execute the actual save here. Using a heap allocated buffer to avoid stack overflow
constexpr uint16_t STRING_LENGTH = 4096;
std::unique_ptr<char[]> lookupBuffer = std::make_unique<char[]>(STRING_LENGTH);
int32_t res = snprintf(lookupBuffer.get(), STRING_LENGTH, queryBase.c_str(), orderBase.data(), filter.c_str(), resultStart, resultEnd);
DluAssert(res != -1);
std::unique_ptr<sql::PreparedStatement> query(Database::CreatePreppedStmt(lookupBuffer.get()));
Game::logger->LogDebug("LeaderboardManager", "Query is %s vars are %i %i %i", lookupBuffer.get(), this->gameID, this->relatedPlayer, relatedPlayerLeaderboardId);
query->setInt(1, this->gameID);
if (this->infoType == InfoType::Friends) {
query->setInt(2, this->relatedPlayer);
query->setInt(3, this->relatedPlayer);
query->setInt(4, this->relatedPlayer);
query->setInt(5, relatedPlayerLeaderboardId);
} else {
query->setInt(2, relatedPlayerLeaderboardId);
}
std::unique_ptr<sql::ResultSet> result(query->executeQuery());
QueryToLdf(result);
uint32_t Leaderboard::GetInfoType() const {
return infoType;
}
void Leaderboard::Send(const LWOOBJID targetID) const {
auto* player = Game::entityManager->GetEntity(relatedPlayer);
void Leaderboard::Send(LWOOBJID targetID) const {
auto* player = EntityManager::Instance()->GetEntity(relatedPlayer);
if (player != nullptr) {
GameMessages::SendActivitySummaryLeaderboardData(targetID, this, player->GetSystemAddress());
}
}
std::string FormatInsert(const Leaderboard::Type& type, const Score& score, const bool useUpdate) {
std::string insertStatement;
if (useUpdate) {
insertStatement =
R"QUERY(
UPDATE leaderboard
SET primaryScore = %f, secondaryScore = %f, tertiaryScore = %f,
timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;
)QUERY";
} else {
insertStatement =
R"QUERY(
INSERT leaderboard SET
primaryScore = %f, secondaryScore = %f, tertiaryScore = %f,
character_id = ?, game_id = ?;
)QUERY";
}
void LeaderboardManager::SaveScore(LWOOBJID playerID, uint32_t gameID, uint32_t score, uint32_t time) {
const auto* player = EntityManager::Instance()->GetEntity(playerID);
if (player == nullptr)
return;
constexpr uint16_t STRING_LENGTH = 400;
// Then fill in our score
char finishedQuery[STRING_LENGTH];
int32_t res = snprintf(finishedQuery, STRING_LENGTH, insertStatement.c_str(), score.GetPrimaryScore(), score.GetSecondaryScore(), score.GetTertiaryScore());
DluAssert(res != -1);
return finishedQuery;
}
auto* character = player->GetCharacter();
if (character == nullptr)
return;
void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID activityId, const float primaryScore, const float secondaryScore, const float tertiaryScore) {
const Leaderboard::Type leaderboardType = GetLeaderboardType(activityId);
auto* select = Database::CreatePreppedStmt("SELECT time, score FROM leaderboard WHERE character_id = ? AND game_id = ?;");
std::unique_ptr<sql::PreparedStatement> query(Database::CreatePreppedStmt("SELECT * FROM leaderboard WHERE character_id = ? AND game_id = ?;"));
query->setInt(1, playerID);
query->setInt(2, activityId);
std::unique_ptr<sql::ResultSet> myScoreResult(query->executeQuery());
select->setUInt64(1, character->GetID());
select->setInt(2, gameID);
auto any = false;
auto* result = select->executeQuery();
auto leaderboardType = GetLeaderboardType(gameID);
// Check if the new score is a high score
while (result->next()) {
any = true;
const auto storedTime = result->getInt(1);
const auto storedScore = result->getInt(2);
auto highscore = true;
bool classicSurvivalScoring = Game::config->GetValue("classic_survival_scoring") == "1";
std::string saveQuery("UPDATE leaderboard SET timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;");
Score newScore(primaryScore, secondaryScore, tertiaryScore);
if (myScoreResult->next()) {
Score oldScore;
bool lowerScoreBetter = false;
switch (leaderboardType) {
// Higher score better
case Leaderboard::Type::ShootingGallery: {
oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore"));
oldScore.SetSecondaryScore(myScoreResult->getInt("secondaryScore"));
oldScore.SetTertiaryScore(myScoreResult->getInt("tertiaryScore"));
case ShootingGallery:
if (score <= storedScore)
highscore = false;
break;
}
case Leaderboard::Type::FootRace: {
oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore"));
case Racing:
if (time >= storedTime)
highscore = false;
break;
}
case Leaderboard::Type::Survival: {
oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore"));
oldScore.SetSecondaryScore(myScoreResult->getInt("secondaryScore"));
case MonumentRace:
if (time >= storedTime)
highscore = false;
break;
}
case Leaderboard::Type::SurvivalNS: {
oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore"));
oldScore.SetSecondaryScore(myScoreResult->getInt("secondaryScore"));
case FootRace:
if (time <= storedTime)
highscore = false;
break;
}
case Leaderboard::Type::UnusedLeaderboard4:
case Leaderboard::Type::Donations: {
oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore"));
newScore.SetPrimaryScore(oldScore.GetPrimaryScore() + newScore.GetPrimaryScore());
case Survival:
if (classicSurvivalScoring) {
if (time <= storedTime) { // Based on time (LU live)
highscore = false;
}
} else {
if (score <= storedScore) // Based on score (DLU)
highscore = false;
}
break;
}
case Leaderboard::Type::Racing: {
oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore"));
oldScore.SetSecondaryScore(myScoreResult->getInt("secondaryScore"));
// For wins we dont care about the score, just the time, so zero out the tertiary.
// Wins are updated later.
oldScore.SetTertiaryScore(0);
newScore.SetTertiaryScore(0);
lowerScoreBetter = true;
case SurvivalNS:
if (!(score > storedScore || (time < storedTime && score >= storedScore)))
highscore = false;
break;
}
case Leaderboard::Type::MonumentRace: {
oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore"));
lowerScoreBetter = true;
// Do score checking here
break;
}
case Leaderboard::Type::None:
default:
Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i for game %i. Cannot save score!", leaderboardType, activityId);
highscore = false;
}
if (!highscore) {
delete select;
delete result;
return;
}
bool newHighScore = lowerScoreBetter ? newScore < oldScore : newScore > oldScore;
// Nimbus station has a weird leaderboard where we need a custom scoring system
if (leaderboardType == Leaderboard::Type::SurvivalNS) {
newHighScore = newScore.GetPrimaryScore() > oldScore.GetPrimaryScore() ||
(newScore.GetPrimaryScore() == oldScore.GetPrimaryScore() && newScore.GetSecondaryScore() < oldScore.GetSecondaryScore());
} else if (leaderboardType == Leaderboard::Type::Survival && Game::config->GetValue("classic_survival_scoring") == "1") {
Score oldScoreFlipped(oldScore.GetSecondaryScore(), oldScore.GetPrimaryScore());
Score newScoreFlipped(newScore.GetSecondaryScore(), newScore.GetPrimaryScore());
newHighScore = newScoreFlipped > oldScoreFlipped;
}
if (newHighScore) {
saveQuery = FormatInsert(leaderboardType, newScore, true);
}
}
delete select;
delete result;
if (any) {
auto* statement = Database::CreatePreppedStmt("UPDATE leaderboard SET time = ?, score = ?, last_played=SYSDATE() WHERE character_id = ? AND game_id = ?;");
statement->setInt(1, time);
statement->setInt(2, score);
statement->setUInt64(3, character->GetID());
statement->setInt(4, gameID);
statement->execute();
delete statement;
} else {
saveQuery = FormatInsert(leaderboardType, newScore, false);
}
Game::logger->Log("LeaderboardManager", "save query %s %i %i", saveQuery.c_str(), playerID, activityId);
std::unique_ptr<sql::PreparedStatement> saveStatement(Database::CreatePreppedStmt(saveQuery));
saveStatement->setInt(1, playerID);
saveStatement->setInt(2, activityId);
saveStatement->execute();
// Note: last_played will be set to SYSDATE() by default when inserting into leaderboard
auto* statement = Database::CreatePreppedStmt("INSERT INTO leaderboard (character_id, game_id, time, score) VALUES (?, ?, ?, ?);");
statement->setUInt64(1, character->GetID());
statement->setInt(2, gameID);
statement->setInt(3, time);
statement->setInt(4, score);
statement->execute();
// track wins separately
if (leaderboardType == Leaderboard::Type::Racing && tertiaryScore != 0.0f) {
std::unique_ptr<sql::PreparedStatement> winUpdate(Database::CreatePreppedStmt("UPDATE leaderboard SET numWins = numWins + 1 WHERE character_id = ? AND game_id = ?;"));
winUpdate->setInt(1, playerID);
winUpdate->setInt(2, activityId);
winUpdate->execute();
delete statement;
}
}
void LeaderboardManager::SendLeaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const LWOOBJID playerID, const LWOOBJID targetID, const uint32_t resultStart, const uint32_t resultEnd) {
Leaderboard leaderboard(gameID, infoType, weekly, playerID, GetLeaderboardType(gameID));
leaderboard.SetupLeaderboard(weekly, resultStart, resultEnd);
leaderboard.Send(targetID);
Leaderboard* LeaderboardManager::GetLeaderboard(uint32_t gameID, InfoType infoType, bool weekly, LWOOBJID playerID) {
auto leaderboardType = GetLeaderboardType(gameID);
std::string query;
bool classicSurvivalScoring = Game::config->GetValue("classic_survival_scoring") == "1";
switch (infoType) {
case InfoType::Standings:
switch (leaderboardType) {
case ShootingGallery:
query = standingsScoreQuery; // Shooting gallery is based on the highest score.
break;
case FootRace:
query = standingsTimeQuery; // The higher your time, the better for FootRace.
break;
case Survival:
query = classicSurvivalScoring ? standingsTimeQuery : standingsScoreQuery;
break;
case SurvivalNS:
query = standingsScoreQueryAsc; // BoNS is scored by highest wave (score) first, then time.
break;
default:
query = standingsTimeQueryAsc; // MonumentRace and Racing are based on the shortest time.
}
break;
case InfoType::Friends:
switch (leaderboardType) {
case ShootingGallery:
query = friendsScoreQuery; // Shooting gallery is based on the highest score.
break;
case FootRace:
query = friendsTimeQuery; // The higher your time, the better for FootRace.
break;
case Survival:
query = classicSurvivalScoring ? friendsTimeQuery : friendsScoreQuery;
break;
case SurvivalNS:
query = friendsScoreQueryAsc; // BoNS is scored by highest wave (score) first, then time.
break;
default:
query = friendsTimeQueryAsc; // MonumentRace and Racing are based on the shortest time.
}
break;
default:
switch (leaderboardType) {
case ShootingGallery:
query = topPlayersScoreQuery; // Shooting gallery is based on the highest score.
break;
case FootRace:
query = topPlayersTimeQuery; // The higher your time, the better for FootRace.
break;
case Survival:
query = classicSurvivalScoring ? topPlayersTimeQuery : topPlayersScoreQuery;
break;
case SurvivalNS:
query = topPlayersScoreQueryAsc; // BoNS is scored by highest wave (score) first, then time.
break;
default:
query = topPlayersTimeQueryAsc; // MonumentRace and Racing are based on the shortest time.
}
}
auto* statement = Database::CreatePreppedStmt(query);
statement->setUInt(1, gameID);
// Only the standings and friends leaderboards require the character ID to be set
if (infoType == Standings || infoType == Friends) {
auto characterID = 0;
const auto* player = EntityManager::Instance()->GetEntity(playerID);
if (player != nullptr) {
auto* character = player->GetCharacter();
if (character != nullptr)
characterID = character->GetID();
}
statement->setUInt64(2, characterID);
}
auto* res = statement->executeQuery();
std::vector<LeaderboardEntry> entries{};
uint32_t index = 0;
while (res->next()) {
LeaderboardEntry entry;
entry.playerID = res->getUInt64(4);
entry.playerName = res->getString(5);
entry.time = res->getUInt(1);
entry.score = res->getUInt(2);
entry.placement = res->getUInt(3);
entry.lastPlayed = res->getUInt(6);
entries.push_back(entry);
index++;
}
delete res;
delete statement;
return new Leaderboard(gameID, infoType, weekly, entries, playerID, leaderboardType);
}
Leaderboard::Type LeaderboardManager::GetLeaderboardType(const GameID gameID) {
auto lookup = leaderboardCache.find(gameID);
if (lookup != leaderboardCache.end()) return lookup->second;
void LeaderboardManager::SendLeaderboard(uint32_t gameID, InfoType infoType, bool weekly, LWOOBJID targetID,
LWOOBJID playerID) {
const auto* leaderboard = LeaderboardManager::GetLeaderboard(gameID, infoType, weekly, playerID);
leaderboard->Send(targetID);
delete leaderboard;
}
LeaderboardType LeaderboardManager::GetLeaderboardType(uint32_t gameID) {
auto* activitiesTable = CDClientManager::Instance().GetTable<CDActivitiesTable>();
std::vector<CDActivities> activities = activitiesTable->Query([gameID](const CDActivities& entry) {
return entry.ActivityID == gameID;
std::vector<CDActivities> activities = activitiesTable->Query([=](const CDActivities& entry) {
return (entry.ActivityID == gameID);
});
auto type = !activities.empty() ? static_cast<Leaderboard::Type>(activities.at(0).leaderboardType) : Leaderboard::Type::None;
leaderboardCache.insert_or_assign(gameID, type);
return type;
for (const auto& activity : activities) {
return static_cast<LeaderboardType>(activity.leaderboardType);
}
return LeaderboardType::None;
}
const std::string LeaderboardManager::topPlayersScoreQuery =
"WITH leaderboard_vales AS ( "
" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, "
"RANK() OVER ( ORDER BY l.score DESC, l.time DESC, last_played ) leaderboard_rank "
" FROM leaderboard l "
"INNER JOIN charinfo c ON l.character_id = c.id "
"WHERE l.game_id = ? "
"ORDER BY leaderboard_rank) "
"SELECT time, score, leaderboard_rank, id, name, last_played "
"FROM leaderboard_vales LIMIT 11;";
const std::string LeaderboardManager::friendsScoreQuery =
"WITH leaderboard_vales AS ( "
" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, f.friend_id, f.player_id, "
" RANK() OVER ( ORDER BY l.score DESC, l.time DESC, last_played ) leaderboard_rank "
" FROM leaderboard l "
" INNER JOIN charinfo c ON l.character_id = c.id "
" INNER JOIN friends f ON f.player_id = c.id "
" WHERE l.game_id = ? "
" ORDER BY leaderboard_rank), "
" personal_values AS ( "
" SELECT id as related_player_id, "
" GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, "
" GREATEST(leaderboard_rank + 5, 11) AS max_rank "
" FROM leaderboard_vales WHERE leaderboard_vales.id = ? LIMIT 1) "
"SELECT time, score, leaderboard_rank, id, name, last_played "
"FROM leaderboard_vales, personal_values "
"WHERE leaderboard_rank BETWEEN min_rank AND max_rank AND (player_id = related_player_id OR friend_id = related_player_id);";
const std::string LeaderboardManager::standingsScoreQuery =
"WITH leaderboard_vales AS ( "
" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, "
" RANK() OVER ( ORDER BY l.score DESC, l.time DESC, last_played ) leaderboard_rank "
" FROM leaderboard l "
" INNER JOIN charinfo c ON l.character_id = c.id "
" WHERE l.game_id = ? "
" ORDER BY leaderboard_rank), "
"personal_values AS ( "
" SELECT GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, "
" GREATEST(leaderboard_rank + 5, 11) AS max_rank "
" FROM leaderboard_vales WHERE id = ? LIMIT 1) "
"SELECT time, score, leaderboard_rank, id, name, last_played "
"FROM leaderboard_vales, personal_values "
"WHERE leaderboard_rank BETWEEN min_rank AND max_rank;";
const std::string LeaderboardManager::topPlayersScoreQueryAsc =
"WITH leaderboard_vales AS ( "
" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, "
"RANK() OVER ( ORDER BY l.score DESC, l.time ASC, last_played ) leaderboard_rank "
" FROM leaderboard l "
"INNER JOIN charinfo c ON l.character_id = c.id "
"WHERE l.game_id = ? "
"ORDER BY leaderboard_rank) "
"SELECT time, score, leaderboard_rank, id, name, last_played "
"FROM leaderboard_vales LIMIT 11;";
const std::string LeaderboardManager::friendsScoreQueryAsc =
"WITH leaderboard_vales AS ( "
" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, f.friend_id, f.player_id, "
" RANK() OVER ( ORDER BY l.score DESC, l.time ASC, last_played ) leaderboard_rank "
" FROM leaderboard l "
" INNER JOIN charinfo c ON l.character_id = c.id "
" INNER JOIN friends f ON f.player_id = c.id "
" WHERE l.game_id = ? "
" ORDER BY leaderboard_rank), "
" personal_values AS ( "
" SELECT id as related_player_id, "
" GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, "
" GREATEST(leaderboard_rank + 5, 11) AS max_rank "
" FROM leaderboard_vales WHERE leaderboard_vales.id = ? LIMIT 1) "
"SELECT time, score, leaderboard_rank, id, name, last_played "
"FROM leaderboard_vales, personal_values "
"WHERE leaderboard_rank BETWEEN min_rank AND max_rank AND (player_id = related_player_id OR friend_id = related_player_id);";
const std::string LeaderboardManager::standingsScoreQueryAsc =
"WITH leaderboard_vales AS ( "
" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, "
" RANK() OVER ( ORDER BY l.score DESC, l.time ASC, last_played ) leaderboard_rank "
" FROM leaderboard l "
" INNER JOIN charinfo c ON l.character_id = c.id "
" WHERE l.game_id = ? "
" ORDER BY leaderboard_rank), "
"personal_values AS ( "
" SELECT GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, "
" GREATEST(leaderboard_rank + 5, 11) AS max_rank "
" FROM leaderboard_vales WHERE id = ? LIMIT 1) "
"SELECT time, score, leaderboard_rank, id, name, last_played "
"FROM leaderboard_vales, personal_values "
"WHERE leaderboard_rank BETWEEN min_rank AND max_rank;";
const std::string LeaderboardManager::topPlayersTimeQuery =
"WITH leaderboard_vales AS ( "
" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, "
"RANK() OVER ( ORDER BY l.time DESC, l.score DESC, last_played ) leaderboard_rank "
" FROM leaderboard l "
"INNER JOIN charinfo c ON l.character_id = c.id "
"WHERE l.game_id = ? "
"ORDER BY leaderboard_rank) "
"SELECT time, score, leaderboard_rank, id, name, last_played "
"FROM leaderboard_vales LIMIT 11;";
const std::string LeaderboardManager::friendsTimeQuery =
"WITH leaderboard_vales AS ( "
" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, f.friend_id, f.player_id, "
" RANK() OVER ( ORDER BY l.time DESC, l.score DESC, last_played ) leaderboard_rank "
" FROM leaderboard l "
" INNER JOIN charinfo c ON l.character_id = c.id "
" INNER JOIN friends f ON f.player_id = c.id "
" WHERE l.game_id = ? "
" ORDER BY leaderboard_rank), "
" personal_values AS ( "
" SELECT id as related_player_id, "
" GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, "
" GREATEST(leaderboard_rank + 5, 11) AS max_rank "
" FROM leaderboard_vales WHERE leaderboard_vales.id = ? LIMIT 1) "
"SELECT time, score, leaderboard_rank, id, name, last_played "
"FROM leaderboard_vales, personal_values "
"WHERE leaderboard_rank BETWEEN min_rank AND max_rank AND (player_id = related_player_id OR friend_id = related_player_id);";
const std::string LeaderboardManager::standingsTimeQuery =
"WITH leaderboard_vales AS ( "
" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, "
" RANK() OVER ( ORDER BY l.time DESC, l.score DESC, last_played ) leaderboard_rank "
" FROM leaderboard l "
" INNER JOIN charinfo c ON l.character_id = c.id "
" WHERE l.game_id = ? "
" ORDER BY leaderboard_rank), "
"personal_values AS ( "
" SELECT GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, "
" GREATEST(leaderboard_rank + 5, 11) AS max_rank "
" FROM leaderboard_vales WHERE id = ? LIMIT 1) "
"SELECT time, score, leaderboard_rank, id, name, last_played "
"FROM leaderboard_vales, personal_values "
"WHERE leaderboard_rank BETWEEN min_rank AND max_rank;";
const std::string LeaderboardManager::topPlayersTimeQueryAsc =
"WITH leaderboard_vales AS ( "
" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, "
"RANK() OVER ( ORDER BY l.time ASC, l.score DESC, last_played ) leaderboard_rank "
" FROM leaderboard l "
"INNER JOIN charinfo c ON l.character_id = c.id "
"WHERE l.game_id = ? "
"ORDER BY leaderboard_rank) "
"SELECT time, score, leaderboard_rank, id, name, last_played "
"FROM leaderboard_vales LIMIT 11;";
const std::string LeaderboardManager::friendsTimeQueryAsc =
"WITH leaderboard_vales AS ( "
" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, f.friend_id, f.player_id, "
" RANK() OVER ( ORDER BY l.time ASC, l.score DESC, last_played ) leaderboard_rank "
" FROM leaderboard l "
" INNER JOIN charinfo c ON l.character_id = c.id "
" INNER JOIN friends f ON f.player_id = c.id "
" WHERE l.game_id = ? "
" ORDER BY leaderboard_rank), "
" personal_values AS ( "
" SELECT id as related_player_id, "
" GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, "
" GREATEST(leaderboard_rank + 5, 11) AS max_rank "
" FROM leaderboard_vales WHERE leaderboard_vales.id = ? LIMIT 1) "
"SELECT time, score, leaderboard_rank, id, name, last_played "
"FROM leaderboard_vales, personal_values "
"WHERE leaderboard_rank BETWEEN min_rank AND max_rank AND (player_id = related_player_id OR friend_id = related_player_id);";
const std::string LeaderboardManager::standingsTimeQueryAsc =
"WITH leaderboard_vales AS ( "
" SELECT l.time, l.score, UNIX_TIMESTAMP(l.last_played) last_played, c.name, c.id, "
" RANK() OVER ( ORDER BY l.time ASC, l.score DESC, last_played ) leaderboard_rank "
" FROM leaderboard l "
" INNER JOIN charinfo c ON l.character_id = c.id "
" WHERE l.game_id = ? "
" ORDER BY leaderboard_rank), "
"personal_values AS ( "
" SELECT GREATEST(CAST(leaderboard_rank AS SIGNED) - 5, 1) AS min_rank, "
" GREATEST(leaderboard_rank + 5, 11) AS max_rank "
" FROM leaderboard_vales WHERE id = ? LIMIT 1) "
"SELECT time, score, leaderboard_rank, id, name, last_played "
"FROM leaderboard_vales, personal_values "
"WHERE leaderboard_rank BETWEEN min_rank AND max_rank;";

View File

@@ -1,134 +1,80 @@
#ifndef __LEADERBOARDMANAGER__H__
#define __LEADERBOARDMANAGER__H__
#include <map>
#include <memory>
#include <string_view>
#pragma once
#include <vector>
#include "Singleton.h"
#include <climits>
#include "dCommonVars.h"
#include "LDFFormat.h"
namespace sql {
class ResultSet;
struct LeaderboardEntry {
uint64_t playerID;
std::string playerName;
uint32_t time;
uint32_t score;
uint32_t placement;
time_t lastPlayed;
};
namespace RakNet {
class BitStream;
enum InfoType : uint32_t {
Top, // Top 11 all time players
Standings, // Ranking of the current player
Friends // Ranking between friends
};
class Score {
public:
Score() {
primaryScore = 0;
secondaryScore = 0;
tertiaryScore = 0;
}
Score(const float primaryScore, const float secondaryScore = 0, const float tertiaryScore = 0) {
this->primaryScore = primaryScore;
this->secondaryScore = secondaryScore;
this->tertiaryScore = tertiaryScore;
}
bool operator<(const Score& rhs) const {
return primaryScore < rhs.primaryScore || (primaryScore == rhs.primaryScore && secondaryScore < rhs.secondaryScore) || (primaryScore == rhs.primaryScore && secondaryScore == rhs.secondaryScore && tertiaryScore < rhs.tertiaryScore);
}
bool operator>(const Score& rhs) const {
return primaryScore > rhs.primaryScore || (primaryScore == rhs.primaryScore && secondaryScore > rhs.secondaryScore) || (primaryScore == rhs.primaryScore && secondaryScore == rhs.secondaryScore && tertiaryScore > rhs.tertiaryScore);
}
void SetPrimaryScore(const float score) { primaryScore = score; }
float GetPrimaryScore() const { return primaryScore; }
void SetSecondaryScore(const float score) { secondaryScore = score; }
float GetSecondaryScore() const { return secondaryScore; }
void SetTertiaryScore(const float score) { tertiaryScore = score; }
float GetTertiaryScore() const { return tertiaryScore; }
private:
float primaryScore;
float secondaryScore;
float tertiaryScore;
enum LeaderboardType : uint32_t {
ShootingGallery,
Racing,
MonumentRace,
FootRace,
Survival = 5,
SurvivalNS = 6,
None = UINT_MAX
};
using GameID = uint32_t;
class Leaderboard {
public:
// Enums for leaderboards
enum InfoType : uint32_t {
Top, // Top 11 all time players
MyStanding, // Ranking of the current player
Friends // Ranking between friends
};
enum Type : uint32_t {
ShootingGallery,
Racing,
MonumentRace,
FootRace,
UnusedLeaderboard4, // There is no 4 defined anywhere in the cdclient, but it takes a Score.
Survival,
SurvivalNS,
Donations,
None
};
Leaderboard() = delete;
Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, LWOOBJID relatedPlayer, const Leaderboard::Type = None);
~Leaderboard();
/**
* @brief Resets the leaderboard state and frees its allocated memory
*
*/
void Clear();
/**
* Serialize the Leaderboard to a BitStream
*
* Expensive! Leaderboards are very string intensive so be wary of performatnce calling this method.
*/
void Serialize(RakNet::BitStream* bitStream) const;
/**
* Builds the leaderboard from the database based on the associated gameID
*
* @param resultStart The index to start the leaderboard at. Zero indexed.
* @param resultEnd The index to end the leaderboard at. Zero indexed.
*/
void SetupLeaderboard(bool weekly, uint32_t resultStart = 0, uint32_t resultEnd = 10);
/**
* Sends the leaderboard to the client specified by targetID.
*/
void Send(const LWOOBJID targetID) const;
// Helper function to get the columns, ordering and insert format for a leaderboard
static const std::string_view GetOrdering(Type leaderboardType);
Leaderboard(uint32_t gameID, uint32_t infoType, bool weekly, std::vector<LeaderboardEntry> entries,
LWOOBJID relatedPlayer = LWOOBJID_EMPTY, LeaderboardType = None);
std::vector<LeaderboardEntry> GetEntries();
[[nodiscard]] std::u16string ToString() const;
[[nodiscard]] uint32_t GetGameID() const;
[[nodiscard]] uint32_t GetInfoType() const;
void Send(LWOOBJID targetID) const;
private:
// Takes the resulting query from a leaderboard lookup and converts it to the LDF we need
// to send it to a client.
void QueryToLdf(std::unique_ptr<sql::ResultSet>& rows);
using LeaderboardEntry = std::vector<LDFBaseData*>;
using LeaderboardEntries = std::vector<LeaderboardEntry>;
LeaderboardEntries entries;
std::vector<LeaderboardEntry> entries{};
LWOOBJID relatedPlayer;
GameID gameID;
InfoType infoType;
Leaderboard::Type leaderboardType;
uint32_t gameID;
uint32_t infoType;
LeaderboardType leaderboardType;
bool weekly;
};
namespace LeaderboardManager {
void SendLeaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const LWOOBJID playerID, const LWOOBJID targetID, const uint32_t resultStart = 0, const uint32_t resultEnd = 10);
class LeaderboardManager {
public:
static LeaderboardManager* Instance() {
if (address == nullptr)
address = new LeaderboardManager;
return address;
}
static void SendLeaderboard(uint32_t gameID, InfoType infoType, bool weekly, LWOOBJID targetID,
LWOOBJID playerID = LWOOBJID_EMPTY);
static Leaderboard* GetLeaderboard(uint32_t gameID, InfoType infoType, bool weekly, LWOOBJID playerID = LWOOBJID_EMPTY);
static void SaveScore(LWOOBJID playerID, uint32_t gameID, uint32_t score, uint32_t time);
static LeaderboardType GetLeaderboardType(uint32_t gameID);
private:
static LeaderboardManager* address;
void SaveScore(const LWOOBJID& playerID, const GameID activityId, const float primaryScore, const float secondaryScore = 0, const float tertiaryScore = 0);
// Modified 12/12/2021: Existing queries were renamed to be more descriptive.
static const std::string topPlayersScoreQuery;
static const std::string friendsScoreQuery;
static const std::string standingsScoreQuery;
static const std::string topPlayersScoreQueryAsc;
static const std::string friendsScoreQueryAsc;
static const std::string standingsScoreQueryAsc;
Leaderboard::Type GetLeaderboardType(const GameID gameID);
extern std::map<GameID, Leaderboard::Type> leaderboardCache;
// Added 12/12/2021: Queries dictated by time are needed for certain minigames.
static const std::string topPlayersTimeQuery;
static const std::string friendsTimeQuery;
static const std::string standingsTimeQuery;
static const std::string topPlayersTimeQueryAsc;
static const std::string friendsTimeQueryAsc;
static const std::string standingsTimeQueryAsc;
};
#endif //!__LEADERBOARDMANAGER__H__

View File

@@ -62,7 +62,7 @@ void Player::SetSystemAddress(const SystemAddress& value) {
void Player::SetRespawnPos(const NiPoint3 position) {
m_respawnPos = position;
m_Character->SetRespawnPoint(Game::zoneManager->GetZone()->GetWorldID(), position);
m_Character->SetRespawnPoint(dZoneManager::Instance()->GetZone()->GetWorldID(), position);
}
void Player::SetRespawnRot(const NiQuaternion rotation) {
@@ -85,7 +85,7 @@ void Player::SendToZone(LWOMAPID zoneId, LWOCLONEID cloneId) {
const auto objid = GetObjectID();
ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, zoneId, cloneId, false, [objid](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) {
auto* entity = Game::entityManager->GetEntity(objid);
auto* entity = EntityManager::Instance()->GetEntity(objid);
if (entity == nullptr) {
return;
@@ -108,7 +108,7 @@ void Player::SendToZone(LWOMAPID zoneId, LWOCLONEID cloneId) {
WorldPackets::SendTransferToWorld(sysAddr, serverIP, serverPort, mythranShift);
Game::entityManager->DestructEntity(entity);
EntityManager::Instance()->DestructEntity(entity);
return;
});
}
@@ -135,13 +135,13 @@ void Player::RemoveLimboConstruction(LWOOBJID objectId) {
void Player::ConstructLimboEntities() {
for (const auto objectId : m_LimboConstructions) {
auto* entity = Game::entityManager->GetEntity(objectId);
auto* entity = EntityManager::Instance()->GetEntity(objectId);
if (entity == nullptr) {
continue;
}
Game::entityManager->ConstructEntity(entity, m_SystemAddress);
EntityManager::Instance()->ConstructEntity(entity, m_SystemAddress);
}
m_LimboConstructions.clear();
@@ -224,7 +224,7 @@ Player* Player::GetPlayer(const SystemAddress& sysAddr) {
}
Player* Player::GetPlayer(const std::string& name) {
const auto characters = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::CHARACTER);
const auto characters = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::CHARACTER);
for (auto* character : characters) {
if (!character->IsPlayer()) continue;
@@ -269,7 +269,7 @@ Player::~Player() {
continue;
}
auto* entity = Game::entityManager->GetGhostCandidate(id);
auto* entity = EntityManager::Instance()->GetGhostCandidate(id);
if (entity != nullptr) {
entity->SetObservers(entity->GetObservers() - 1);
@@ -285,12 +285,12 @@ Player::~Player() {
}
if (IsPlayer()) {
Entity* zoneControl = Game::entityManager->GetZoneControlEntity();
Entity* zoneControl = EntityManager::Instance()->GetZoneControlEntity();
for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) {
script->OnPlayerExit(zoneControl, this);
}
std::vector<Entity*> scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY);
std::vector<Entity*> scriptedActs = EntityManager::Instance()->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)) {

View File

@@ -40,11 +40,11 @@ LWOOBJID Trade::GetParticipantB() const {
}
Entity* Trade::GetParticipantAEntity() const {
return Game::entityManager->GetEntity(m_ParticipantA);
return EntityManager::Instance()->GetEntity(m_ParticipantA);
}
Entity* Trade::GetParticipantBEntity() const {
return Game::entityManager->GetEntity(m_ParticipantB);
return EntityManager::Instance()->GetEntity(m_ParticipantB);
}
void Trade::SetCoins(LWOOBJID participant, uint64_t coins) {

View File

@@ -220,7 +220,7 @@ void UserManager::RequestCharacterList(const SystemAddress& sysAddr) {
skillComponent->Reset();
}
Game::entityManager->DestroyEntity(chars[i]->GetEntity());
EntityManager::Instance()->DestroyEntity(chars[i]->GetEntity());
chars[i]->SaveXMLToDatabase();

View File

@@ -39,7 +39,7 @@ void AirMovementBehavior::Sync(BehaviorContext* context, RakNet::BitStream* bitS
auto* behavior = CreateBehavior(behaviorId);
if (Game::entityManager->GetEntity(target) != nullptr) {
if (EntityManager::Instance()->GetEntity(target) != nullptr) {
branch.target = target;
}

View File

@@ -6,7 +6,7 @@
void ApplyBuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* entity = Game::entityManager->GetEntity(branch.target == LWOOBJID_EMPTY ? context->originator : branch.target);
auto* entity = EntityManager::Instance()->GetEntity(branch.target == LWOOBJID_EMPTY ? context->originator : branch.target);
if (entity == nullptr) return;
@@ -19,7 +19,7 @@ void ApplyBuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitS
}
void ApplyBuffBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) {
auto* entity = Game::entityManager->GetEntity(branch.target);
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
if (entity == nullptr) return;

View File

@@ -47,7 +47,7 @@ void AreaOfEffectBehavior::Handle(BehaviorContext* context, RakNet::BitStream* b
}
void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* self = Game::entityManager->GetEntity(context->caster);
auto* self = EntityManager::Instance()->GetEntity(context->caster);
if (self == nullptr) {
Game::logger->Log("AreaOfEffectBehavior", "Invalid self for (%llu)!", context->originator);
@@ -58,7 +58,7 @@ void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream
std::vector<Entity*> targets;
auto* presetTarget = Game::entityManager->GetEntity(branch.target);
auto* presetTarget = EntityManager::Instance()->GetEntity(branch.target);
if (presetTarget != nullptr) {
if (this->m_radius * this->m_radius >= Vector3::DistanceSquared(reference, presetTarget->GetPosition())) {
@@ -75,7 +75,7 @@ void AreaOfEffectBehavior::Calculate(BehaviorContext* context, RakNet::BitStream
// Gets all of the valid targets, passing in if should target enemies and friends
for (auto validTarget : context->GetValidTargets(m_ignoreFaction, includeFaction, m_TargetSelf == 1, m_targetEnemy == 1, m_targetFriend == 1)) {
auto* entity = Game::entityManager->GetEntity(validTarget);
auto* entity = EntityManager::Instance()->GetEntity(validTarget);
if (entity == nullptr) {
Game::logger->Log("AreaOfEffectBehavior", "Invalid target (%llu) for (%llu)!", validTarget, context->originator);

View File

@@ -9,7 +9,7 @@
void BasicAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
if (context->unmanaged) {
auto* entity = Game::entityManager->GetEntity(branch.target);
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
auto* destroyableComponent = entity->GetComponent<DestroyableComponent>();
if (destroyableComponent != nullptr) {
@@ -38,7 +38,7 @@ void BasicAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bi
}
void BasicAttackBehavior::DoHandleBehavior(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* targetEntity = Game::entityManager->GetEntity(branch.target);
auto* targetEntity = EntityManager::Instance()->GetEntity(branch.target);
if (!targetEntity) {
Game::logger->Log("BasicAttackBehavior", "Target targetEntity %llu not found.", branch.target);
return;
@@ -61,7 +61,7 @@ void BasicAttackBehavior::DoHandleBehavior(BehaviorContext* context, RakNet::Bit
if (isBlocked) {
destroyableComponent->SetAttacksToBlock(std::min(destroyableComponent->GetAttacksToBlock() - 1, 0U));
Game::entityManager->SerializeEntity(targetEntity);
EntityManager::Instance()->SerializeEntity(targetEntity);
this->m_OnFailBlocked->Handle(context, bitStream, branch);
return;
}
@@ -155,7 +155,7 @@ void BasicAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream*
}
void BasicAttackBehavior::DoBehaviorCalculation(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* targetEntity = Game::entityManager->GetEntity(branch.target);
auto* targetEntity = EntityManager::Instance()->GetEntity(branch.target);
if (!targetEntity) {
Game::logger->Log("BasicAttackBehavior", "Target entity %llu is null!", branch.target);
return;
@@ -173,7 +173,7 @@ void BasicAttackBehavior::DoBehaviorCalculation(BehaviorContext* context, RakNet
if (isBlocking) {
destroyableComponent->SetAttacksToBlock(destroyableComponent->GetAttacksToBlock() - 1);
Game::entityManager->SerializeEntity(targetEntity);
EntityManager::Instance()->SerializeEntity(targetEntity);
this->m_OnFailBlocked->Calculate(context, bitStream, branch);
return;
}

View File

@@ -314,7 +314,7 @@ BehaviorTemplates Behavior::GetBehaviorTemplate(const uint32_t behaviorId) {
// For use with enemies, to display the correct damage animations on the players
void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID secondary) {
auto* targetEntity = Game::entityManager->GetEntity(target);
auto* targetEntity = EntityManager::Instance()->GetEntity(target);
if (targetEntity == nullptr) {
return;

View File

@@ -27,7 +27,7 @@ BehaviorEndEntry::BehaviorEndEntry() {
}
uint32_t BehaviorContext::GetUniqueSkillId() const {
auto* entity = Game::entityManager->GetEntity(this->originator);
auto* entity = EntityManager::Instance()->GetEntity(this->originator);
if (entity == nullptr) {
Game::logger->Log("BehaviorContext", "Invalid entity for (%llu)!", this->originator);
@@ -94,11 +94,11 @@ void BehaviorContext::ScheduleUpdate(const LWOOBJID id) {
void BehaviorContext::ExecuteUpdates() {
for (const auto& id : this->scheduledUpdates) {
auto* entity = Game::entityManager->GetEntity(id);
auto* entity = EntityManager::Instance()->GetEntity(id);
if (entity == nullptr) continue;
Game::entityManager->SerializeEntity(entity);
EntityManager::Instance()->SerializeEntity(entity);
}
this->scheduledUpdates.clear();
@@ -308,7 +308,7 @@ void BehaviorContext::Reset() {
}
std::vector<LWOOBJID> BehaviorContext::GetValidTargets(int32_t ignoreFaction, int32_t includeFaction, bool targetSelf, bool targetEnemy, bool targetFriend) const {
auto* entity = Game::entityManager->GetEntity(this->caster);
auto* entity = EntityManager::Instance()->GetEntity(this->caster);
std::vector<LWOOBJID> targets;
@@ -320,7 +320,7 @@ std::vector<LWOOBJID> BehaviorContext::GetValidTargets(int32_t ignoreFaction, in
if (!ignoreFaction && !includeFaction) {
for (auto entry : entity->GetTargetsInPhantom()) {
auto* instance = Game::entityManager->GetEntity(entry);
auto* instance = EntityManager::Instance()->GetEntity(entry);
if (instance == nullptr) {
continue;
@@ -336,7 +336,7 @@ std::vector<LWOOBJID> BehaviorContext::GetValidTargets(int32_t ignoreFaction, in
return targets;
}
auto entities = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS);
auto entities = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::CONTROLLABLE_PHYSICS);
for (auto* candidate : entities) {
const auto id = candidate->GetObjectID();

View File

@@ -10,7 +10,7 @@
void BlockBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
const auto target = context->originator;
auto* entity = Game::entityManager->GetEntity(target);
auto* entity = EntityManager::Instance()->GetEntity(target);
if (entity == nullptr) {
Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", branch.target);
@@ -40,7 +40,7 @@ void BlockBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitSt
void BlockBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) {
const auto target = context->originator;
auto* entity = Game::entityManager->GetEntity(target);
auto* entity = EntityManager::Instance()->GetEntity(target);
if (entity == nullptr) {
Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", branch.target);

View File

@@ -10,7 +10,7 @@
void BuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
const auto target = branch.target != LWOOBJID_EMPTY ? branch.target : context->originator;
auto* entity = Game::entityManager->GetEntity(target);
auto* entity = EntityManager::Instance()->GetEntity(target);
if (entity == nullptr) {
Game::logger->Log("BuffBehavior", "Invalid target (%llu)!", target);
@@ -30,7 +30,7 @@ void BuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream
component->SetMaxArmor(component->GetMaxArmor() + this->m_armor);
component->SetMaxImagination(component->GetMaxImagination() + this->m_imagination);
Game::entityManager->SerializeEntity(entity);
EntityManager::Instance()->SerializeEntity(entity);
if (!context->unmanaged) {
if (branch.duration > 0) {
@@ -44,7 +44,7 @@ void BuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream
void BuffBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) {
const auto target = branch.target != LWOOBJID_EMPTY ? branch.target : context->originator;
auto* entity = Game::entityManager->GetEntity(target);
auto* entity = EntityManager::Instance()->GetEntity(target);
if (entity == nullptr) {
Game::logger->Log("BuffBehavior", "Invalid target (%llu)!", target);
@@ -64,7 +64,7 @@ void BuffBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch
component->SetMaxArmor(component->GetMaxArmor() - this->m_armor);
component->SetMaxImagination(component->GetMaxImagination() - this->m_imagination);
Game::entityManager->SerializeEntity(entity);
EntityManager::Instance()->SerializeEntity(entity);
}
void BuffBehavior::Timer(BehaviorContext* context, const BehaviorBranchContext branch, LWOOBJID second) {

View File

@@ -11,7 +11,7 @@
void CarBoostBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
GameMessages::SendVehicleAddPassiveBoostAction(branch.target, UNASSIGNED_SYSTEM_ADDRESS);
auto* entity = Game::entityManager->GetEntity(context->originator);
auto* entity = EntityManager::Instance()->GetEntity(context->originator);
if (entity == nullptr) {
return;
@@ -22,7 +22,7 @@ void CarBoostBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitSt
auto* possessableComponent = entity->GetComponent<PossessableComponent>();
if (possessableComponent != nullptr) {
auto* possessor = Game::entityManager->GetEntity(possessableComponent->GetPossessor());
auto* possessor = EntityManager::Instance()->GetEntity(possessableComponent->GetPossessor());
if (possessor != nullptr) {
auto* characterComponent = possessor->GetComponent<CharacterComponent>();

View File

@@ -5,14 +5,14 @@
void ChangeOrientationBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
Entity* sourceEntity;
if (this->m_orientCaster) sourceEntity = Game::entityManager->GetEntity(context->originator);
else sourceEntity = Game::entityManager->GetEntity(branch.target);
if (this->m_orientCaster) sourceEntity = EntityManager::Instance()->GetEntity(context->originator);
else sourceEntity = EntityManager::Instance()->GetEntity(branch.target);
if (!sourceEntity) return;
if (this->m_toTarget) {
Entity* destinationEntity;
if (this->m_orientCaster) destinationEntity = Game::entityManager->GetEntity(branch.target);
else destinationEntity = Game::entityManager->GetEntity(context->originator);
if (this->m_orientCaster) destinationEntity = EntityManager::Instance()->GetEntity(branch.target);
else destinationEntity = EntityManager::Instance()->GetEntity(context->originator);
if (!destinationEntity) return;
sourceEntity->SetRotation(
@@ -23,7 +23,7 @@ void ChangeOrientationBehavior::Calculate(BehaviorContext* context, RakNet::BitS
if (this->m_relative) baseAngle += sourceEntity->GetRotation().GetForwardVector();
sourceEntity->SetRotation(NiQuaternion::FromEulerAngles(baseAngle));
} else return;
Game::entityManager->SerializeEntity(sourceEntity);
EntityManager::Instance()->SerializeEntity(sourceEntity);
return;
}

View File

@@ -8,7 +8,7 @@
#include "DestroyableComponent.h"
void DamageAbsorptionBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) {
auto* target = Game::entityManager->GetEntity(branch.target);
auto* target = EntityManager::Instance()->GetEntity(branch.target);
if (target == nullptr) {
Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", branch.target);
@@ -34,7 +34,7 @@ void DamageAbsorptionBehavior::Calculate(BehaviorContext* context, RakNet::BitSt
}
void DamageAbsorptionBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, const LWOOBJID second) {
auto* target = Game::entityManager->GetEntity(second);
auto* target = EntityManager::Instance()->GetEntity(second);
if (target == nullptr) {
Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", second);

View File

@@ -8,7 +8,7 @@
#include "DestroyableComponent.h"
void DamageReductionBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) {
auto* target = Game::entityManager->GetEntity(branch.target);
auto* target = EntityManager::Instance()->GetEntity(branch.target);
if (target == nullptr) {
Game::logger->Log("DamageReductionBehavior", "Failed to find target (%llu)!", branch.target);
@@ -32,7 +32,7 @@ void DamageReductionBehavior::Calculate(BehaviorContext* context, RakNet::BitStr
}
void DamageReductionBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, const LWOOBJID second) {
auto* target = Game::entityManager->GetEntity(second);
auto* target = EntityManager::Instance()->GetEntity(second);
if (target == nullptr) {
Game::logger->Log("DamageReductionBehavior", "Failed to find target (%llu)!", second);

View File

@@ -7,7 +7,7 @@
#include "BehaviorContext.h"
void DarkInspirationBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) {
auto* target = Game::entityManager->GetEntity(branch.target);
auto* target = EntityManager::Instance()->GetEntity(branch.target);
if (target == nullptr) {
Game::logger->LogDebug("DarkInspirationBehavior", "Failed to find target (%llu)!", branch.target);
@@ -26,7 +26,7 @@ void DarkInspirationBehavior::Handle(BehaviorContext* context, RakNet::BitStream
}
void DarkInspirationBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* target = Game::entityManager->GetEntity(branch.target);
auto* target = EntityManager::Instance()->GetEntity(branch.target);
if (target == nullptr) {
Game::logger->LogDebug("DarkInspirationBehavior", "Failed to find target (%llu)!", branch.target);

View File

@@ -8,13 +8,13 @@
void FallSpeedBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
// make sure required parameter has non-default value
if (m_PercentSlowed == 0.0f) return;
auto* target = Game::entityManager->GetEntity(branch.target);
auto* target = EntityManager::Instance()->GetEntity(branch.target);
if (!target) return;
auto* controllablePhysicsComponent = target->GetComponent<ControllablePhysicsComponent>();
if (!controllablePhysicsComponent) return;
controllablePhysicsComponent->SetGravityScale(m_PercentSlowed);
Game::entityManager->SerializeEntity(target);
EntityManager::Instance()->SerializeEntity(target);
if (branch.duration > 0.0f) {
context->RegisterTimerBehavior(this, branch);
@@ -36,13 +36,13 @@ void FallSpeedBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext b
}
void FallSpeedBehavior::End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) {
auto* target = Game::entityManager->GetEntity(branch.target);
auto* target = EntityManager::Instance()->GetEntity(branch.target);
if (!target) return;
auto* controllablePhysicsComponent = target->GetComponent<ControllablePhysicsComponent>();
if (!controllablePhysicsComponent) return;
controllablePhysicsComponent->SetGravityScale(1);
Game::entityManager->SerializeEntity(target);
EntityManager::Instance()->SerializeEntity(target);
}
void FallSpeedBehavior::Load(){

View File

@@ -42,7 +42,7 @@ void ForceMovementBehavior::Calculate(BehaviorContext* context, RakNet::BitStrea
return;
}
auto* casterEntity = Game::entityManager->GetEntity(context->caster);
auto* casterEntity = EntityManager::Instance()->GetEntity(context->caster);
if (casterEntity != nullptr) {
auto* controllablePhysicsComponent = casterEntity->GetComponent<ControllablePhysicsComponent>();
if (controllablePhysicsComponent != nullptr) {
@@ -51,7 +51,7 @@ void ForceMovementBehavior::Calculate(BehaviorContext* context, RakNet::BitStrea
controllablePhysicsComponent->SetVelocity(controllablePhysicsComponent->GetRotation().GetForwardVector() * 25);
}
Game::entityManager->SerializeEntity(casterEntity);
EntityManager::Instance()->SerializeEntity(casterEntity);
}
}
@@ -72,7 +72,7 @@ void ForceMovementBehavior::Load() {
}
void ForceMovementBehavior::SyncCalculation(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* casterEntity = Game::entityManager->GetEntity(context->caster);
auto* casterEntity = EntityManager::Instance()->GetEntity(context->caster);
if (casterEntity != nullptr) {
auto* controllablePhysicsComponent = casterEntity->GetComponent<ControllablePhysicsComponent>();
if (controllablePhysicsComponent != nullptr) {
@@ -80,7 +80,7 @@ void ForceMovementBehavior::SyncCalculation(BehaviorContext* context, RakNet::Bi
controllablePhysicsComponent->SetPosition(controllablePhysicsComponent->GetPosition() + controllablePhysicsComponent->GetVelocity() * m_Duration);
controllablePhysicsComponent->SetVelocity({});
Game::entityManager->SerializeEntity(casterEntity);
EntityManager::Instance()->SerializeEntity(casterEntity);
}
}

View File

@@ -8,7 +8,7 @@
void HealBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, const BehaviorBranchContext branch) {
auto* entity = Game::entityManager->GetEntity(branch.target);
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
if (entity == nullptr) {
Game::logger->Log("HealBehavior", "Failed to find entity for (%llu)!", branch.target);

View File

@@ -7,7 +7,7 @@
void ImaginationBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, const BehaviorBranchContext branch) {
auto* entity = Game::entityManager->GetEntity(branch.target);
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
if (entity == nullptr) {
return;

View File

@@ -10,7 +10,7 @@
#include "eStateChangeType.h"
void ImmunityBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) {
auto* target = Game::entityManager->GetEntity(branch.target);
auto* target = EntityManager::Instance()->GetEntity(branch.target);
if (!target) {
Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", branch.target);
@@ -56,7 +56,7 @@ void ImmunityBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bi
}
void ImmunityBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, const LWOOBJID second) {
auto* target = Game::entityManager->GetEntity(second);
auto* target = EntityManager::Instance()->GetEntity(second);
if (!target) {
Game::logger->Log("DamageAbsorptionBehavior", "Failed to find target (%llu)!", second);

View File

@@ -42,7 +42,7 @@ void InterruptBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitS
if (branch.target == context->originator) return;
auto* target = Game::entityManager->GetEntity(branch.target);
auto* target = EntityManager::Instance()->GetEntity(branch.target);
if (target == nullptr) return;
@@ -67,7 +67,7 @@ void InterruptBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* b
if (branch.target == context->originator) return;
auto* target = Game::entityManager->GetEntity(branch.target);
auto* target = EntityManager::Instance()->GetEntity(branch.target);
if (target == nullptr) return;

View File

@@ -6,7 +6,7 @@
#include "Character.h"
void JetPackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, const BehaviorBranchContext branch) {
auto* entity = Game::entityManager->GetEntity(branch.target);
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
GameMessages::SendSetJetPackMode(entity, true, this->m_BypassChecks, this->m_EnableHover, this->m_effectId, this->m_Airspeed, this->m_MaxAirspeed, this->m_VerticalVelocity, this->m_WarningEffectID);
@@ -20,7 +20,7 @@ void JetPackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_st
}
void JetPackBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) {
auto* entity = Game::entityManager->GetEntity(branch.target);
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
GameMessages::SendSetJetPackMode(entity, false);

View File

@@ -21,7 +21,7 @@ void KnockbackBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitS
void KnockbackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
bool blocked = false;
auto* target = Game::entityManager->GetEntity(branch.target);
auto* target = EntityManager::Instance()->GetEntity(branch.target);
if (target != nullptr) {
auto* destroyableComponent = target->GetComponent<DestroyableComponent>();

View File

@@ -1,14 +1,14 @@
#include "LootBuffBehavior.h"
void LootBuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto target = Game::entityManager->GetEntity(context->caster);
auto target = EntityManager::Instance()->GetEntity(context->caster);
if (!target) return;
auto controllablePhysicsComponent = target->GetComponent<ControllablePhysicsComponent>();
if (!controllablePhysicsComponent) return;
controllablePhysicsComponent->AddPickupRadiusScale(m_Scale);
Game::entityManager->SerializeEntity(target);
EntityManager::Instance()->SerializeEntity(target);
if (branch.duration > 0) context->RegisterTimerBehavior(this, branch);
@@ -19,14 +19,14 @@ void LootBuffBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bi
}
void LootBuffBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) {
auto target = Game::entityManager->GetEntity(context->caster);
auto target = EntityManager::Instance()->GetEntity(context->caster);
if (!target) return;
auto controllablePhysicsComponent = target->GetComponent<ControllablePhysicsComponent>();
if (!controllablePhysicsComponent) return;
controllablePhysicsComponent->RemovePickupRadiusScale(m_Scale);
Game::entityManager->SerializeEntity(target);
EntityManager::Instance()->SerializeEntity(target);
}
void LootBuffBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) {

View File

@@ -14,13 +14,13 @@
void OverTimeBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
const auto originator = context->originator;
auto* entity = Game::entityManager->GetEntity(originator);
auto* entity = EntityManager::Instance()->GetEntity(originator);
if (entity == nullptr) return;
for (size_t i = 0; i < m_NumIntervals; i++) {
entity->AddCallbackTimer((i + 1) * m_Delay, [originator, branch, this]() {
auto* entity = Game::entityManager->GetEntity(originator);
auto* entity = EntityManager::Instance()->GetEntity(originator);
if (entity == nullptr) return;

View File

@@ -16,7 +16,7 @@ void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStrea
return;
};
auto* entity = Game::entityManager->GetEntity(context->originator);
auto* entity = EntityManager::Instance()->GetEntity(context->originator);
if (entity == nullptr) {
Game::logger->Log("ProjectileAttackBehavior", "Failed to find originator (%llu)!", context->originator);
@@ -40,7 +40,7 @@ void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStrea
};
}
auto* targetEntity = Game::entityManager->GetEntity(target);
auto* targetEntity = EntityManager::Instance()->GetEntity(target);
for (auto i = 0u; i < this->m_projectileCount; ++i) {
LWOOBJID projectileId{};
@@ -61,7 +61,7 @@ void ProjectileAttackBehavior::Handle(BehaviorContext* context, RakNet::BitStrea
void ProjectileAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
bitStream->Write(branch.target);
auto* entity = Game::entityManager->GetEntity(context->originator);
auto* entity = EntityManager::Instance()->GetEntity(context->originator);
if (entity == nullptr) {
Game::logger->Log("ProjectileAttackBehavior", "Failed to find originator (%llu)!", context->originator);
@@ -78,7 +78,7 @@ void ProjectileAttackBehavior::Calculate(BehaviorContext* context, RakNet::BitSt
}
auto* other = Game::entityManager->GetEntity(branch.target);
auto* other = EntityManager::Instance()->GetEntity(branch.target);
if (other == nullptr) {
Game::logger->Log("ProjectileAttackBehavior", "Invalid projectile target (%llu)!", branch.target);

View File

@@ -12,7 +12,7 @@
#include "dZoneManager.h"
void PropertyTeleportBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* caster = Game::entityManager->GetEntity(context->caster);
auto* caster = EntityManager::Instance()->GetEntity(context->caster);
if (!caster) return;
auto* character = caster->GetCharacter();
@@ -23,16 +23,16 @@ void PropertyTeleportBehavior::Handle(BehaviorContext* context, RakNet::BitStrea
LWOMAPID targetMapId = m_MapId;
LWOCLONEID targetCloneId = character->GetPropertyCloneID();
if (Game::zoneManager->GetZoneID().GetCloneID() == character->GetPropertyCloneID()) {
if (dZoneManager::Instance()->GetZoneID().GetCloneID() == character->GetPropertyCloneID()) {
targetMapId = character->GetLastNonInstanceZoneID();
targetCloneId = 0;
} else {
character->SetLastNonInstanceZoneID(Game::zoneManager->GetZoneID().GetMapID());
character->SetLastNonInstanceZoneID(dZoneManager::Instance()->GetZoneID().GetMapID());
}
ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, targetMapId, targetCloneId, false, [objId](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) {
auto* entity = Game::entityManager->GetEntity(objId);
auto* entity = EntityManager::Instance()->GetEntity(objId);
if (!entity) return;
const auto sysAddr = entity->GetSystemAddress();

View File

@@ -6,9 +6,9 @@
#include "MovementAIComponent.h"
void PullToPointBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* entity = Game::entityManager->GetEntity(context->originator);
auto* entity = EntityManager::Instance()->GetEntity(context->originator);
auto* target = Game::entityManager->GetEntity(branch.target);
auto* target = EntityManager::Instance()->GetEntity(branch.target);
if (entity == nullptr || target == nullptr) {
return;

View File

@@ -6,7 +6,7 @@
#include "BuffComponent.h"
void RemoveBuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* entity = Game::entityManager->GetEntity(context->caster);
auto* entity = EntityManager::Instance()->GetEntity(context->caster);
if (!entity) return;
auto* buffComponent = entity->GetComponent<BuffComponent>();

View File

@@ -8,7 +8,7 @@
#include "eReplicaComponentType.h"
void RepairBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit_stream, const BehaviorBranchContext branch) {
auto* entity = Game::entityManager->GetEntity(branch.target);
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
if (entity == nullptr) {
Game::logger->Log("RepairBehavior", "Failed to find entity for (%llu)!", branch.target);

View File

@@ -5,8 +5,8 @@
#include "CppScripts.h"
void SkillEventBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* target = Game::entityManager->GetEntity(branch.target);
auto* caster = Game::entityManager->GetEntity(context->originator);
auto* target = EntityManager::Instance()->GetEntity(branch.target);
auto* caster = EntityManager::Instance()->GetEntity(context->originator);
if (caster != nullptr && target != nullptr && this->m_effectHandle != nullptr && !this->m_effectHandle->empty()) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(target)) {
@@ -17,8 +17,8 @@ void SkillEventBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bit
void
SkillEventBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* target = Game::entityManager->GetEntity(branch.target);
auto* caster = Game::entityManager->GetEntity(context->originator);
auto* target = EntityManager::Instance()->GetEntity(branch.target);
auto* caster = EntityManager::Instance()->GetEntity(context->originator);
if (caster != nullptr && target != nullptr && this->m_effectHandle != nullptr && !this->m_effectHandle->empty()) {
for (CppScripts::Script* script : CppScripts::GetEntityScripts(target)) {

View File

@@ -12,7 +12,7 @@
#include "eReplicaComponentType.h"
void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* origin = Game::entityManager->GetEntity(context->originator);
auto* origin = EntityManager::Instance()->GetEntity(context->originator);
if (origin == nullptr) {
Game::logger->Log("SpawnBehavior", "Failed to find self entity (%llu)!", context->originator);
@@ -21,7 +21,7 @@ void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStrea
}
if (branch.isProjectile) {
auto* target = Game::entityManager->GetEntity(branch.target);
auto* target = EntityManager::Instance()->GetEntity(branch.target);
if (target != nullptr) {
origin = target;
@@ -38,10 +38,10 @@ void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStrea
info.spawnerNodeID = 0;
info.pos = info.pos + (info.rot.GetForwardVector() * m_Distance);
auto* entity = Game::entityManager->CreateEntity(
auto* entity = EntityManager::Instance()->CreateEntity(
info,
nullptr,
Game::entityManager->GetEntity(context->originator)
EntityManager::Instance()->GetEntity(context->originator)
);
if (entity == nullptr) {
@@ -59,7 +59,7 @@ void SpawnBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStrea
rebuildComponent->SetRepositionPlayer(false);
}
Game::entityManager->ConstructEntity(entity);
EntityManager::Instance()->ConstructEntity(entity);
if (branch.duration > 0) {
context->RegisterTimerBehavior(this, branch, entity->GetObjectID());
@@ -79,7 +79,7 @@ void SpawnBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitSt
}
void SpawnBehavior::Timer(BehaviorContext* context, const BehaviorBranchContext branch, const LWOOBJID second) {
auto* entity = Game::entityManager->GetEntity(second);
auto* entity = EntityManager::Instance()->GetEntity(second);
if (entity == nullptr) {
Game::logger->Log("SpawnBehavior", "Failed to find spawned entity (%llu)!", second);

View File

@@ -9,14 +9,14 @@
void SpeedBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
if (m_AffectsCaster) branch.target = context->caster;
auto* target = Game::entityManager->GetEntity(branch.target);
auto* target = EntityManager::Instance()->GetEntity(branch.target);
if (!target) return;
auto* controllablePhysicsComponent = target->GetComponent<ControllablePhysicsComponent>();
if (!controllablePhysicsComponent) return;
controllablePhysicsComponent->AddSpeedboost(m_RunSpeed);
Game::entityManager->SerializeEntity(target);
EntityManager::Instance()->SerializeEntity(target);
if (branch.duration > 0.0f) {
context->RegisterTimerBehavior(this, branch);
@@ -38,14 +38,14 @@ void SpeedBehavior::Timer(BehaviorContext* context, BehaviorBranchContext branch
}
void SpeedBehavior::End(BehaviorContext* context, BehaviorBranchContext branch, LWOOBJID second) {
auto* target = Game::entityManager->GetEntity(branch.target);
auto* target = EntityManager::Instance()->GetEntity(branch.target);
if (!target) return;
auto* controllablePhysicsComponent = target->GetComponent<ControllablePhysicsComponent>();
if (!controllablePhysicsComponent) return;
controllablePhysicsComponent->RemoveSpeedboost(m_RunSpeed);
Game::entityManager->SerializeEntity(target);
EntityManager::Instance()->SerializeEntity(target);
}
void SpeedBehavior::Load() {

View File

@@ -21,7 +21,7 @@ void StunBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream
return;
};
auto* target = Game::entityManager->GetEntity(branch.target);
auto* target = EntityManager::Instance()->GetEntity(branch.target);
if (target == nullptr) {
Game::logger->Log("StunBehavior", "Failed to find target (%llu)!", branch.target);
@@ -44,7 +44,7 @@ void StunBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream
void StunBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, const BehaviorBranchContext branch) {
if (this->m_stunCaster || branch.target == context->originator) {
auto* self = Game::entityManager->GetEntity(context->originator);
auto* self = EntityManager::Instance()->GetEntity(context->originator);
if (self == nullptr) {
Game::logger->Log("StunBehavior", "Invalid self entity (%llu)!", context->originator);
@@ -69,7 +69,7 @@ void StunBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStr
bool blocked = false;
auto* target = Game::entityManager->GetEntity(branch.target);
auto* target = EntityManager::Instance()->GetEntity(branch.target);
if (target != nullptr) {
auto* destroyableComponent = target->GetComponent<DestroyableComponent>();

View File

@@ -16,7 +16,7 @@ void SwitchBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre
};
}
auto* entity = Game::entityManager->GetEntity(context->originator);
auto* entity = EntityManager::Instance()->GetEntity(context->originator);
if (entity == nullptr) {
return;
@@ -41,7 +41,7 @@ void SwitchBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitS
auto state = true;
if (this->m_imagination > 0 || !this->m_isEnemyFaction) {
auto* entity = Game::entityManager->GetEntity(branch.target);
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
state = entity != nullptr;

View File

@@ -76,7 +76,7 @@ void TacArcBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStre
}
void TacArcBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* self = Game::entityManager->GetEntity(context->originator);
auto* self = EntityManager::Instance()->GetEntity(context->originator);
if (self == nullptr) {
Game::logger->Log("TacArcBehavior", "Invalid self for (%llu)!", context->originator);
return;
@@ -85,7 +85,7 @@ void TacArcBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitS
const auto* destroyableComponent = self->GetComponent<DestroyableComponent>();
if ((this->m_usePickedTarget || context->clientInitalized) && branch.target > 0) {
const auto* target = Game::entityManager->GetEntity(branch.target);
const auto* target = EntityManager::Instance()->GetEntity(branch.target);
if (target == nullptr) {
return;
@@ -120,7 +120,7 @@ void TacArcBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitS
// Find all valid targets, based on whether we target enemies or friends
for (const auto& contextTarget : context->GetValidTargets()) {
if (destroyableComponent != nullptr) {
const auto* targetEntity = Game::entityManager->GetEntity(contextTarget);
const auto* targetEntity = EntityManager::Instance()->GetEntity(contextTarget);
if (m_targetEnemy && destroyableComponent->IsEnemy(targetEntity)
|| m_targetFriend && destroyableComponent->IsFriend(targetEntity)) {
@@ -136,7 +136,7 @@ void TacArcBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitS
break;
}
auto* entity = Game::entityManager->GetEntity(validTarget);
auto* entity = EntityManager::Instance()->GetEntity(validTarget);
if (entity == nullptr) {
Game::logger->Log("TacArcBehavior", "Invalid target (%llu) for (%llu)!", validTarget, context->originator);

View File

@@ -7,7 +7,7 @@
void TauntBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* target = Game::entityManager->GetEntity(branch.target);
auto* target = EntityManager::Instance()->GetEntity(branch.target);
if (target == nullptr) {
Game::logger->Log("TauntBehavior", "Failed to find target (%llu)!", branch.target);
@@ -23,7 +23,7 @@ void TauntBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStrea
}
void TauntBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* target = Game::entityManager->GetEntity(branch.target);
auto* target = EntityManager::Instance()->GetEntity(branch.target);
if (target == nullptr) {
Game::logger->Log("TauntBehavior", "Failed to find target (%llu)!", branch.target);

View File

@@ -5,7 +5,7 @@
void VentureVisionBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
const auto targetEntity = Game::entityManager->GetEntity(branch.target);
const auto targetEntity = EntityManager::Instance()->GetEntity(branch.target);
if (targetEntity) {
auto characterComponent = targetEntity->GetComponent<CharacterComponent>();
@@ -21,7 +21,7 @@ void VentureVisionBehavior::Handle(BehaviorContext* context, RakNet::BitStream*
}
void VentureVisionBehavior::UnCast(BehaviorContext* context, BehaviorBranchContext branch) {
const auto targetEntity = Game::entityManager->GetEntity(branch.target);
const auto targetEntity = EntityManager::Instance()->GetEntity(branch.target);
if (targetEntity) {
auto characterComponent = targetEntity->GetComponent<CharacterComponent>();

View File

@@ -8,14 +8,14 @@
void VerifyBehavior::Calculate(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* entity = Game::entityManager->GetEntity(branch.target);
auto* entity = EntityManager::Instance()->GetEntity(branch.target);
auto success = true;
if (entity == nullptr) {
success = false;
} else if (this->m_rangeCheck) {
auto* self = Game::entityManager->GetEntity(context->originator);
auto* self = EntityManager::Instance()->GetEntity(context->originator);
if (self == nullptr) {
Game::logger->Log("VerifyBehavior", "Invalid self for (%llu)", context->originator);

View File

@@ -173,7 +173,7 @@ void BaseCombatAIComponent::Update(const float deltaTime) {
}
if (m_SoftTimer <= 0.0f) {
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
m_SoftTimer = 5.0f;
} else {
@@ -305,7 +305,7 @@ void BaseCombatAIComponent::CalculateCombat(const float deltaTime) {
}
if (serilizationRequired) {
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
GameMessages::SendPlayFXEffect(m_Parent->GetObjectID(), 6270, u"tether", "tether");
@@ -318,7 +318,7 @@ void BaseCombatAIComponent::CalculateCombat(const float deltaTime) {
// Speed towards start position
if (m_MovementAI != nullptr) {
m_MovementAI->SetHaltDistance(0);
m_MovementAI->SetMaxSpeed(m_PursuitSpeed);
m_MovementAI->SetSpeed(m_PursuitSpeed);
m_MovementAI->SetDestination(m_StartPosition);
}
@@ -382,6 +382,8 @@ void BaseCombatAIComponent::CalculateCombat(const float deltaTime) {
}
LWOOBJID BaseCombatAIComponent::FindTarget() {
//const auto reference = m_MovementAI == nullptr ? m_StartPosition : m_MovementAI->ApproximateLocation();
NiPoint3 reference = m_StartPosition;
if (m_MovementAI) reference = m_MovementAI->ApproximateLocation();
@@ -410,7 +412,7 @@ LWOOBJID BaseCombatAIComponent::FindTarget() {
float biggestThreat = 0;
for (const auto& entry : possibleTargets) {
auto* entity = Game::entityManager->GetEntity(entry);
auto* entity = EntityManager::Instance()->GetEntity(entry);
if (entity == nullptr) {
continue;
@@ -456,7 +458,7 @@ LWOOBJID BaseCombatAIComponent::FindTarget() {
std::vector<LWOOBJID> deadThreats{};
for (const auto& threatTarget : m_ThreatEntries) {
auto* entity = Game::entityManager->GetEntity(threatTarget.first);
auto* entity = EntityManager::Instance()->GetEntity(threatTarget.first);
if (entity == nullptr) {
deadThreats.push_back(threatTarget.first);
@@ -495,7 +497,7 @@ std::vector<LWOOBJID> BaseCombatAIComponent::GetTargetWithinAggroRange() const {
std::vector<LWOOBJID> targets;
for (auto id : m_Parent->GetTargetsInPhantom()) {
auto* other = Game::entityManager->GetEntity(id);
auto* other = EntityManager::Instance()->GetEntity(id);
const auto distance = Vector3::DistanceSquared(m_Parent->GetPosition(), other->GetPosition());
@@ -533,11 +535,11 @@ void BaseCombatAIComponent::SetAiState(AiState newState) {
if (newState == this->m_State) return;
this->m_State = newState;
m_DirtyStateOrTarget = true;
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
bool BaseCombatAIComponent::IsEnemy(LWOOBJID target) const {
auto* entity = Game::entityManager->GetEntity(target);
auto* entity = EntityManager::Instance()->GetEntity(target);
if (entity == nullptr) {
Game::logger->Log("BaseCombatAIComponent", "Invalid entity for checking validity (%llu)!", target);
@@ -586,11 +588,11 @@ void BaseCombatAIComponent::SetTarget(const LWOOBJID target) {
if (this->m_Target == target) return;
m_Target = target;
m_DirtyStateOrTarget = true;
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
Entity* BaseCombatAIComponent::GetTargetEntity() const {
return Game::entityManager->GetEntity(m_Target);
return EntityManager::Instance()->GetEntity(m_Target);
}
void BaseCombatAIComponent::Taunt(LWOOBJID offender, float threat) {
@@ -658,17 +660,17 @@ void BaseCombatAIComponent::Wander() {
destination.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(destination);
}
if (Vector3::DistanceSquared(destination, m_MovementAI->GetParent()->GetPosition()) < 2 * 2) {
if (Vector3::DistanceSquared(destination, m_MovementAI->GetCurrentPosition()) < 2 * 2) {
m_MovementAI->Stop();
return;
}
m_MovementAI->SetMaxSpeed(m_TetherSpeed);
m_MovementAI->SetSpeed(m_TetherSpeed);
m_MovementAI->SetDestination(destination);
m_Timer += (m_MovementAI->GetParent()->GetPosition().x - destination.x) / m_TetherSpeed;
m_Timer += (m_MovementAI->GetCurrentPosition().x - destination.x) / m_TetherSpeed;
}
void BaseCombatAIComponent::OnAggro() {
@@ -683,21 +685,21 @@ void BaseCombatAIComponent::OnAggro() {
m_MovementAI->SetHaltDistance(m_AttackRadius);
NiPoint3 targetPos = target->GetPosition();
NiPoint3 currentPos = m_MovementAI->GetParent()->GetPosition();
NiPoint3 currentPos = m_MovementAI->GetCurrentPosition();
// If the player's position is within range, attack
if (Vector3::DistanceSquared(currentPos, targetPos) <= m_AttackRadius * m_AttackRadius) {
m_MovementAI->Stop();
} else if (Vector3::DistanceSquared(m_StartPosition, targetPos) > m_HardTetherRadius * m_HardTetherRadius) //Return to spawn if we're too far
{
m_MovementAI->SetMaxSpeed(m_PursuitSpeed);
m_MovementAI->SetSpeed(m_PursuitSpeed);
m_MovementAI->SetDestination(m_StartPosition);
} else //Chase the player's new position
{
if (IsMech() && Vector3::DistanceSquared(targetPos, currentPos) > m_AttackRadius * m_AttackRadius * 3 * 3) return;
m_MovementAI->SetMaxSpeed(m_PursuitSpeed);
m_MovementAI->SetSpeed(m_PursuitSpeed);
m_MovementAI->SetDestination(targetPos);
@@ -723,7 +725,7 @@ void BaseCombatAIComponent::OnTether() {
m_MovementAI->Stop();
} else if (Vector3::DistanceSquared(m_StartPosition, targetPos) > m_HardTetherRadius * m_HardTetherRadius) //Return to spawn if we're too far
{
m_MovementAI->SetMaxSpeed(m_PursuitSpeed);
m_MovementAI->SetSpeed(m_PursuitSpeed);
m_MovementAI->SetDestination(m_StartPosition);
@@ -731,7 +733,7 @@ void BaseCombatAIComponent::OnTether() {
} else {
if (IsMech() && Vector3::DistanceSquared(targetPos, currentPos) > m_AttackRadius * m_AttackRadius * 3 * 3) return;
m_MovementAI->SetMaxSpeed(m_PursuitSpeed);
m_MovementAI->SetSpeed(m_PursuitSpeed);
m_MovementAI->SetDestination(targetPos);
}

View File

@@ -36,7 +36,7 @@ Entity* BouncerComponent::GetParentEntity() const {
void BouncerComponent::SetPetEnabled(bool value) {
m_PetEnabled = value;
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
void BouncerComponent::SetPetBouncerEnabled(bool value) {
@@ -44,7 +44,7 @@ void BouncerComponent::SetPetBouncerEnabled(bool value) {
GameMessages::SendBouncerActiveStatus(m_Parent->GetObjectID(), value, UNASSIGNED_SYSTEM_ADDRESS);
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
if (value) {
m_Parent->TriggerEvent(eTriggerEventType::PET_ON_SWITCH, m_Parent);
@@ -68,7 +68,7 @@ void BouncerComponent::LookupPetSwitch() {
const auto& groups = m_Parent->GetGroups();
for (const auto& group : groups) {
const auto& entities = Game::entityManager->GetEntitiesInGroup(group);
const auto& entities = EntityManager::Instance()->GetEntitiesInGroup(group);
for (auto* entity : entities) {
auto* switchComponent = entity->GetComponent<SwitchComponent>();
@@ -79,7 +79,7 @@ void BouncerComponent::LookupPetSwitch() {
m_PetSwitchLoaded = true;
m_PetEnabled = true;
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
Game::logger->Log("BouncerComponent", "Loaded pet bouncer");
}

View File

@@ -17,7 +17,7 @@ BuildBorderComponent::~BuildBorderComponent() {
void BuildBorderComponent::OnUse(Entity* originator) {
if (originator->GetCharacter()) {
const auto& entities = Game::entityManager->GetEntitiesInGroup("PropertyPlaque");
const auto& entities = EntityManager::Instance()->GetEntitiesInGroup("PropertyPlaque");
auto buildArea = m_Parent->GetObjectID();

View File

@@ -6,7 +6,6 @@ set(DGAME_DCOMPONENTS_SOURCES "BaseCombatAIComponent.cpp"
"Component.cpp"
"ControllablePhysicsComponent.cpp"
"DestroyableComponent.cpp"
"DonationVendorComponent.cpp"
"InventoryComponent.cpp"
"LevelProgressionComponent.cpp"
"LUPExhibitComponent.cpp"

View File

@@ -419,7 +419,7 @@ void CharacterComponent::TrackMissionCompletion(bool isAchievement) {
// Achievements are tracked separately for the zone
if (isAchievement) {
const auto mapID = Game::zoneManager->GetZoneID().GetMapID();
const auto mapID = dZoneManager::Instance()->GetZoneID().GetMapID();
GetZoneStatisticsForMap(mapID).m_AchievementsCollected++;
}
}
@@ -480,7 +480,7 @@ void CharacterComponent::TrackArmorDelta(int32_t armor) {
void CharacterComponent::TrackRebuildComplete() {
UpdatePlayerStatistic(QuickBuildsCompleted);
const auto mapID = Game::zoneManager->GetZoneID().GetMapID();
const auto mapID = dZoneManager::Instance()->GetZoneID().GetMapID();
GetZoneStatisticsForMap(mapID).m_QuickBuildsCompleted++;
}

View File

@@ -276,10 +276,6 @@ public:
*/
void UpdateClientMinimap(bool showFaction, std::string ventureVisionType) const;
void SetCurrentInteracting(LWOOBJID objectID) {m_CurrentInteracting = objectID;};
LWOOBJID GetCurrentInteracting() {return m_CurrentInteracting;};
/**
* Character info regarding this character, including clothing styles, etc.
*/
@@ -564,8 +560,6 @@ private:
* ID of the last rocket used
*/
LWOOBJID m_LastRocketItemID = LWOOBJID_EMPTY;
LWOOBJID m_CurrentInteracting = LWOOBJID_EMPTY;
};
#endif // CHARACTERCOMPONENT_H

View File

@@ -194,7 +194,7 @@ void ControllablePhysicsComponent::UpdateXml(tinyxml2::XMLDocument* doc) {
return;
}
auto zoneInfo = Game::zoneManager->GetZone()->GetZoneID();
auto zoneInfo = dZoneManager::Instance()->GetZone()->GetZoneID();
if (zoneInfo.GetMapID() != 0 && zoneInfo.GetCloneID() == 0) {
character->SetAttribute("lzx", m_Position.x);
@@ -300,7 +300,7 @@ void ControllablePhysicsComponent::RemovePickupRadiusScale(float value) {
auto candidateRadius = m_ActivePickupRadiusScales[i];
if (m_PickupRadius < candidateRadius) m_PickupRadius = candidateRadius;
}
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
void ControllablePhysicsComponent::AddSpeedboost(float value) {
@@ -327,7 +327,7 @@ void ControllablePhysicsComponent::RemoveSpeedboost(float value) {
m_SpeedBoost = m_ActiveSpeedBoosts.back();
}
SetSpeedMultiplier(m_SpeedBoost / 500.0f); // 500 being the base speed
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
void ControllablePhysicsComponent::ActivateBubbleBuff(eBubbleType bubbleType, bool specialAnims){
@@ -339,13 +339,13 @@ void ControllablePhysicsComponent::ActivateBubbleBuff(eBubbleType bubbleType, bo
m_IsInBubble = true;
m_DirtyBubble = true;
m_SpecialAnims = specialAnims;
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
void ControllablePhysicsComponent::DeactivateBubbleBuff(){
m_DirtyBubble = true;
m_IsInBubble = false;
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
};
void ControllablePhysicsComponent::SetStunImmunity(

View File

@@ -253,7 +253,7 @@ void DestroyableComponent::SetMaxHealth(float value, bool playAnim) {
GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", args);
}
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
void DestroyableComponent::SetArmor(int32_t value) {
@@ -294,7 +294,7 @@ void DestroyableComponent::SetMaxArmor(float value, bool playAnim) {
GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", args);
}
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
void DestroyableComponent::SetImagination(int32_t value) {
@@ -333,7 +333,7 @@ void DestroyableComponent::SetMaxImagination(float value, bool playAnim) {
GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", args);
}
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
void DestroyableComponent::SetDamageToAbsorb(int32_t value) {
@@ -482,11 +482,11 @@ LWOOBJID DestroyableComponent::GetKillerID() const {
}
Entity* DestroyableComponent::GetKiller() const {
return Game::entityManager->GetEntity(m_KillerID);
return EntityManager::Instance()->GetEntity(m_KillerID);
}
bool DestroyableComponent::CheckValidity(const LWOOBJID target, const bool ignoreFactions, const bool targetEnemy, const bool targetFriend) const {
auto* targetEntity = Game::entityManager->GetEntity(target);
auto* targetEntity = EntityManager::Instance()->GetEntity(target);
if (targetEntity == nullptr) {
Game::logger->Log("DestroyableComponent", "Invalid entity for checking validity (%llu)!", target);
@@ -532,7 +532,7 @@ void DestroyableComponent::Heal(const uint32_t health) {
SetHealth(current);
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
@@ -550,7 +550,7 @@ void DestroyableComponent::Imagine(const int32_t deltaImagination) {
SetImagination(current);
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
@@ -564,7 +564,7 @@ void DestroyableComponent::Repair(const uint32_t armor) {
SetArmor(current);
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
@@ -626,7 +626,7 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32
if (possessor) {
auto possessableId = possessor->GetPossessable();
if (possessableId != LWOOBJID_EMPTY) {
auto possessable = Game::entityManager->GetEntity(possessableId);
auto possessable = EntityManager::Instance()->GetEntity(possessableId);
if (possessable) {
possessor->Dismount(possessable);
}
@@ -638,10 +638,10 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32
}
if (echo) {
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
auto* attacker = Game::entityManager->GetEntity(source);
auto* attacker = EntityManager::Instance()->GetEntity(source);
m_Parent->OnHit(attacker);
m_Parent->OnHitOrHealResult(attacker, sourceDamage);
NotifySubscribers(attacker, sourceDamage);
@@ -661,7 +661,7 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32
}
//check if hardcore mode is enabled
if (Game::entityManager->GetHardcoreMode()) {
if (EntityManager::Instance()->GetHardcoreMode()) {
DoHardcoreModeDrops(source);
}
@@ -696,12 +696,12 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType
SetArmor(0);
SetHealth(0);
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
m_KillerID = source;
auto* owner = Game::entityManager->GetEntity(source);
auto* owner = EntityManager::Instance()->GetEntity(source);
if (owner != nullptr) {
owner = owner->GetOwner(); // If the owner is overwritten, we collect that here
@@ -721,7 +721,7 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType
if (missions != nullptr) {
if (team != nullptr) {
for (const auto memberId : team->members) {
auto* member = Game::entityManager->GetEntity(memberId);
auto* member = EntityManager::Instance()->GetEntity(memberId);
if (member == nullptr) continue;
@@ -761,12 +761,12 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType
if (team->lootOption == 0) { // Round robin
specificOwner = TeamManager::Instance()->GetNextLootOwner(team);
auto* member = Game::entityManager->GetEntity(specificOwner);
auto* member = EntityManager::Instance()->GetEntity(specificOwner);
if (member) LootGenerator::Instance().DropLoot(member, m_Parent, lootMatrixId, GetMinCoins(), GetMaxCoins());
} else {
for (const auto memberId : team->members) { // Free for all
auto* member = Game::entityManager->GetEntity(memberId);
auto* member = EntityManager::Instance()->GetEntity(memberId);
if (member == nullptr) continue;
@@ -779,13 +779,13 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType
}
} else {
//Check if this zone allows coin drops
if (Game::zoneManager->GetPlayerLoseCoinOnDeath()) {
if (dZoneManager::Instance()->GetPlayerLoseCoinOnDeath()) {
auto* character = m_Parent->GetCharacter();
uint64_t coinsTotal = character->GetCoins();
const uint64_t minCoinsToLose = Game::zoneManager->GetWorldConfig()->coinsLostOnDeathMin;
const uint64_t minCoinsToLose = dZoneManager::Instance()->GetWorldConfig()->coinsLostOnDeathMin;
if (coinsTotal >= minCoinsToLose) {
const uint64_t maxCoinsToLose = Game::zoneManager->GetWorldConfig()->coinsLostOnDeathMax;
const float coinPercentageToLose = Game::zoneManager->GetWorldConfig()->coinsLostOnDeathPercent;
const uint64_t maxCoinsToLose = dZoneManager::Instance()->GetWorldConfig()->coinsLostOnDeathMax;
const float coinPercentageToLose = dZoneManager::Instance()->GetWorldConfig()->coinsLostOnDeathPercent;
uint64_t coinsToLose = std::max(static_cast<uint64_t>(coinsTotal * coinPercentageToLose), minCoinsToLose);
coinsToLose = std::min(maxCoinsToLose, coinsToLose);
@@ -797,12 +797,12 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType
}
}
Entity* zoneControl = Game::entityManager->GetZoneControlEntity();
Entity* zoneControl = EntityManager::Instance()->GetZoneControlEntity();
for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) {
script->OnPlayerDied(zoneControl, m_Parent);
}
std::vector<Entity*> scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPTED_ACTIVITY);
std::vector<Entity*> scriptedActs = EntityManager::Instance()->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)) {
@@ -965,7 +965,7 @@ void DestroyableComponent::FixStats() {
destroyableComponent->SetImagination(currentImagination);
// Serialize the entity
Game::entityManager->SerializeEntity(entity);
EntityManager::Instance()->SerializeEntity(entity);
}
void DestroyableComponent::AddOnHitCallback(const std::function<void(Entity*)>& callback) {
@@ -979,12 +979,12 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source){
auto* character = m_Parent->GetComponent<CharacterComponent>();
auto uscore = character->GetUScore();
auto uscoreToLose = uscore * (Game::entityManager->GetHardcoreLoseUscoreOnDeathPercent() / 100);
auto uscoreToLose = uscore * (EntityManager::Instance()->GetHardcoreLoseUscoreOnDeathPercent() / 100);
character->SetUScore(uscore - uscoreToLose);
GameMessages::SendModifyLEGOScore(m_Parent, m_Parent->GetSystemAddress(), -uscoreToLose, eLootSourceType::MISSION);
if (Game::entityManager->GetHardcoreDropinventoryOnDeath()) {
if (EntityManager::Instance()->GetHardcoreDropinventoryOnDeath()) {
//drop all items from inventory:
auto* inventory = m_Parent->GetComponent<InventoryComponent>();
if (inventory) {
@@ -1001,7 +1001,7 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source){
GameMessages::SendDropClientLoot(m_Parent, source, item.second->GetLot(), 0, m_Parent->GetPosition(), item.second->GetCount());
item.second->SetCount(0, false, false);
}
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
}
}
@@ -1021,25 +1021,25 @@ void DestroyableComponent::DoHardcoreModeDrops(const LWOOBJID source){
// Reload the player since we can't normally reduce uscore from the server and we want the UI to update
// do this last so we don't get killed.... again
Game::entityManager->DestructEntity(m_Parent);
Game::entityManager->ConstructEntity(m_Parent);
EntityManager::Instance()->DestructEntity(m_Parent);
EntityManager::Instance()->ConstructEntity(m_Parent);
return;
}
//award the player some u-score:
auto* player = Game::entityManager->GetEntity(source);
auto* player = EntityManager::Instance()->GetEntity(source);
if (player && player->IsPlayer()) {
auto* playerStats = player->GetComponent<CharacterComponent>();
if (playerStats) {
//get the maximum health from this enemy:
auto maxHealth = GetMaxHealth();
int uscore = maxHealth * Game::entityManager->GetHardcoreUscoreEnemiesMultiplier();
int uscore = maxHealth * EntityManager::Instance()->GetHardcoreUscoreEnemiesMultiplier();
playerStats->SetUScore(playerStats->GetUScore() + uscore);
GameMessages::SendModifyLEGOScore(player, player->GetSystemAddress(), uscore, eLootSourceType::MISSION);
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
}
}

View File

@@ -1,50 +0,0 @@
#include "DonationVendorComponent.h"
#include "Database.h"
DonationVendorComponent::DonationVendorComponent(Entity* parent) : VendorComponent(parent) {
//LoadConfigData
m_PercentComplete = 0.0;
m_TotalDonated = 0;
m_TotalRemaining = 0;
// custom attribute to calculate other values
m_Goal = m_Parent->GetVar<int32_t>(u"donationGoal");
if (m_Goal == 0) m_Goal = INT32_MAX;
// Default to the nexus tower jawbox activity and setup settings
m_ActivityId = m_Parent->GetVar<uint32_t>(u"activityID");
if ((m_ActivityId == 0) || (m_ActivityId == 117)) {
m_ActivityId = 117;
m_PercentComplete = 1.0;
m_TotalDonated = INT32_MAX;
m_TotalRemaining = 0;
m_Goal = INT32_MAX;
return;
}
std::unique_ptr<sql::PreparedStatement> query(Database::CreatePreppedStmt("SELECT SUM(primaryScore) as donation_total FROM leaderboard WHERE game_id = ?;"));
query->setInt(1, m_ActivityId);
std::unique_ptr<sql::ResultSet> donation_total(query->executeQuery());
if (donation_total->next()) m_TotalDonated = donation_total->getInt("donation_total");
m_TotalRemaining = m_Goal - m_TotalDonated;
m_PercentComplete = m_TotalDonated/static_cast<float>(m_Goal);
}
void DonationVendorComponent::SubmitDonation(uint32_t count) {
if (count <= 0 && ((m_TotalDonated + count) > 0)) return;
m_TotalDonated += count;
m_TotalRemaining = m_Goal - m_TotalDonated;
m_PercentComplete = m_TotalDonated/static_cast<float>(m_Goal);
m_DirtyDonationVendor = true;
}
void DonationVendorComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) {
VendorComponent::Serialize(outBitStream, bIsInitialUpdate, flags);
outBitStream->Write(bIsInitialUpdate || m_DirtyDonationVendor);
if (bIsInitialUpdate || m_DirtyDonationVendor) {
outBitStream->Write(m_PercentComplete);
outBitStream->Write(m_TotalDonated);
outBitStream->Write(m_TotalRemaining);
if (!bIsInitialUpdate) m_DirtyDonationVendor = false;
}
}

View File

@@ -1,27 +0,0 @@
#ifndef __DONATIONVENDORCOMPONENT__H__
#define __DONATIONVENDORCOMPONENT__H__
#include "VendorComponent.h"
#include "eReplicaComponentType.h"
class Entity;
class DonationVendorComponent final : public VendorComponent {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::DONATION_VENDOR;
DonationVendorComponent(Entity* parent);
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags);
uint32_t GetActivityID() {return m_ActivityId;};
void SubmitDonation(uint32_t count);
private:
bool m_DirtyDonationVendor = false;
float m_PercentComplete = 0.0;
int32_t m_TotalDonated = 0;
int32_t m_TotalRemaining = 0;
uint32_t m_ActivityId = 0;
int32_t m_Goal = 0;
};
#endif //!__DONATIONVENDORCOMPONENT__H__

View File

@@ -38,7 +38,7 @@
#include "CDObjectSkillsTable.h"
#include "CDSkillBehaviorTable.h"
InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document) : Component(parent) {
InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* document): Component(parent) {
this->m_Dirty = true;
this->m_Equipped = {};
this->m_Pushed = {};
@@ -116,9 +116,6 @@ Inventory* InventoryComponent::GetInventory(const eInventoryType type) {
case eInventoryType::VENDOR_BUYBACK:
size = 27u;
break;
case eInventoryType::DONATION:
size = 24u;
break;
default:
break;
}
@@ -829,26 +826,18 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) {
if (character != nullptr && !skipChecks) {
// Hacky proximity rocket
if (item->GetLot() == 6416) {
const auto rocketLauchPads = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::ROCKET_LAUNCH);
const auto rocketLauchPads = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::ROCKET_LAUNCH);
const auto position = m_Parent->GetPosition();
for (auto* launchPad : rocketLauchPads) {
if (!launchPad) continue;
auto prereq = launchPad->GetVarAsString(u"rocketLaunchPreCondition");
if (!prereq.empty()) {
PreconditionExpression expression(prereq);
if (!expression.Check(m_Parent)) continue;
}
if (Vector3::DistanceSquared(launchPad->GetPosition(), position) > 13 * 13) continue;
for (auto* lauchPad : rocketLauchPads) {
if (Vector3::DistanceSquared(lauchPad->GetPosition(), position) > 13 * 13) continue;
auto* characterComponent = m_Parent->GetComponent<CharacterComponent>();
if (characterComponent != nullptr) characterComponent->SetLastRocketItemID(item->GetId());
launchPad->OnUse(m_Parent);
lauchPad->OnUse(m_Parent);
break;
}
@@ -890,7 +879,7 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) {
EquipScripts(item);
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
void InventoryComponent::UnEquipItem(Item* item) {
@@ -920,12 +909,12 @@ void InventoryComponent::UnEquipItem(Item* item) {
UnequipScripts(item);
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
// Trigger property event
if (PropertyManagementComponent::Instance() != nullptr && item->GetCount() > 0 && Inventory::FindInventoryTypeForLot(item->GetLot()) == MODELS) {
PropertyManagementComponent::Instance()->GetParent()->OnZonePropertyModelRemovedWhileEquipped(m_Parent);
Game::zoneManager->GetZoneControlObject()->OnZonePropertyModelRemovedWhileEquipped(m_Parent);
dZoneManager::Instance()->GetZoneControlObject()->OnZonePropertyModelRemovedWhileEquipped(m_Parent);
}
}
@@ -971,7 +960,7 @@ void InventoryComponent::HandlePossession(Item* item) {
if (possessorComponent->GetIsDismounting()) return;
// Check to see if we are already mounting something
auto* currentlyPossessedEntity = Game::entityManager->GetEntity(possessorComponent->GetPossessable());
auto* currentlyPossessedEntity = EntityManager::Instance()->GetEntity(possessorComponent->GetPossessable());
auto currentlyPossessedItem = possessorComponent->GetMountItemID();
if (currentlyPossessedItem) {
@@ -994,11 +983,21 @@ void InventoryComponent::HandlePossession(Item* item) {
info.rot = startRotation;
info.spawnerID = m_Parent->GetObjectID();
auto* mount = Game::entityManager->CreateEntity(info, nullptr, m_Parent);
auto* mount = EntityManager::Instance()->CreateEntity(info, nullptr, m_Parent);
// Check to see if the mount is a vehicle, if so, flip it
auto* vehicleComponent = mount->GetComponent<VehiclePhysicsComponent>();
if (vehicleComponent) characterComponent->SetIsRacing(true);
if (vehicleComponent) {
auto angles = startRotation.GetEulerAngles();
// Make it right side up
angles.x -= PI;
// Make it going in the direction of the player
angles.y -= PI;
startRotation = NiQuaternion::FromEulerAngles(angles);
mount->SetRotation(startRotation);
// We're pod racing now
characterComponent->SetIsRacing(true);
}
// Setup the destroyable stats
auto* destroyableComponent = mount->GetComponent<DestroyableComponent>();
@@ -1019,9 +1018,9 @@ void InventoryComponent::HandlePossession(Item* item) {
GameMessages::SendSetJetPackMode(m_Parent, false);
// Make it go to the client
Game::entityManager->ConstructEntity(mount);
EntityManager::Instance()->ConstructEntity(mount);
// Update the possessor
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
// have to unlock the input so it vehicle can be driven
if (vehicleComponent) GameMessages::SendVehicleUnlockInput(mount->GetObjectID(), false, m_Parent->GetSystemAddress());
@@ -1083,7 +1082,7 @@ void InventoryComponent::PopEquippedItems() {
destroyableComponent->SetHealth(static_cast<int32_t>(destroyableComponent->GetMaxHealth()));
destroyableComponent->SetArmor(static_cast<int32_t>(destroyableComponent->GetMaxArmor()));
destroyableComponent->SetImagination(static_cast<int32_t>(destroyableComponent->GetMaxImagination()));
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
m_Dirty = true;
@@ -1259,7 +1258,7 @@ void InventoryComponent::SpawnPet(Item* item) {
info.rot = NiQuaternion::IDENTITY;
info.spawnerID = m_Parent->GetObjectID();
auto* pet = Game::entityManager->CreateEntity(info);
auto* pet = EntityManager::Instance()->CreateEntity(info);
auto* petComponent = pet->GetComponent<PetComponent>();
@@ -1267,7 +1266,7 @@ void InventoryComponent::SpawnPet(Item* item) {
petComponent->Activate(item);
}
Game::entityManager->ConstructEntity(pet);
EntityManager::Instance()->ConstructEntity(pet);
}
void InventoryComponent::SetDatabasePet(LWOOBJID id, const DatabasePet& data) {
@@ -1376,7 +1375,7 @@ void InventoryComponent::SetNPCItems(const std::vector<LOT>& items) {
UpdateSlot(info.equipLocation, { id, static_cast<LOT>(item), 1, slot++ }, true);
}
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
InventoryComponent::~InventoryComponent() {

View File

@@ -35,7 +35,7 @@ void LUPExhibitComponent::NextExhibit() {
m_Exhibit = m_Exhibits[m_ExhibitIndex];
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
void LUPExhibitComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, uint32_t& flags) {

View File

@@ -26,7 +26,7 @@ std::unordered_map<AchievementCacheKey, std::vector<uint32_t>> MissionComponent:
//! Initializer
MissionComponent::MissionComponent(Entity* parent) : Component(parent) {
m_LastUsedMissionOrderUID = Game::zoneManager->GetUniqueMissionIdStartingValue();
m_LastUsedMissionOrderUID = dZoneManager::Instance()->GetUniqueMissionIdStartingValue();
}
//! Destructor

View File

@@ -10,77 +10,85 @@
#include "EntityManager.h"
#include "SimplePhysicsComponent.h"
#include "CDClientManager.h"
#include "Game.h"
#include "dZoneManager.h"
#include "CDComponentsRegistryTable.h"
#include "CDPhysicsComponentTable.h"
namespace {
/**
* Cache of all lots and their respective speeds
*/
std::map<LOT, float> m_PhysicsSpeedCache;
}
std::map<LOT, float> MovementAIComponent::m_PhysicsSpeedCache = {};
MovementAIComponent::MovementAIComponent(Entity* parent, MovementAIInfo info) : Component(parent) {
m_Info = info;
m_AtFinalWaypoint = true;
m_Info = std::move(info);
m_Done = true;
m_BaseCombatAI = nullptr;
m_BaseCombatAI = m_Parent->GetComponent<BaseCombatAIComponent>();
m_BaseCombatAI = reinterpret_cast<BaseCombatAIComponent*>(m_Parent->GetComponent(eReplicaComponentType::BASE_COMBAT_AI));
//Try and fix the insane values:
if (m_Info.wanderRadius > 5.0f) m_Info.wanderRadius *= 0.5f;
if (m_Info.wanderRadius > 5.0f) m_Info.wanderRadius = m_Info.wanderRadius * 0.5f;
if (m_Info.wanderRadius > 8.0f) m_Info.wanderRadius = 8.0f;
if (m_Info.wanderSpeed > 0.5f) m_Info.wanderSpeed *= 0.5f;
if (m_Info.wanderSpeed > 0.5f) m_Info.wanderSpeed = m_Info.wanderSpeed * 0.5f;
m_BaseSpeed = GetBaseSpeed(m_Parent->GetLOT());
m_NextWaypoint = m_Parent->GetPosition();
m_NextWaypoint = GetCurrentPosition();
m_Acceleration = 0.4f;
m_PullingToPoint = false;
m_PullPoint = NiPoint3::ZERO;
m_Interrupted = false;
m_PullPoint = {};
m_HaltDistance = 0;
m_TimeToTravel = 0;
m_TimeTravelled = 0;
m_Timer = 0;
m_CurrentSpeed = 0;
m_MaxSpeed = 0;
m_Speed = 0;
m_TotalTime = 0;
m_LockRotation = false;
}
MovementAIComponent::~MovementAIComponent() = default;
void MovementAIComponent::Update(const float deltaTime) {
if (m_PullingToPoint) {
if (m_Interrupted) {
const auto source = GetCurrentWaypoint();
const auto speed = deltaTime * 2.5f;
NiPoint3 velocity = (m_PullPoint - source) * speed;
NiPoint3 velocity;
velocity.x = (m_PullPoint.x - source.x) * speed;
velocity.y = (m_PullPoint.y - source.y) * speed;
velocity.z = (m_PullPoint.z - source.z) * speed;
SetPosition(source + velocity);
if (Vector3::DistanceSquared(m_Parent->GetPosition(), m_PullPoint) < std::pow(2, 2)) {
m_PullingToPoint = false;
if (Vector3::DistanceSquared(GetCurrentPosition(), m_PullPoint) < 2 * 2) {
m_Interrupted = false;
}
return;
}
// Are we done?
if (AtFinalWaypoint()) return;
if (AtFinalWaypoint()) // Are we done?
{
return;
}
if (m_HaltDistance > 0) {
// Prevent us from hugging the target
if (Vector3::DistanceSquared(ApproximateLocation(), GetDestination()) < std::pow(m_HaltDistance, 2)) {
if (Vector3::DistanceSquared(ApproximateLocation(), GetDestination()) < m_HaltDistance * m_HaltDistance) // Prevent us from hugging the target
{
Stop();
return;
}
}
m_TimeTravelled += deltaTime;
if (m_TimeTravelled < m_TimeToTravel) return;
m_TimeTravelled = 0.0f;
if (m_Timer > 0) {
m_Timer -= deltaTime;
if (m_Timer > 0) {
return;
}
m_Timer = 0;
}
const auto source = GetCurrentWaypoint();
@@ -93,51 +101,55 @@ void MovementAIComponent::Update(const float deltaTime) {
m_NextWaypoint = GetCurrentWaypoint();
if (m_NextWaypoint == source) {
m_TimeToTravel = 0.0f;
m_Timer = 0;
goto nextAction;
}
if (m_CurrentSpeed < m_MaxSpeed) {
if (m_CurrentSpeed < m_Speed) {
m_CurrentSpeed += m_Acceleration;
}
if (m_CurrentSpeed > m_MaxSpeed) {
m_CurrentSpeed = m_MaxSpeed;
if (m_CurrentSpeed > m_Speed) {
m_CurrentSpeed = m_Speed;
}
const auto speed = m_CurrentSpeed * m_BaseSpeed; // scale speed based on base speed
const auto speed = m_CurrentSpeed * m_BaseSpeed;
const auto delta = m_NextWaypoint - source;
// Normalize the vector
const auto length = delta.Length();
const auto length = sqrtf(delta.x * delta.x + delta.y * delta.y + delta.z * delta.z);
if (length > 0) {
velocity = (delta / length) * speed;
velocity.x = (delta.x / length) * speed;
velocity.y = (delta.y / length) * speed;
velocity.z = (delta.z / length) * speed;
}
// Calclute the time it will take to reach the next waypoint with the current speed
m_TimeTravelled = 0.0f;
m_TimeToTravel = length / speed;
m_TotalTime = m_Timer = length / speed;
SetRotation(NiQuaternion::LookAt(source, m_NextWaypoint));
} else {
// Check if there are more waypoints in the queue, if so set our next destination to the next waypoint
if (m_CurrentPath.empty()) {
if (!m_Queue.empty()) {
SetDestination(m_Queue.top());
m_Queue.pop();
} else {
// We have reached our final waypoint
Stop();
return;
}
SetDestination(m_CurrentPath.top());
m_CurrentPath.pop();
}
nextAction:
SetVelocity(velocity);
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
const MovementAIInfo& MovementAIComponent::GetInfo() const {
@@ -145,7 +157,7 @@ const MovementAIInfo& MovementAIComponent::GetInfo() const {
}
bool MovementAIComponent::AdvanceWaypointIndex() {
if (m_PathIndex >= m_InterpolatedWaypoints.size()) {
if (m_PathIndex >= m_CurrentPath.size()) {
return false;
}
@@ -155,19 +167,37 @@ bool MovementAIComponent::AdvanceWaypointIndex() {
}
NiPoint3 MovementAIComponent::GetCurrentWaypoint() const {
return m_PathIndex >= m_InterpolatedWaypoints.size() ? m_Parent->GetPosition() : m_InterpolatedWaypoints[m_PathIndex];
if (m_PathIndex >= m_CurrentPath.size()) {
return GetCurrentPosition();
}
return m_CurrentPath[m_PathIndex];
}
NiPoint3 MovementAIComponent::GetNextWaypoint() const {
return m_NextWaypoint;
}
NiPoint3 MovementAIComponent::GetCurrentPosition() const {
return m_Parent->GetPosition();
}
NiPoint3 MovementAIComponent::ApproximateLocation() const {
auto source = m_Parent->GetPosition();
auto source = GetCurrentPosition();
if (AtFinalWaypoint()) return source;
if (m_Done) {
return source;
}
auto destination = m_NextWaypoint;
auto percentageToWaypoint = m_TimeToTravel > 0 ? m_TimeTravelled / m_TimeToTravel : 0;
auto factor = m_TotalTime > 0 ? (m_TotalTime - m_Timer) / m_TotalTime : 0;
auto approximation = source + ((destination - source) * percentageToWaypoint);
auto x = source.x + factor * (destination.x - source.x);
auto y = source.y + factor * (destination.y - source.y);
auto z = source.z + factor * (destination.z - source.z);
NiPoint3 approximation = NiPoint3(x, y, z);
if (dpWorld::Instance().IsLoaded()) {
approximation.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(approximation);
@@ -191,47 +221,58 @@ bool MovementAIComponent::Warp(const NiPoint3& point) {
SetPosition(destination);
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
return true;
}
float MovementAIComponent::GetTimer() const {
return m_Timer;
}
bool MovementAIComponent::AtFinalWaypoint() const {
return m_Done;
}
void MovementAIComponent::Stop() {
if (AtFinalWaypoint()) return;
if (m_Done) {
return;
}
SetPosition(ApproximateLocation());
SetVelocity(NiPoint3::ZERO);
m_TimeToTravel = 0;
m_TimeTravelled = 0;
m_TotalTime = m_Timer = 0;
m_AtFinalWaypoint = true;
m_Done = true;
m_InterpolatedWaypoints.clear();
while (!m_CurrentPath.empty()) m_CurrentPath.pop();
m_CurrentPath = {};
m_PathIndex = 0;
m_CurrentSpeed = 0;
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
void MovementAIComponent::PullToPoint(const NiPoint3& point) {
Stop();
m_PullingToPoint = true;
m_Interrupted = true;
m_PullPoint = point;
}
void MovementAIComponent::SetPath(std::vector<NiPoint3> path) {
if (path.empty()) return;
std::for_each(path.rbegin(), path.rend() - 1, [this](const NiPoint3& point) {
this->m_CurrentPath.push(point);
});
std::reverse(path.begin(), path.end());
SetDestination(path.front());
for (const auto& point : path) {
m_Queue.push(point);
}
SetDestination(m_Queue.top());
m_Queue.pop();
}
float MovementAIComponent::GetBaseSpeed(LOT lot) {
@@ -250,14 +291,26 @@ float MovementAIComponent::GetBaseSpeed(LOT lot) {
componentID = componentRegistryTable->GetByIDAndType(lot, eReplicaComponentType::CONTROLLABLE_PHYSICS, -1);
if (componentID == -1) {
componentID = componentRegistryTable->GetByIDAndType(lot, eReplicaComponentType::SIMPLE_PHYSICS, -1);
if (componentID != -1) {
physicsComponent = physicsComponentTable->GetByID(componentID);
goto foundComponent;
}
physicsComponent = physicsComponentTable->GetByID(componentID);
componentID = componentRegistryTable->GetByIDAndType(lot, eReplicaComponentType::SIMPLE_PHYSICS, -1);
if (componentID != -1) {
physicsComponent = physicsComponentTable->GetByID(componentID);
goto foundComponent;
}
foundComponent:
// Client defaults speed to 10 and if the speed is also null in the table, it defaults to 10.
float speed = physicsComponent != nullptr ? physicsComponent->speed : 10.0f;
float speed = 10.0f;
if (physicsComponent) speed = physicsComponent->speed;
float delta = fabs(speed) - 1.0f;
@@ -269,11 +322,39 @@ float MovementAIComponent::GetBaseSpeed(LOT lot) {
}
void MovementAIComponent::SetPosition(const NiPoint3& value) {
m_Parent->SetPosition(value);
auto* controllablePhysicsComponent = m_Parent->GetComponent<ControllablePhysicsComponent>();
if (controllablePhysicsComponent != nullptr) {
controllablePhysicsComponent->SetPosition(value);
return;
}
auto* simplePhysicsComponent = m_Parent->GetComponent<SimplePhysicsComponent>();
if (simplePhysicsComponent != nullptr) {
simplePhysicsComponent->SetPosition(value);
}
}
void MovementAIComponent::SetRotation(const NiQuaternion& value) {
if (!m_LockRotation) m_Parent->SetRotation(value);
if (m_LockRotation) {
return;
}
auto* controllablePhysicsComponent = m_Parent->GetComponent<ControllablePhysicsComponent>();
if (controllablePhysicsComponent != nullptr) {
controllablePhysicsComponent->SetRotation(value);
return;
}
auto* simplePhysicsComponent = m_Parent->GetComponent<SimplePhysicsComponent>();
if (simplePhysicsComponent != nullptr) {
simplePhysicsComponent->SetRotation(value);
}
}
void MovementAIComponent::SetVelocity(const NiPoint3& value) {
@@ -292,8 +373,15 @@ void MovementAIComponent::SetVelocity(const NiPoint3& value) {
}
}
void MovementAIComponent::SetDestination(const NiPoint3& destination) {
if (m_PullingToPoint) return;
void MovementAIComponent::SetDestination(const NiPoint3& value) {
if (m_Interrupted) {
return;
}
/*if (Vector3::DistanceSquared(value, GetDestination()) < 2 * 2)
{
return;
}*/
const auto location = ApproximateLocation();
@@ -302,53 +390,97 @@ 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);
}
// Somehow failed
if (computedPath.empty()) {
if (dpWorld::Instance().IsLoaded()) {
computedPath = dpWorld::Instance().GetNavMesh()->GetPath(GetCurrentPosition(), value, m_Info.wanderSpeed);
} else {
// Than take 10 points between the current position and the destination and make that the path
auto start = location;
auto point = location;
auto delta = destination - start;
auto delta = value - point;
auto step = delta / 10.0f;
auto step = delta / 10;
for (int i = 0; i < 10; i++) {
// TODO: Replace this with += when the NiPoint3::operator+= is fixed
start = start + step;
point = point + step;
computedPath.push_back(start);
computedPath.push_back(point);
}
}
m_InterpolatedWaypoints.clear();
if (computedPath.empty()) // Somehow failed
{
return;
}
m_CurrentPath.clear();
m_CurrentPath.push_back(location);
// Simply path
for (auto& point : computedPath) {
for (auto point : computedPath) {
if (dpWorld::Instance().IsLoaded()) {
point.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(point);
}
m_InterpolatedWaypoints.push_back(point);
m_CurrentPath.push_back(point);
}
m_CurrentPath.push_back(computedPath[computedPath.size() - 1]);
m_PathIndex = 0;
m_TimeTravelled = 0;
m_TimeToTravel = 0;
m_TotalTime = m_Timer = 0;
m_AtFinalWaypoint = false;
m_Done = false;
}
NiPoint3 MovementAIComponent::GetDestination() const {
return m_InterpolatedWaypoints.empty() ? m_Parent->GetPosition() : m_InterpolatedWaypoints.back();
if (m_CurrentPath.empty()) {
return GetCurrentPosition();
}
return m_CurrentPath[m_CurrentPath.size() - 1];
}
void MovementAIComponent::SetMaxSpeed(const float value) {
if (value == m_MaxSpeed) return;
m_MaxSpeed = value;
void MovementAIComponent::SetSpeed(const float value) {
m_Speed = value;
m_Acceleration = value / 5;
}
float MovementAIComponent::GetSpeed() const {
return m_Speed;
}
void MovementAIComponent::SetAcceleration(const float value) {
m_Acceleration = value;
}
float MovementAIComponent::GetAcceleration() const {
return m_Acceleration;
}
void MovementAIComponent::SetHaltDistance(const float value) {
m_HaltDistance = value;
}
float MovementAIComponent::GetHaltDistance() const {
return m_HaltDistance;
}
void MovementAIComponent::SetCurrentSpeed(float value) {
m_CurrentSpeed = value;
}
float MovementAIComponent::GetCurrentSpeed() const {
return m_CurrentSpeed;
}
void MovementAIComponent::SetLockRotation(bool value) {
m_LockRotation = value;
}
bool MovementAIComponent::GetLockRotation() const {
return m_LockRotation;
}

View File

@@ -1,6 +1,6 @@
/*
* Darkflame Universe
* Copyright 2023
* Copyright 2018
*/
#ifndef MOVEMENTAICOMPONENT_H
@@ -60,6 +60,7 @@ public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::MOVEMENT_AI;
MovementAIComponent(Entity* parentEntity, MovementAIInfo info);
~MovementAIComponent() override;
void Update(float deltaTime) override;
@@ -85,55 +86,61 @@ public:
* Sets the max speed at which this entity may run
* @param value the speed value to set
*/
void SetMaxSpeed(float value);
void SetSpeed(float value);
/**
* Returns the max speed at which this entity may run
* @return the max speed at which this entity may run
*/
float GetSpeed() const;
/**
* Sets how fast the entity will accelerate when not running at full speed
* @param value the acceleration to set
*/
void SetAcceleration(float value) { m_Acceleration = value; };
void SetAcceleration(float value);
/**
* Returns the current speed at which this entity accelerates when not running at full speed
* @return the current speed at which this entity accelerates when not running at full speed
*/
float GetAcceleration() const { return m_Acceleration; };
float GetAcceleration() const;
/**
* Sets the halting distance (the distance at which we consider the target to be reached)
* @param value the halting distance to set
*/
void SetHaltDistance(float value) { m_HaltDistance = value; }
void SetHaltDistance(float value);
/**
* Returns the current halting distance (the distance at which we consider the target to be reached)
* @return the current halting distance
*/
float GetHaltDistance() const { return m_HaltDistance; }
float GetHaltDistance() const;
/**
* Sets the speed the entity is currently running at
* @param value the speed value to set
*/
void SetCurrentSpeed(float value) { m_CurrentSpeed = value; }
void SetCurrentSpeed(float value);
/**
* Returns the speed the entity is currently running at
* @return the speed the entity is currently running at
*/
float GetCurrentSpeed() const { return m_CurrentSpeed; }
float GetCurrentSpeed() const;
/**
* Locks the rotation of this entity in place, depending on the argument
* @param value if true, the entity will be rotationally locked
*/
void SetLockRotation(bool value) { m_LockRotation = value; }
void SetLockRotation(bool value);
/**
* Returns whether this entity is currently rotationally locked
* @return true if the entity is rotationally locked, false otherwise
*/
bool GetLockRotation() const { return m_LockRotation; };
bool GetLockRotation() const;
/**
* Attempts to update the waypoint index, making the entity move to the next waypoint
@@ -151,7 +158,13 @@ public:
* Returns the waypoint this entity is supposed to move towards next
* @return the waypoint this entity is supposed to move towards next
*/
NiPoint3 GetNextWaypoint() const { return m_NextWaypoint; }
NiPoint3 GetNextWaypoint() const;
/**
* Returns the current position of this entity
* @return the current position of this entity
*/
NiPoint3 GetCurrentPosition() const;
/**
* Returns the approximate current location of the entity, including y coordinates
@@ -167,11 +180,17 @@ public:
*/
bool Warp(const NiPoint3& point);
/**
* Returns the time it will take to reach the final waypoint according to the current speed
* @return the time it will take to reach the final waypoint according to the current speed
*/
float GetTimer() const;
/**
* Returns if the entity is at its final waypoint
* @return if the entity is at its final waypoint
*/
bool AtFinalWaypoint() const { return m_AtFinalWaypoint; }
bool AtFinalWaypoint() const;
/**
* Renders the entity stationary
@@ -231,12 +250,17 @@ private:
/**
* The max speed this entity may move at
*/
float m_MaxSpeed;
float m_Speed;
/**
* The time it will take to reach the next waypoint using the current speed
*/
float m_TimeTravelled;
float m_Timer;
/**
* The total time it will take to reach the waypoint form its starting point
*/
float m_TotalTime;
/**
* The path this entity is currently traversing
@@ -246,7 +270,7 @@ private:
/**
* If the entity has reached it last waypoint
*/
bool m_AtFinalWaypoint;
bool m_Done;
/**
* The speed the entity is currently moving at
@@ -263,11 +287,6 @@ private:
*/
float m_HaltDistance;
/**
* The total time it will take to reach the waypoint form its starting point
*/
float m_TimeToTravel;
/**
* The base speed this entity has
*/
@@ -276,7 +295,7 @@ private:
/**
* If the AI is currently turned of (e.g. when teleporting to some location)
*/
bool m_PullingToPoint;
bool m_Interrupted;
/**
* A position that the entity is currently moving towards while being interrupted
@@ -296,12 +315,17 @@ private:
/**
* The path the entity is currently following
*/
std::vector<NiPoint3> m_InterpolatedWaypoints;
std::vector<NiPoint3> m_CurrentPath;
/**
* The path from the current position to the destination.
* Queue of positions to traverse
*/
std::stack<NiPoint3> m_CurrentPath;
std::stack<NiPoint3> m_Queue;
/**
* Cache of all lots and their respective speeds
*/
static std::map<LOT, float> m_PhysicsSpeedCache;
};
#endif // MOVEMENTAICOMPONENT_H

View File

@@ -59,7 +59,7 @@ MovingPlatformComponent::MovingPlatformComponent(Entity* parent, const std::stri
m_MoverSubComponentType = eMoverSubComponentType::mover;
m_MoverSubComponent = new MoverSubComponent(m_Parent->GetDefaultPosition());
m_PathName = GeneralUtils::ASCIIToUTF16(pathName);
m_Path = Game::zoneManager->GetZone()->GetPath(pathName);
m_Path = dZoneManager::Instance()->GetZone()->GetPath(pathName);
m_NoAutoStart = false;
if (m_Path == nullptr) {
@@ -133,7 +133,7 @@ void MovingPlatformComponent::SetMovementState(eMovementPlatformState value) {
subComponent->mState = value;
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
void MovingPlatformComponent::GotoWaypoint(uint32_t index, bool stopAtWaypoint) {
@@ -194,7 +194,7 @@ void MovingPlatformComponent::StartPathing() {
//GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS);
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
void MovingPlatformComponent::ContinuePathing() {
@@ -242,7 +242,7 @@ void MovingPlatformComponent::ContinuePathing() {
subComponent->mCurrentWaypointIndex = pathSize;
switch (behavior) {
case PathBehavior::Once:
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
return;
case PathBehavior::Bounce:
@@ -304,7 +304,7 @@ void MovingPlatformComponent::ContinuePathing() {
ContinuePathing();
});
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
void MovingPlatformComponent::StopPathing() {
@@ -318,7 +318,7 @@ void MovingPlatformComponent::StopPathing() {
subComponent->mDesiredWaypointIndex = -1;
subComponent->mShouldStopAtDesiredWaypoint = false;
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
//GameMessages::SendPlatformResync(m_Parent, UNASSIGNED_SYSTEM_ADDRESS);
}
@@ -341,7 +341,7 @@ void MovingPlatformComponent::WarpToWaypoint(size_t index) {
m_Parent->SetPosition(waypoint.position);
m_Parent->SetRotation(waypoint.rotation);
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
size_t MovingPlatformComponent::GetLastWaypointIndex() const {

View File

@@ -154,7 +154,7 @@ void PetComponent::OnUse(Entity* originator) {
}
if (m_Tamer != LWOOBJID_EMPTY) {
auto* tamer = Game::entityManager->GetEntity(m_Tamer);
auto* tamer = EntityManager::Instance()->GetEntity(m_Tamer);
if (tamer != nullptr) {
return;
@@ -236,7 +236,7 @@ void PetComponent::OnUse(Entity* originator) {
return;
}
const auto& bricks = BrickDatabase::GetBricks(buildFile);
auto& bricks = BrickDatabase::Instance()->GetBricks(buildFile);
if (bricks.empty()) {
ChatPackets::SendSystemMessage(originator->GetSystemAddress(), u"Failed to load the puzzle minigame for this pet.");
@@ -344,7 +344,7 @@ void PetComponent::Update(float deltaTime) {
if (m_Timer <= 0) {
Wander();
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
} else {
m_Timer = 5;
@@ -369,7 +369,7 @@ void PetComponent::Update(float deltaTime) {
}
if (m_TresureTime > 0) {
auto* tresure = Game::entityManager->GetEntity(m_Interaction);
auto* tresure = EntityManager::Instance()->GetEntity(m_Interaction);
if (tresure == nullptr) {
m_TresureTime = 0;
@@ -395,7 +395,7 @@ void PetComponent::Update(float deltaTime) {
}
auto destination = owner->GetPosition();
NiPoint3 position = m_MovementAI->GetParent()->GetPosition();
NiPoint3 position = m_MovementAI->GetCurrentPosition();
float distanceToOwner = Vector3::DistanceSquared(position, destination);
@@ -449,7 +449,7 @@ void PetComponent::Update(float deltaTime) {
NiPoint3 tresurePosition = closestTresure->GetPosition();
float distance = Vector3::DistanceSquared(position, tresurePosition);
if (distance < 5 * 5) {
if (distance < 3 * 3) {
m_Interaction = closestTresure->GetObjectID();
Command(NiPoint3::ZERO, LWOOBJID_EMPTY, 1, 202, true);
@@ -466,7 +466,7 @@ skipTresure:
m_MovementAI->SetHaltDistance(haltDistance);
m_MovementAI->SetMaxSpeed(2.5f);
m_MovementAI->SetSpeed(2.5f);
m_MovementAI->SetDestination(destination);
@@ -476,7 +476,7 @@ skipTresure:
void PetComponent::TryBuild(uint32_t numBricks, bool clientFailed) {
if (m_Tamer == LWOOBJID_EMPTY) return;
auto* tamer = Game::entityManager->GetEntity(m_Tamer);
auto* tamer = EntityManager::Instance()->GetEntity(m_Tamer);
if (tamer == nullptr) {
m_Tamer = LWOOBJID_EMPTY;
@@ -498,7 +498,7 @@ void PetComponent::TryBuild(uint32_t numBricks, bool clientFailed) {
destroyableComponent->SetImagination(imagination);
Game::entityManager->SerializeEntity(tamer);
EntityManager::Instance()->SerializeEntity(tamer);
if (clientFailed) {
if (imagination < cached->second.imaginationCost) {
@@ -516,7 +516,7 @@ void PetComponent::TryBuild(uint32_t numBricks, bool clientFailed) {
void PetComponent::NotifyTamingBuildSuccess(NiPoint3 position) {
if (m_Tamer == LWOOBJID_EMPTY) return;
auto* tamer = Game::entityManager->GetEntity(m_Tamer);
auto* tamer = EntityManager::Instance()->GetEntity(m_Tamer);
if (tamer == nullptr) {
m_Tamer = LWOOBJID_EMPTY;
@@ -539,11 +539,11 @@ void PetComponent::NotifyTamingBuildSuccess(NiPoint3 position) {
info.rot = NiQuaternion::IDENTITY;
info.spawnerID = tamer->GetObjectID();
auto* modelEntity = Game::entityManager->CreateEntity(info);
auto* modelEntity = EntityManager::Instance()->CreateEntity(info);
m_ModelId = modelEntity->GetObjectID();
Game::entityManager->ConstructEntity(modelEntity);
EntityManager::Instance()->ConstructEntity(modelEntity);
GameMessages::SendNotifyTamingModelLoadedOnServer(m_Tamer, tamer->GetSystemAddress());
@@ -639,7 +639,7 @@ void PetComponent::RequestSetPetName(std::u16string name) {
return;
}
auto* tamer = Game::entityManager->GetEntity(m_Tamer);
auto* tamer = EntityManager::Instance()->GetEntity(m_Tamer);
if (tamer == nullptr) {
m_Tamer = LWOOBJID_EMPTY;
@@ -661,7 +661,7 @@ void PetComponent::RequestSetPetName(std::u16string name) {
//Save our pet's new name to the db:
SetPetNameForModeration(GeneralUtils::UTF16ToWTF8(name));
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
std::u16string u16name = GeneralUtils::UTF8ToUTF16(m_Name);
std::u16string u16ownerName = GeneralUtils::UTF8ToUTF16(m_OwnerName);
@@ -684,7 +684,7 @@ void PetComponent::RequestSetPetName(std::u16string name) {
GameMessages::SendTerminateInteraction(m_Tamer, eTerminateType::FROM_INTERACTION, m_Parent->GetObjectID());
auto* modelEntity = Game::entityManager->GetEntity(m_ModelId);
auto* modelEntity = EntityManager::Instance()->GetEntity(m_ModelId);
if (modelEntity != nullptr) {
modelEntity->Smash(m_Tamer);
@@ -703,7 +703,7 @@ void PetComponent::RequestSetPetName(std::u16string name) {
void PetComponent::ClientExitTamingMinigame(bool voluntaryExit) {
if (m_Tamer == LWOOBJID_EMPTY) return;
auto* tamer = Game::entityManager->GetEntity(m_Tamer);
auto* tamer = EntityManager::Instance()->GetEntity(m_Tamer);
if (tamer == nullptr) {
m_Tamer = LWOOBJID_EMPTY;
@@ -733,7 +733,7 @@ void PetComponent::ClientExitTamingMinigame(bool voluntaryExit) {
m_Tamer = LWOOBJID_EMPTY;
m_Timer = 0;
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
// Notify the end of a pet taming minigame
for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) {
@@ -754,7 +754,7 @@ void PetComponent::StartTimer() {
void PetComponent::ClientFailTamingMinigame() {
if (m_Tamer == LWOOBJID_EMPTY) return;
auto* tamer = Game::entityManager->GetEntity(m_Tamer);
auto* tamer = EntityManager::Instance()->GetEntity(m_Tamer);
if (tamer == nullptr) {
m_Tamer = LWOOBJID_EMPTY;
@@ -784,7 +784,7 @@ void PetComponent::ClientFailTamingMinigame() {
m_Tamer = LWOOBJID_EMPTY;
m_Timer = 0;
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
// Notify the end of a pet taming minigame
for (CppScripts::Script* script : CppScripts::GetEntityScripts(m_Parent)) {
@@ -822,17 +822,17 @@ void PetComponent::Wander() {
destination.y = dpWorld::Instance().GetNavMesh()->GetHeightAtPoint(destination);
}
if (Vector3::DistanceSquared(destination, m_MovementAI->GetParent()->GetPosition()) < 2 * 2) {
if (Vector3::DistanceSquared(destination, m_MovementAI->GetCurrentPosition()) < 2 * 2) {
m_MovementAI->Stop();
return;
}
m_MovementAI->SetMaxSpeed(info.wanderSpeed);
m_MovementAI->SetSpeed(info.wanderSpeed);
m_MovementAI->SetDestination(destination);
m_Timer += (m_MovementAI->GetParent()->GetPosition().x - destination.x) / info.wanderSpeed;
m_Timer += (m_MovementAI->GetCurrentPosition().x - destination.x) / info.wanderSpeed;
}
void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) {
@@ -887,7 +887,7 @@ void PetComponent::Activate(Item* item, bool registerPet, bool fromTaming) {
m_Timer = 3;
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
owner->GetCharacter()->SetPlayerFlag(ePlayerFlag::FIRST_MANUAL_PET_HIBERNATE, true);
@@ -1004,7 +1004,7 @@ LWOOBJID PetComponent::GetOwnerId() const {
}
Entity* PetComponent::GetOwner() const {
return Game::entityManager->GetEntity(m_Owner);
return EntityManager::Instance()->GetEntity(m_Owner);
}
LWOOBJID PetComponent::GetDatabaseId() const {
@@ -1046,7 +1046,7 @@ PetComponent* PetComponent::GetTamingPet(LWOOBJID tamer) {
return nullptr;
}
auto* entity = Game::entityManager->GetEntity(pair->second);
auto* entity = EntityManager::Instance()->GetEntity(pair->second);
if (entity == nullptr) {
currentActivities.erase(tamer);
@@ -1064,7 +1064,7 @@ PetComponent* PetComponent::GetActivePet(LWOOBJID owner) {
return nullptr;
}
auto* entity = Game::entityManager->GetEntity(pair->second);
auto* entity = EntityManager::Instance()->GetEntity(pair->second);
if (entity == nullptr) {
activePets.erase(owner);

View File

@@ -362,7 +362,7 @@ void PhantomPhysicsComponent::Update(float deltaTime) {
//If we are a respawn volume, inform the client:
if (m_IsRespawnVolume) {
auto entity = Game::entityManager->GetEntity(en->GetObjectID());
auto entity = EntityManager::Instance()->GetEntity(en->GetObjectID());
if (entity) {
GameMessages::SendPlayerReachedRespawnCheckpoint(entity, m_RespawnPos, m_RespawnRot);
@@ -403,8 +403,8 @@ void PhantomPhysicsComponent::SpawnVertices() {
info.spawnerID = m_Parent->GetObjectID();
info.spawnerNodeID = 0;
Entity* newEntity = Game::entityManager->CreateEntity(info, nullptr);
Game::entityManager->ConstructEntity(newEntity);
Entity* newEntity = EntityManager::Instance()->CreateEntity(info, nullptr);
EntityManager::Instance()->ConstructEntity(newEntity);
}
}

View File

@@ -13,7 +13,7 @@ PossessorComponent::PossessorComponent(Entity* parent) : Component(parent) {
PossessorComponent::~PossessorComponent() {
if (m_Possessable != LWOOBJID_EMPTY) {
auto* mount = Game::entityManager->GetEntity(m_Possessable);
auto* mount = EntityManager::Instance()->GetEntity(m_Possessable);
if (mount) {
auto* possessable = mount->GetComponent<PossessableComponent>();
if (possessable) {
@@ -58,8 +58,8 @@ void PossessorComponent::Mount(Entity* mount) {
GameMessages::SendVehicleUnlockInput(mount->GetObjectID(), false, m_Parent->GetSystemAddress());
GameMessages::SendSetStunned(m_Parent->GetObjectID(), eStateChangeType::PUSH, m_Parent->GetSystemAddress(), LWOOBJID_EMPTY, true, false, true, false, false, false, false, true, true, true, true, true, true, true, true, true);
Game::entityManager->SerializeEntity(m_Parent);
Game::entityManager->SerializeEntity(mount);
EntityManager::Instance()->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(mount);
}
void PossessorComponent::Dismount(Entity* mount, bool forceDismount) {
@@ -73,8 +73,8 @@ void PossessorComponent::Dismount(Entity* mount, bool forceDismount) {
possessableComponent->SetPossessor(LWOOBJID_EMPTY);
if (forceDismount) possessableComponent->ForceDepossess();
}
Game::entityManager->SerializeEntity(m_Parent);
Game::entityManager->SerializeEntity(mount);
EntityManager::Instance()->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(mount);
auto characterComponent = m_Parent->GetComponent<CharacterComponent>();
if (characterComponent) characterComponent->SetIsRacing(false);

View File

@@ -38,7 +38,7 @@ PropertyManagementComponent::PropertyManagementComponent(Entity* parent) : Compo
instance = this;
const auto& worldId = Game::zoneManager->GetZone()->GetZoneID();
const auto& worldId = dZoneManager::Instance()->GetZone()->GetZoneID();
const auto zoneId = worldId.GetMapID();
const auto cloneId = worldId.GetCloneID();
@@ -90,7 +90,7 @@ LWOOBJID PropertyManagementComponent::GetOwnerId() const {
}
Entity* PropertyManagementComponent::GetOwner() const {
return Game::entityManager->GetEntity(owner);
return EntityManager::Instance()->GetEntity(owner);
}
void PropertyManagementComponent::SetOwner(Entity* value) {
@@ -98,7 +98,7 @@ void PropertyManagementComponent::SetOwner(Entity* value) {
}
std::vector<NiPoint3> PropertyManagementComponent::GetPaths() const {
const auto zoneId = Game::zoneManager->GetZone()->GetWorldID();
const auto zoneId = dZoneManager::Instance()->GetZone()->GetWorldID();
auto query = CDClientDatabase::CreatePreppedStmt(
"SELECT path FROM PropertyTemplate WHERE mapID = ?;");
@@ -185,14 +185,14 @@ bool PropertyManagementComponent::Claim(const LWOOBJID playerId) {
return false;
}
auto* entity = Game::entityManager->GetEntity(playerId);
auto* entity = EntityManager::Instance()->GetEntity(playerId);
auto* user = entity->GetParentUser();
auto character = entity->GetCharacter();
if (!character) return false;
auto* zone = Game::zoneManager->GetZone();
auto* zone = dZoneManager::Instance()->GetZone();
const auto& worldId = zone->GetZoneID();
const auto propertyZoneId = worldId.GetMapID();
@@ -240,7 +240,7 @@ bool PropertyManagementComponent::Claim(const LWOOBJID playerId) {
return false;
}
auto* zoneControlObject = Game::zoneManager->GetZoneControlObject();
auto* zoneControlObject = dZoneManager::Instance()->GetZoneControlObject();
for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControlObject)) {
script->OnZonePropertyRented(zoneControlObject, entity);
}
@@ -256,7 +256,7 @@ void PropertyManagementComponent::OnStartBuilding() {
LWOMAPID zoneId = 1100;
const auto entrance = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::PROPERTY_ENTRANCE);
const auto entrance = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::PROPERTY_ENTRANCE);
originalPrivacyOption = privacyOption;
@@ -339,9 +339,9 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N
info.settings.push_back(setting->Copy());
}
Entity* newEntity = Game::entityManager->CreateEntity(info);
Entity* newEntity = EntityManager::Instance()->CreateEntity(info);
if (newEntity != nullptr) {
Game::entityManager->ConstructEntity(newEntity);
EntityManager::Instance()->ConstructEntity(newEntity);
// Make sure the propMgmt doesn't delete our model after the server dies
// Trying to do this after the entity is constructed. Shouldn't really change anything but
@@ -371,14 +371,14 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N
info.respawnTime = 10;
info.emulated = true;
info.emulator = Game::entityManager->GetZoneControlEntity()->GetObjectID();
info.emulator = EntityManager::Instance()->GetZoneControlEntity()->GetObjectID();
info.spawnerID = persistentId;
GeneralUtils::SetBit(info.spawnerID, eObjectBits::CLIENT);
const auto spawnerId = Game::zoneManager->MakeSpawner(info);
const auto spawnerId = dZoneManager::Instance()->MakeSpawner(info);
auto* spawner = Game::zoneManager->GetSpawner(spawnerId);
auto* spawner = dZoneManager::Instance()->GetSpawner(spawnerId);
auto ldfModelBehavior = new LDFData<LWOOBJID>(u"modelBehaviors", 0);
auto userModelID = new LDFData<LWOOBJID>(u"userModelID", info.spawnerID);
@@ -401,7 +401,7 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N
GameMessages::SendGetModelsOnProperty(entity->GetObjectID(), GetModels(), UNASSIGNED_SYSTEM_ADDRESS);
Game::entityManager->GetZoneControlEntity()->OnZonePropertyModelPlaced(entity);
EntityManager::Instance()->GetZoneControlEntity()->OnZonePropertyModelPlaced(entity);
});
// Progress place model missions
auto missionComponent = entity->GetComponent<MissionComponent>();
@@ -433,7 +433,7 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet
const auto spawnerId = index->second;
auto* spawner = Game::zoneManager->GetSpawner(spawnerId);
auto* spawner = dZoneManager::Instance()->GetSpawner(spawnerId);
models.erase(id);
@@ -441,7 +441,7 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet
Game::logger->Log("PropertyManagementComponent", "Failed to find spawner");
}
auto* model = Game::entityManager->GetEntity(id);
auto* model = EntityManager::Instance()->GetEntity(id);
if (model == nullptr) {
Game::logger->Log("PropertyManagementComponent", "Failed to find model entity");
@@ -449,7 +449,7 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet
return;
}
Game::entityManager->DestructEntity(model);
EntityManager::Instance()->DestructEntity(model);
Game::logger->Log("PropertyManagementComponent", "Deleting model LOT %i", model->GetLOT());
@@ -496,7 +496,7 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet
GameMessages::SendPlaceModelResponse(entity->GetObjectID(), entity->GetSystemAddress(), NiPoint3::ZERO, LWOOBJID_EMPTY, 16, NiQuaternion::IDENTITY);
if (spawner != nullptr) {
Game::zoneManager->RemoveSpawner(spawner->m_Info.spawnerID);
dZoneManager::Instance()->RemoveSpawner(spawner->m_Info.spawnerID);
} else {
model->Smash(LWOOBJID_EMPTY, eKillType::SILENT);
}
@@ -520,13 +520,13 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet
item->Equip();
GameMessages::SendUGCEquipPostDeleteBasedOnEditMode(entity->GetObjectID(), entity->GetSystemAddress(), item->GetId(), item->GetCount());
Game::entityManager->GetZoneControlEntity()->OnZonePropertyModelPickedUp(entity);
EntityManager::Instance()->GetZoneControlEntity()->OnZonePropertyModelPickedUp(entity);
break;
}
case 1: // Return to inv
{
Game::entityManager->GetZoneControlEntity()->OnZonePropertyModelRemoved(entity);
EntityManager::Instance()->GetZoneControlEntity()->OnZonePropertyModelRemoved(entity);
break;
}
@@ -549,7 +549,7 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet
GameMessages::SendPlaceModelResponse(entity->GetObjectID(), entity->GetSystemAddress(), NiPoint3::ZERO, LWOOBJID_EMPTY, 16, NiQuaternion::IDENTITY);
if (spawner != nullptr) {
Game::zoneManager->RemoveSpawner(spawner->m_Info.spawnerID);
dZoneManager::Instance()->RemoveSpawner(spawner->m_Info.spawnerID);
} else {
model->Smash(LWOOBJID_EMPTY, eKillType::SILENT);
}
@@ -613,7 +613,7 @@ void PropertyManagementComponent::Load() {
info.respawnTime = 10;
//info.emulated = true;
//info.emulator = Game::entityManager->GetZoneControlEntity()->GetObjectID();
//info.emulator = EntityManager::Instance()->GetZoneControlEntity()->GetObjectID();
info.spawnerID = id;
@@ -652,9 +652,9 @@ void PropertyManagementComponent::Load() {
node->config = settings;
const auto spawnerId = Game::zoneManager->MakeSpawner(info);
const auto spawnerId = dZoneManager::Instance()->MakeSpawner(info);
auto* spawner = Game::zoneManager->GetSpawner(spawnerId);
auto* spawner = dZoneManager::Instance()->GetSpawner(spawnerId);
auto* model = spawner->Spawn();
@@ -698,7 +698,7 @@ void PropertyManagementComponent::Save() {
modelIds.push_back(id);
auto* entity = Game::entityManager->GetEntity(pair.first);
auto* entity = EntityManager::Instance()->GetEntity(pair.first);
if (entity == nullptr) {
continue;
@@ -786,7 +786,7 @@ void PropertyManagementComponent::OnQueryPropertyData(Entity* originator, const
author = m_Parent->GetObjectID();
}
const auto& worldId = Game::zoneManager->GetZone()->GetZoneID();
const auto& worldId = dZoneManager::Instance()->GetZone()->GetZoneID();
const auto zoneId = worldId.GetMapID();
Game::logger->Log("Properties", "Getting property info for %d", zoneId);

View File

@@ -43,7 +43,7 @@ void PropertyVendorComponent::OnBuyFromVendor(Entity* originator, const bool con
GameMessages::SendPropertyRentalResponse(m_Parent->GetObjectID(), 0, 0, 0, 0, originator->GetSystemAddress());
auto* controller = Game::zoneManager->GetZoneControlObject();
auto* controller = dZoneManager::Instance()->GetZoneControlObject();
controller->OnFireEventServerSide(m_Parent, "propertyRented");

View File

@@ -23,7 +23,6 @@
#include "dConfig.h"
#include "Loot.h"
#include "eMissionTaskType.h"
#include "LeaderboardManager.h"
#include "dZoneManager.h"
#include "CDActivitiesTable.h"
@@ -50,7 +49,7 @@ RacingControlComponent::RacingControlComponent(Entity* parent)
m_MainWorld = 1200;
const auto worldID = Game::server->GetZoneID();
if (Game::zoneManager->CheckIfAccessibleZone((worldID/10)*10)) m_MainWorld = (worldID/10)*10;
if (dZoneManager::Instance()->CheckIfAccessibleZone((worldID/10)*10)) m_MainWorld = (worldID/10)*10;
m_ActivityID = 42;
CDActivitiesTable* activitiesTable = CDClientManager::Instance().GetTable<CDActivitiesTable>();
@@ -106,10 +105,10 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player,
// Calculate the vehicle's starting position.
auto* path = Game::zoneManager->GetZone()->GetPath(
auto* path = dZoneManager::Instance()->GetZone()->GetPath(
GeneralUtils::UTF16ToWTF8(m_PathName));
auto spawnPointEntities = Game::entityManager->GetEntitiesByLOT(4843);
auto spawnPointEntities = EntityManager::Instance()->GetEntitiesByLOT(4843);
auto startPosition = NiPoint3::ZERO;
auto startRotation = NiQuaternion::IDENTITY;
const std::string placementAsString = std::to_string(positionNumber);
@@ -125,7 +124,8 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player,
// Make sure the player is at the correct position.
GameMessages::SendTeleport(player->GetObjectID(), startPosition,
startRotation, player->GetSystemAddress(), true);
startRotation, player->GetSystemAddress(), true,
true);
// Spawn the vehicle entity.
@@ -136,7 +136,7 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player,
info.spawnerID = m_Parent->GetObjectID();
auto* carEntity =
Game::entityManager->CreateEntity(info, nullptr, m_Parent);
EntityManager::Instance()->CreateEntity(info, nullptr, m_Parent);
// Make the vehicle a child of the racing controller.
m_Parent->AddChild(carEntity);
@@ -207,9 +207,9 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player,
// Construct and serialize everything when done.
Game::entityManager->ConstructEntity(carEntity);
Game::entityManager->SerializeEntity(player);
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->ConstructEntity(carEntity);
EntityManager::Instance()->SerializeEntity(player);
EntityManager::Instance()->SerializeEntity(m_Parent);
GameMessages::SendRacingSetPlayerResetInfo(
m_Parent->GetObjectID(), 0, 0, player->GetObjectID(), startPosition, 1,
@@ -220,7 +220,7 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player,
// Reset the player to the start position during downtime, in case something
// went wrong.
m_Parent->AddCallbackTimer(1, [this, playerID]() {
auto* player = Game::entityManager->GetEntity(playerID);
auto* player = EntityManager::Instance()->GetEntity(playerID);
if (player == nullptr) {
return;
@@ -243,9 +243,11 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player,
// Make sure everything has the correct position.
GameMessages::SendTeleport(player->GetObjectID(), startPosition,
startRotation, player->GetSystemAddress(), true);
startRotation, player->GetSystemAddress(), true,
true);
GameMessages::SendTeleport(carEntity->GetObjectID(), startPosition,
startRotation, player->GetSystemAddress(), true);
startRotation, player->GetSystemAddress(), true,
true);
}
void RacingControlComponent::OnRacingClientReady(Entity* player) {
@@ -269,7 +271,7 @@ void RacingControlComponent::OnRacingClientReady(Entity* player) {
racingPlayer.vehicleID, UNASSIGNED_SYSTEM_ADDRESS);
}
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
void RacingControlComponent::OnRequestDie(Entity* player) {
@@ -282,7 +284,7 @@ void RacingControlComponent::OnRequestDie(Entity* player) {
}
auto* vehicle =
Game::entityManager->GetEntity(racingPlayer.vehicleID);
EntityManager::Instance()->GetEntity(racingPlayer.vehicleID);
if (!vehicle) return;
@@ -319,7 +321,7 @@ void RacingControlComponent::OnRequestDie(Entity* player) {
auto* destroyableComponent = vehicle->GetComponent<DestroyableComponent>();
// Reset imagination to half its current value, rounded up to the nearest value divisible by 10, as it was done in live.
if (destroyableComponent) destroyableComponent->SetImagination(respawnImagination);
Game::entityManager->SerializeEntity(vehicle);
EntityManager::Instance()->SerializeEntity(vehicle);
});
auto* characterComponent = player->GetComponent<CharacterComponent>();
@@ -348,7 +350,7 @@ void RacingControlComponent::OnRacingPlayerInfoResetFinished(Entity* player) {
}
auto* vehicle =
Game::entityManager->GetEntity(racingPlayer.vehicleID);
EntityManager::Instance()->GetEntity(racingPlayer.vehicleID);
if (vehicle == nullptr) {
return;
@@ -368,17 +370,15 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, int32_t bu
}
if (id == "rewardButton") {
if (data->collectedRewards) return;
if (data->collectedRewards) {
return;
}
data->collectedRewards = true;
// Calculate the score, different loot depending on player count
auto playersRating = m_LoadedPlayers;
if(m_LoadedPlayers == 1 && m_SoloRacing) {
playersRating *= 2;
}
const auto score = m_LoadedPlayers * 10 + data->finished;
const auto score = playersRating * 10 + data->finished;
LootGenerator::Instance().GiveActivityLoot(player, m_Parent, m_ActivityID, score);
// Giving rewards
@@ -397,15 +397,15 @@ void RacingControlComponent::HandleMessageBoxResponse(Entity* player, int32_t bu
if (m_SoloRacing || m_LoadedPlayers > 2) {
missionComponent->Progress(eMissionTaskType::RACING, data->finished, (LWOOBJID)eRacingTaskParam::FINISH_WITH_PLACEMENT); // Finish in 1st place on a race
if (data->finished == 1) {
missionComponent->Progress(eMissionTaskType::RACING, Game::zoneManager->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::FIRST_PLACE_MULTIPLE_TRACKS); // Finish in 1st place on multiple tracks.
missionComponent->Progress(eMissionTaskType::RACING, Game::zoneManager->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::WIN_RACE_IN_WORLD); // Finished first place in specific world.
missionComponent->Progress(eMissionTaskType::RACING, dZoneManager::Instance()->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::FIRST_PLACE_MULTIPLE_TRACKS); // Finish in 1st place on multiple tracks.
missionComponent->Progress(eMissionTaskType::RACING, dZoneManager::Instance()->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::WIN_RACE_IN_WORLD); // Finished first place in specific world.
}
if (data->finished == m_LoadedPlayers) {
missionComponent->Progress(eMissionTaskType::RACING, Game::zoneManager->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::LAST_PLACE_FINISH); // Finished first place in specific world.
missionComponent->Progress(eMissionTaskType::RACING, dZoneManager::Instance()->GetZone()->GetWorldID(), (LWOOBJID)eRacingTaskParam::LAST_PLACE_FINISH); // Finished first place in specific world.
}
}
} else if ((id == "ACT_RACE_EXIT_THE_RACE?" || id == "Exit") && button == m_ActivityExitConfirm) {
auto* vehicle = Game::entityManager->GetEntity(data->vehicleID);
auto* vehicle = EntityManager::Instance()->GetEntity(data->vehicleID);
if (vehicle == nullptr) {
return;
@@ -506,7 +506,7 @@ void RacingControlComponent::Update(float deltaTime) {
// Check if any players has disconnected before loading in
for (size_t i = 0; i < m_LobbyPlayers.size(); i++) {
auto* playerEntity =
Game::entityManager->GetEntity(m_LobbyPlayers[i]);
EntityManager::Instance()->GetEntity(m_LobbyPlayers[i]);
if (playerEntity == nullptr) {
--m_LoadedPlayers;
@@ -528,7 +528,7 @@ void RacingControlComponent::Update(float deltaTime) {
if (m_EmptyTimer >= 30) {
for (const auto player : m_LobbyPlayers) {
auto* playerEntity =
Game::entityManager->GetEntity(player);
EntityManager::Instance()->GetEntity(player);
if (playerEntity == nullptr) {
continue;
@@ -553,7 +553,7 @@ void RacingControlComponent::Update(float deltaTime) {
"Loading player now!");
auto* player =
Game::entityManager->GetEntity(m_LobbyPlayers[positionNumber]);
EntityManager::Instance()->GetEntity(m_LobbyPlayers[positionNumber]);
if (player == nullptr) {
return;
@@ -577,7 +577,7 @@ void RacingControlComponent::Update(float deltaTime) {
if (!m_Started) {
// Check if anyone has disconnected during this period
for (size_t i = 0; i < m_RacingPlayers.size(); i++) {
auto* playerEntity = Game::entityManager->GetEntity(
auto* playerEntity = EntityManager::Instance()->GetEntity(
m_RacingPlayers[i].playerID);
if (playerEntity == nullptr) {
@@ -593,7 +593,7 @@ void RacingControlComponent::Update(float deltaTime) {
if (m_LoadedPlayers < 2 && !(m_LoadedPlayers == 1 && m_SoloRacing)) {
for (const auto player : m_LobbyPlayers) {
auto* playerEntity =
Game::entityManager->GetEntity(player);
EntityManager::Instance()->GetEntity(player);
if (playerEntity == nullptr) {
continue;
@@ -626,15 +626,15 @@ void RacingControlComponent::Update(float deltaTime) {
for (const auto& player : m_RacingPlayers) {
auto* vehicle =
Game::entityManager->GetEntity(player.vehicleID);
EntityManager::Instance()->GetEntity(player.vehicleID);
auto* playerEntity =
Game::entityManager->GetEntity(player.playerID);
EntityManager::Instance()->GetEntity(player.playerID);
if (vehicle != nullptr && playerEntity != nullptr) {
GameMessages::SendTeleport(
player.playerID, player.respawnPosition,
player.respawnRotation,
playerEntity->GetSystemAddress(), true);
playerEntity->GetSystemAddress(), true, true);
vehicle->SetPosition(player.respawnPosition);
vehicle->SetRotation(player.respawnRotation);
@@ -646,18 +646,18 @@ void RacingControlComponent::Update(float deltaTime) {
destroyableComponent->SetImagination(0);
}
Game::entityManager->SerializeEntity(vehicle);
Game::entityManager->SerializeEntity(
EntityManager::Instance()->SerializeEntity(vehicle);
EntityManager::Instance()->SerializeEntity(
playerEntity);
}
}
// Spawn imagination pickups
auto* minSpawner = Game::zoneManager->GetSpawnersByName(
auto* minSpawner = dZoneManager::Instance()->GetSpawnersByName(
"ImaginationSpawn_Min")[0];
auto* medSpawner = Game::zoneManager->GetSpawnersByName(
auto* medSpawner = dZoneManager::Instance()->GetSpawnersByName(
"ImaginationSpawn_Med")[0];
auto* maxSpawner = Game::zoneManager->GetSpawnersByName(
auto* maxSpawner = dZoneManager::Instance()->GetSpawnersByName(
"ImaginationSpawn_Max")[0];
minSpawner->Activate();
@@ -673,9 +673,9 @@ void RacingControlComponent::Update(float deltaTime) {
// Reset players to their start location, without smashing them
for (auto& player : m_RacingPlayers) {
auto* vehicleEntity =
Game::entityManager->GetEntity(player.vehicleID);
EntityManager::Instance()->GetEntity(player.vehicleID);
auto* playerEntity =
Game::entityManager->GetEntity(player.playerID);
EntityManager::Instance()->GetEntity(player.playerID);
if (vehicleEntity == nullptr || playerEntity == nullptr) {
continue;
@@ -692,9 +692,9 @@ void RacingControlComponent::Update(float deltaTime) {
// Activate the players movement
for (auto& player : m_RacingPlayers) {
auto* vehicleEntity =
Game::entityManager->GetEntity(player.vehicleID);
EntityManager::Instance()->GetEntity(player.vehicleID);
auto* playerEntity =
Game::entityManager->GetEntity(player.playerID);
EntityManager::Instance()->GetEntity(player.playerID);
if (vehicleEntity == nullptr || playerEntity == nullptr) {
continue;
@@ -712,7 +712,7 @@ void RacingControlComponent::Update(float deltaTime) {
Game::logger->Log("RacingControlComponent", "Starting race");
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
m_StartTime = std::time(nullptr);
}
@@ -726,13 +726,13 @@ void RacingControlComponent::Update(float deltaTime) {
}
// Race routines
auto* path = Game::zoneManager->GetZone()->GetPath(
auto* path = dZoneManager::Instance()->GetZone()->GetPath(
GeneralUtils::UTF16ToWTF8(m_PathName));
for (auto& player : m_RacingPlayers) {
auto* vehicle = Game::entityManager->GetEntity(player.vehicleID);
auto* vehicle = EntityManager::Instance()->GetEntity(player.vehicleID);
auto* playerEntity =
Game::entityManager->GetEntity(player.playerID);
EntityManager::Instance()->GetEntity(player.playerID);
if (vehicle == nullptr || playerEntity == nullptr) {
continue;
@@ -838,7 +838,6 @@ void RacingControlComponent::Update(float deltaTime) {
"Completed time %llu, %llu",
raceTime, raceTime * 1000);
LeaderboardManager::SaveScore(playerEntity->GetObjectID(), m_ActivityID, static_cast<float>(player.raceTime), static_cast<float>(player.bestLapTime), static_cast<float>(player.finished == 1));
// Entire race time
missionComponent->Progress(eMissionTaskType::RACING, (raceTime) * 1000, (LWOOBJID)eRacingTaskParam::TOTAL_TRACK_TIME);

View File

@@ -1,15 +0,0 @@
#ifndef __RACINGSOUNDTRIGGERCOMPONENT__H__
#define __RACINGSOUNDTRIGGERCOMPONENT__H__
#include "SoundTriggerComponent.h"
#include "eReplicaComponentType.h"
class Entity;
class RacingSoundTriggerComponent : public SoundTriggerComponent {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::RACING_SOUND_TRIGGER;
RacingSoundTriggerComponent(Entity* parent) : SoundTriggerComponent(parent){};
};
#endif //!__RACINGSOUNDTRIGGERCOMPONENT__H__

View File

@@ -68,7 +68,7 @@ void RailActivatorComponent::OnUse(Entity* originator) {
const auto originatorID = originator->GetObjectID();
m_Parent->AddCallbackTimer(animationLength, [originatorID, this]() {
auto* originator = Game::entityManager->GetEntity(originatorID);
auto* originator = EntityManager::Instance()->GetEntity(originatorID);
if (originator == nullptr) {
return;

View File

@@ -120,7 +120,7 @@ void RebuildComponent::Update(float deltaTime) {
else {
m_SoftTimer = 5.0f;
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}*/
switch (m_State) {
@@ -139,7 +139,7 @@ void RebuildComponent::Update(float deltaTime) {
if (m_TimerIncomplete >= m_TimeBeforeSmash - 4.0f) {
m_ShowResetEffect = true;
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
if (m_TimerIncomplete >= m_TimeBeforeSmash) {
@@ -163,7 +163,7 @@ void RebuildComponent::Update(float deltaTime) {
if (!m_ShowResetEffect) {
m_ShowResetEffect = true;
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
}
@@ -180,7 +180,7 @@ void RebuildComponent::Update(float deltaTime) {
{
Entity* builder = GetBuilder();
if (!builder) {
if (builder == nullptr) {
ResetRebuild(false);
return;
@@ -198,17 +198,17 @@ void RebuildComponent::Update(float deltaTime) {
if (!destComp) break;
int newImagination = destComp->GetImagination();
++m_DrainedImagination;
--newImagination;
destComp->SetImagination(newImagination);
Game::entityManager->SerializeEntity(builder);
if (newImagination <= 0) {
CancelRebuild(builder, eQuickBuildFailReason::OUT_OF_IMAGINATION, true);
break;
}
++m_DrainedImagination;
--newImagination;
destComp->SetImagination(newImagination);
EntityManager::Instance()->SerializeEntity(builder);
}
if (m_Timer >= m_CompleteTime && m_DrainedImagination >= m_TakeImagination) {
@@ -225,7 +225,7 @@ void RebuildComponent::Update(float deltaTime) {
if (m_TimerIncomplete >= m_TimeBeforeSmash - 4.0f) {
m_ShowResetEffect = true;
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
if (m_TimerIncomplete >= m_TimeBeforeSmash) {
@@ -263,20 +263,20 @@ void RebuildComponent::SpawnActivator() {
info.spawnerID = m_Parent->GetObjectID();
info.pos = m_ActivatorPosition == NiPoint3::ZERO ? m_Parent->GetPosition() : m_ActivatorPosition;
m_Activator = Game::entityManager->CreateEntity(info, nullptr, m_Parent);
m_Activator = EntityManager::Instance()->CreateEntity(info, nullptr, m_Parent);
if (m_Activator) {
m_ActivatorId = m_Activator->GetObjectID();
Game::entityManager->ConstructEntity(m_Activator);
EntityManager::Instance()->ConstructEntity(m_Activator);
}
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
}
}
void RebuildComponent::DespawnActivator() {
if (m_Activator) {
Game::entityManager->DestructEntity(m_Activator);
EntityManager::Instance()->DestructEntity(m_Activator);
m_Activator->ScheduleKillAfterUpdate();
@@ -287,7 +287,7 @@ void RebuildComponent::DespawnActivator() {
}
Entity* RebuildComponent::GetActivator() {
return Game::entityManager->GetEntity(m_ActivatorId);
return EntityManager::Instance()->GetEntity(m_ActivatorId);
}
NiPoint3 RebuildComponent::GetActivatorPosition() {
@@ -335,7 +335,7 @@ eRebuildState RebuildComponent::GetState() {
}
Entity* RebuildComponent::GetBuilder() const {
auto* builder = Game::entityManager->GetEntity(m_Builder);
auto* builder = EntityManager::Instance()->GetEntity(m_Builder);
return builder;
}
@@ -403,14 +403,14 @@ void RebuildComponent::StartRebuild(Entity* user) {
auto* character = user->GetComponent<CharacterComponent>();
character->SetCurrentActivity(eGameActivity::QUICKBUILDING);
Game::entityManager->SerializeEntity(user);
EntityManager::Instance()->SerializeEntity(user);
GameMessages::SendRebuildNotifyState(m_Parent, m_State, eRebuildState::BUILDING, user->GetObjectID());
GameMessages::SendEnableRebuild(m_Parent, true, false, false, eQuickBuildFailReason::NOT_GIVEN, 0.0f, user->GetObjectID());
m_State = eRebuildState::BUILDING;
m_StateDirty = true;
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
auto* movingPlatform = m_Parent->GetComponent<MovingPlatformComponent>();
if (movingPlatform != nullptr) {
@@ -443,7 +443,7 @@ void RebuildComponent::CompleteRebuild(Entity* user) {
return;
}
Game::entityManager->SerializeEntity(user);
EntityManager::Instance()->SerializeEntity(user);
GameMessages::SendRebuildNotifyState(m_Parent, m_State, eRebuildState::COMPLETED, user->GetObjectID());
GameMessages::SendPlayFXEffect(m_Parent, 507, u"create", "BrickFadeUpVisCompleteEffect", LWOOBJID_EMPTY, 0.4f, 1.0f, true);
@@ -456,7 +456,7 @@ void RebuildComponent::CompleteRebuild(Entity* user) {
m_Timer = 0.0f;
m_DrainedImagination = 0;
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
// Removes extra item requirements, isn't live accurate.
// In live, all items were removed at the start of the quickbuild, then returned if it was cancelled.
@@ -476,13 +476,13 @@ void RebuildComponent::CompleteRebuild(Entity* user) {
auto* team = TeamManager::Instance()->GetTeam(builder->GetObjectID());
if (team) {
for (const auto memberId : team->members) { // progress missions for all team members
auto* member = Game::entityManager->GetEntity(memberId);
auto* member = EntityManager::Instance()->GetEntity(memberId);
if (member) {
auto* missionComponent = member->GetComponent<MissionComponent>();
if (missionComponent) missionComponent->Progress(eMissionTaskType::ACTIVITY, m_ActivityId);
}
}
} else {
} else{
auto* missionComponent = builder->GetComponent<MissionComponent>();
if (missionComponent) missionComponent->Progress(eMissionTaskType::ACTIVITY, m_ActivityId);
}
@@ -541,7 +541,7 @@ void RebuildComponent::ResetRebuild(bool failed) {
m_ShowResetEffect = false;
m_DrainedImagination = 0;
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
// Notify scripts and possible subscribers
for (auto* script : CppScripts::GetEntityScripts(m_Parent))
@@ -581,7 +581,7 @@ void RebuildComponent::CancelRebuild(Entity* entity, eQuickBuildFailReason failR
for (const auto& cb : m_RebuildStateCallbacks)
cb(m_State);
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
if (entity == nullptr) {
@@ -591,7 +591,7 @@ void RebuildComponent::CancelRebuild(Entity* entity, eQuickBuildFailReason failR
CharacterComponent* characterComponent = entity->GetComponent<CharacterComponent>();
if (characterComponent) {
characterComponent->SetCurrentActivity(eGameActivity::NONE);
Game::entityManager->SerializeEntity(entity);
EntityManager::Instance()->SerializeEntity(entity);
}
}

View File

@@ -81,7 +81,7 @@ void RocketLaunchpadControlComponent::Launch(Entity* originator, LWOMAPID mapId,
GameMessages::SendChangeObjectWorldState(rocket->GetId(), eObjectWorldState::ATTACHED, UNASSIGNED_SYSTEM_ADDRESS);
Game::entityManager->SerializeEntity(originator);
EntityManager::Instance()->SerializeEntity(originator);
}
void RocketLaunchpadControlComponent::OnUse(Entity* originator) {

View File

@@ -36,7 +36,7 @@ ScriptedActivityComponent::ScriptedActivityComponent(Entity* parent, int activit
for (CDActivities activity : activities) {
m_ActivityInfo = activity;
if (static_cast<Leaderboard::Type>(activity.leaderboardType) == Leaderboard::Type::Racing && Game::config->GetValue("solo_racing") == "1") {
if (static_cast<LeaderboardType>(activity.leaderboardType) == LeaderboardType::Racing && Game::config->GetValue("solo_racing") == "1") {
m_ActivityInfo.minTeamSize = 1;
m_ActivityInfo.minTeams = 1;
}
@@ -137,7 +137,7 @@ void ScriptedActivityComponent::PlayerJoin(Entity* player) {
instance->AddParticipant(player);
}
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
void ScriptedActivityComponent::PlayerJoinLobby(Entity* player) {
@@ -149,7 +149,7 @@ void ScriptedActivityComponent::PlayerJoinLobby(Entity* player) {
auto* character = player->GetCharacter();
if (character != nullptr)
character->SetLastNonInstanceZoneID(Game::zoneManager->GetZone()->GetWorldID());
character->SetLastNonInstanceZoneID(dZoneManager::Instance()->GetZone()->GetWorldID());
for (Lobby* lobby : m_Queue) {
if (lobby->players.size() < m_ActivityInfo.maxTeamSize || m_ActivityInfo.maxTeamSize == 1 && lobby->players.size() < m_ActivityInfo.maxTeams) {
@@ -310,7 +310,7 @@ bool ScriptedActivityComponent::IsValidActivity(Entity* player) {
}
ChatPackets::SendSystemMessage(player->GetSystemAddress(), u"Sorry, this activity is not ready.");
static_cast<Player*>(player)->SendToZone(Game::zoneManager->GetZone()->GetWorldID()); // Gets them out of this stuck state
static_cast<Player*>(player)->SendToZone(dZoneManager::Instance()->GetZone()->GetWorldID()); // Gets them out of this stuck state
return false;
}*/
@@ -445,7 +445,7 @@ void ScriptedActivityComponent::RemoveActivityPlayerData(LWOOBJID playerID) {
m_ActivityPlayers[i] = nullptr;
m_ActivityPlayers.erase(m_ActivityPlayers.begin() + i);
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
return;
}
@@ -458,7 +458,7 @@ ActivityPlayer* ScriptedActivityComponent::AddActivityPlayerData(LWOOBJID player
return data;
m_ActivityPlayers.push_back(new ActivityPlayer{ playerID, {} });
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
return GetActivityPlayerData(playerID);
}
@@ -480,7 +480,7 @@ void ScriptedActivityComponent::SetActivityValue(LWOOBJID playerID, uint32_t ind
data->values[std::min(index, (uint32_t)9)] = value;
}
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
void ScriptedActivityComponent::PlayerRemove(LWOOBJID playerID) {
@@ -535,7 +535,7 @@ void ActivityInstance::StartZone() {
const auto objid = player->GetObjectID();
ZoneInstanceManager::Instance()->RequestZoneTransfer(Game::server, m_ActivityInfo.instanceMapID, cloneId, false, [objid](bool mythranShift, uint32_t zoneID, uint32_t zoneInstance, uint32_t zoneClone, std::string serverIP, uint16_t serverPort) {
auto* player = Game::entityManager->GetEntity(objid);
auto* player = EntityManager::Instance()->GetEntity(objid);
if (player == nullptr)
return;
@@ -585,7 +585,7 @@ std::vector<Entity*> ActivityInstance::GetParticipants() const {
entities.reserve(m_Participants.size());
for (const auto& id : m_Participants) {
auto* entity = Game::entityManager->GetEntity(id);
auto* entity = EntityManager::Instance()->GetEntity(id);
if (entity != nullptr)
entities.push_back(entity);
}
@@ -617,5 +617,5 @@ void ActivityInstance::SetScore(uint32_t score) {
}
Entity* LobbyPlayer::GetEntity() const {
return Game::entityManager->GetEntity(entityID);
return EntityManager::Instance()->GetEntity(entityID);
}

View File

@@ -14,7 +14,7 @@ void ShootingGalleryComponent::SetStaticParams(const StaticShootingGalleryParams
void ShootingGalleryComponent::SetDynamicParams(const DynamicShootingGalleryParams& params) {
m_DynamicParams = params;
m_Dirty = true;
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
void ShootingGalleryComponent::Serialize(RakNet::BitStream* outBitStream, bool isInitialUpdate, uint32_t& flags) const {

View File

@@ -292,7 +292,7 @@ SkillExecutionResult SkillComponent::CalculateBehavior(const uint32_t skillId, c
start.optionalOriginatorID = context->originator;
start.optionalTargetID = target;
auto* originator = Game::entityManager->GetEntity(context->originator);
auto* originator = EntityManager::Instance()->GetEntity(context->originator);
if (originator != nullptr) {
start.originatorRot = originator->GetRotation();
@@ -338,7 +338,7 @@ void SkillComponent::CalculateUpdate(const float deltaTime) {
entry.time += deltaTime;
auto* origin = Game::entityManager->GetEntity(entry.context->originator);
auto* origin = EntityManager::Instance()->GetEntity(entry.context->originator);
if (origin == nullptr) {
continue;
@@ -349,7 +349,7 @@ void SkillComponent::CalculateUpdate(const float deltaTime) {
const auto position = entry.startPosition + (entry.velocity * entry.time);
for (const auto& targetId : targets) {
auto* target = Game::entityManager->GetEntity(targetId);
auto* target = EntityManager::Instance()->GetEntity(targetId);
const auto targetPosition = target->GetPosition();
@@ -397,7 +397,7 @@ void SkillComponent::CalculateUpdate(const float deltaTime) {
void SkillComponent::SyncProjectileCalculation(const ProjectileSyncEntry& entry) const {
auto* other = Game::entityManager->GetEntity(entry.branchContext.target);
auto* other = EntityManager::Instance()->GetEntity(entry.branchContext.target);
if (other == nullptr) {
if (entry.branchContext.target != LWOOBJID_EMPTY) {

View File

@@ -1,114 +1,93 @@
#include "SoundTriggerComponent.h"
#include "EntityManager.h"
#include "Game.h"
#include "dLogger.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 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){
guid.Serialize(outBitStream);
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) {
const auto musicCueName = parent->GetVar<std::string>(u"NDAudioMusicCue_Name");
if (!musicCueName.empty()) {
auto newCue = MusicCue(musicCueName);
const auto musicCueBoredomTime = parent->GetVar<float>(u"NDAudioMusicCue_BoredomTime");
if (musicCueBoredomTime) newCue.boredomTime = musicCueBoredomTime;
this->m_MusicCues.push_back(newCue);
}
const auto musicCueBoredomTime = parent->GetVar<float>(u"NDAudioMusicCue_BoredomTime");
const auto musicParameterName = parent->GetVar<std::string>(u"NDAudioMusicParameter_Name");
if (!musicParameterName.empty()) {
auto newParams = MusicParameter(musicParameterName);
const auto musicParameterValue = parent->GetVar<float>(u"NDAudioMusicParameter_Value");
if (musicParameterValue) newParams.value = musicParameterValue;
this->m_MusicParameters.push_back(newParams);
}
const auto guidString = parent->GetVar<std::string>(u"NDAudioEventGUID");
if (!guidString.empty())
this->m_2DAmbientSounds.push_back(GUIDResults(guidString));
const auto guid2String = parent->GetVar<std::string>(u"NDAudioEventGUID2");
if (!guid2String.empty())
this->m_3DAmbientSounds.push_back(GUIDResults(guid2String));
this->musicCues.push_back({
musicCueName,
1,
musicCueBoredomTime
});
const auto mixerName = parent->GetVar<std::string>(u"NDAudioMixerProgram_Name");
if (!mixerName.empty()) this->m_MixerPrograms.push_back(MixerProgram(mixerName));
}
this->mixerPrograms.push_back(mixerName);
void SoundTriggerComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) {
outBitStream->Write(this->m_Dirty || bIsInitialUpdate);
if (this->m_Dirty || bIsInitialUpdate) {
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());
for (auto& musicParam : this->m_MusicParameters) {
musicParam.Serialize(outBitStream);
}
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());
for (auto threeDAmbientSound : this->m_3DAmbientSounds) {
threeDAmbientSound.Serialize(outBitStream);
}
outBitStream->Write<uint8_t>(this->m_MixerPrograms.size());
for (auto& mixerProgram : this->m_MixerPrograms) {
mixerProgram.Serialize(outBitStream);
}
if (!bIsInitialUpdate) this->m_Dirty = false;
const auto guid2String = parent->GetVar<std::string>(u"NDAudioEventGUID2");
if (!guid2String.empty()) {
this->guids.emplace_back(guid2String);
}
}
void SoundTriggerComponent::ActivateMusicCue(const std::string& name, float bordemTime) {
const auto musicCue = std::find_if(this->m_MusicCues.begin(), this->m_MusicCues.end(), [name](const MusicCue& musicCue) {
return musicCue.name == name;
}
);
SoundTriggerComponent::~SoundTriggerComponent() = default;
if (musicCue == this->m_MusicCues.end()) {
this->m_MusicCues.push_back(MusicCue(name, bordemTime));
this->m_Dirty = true;
Game::entityManager->SerializeEntity(m_Parent);
void SoundTriggerComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) {
if (bIsInitialUpdate)
dirty = true;
outBitStream->Write(dirty);
if (dirty) {
outBitStream->Write<uint8_t>(this->musicCues.size());
for (const auto& musicCue : this->musicCues) {
outBitStream->Write<uint8_t>(musicCue.name.size());
outBitStream->Write(musicCue.name.c_str(), musicCue.name.size());
outBitStream->Write<uint32_t>(musicCue.result);
outBitStream->Write<float_t>(musicCue.boredomTime);
}
// Unknown part
outBitStream->Write<uint16_t>(0);
// GUID part
outBitStream->Write<uint8_t>(this->guids.size());
for (const auto guid : this->guids) {
outBitStream->Write<uint32_t>(guid.GetData1());
outBitStream->Write<uint16_t>(guid.GetData2());
outBitStream->Write<uint16_t>(guid.GetData3());
for (const auto& guidSubPart : guid.GetData4()) {
outBitStream->Write<uint8_t>(guidSubPart);
}
outBitStream->Write<uint32_t>(1); // Unknown
}
// Mixer program part
outBitStream->Write<uint8_t>(this->mixerPrograms.size());
for (const auto& mixerProgram : mixerPrograms) {
outBitStream->Write<uint8_t>(mixerProgram.size());
outBitStream->Write(mixerProgram.c_str(), mixerProgram.size());
outBitStream->Write<uint32_t>(1); // Unknown
}
dirty = false;
}
}
void SoundTriggerComponent::ActivateMusicCue(const std::string& name) {
if (std::find_if(this->musicCues.begin(), this->musicCues.end(), [name](const MusicCue& musicCue) {
return musicCue.name == name;
}) == this->musicCues.end()) {
this->musicCues.push_back({
name,
1,
-1.0f
});
dirty = true;
EntityManager::Instance()->SerializeEntity(m_Parent);
}
}
void SoundTriggerComponent::DeactivateMusicCue(const std::string& name) {
const auto musicCue = std::find_if(this->m_MusicCues.begin(), this->m_MusicCues.end(), [name](const MusicCue& musicCue) {
const auto musicCue = std::find_if(this->musicCues.begin(), this->musicCues.end(), [name](const MusicCue& musicCue) {
return musicCue.name == name;
}
);
});
if (musicCue != this->m_MusicCues.end()) {
this->m_MusicCues.erase(musicCue);
this->m_Dirty = true;
Game::entityManager->SerializeEntity(m_Parent);
if (musicCue != this->musicCues.end()) {
this->musicCues.erase(musicCue);
dirty = true;
EntityManager::Instance()->SerializeEntity(m_Parent);
}
}

View File

@@ -5,73 +5,55 @@
#include "Component.h"
#include "eReplicaComponentType.h"
/**
* Music that should be played by the client
*/
struct MusicCue {
std::string name;
uint32_t result;
float boredomTime;
MusicCue(std::string name, float boredomTime = -1.0, uint32_t result = 1){
this->name = name;
this->result = result;
this->boredomTime = boredomTime;
};
void Serialize(RakNet::BitStream* outBitStream);
};
struct MusicParameter {
std::string name;
float value;
MusicParameter(std::string name, float value = 0.0){
this->name = name;
this->value = value;
}
void Serialize(RakNet::BitStream* outBitStream);
};
struct GUIDResults{
GUID guid;
uint32_t result;
GUIDResults(std::string guidString, uint32_t result = 1){
this->guid = GUID(guidString);
this->result = result;
}
void Serialize(RakNet::BitStream* outBitStream);
};
struct MixerProgram{
std::string name;
uint32_t result;
MixerProgram(std::string name, uint32_t result = 0){
this->name = name;
this->result = result;
}
void Serialize(RakNet::BitStream* outBitStream);
};
/**
* Handles specific music triggers like the instruments in Red Block
* Credits to https://github.com/SimonNitzsche/OpCrux-Server/blob/master/src/Entity/Components/SoundTriggerComponent.hpp
*/
class SoundTriggerComponent : public Component {
public:
static const eReplicaComponentType ComponentType = eReplicaComponentType::SOUND_TRIGGER;
explicit SoundTriggerComponent(Entity* parent);
~SoundTriggerComponent() override;
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags);
void ActivateMusicCue(const std::string& name, float bordemTime = -1.0);
/**
* Activates a music cue, making it played by any client in range
* @param name the name of the music to play
*/
void ActivateMusicCue(const std::string& name);
/**
* Deactivates a music cue (if active)
* @param name name of the music to deactivate
*/
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 = {};
/**
* Currently active cues
*/
std::vector<MusicCue> musicCues = {};
bool m_Dirty = false;
/**
* Currently active mixer programs
*/
std::vector<std::string> mixerPrograms = {};
/**
* GUID found in the LDF
*/
std::vector<GUID> guids = {};
bool dirty = false;
};

View File

@@ -49,7 +49,7 @@ void SwitchComponent::EntityEnter(Entity* entity) {
const auto grpName = m_Parent->GetVarAsString(u"grp_name");
if (!grpName.empty()) {
const auto entities = Game::entityManager->GetEntitiesInGroup(grpName);
const auto entities = EntityManager::Instance()->GetEntitiesInGroup(grpName);
for (auto* entity : entities) {
entity->OnFireEventServerSide(entity, "OnActivated");
@@ -63,7 +63,7 @@ void SwitchComponent::EntityEnter(Entity* entity) {
RenderComponent::PlayAnimation(m_Parent, u"engaged");
m_PetBouncer->SetPetBouncerEnabled(true);
} else {
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
}
@@ -85,7 +85,7 @@ void SwitchComponent::Update(float deltaTime) {
const auto grpName = m_Parent->GetVarAsString(u"grp_name");
if (!grpName.empty()) {
const auto entities = Game::entityManager->GetEntitiesInGroup(grpName);
const auto entities = EntityManager::Instance()->GetEntitiesInGroup(grpName);
for (auto* entity : entities) {
entity->OnFireEventServerSide(entity, "OnDectivated");
@@ -95,7 +95,7 @@ void SwitchComponent::Update(float deltaTime) {
if (m_PetBouncer != nullptr) {
m_PetBouncer->SetPetBouncerEnabled(false);
} else {
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
}
}

View File

@@ -26,7 +26,7 @@ TriggerComponent::TriggerComponent(Entity* parent, const std::string triggerInfo
uint32_t triggerID;
GeneralUtils::TryParse<uint32_t>(tokens.at(1), triggerID);
m_Trigger = Game::zoneManager->GetZone()->GetTrigger(sceneID, triggerID);
m_Trigger = dZoneManager::Instance()->GetZone()->GetTrigger(sceneID, triggerID);
if (!m_Trigger) m_Trigger = new LUTriggers::Trigger();
}
@@ -170,10 +170,10 @@ std::vector<Entity*> TriggerComponent::GatherTargets(LUTriggers::Command* comman
else if (command->target == "targetTeam" && optionalTarget) {
auto* team = TeamManager::Instance()->GetTeam(optionalTarget->GetObjectID());
for (const auto memberId : team->members) {
auto* member = Game::entityManager->GetEntity(memberId);
auto* member = EntityManager::Instance()->GetEntity(memberId);
if (member) entities.push_back(member);
}
} else if (command->target == "objGroup") entities = Game::entityManager->GetEntitiesInGroup(command->targetName);
} else if (command->target == "objGroup") entities = EntityManager::Instance()->GetEntitiesInGroup(command->targetName);
else if (command->target == "allPlayers") {
for (auto* player : Player::GetAllPlayers()) {
entities.push_back(player);
@@ -249,7 +249,7 @@ void TriggerComponent::HandlePushObject(Entity* targetEntity, std::vector<std::s
GeneralUtils::TryParse(argArray.at(0), argArray.at(1), argArray.at(2), direction);
phantomPhysicsComponent->SetDirection(direction);
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
@@ -274,7 +274,7 @@ void TriggerComponent::HandleRepelObject(Entity* targetEntity, std::string args)
NiPoint3 direction = delta / length;
phantomPhysicsComponent->SetDirection(direction);
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
}
void TriggerComponent::HandleSetTimer(Entity* targetEntity, std::vector<std::string> argArray){
@@ -395,7 +395,7 @@ void TriggerComponent::HandleSetPhysicsVolumeEffect(Entity* targetEntity, std::v
phantomPhysicsComponent->SetMax(max);
}
Game::entityManager->SerializeEntity(targetEntity);
EntityManager::Instance()->SerializeEntity(targetEntity);
}
void TriggerComponent::HandleSetPhysicsVolumeStatus(Entity* targetEntity, std::string args) {
@@ -405,29 +405,29 @@ void TriggerComponent::HandleSetPhysicsVolumeStatus(Entity* targetEntity, std::s
return;
}
phantomPhysicsComponent->SetPhysicsEffectActive(args == "On");
Game::entityManager->SerializeEntity(targetEntity);
EntityManager::Instance()->SerializeEntity(targetEntity);
}
void TriggerComponent::HandleActivateSpawnerNetwork(std::string args){
for (auto* spawner : Game::zoneManager->GetSpawnersByName(args)) {
for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) {
if (spawner) spawner->Activate();
}
}
void TriggerComponent::HandleDeactivateSpawnerNetwork(std::string args){
for (auto* spawner : Game::zoneManager->GetSpawnersByName(args)) {
for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) {
if (spawner) spawner->Deactivate();
}
}
void TriggerComponent::HandleResetSpawnerNetwork(std::string args){
for (auto* spawner : Game::zoneManager->GetSpawnersByName(args)) {
for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) {
if (spawner) spawner->Reset();
}
}
void TriggerComponent::HandleDestroySpawnerNetworkObjects(std::string args){
for (auto* spawner : Game::zoneManager->GetSpawnersByName(args)) {
for (auto* spawner : dZoneManager::Instance()->GetSpawnersByName(args)) {
if (spawner) spawner->DestroyAllEntities();
}
}

View File

@@ -19,47 +19,34 @@ VehiclePhysicsComponent::~VehiclePhysicsComponent() {
}
void VehiclePhysicsComponent::SetPosition(const NiPoint3& pos) {
if (pos == m_Position) return;
m_DirtyPosition = true;
m_Position = pos;
}
void VehiclePhysicsComponent::SetRotation(const NiQuaternion& rot) {
if (rot == m_Rotation) return;
m_DirtyPosition = true;
m_Rotation = rot;
}
void VehiclePhysicsComponent::SetVelocity(const NiPoint3& vel) {
if (vel == m_Velocity) return;
m_DirtyPosition = true;
m_Velocity = vel;
}
void VehiclePhysicsComponent::SetAngularVelocity(const NiPoint3& vel) {
if (vel == m_AngularVelocity) return;
m_DirtyPosition = true;
m_AngularVelocity = vel;
}
void VehiclePhysicsComponent::SetIsOnGround(bool val) {
if (val == m_IsOnGround) return;
m_DirtyPosition = true;
m_IsOnGround = val;
}
void VehiclePhysicsComponent::SetIsOnRail(bool val) {
if (val == m_IsOnRail) return;
m_DirtyPosition = true;
m_IsOnRail = val;
}
void VehiclePhysicsComponent::SetRemoteInputInfo(const RemoteInputInfo& remoteInputInfo) {
if (m_RemoteInputInfo == remoteInputInfo) return;
this->m_RemoteInputInfo = remoteInputInfo;
m_DirtyRemoteInput = true;
}
void VehiclePhysicsComponent::SetDirtyPosition(bool val) {
m_DirtyPosition = val;
}
@@ -76,15 +63,9 @@ void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI
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);
outBitStream->Write(m_Rotation.x);
outBitStream->Write(m_Rotation.y);
outBitStream->Write(m_Rotation.z);
outBitStream->Write(m_Rotation.w);
outBitStream->Write(m_Rotation);
outBitStream->Write(m_IsOnGround);
outBitStream->Write(m_IsOnRail);
@@ -92,33 +73,20 @@ void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI
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;
outBitStream->Write(m_Velocity);
}
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;
outBitStream->Write(m_AngularVelocity);
}
outBitStream->Write0(); // local_space_info. TODO: Implement this
outBitStream->Write0();
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;
}
outBitStream->Write0();
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(0.0f);
if (!bIsInitialUpdate) {
outBitStream->Write0();
@@ -127,7 +95,7 @@ void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI
if (bIsInitialUpdate) {
outBitStream->Write<uint8_t>(m_EndBehavior);
outBitStream->Write1(); // is input locked?
outBitStream->Write1();
}
outBitStream->Write0();
@@ -135,7 +103,8 @@ void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI
void VehiclePhysicsComponent::Update(float deltaTime) {
if (m_SoftUpdate > 5) {
Game::entityManager->SerializeEntity(m_Parent);
EntityManager::Instance()->SerializeEntity(m_Parent);
m_SoftUpdate = 0;
} else {
m_SoftUpdate += deltaTime;

View File

@@ -5,24 +5,6 @@
#include "Component.h"
#include "eReplicaComponentType.h"
struct RemoteInputInfo {
void operator=(const RemoteInputInfo& other) {
m_RemoteInputX = other.m_RemoteInputX;
m_RemoteInputY = other.m_RemoteInputY;
m_IsPowersliding = other.m_IsPowersliding;
m_IsModified = other.m_IsModified;
}
bool operator==(const RemoteInputInfo& other) {
return m_RemoteInputX == other.m_RemoteInputX && m_RemoteInputY == other.m_RemoteInputY && m_IsPowersliding == other.m_IsPowersliding && m_IsModified == other.m_IsModified;
}
float m_RemoteInputX;
float m_RemoteInputY;
bool m_IsPowersliding;
bool m_IsModified;
};
/**
* Physics component for vehicles.
*/
@@ -112,7 +94,6 @@ public:
void SetDirtyPosition(bool val);
void SetDirtyVelocity(bool val);
void SetDirtyAngularVelocity(bool val);
void SetRemoteInputInfo(const RemoteInputInfo&);
private:
bool m_DirtyPosition;
@@ -129,6 +110,4 @@ private:
float m_SoftUpdate = 0;
uint32_t m_EndBehavior;
RemoteInputInfo m_RemoteInputInfo;
bool m_DirtyRemoteInput;
};

View File

@@ -1,28 +1,26 @@
#include "VendorComponent.h"
#include "BitStream.h"
#include <BitStream.h>
#include "Game.h"
#include "dServer.h"
#include "dZoneManager.h"
#include "WorldConfig.h"
#include "CDComponentsRegistryTable.h"
#include "CDVendorComponentTable.h"
#include "CDLootMatrixTable.h"
#include "CDLootTableTable.h"
#include "CDItemComponentTable.h"
VendorComponent::VendorComponent(Entity* parent) : Component(parent) {
m_HasStandardCostItems = false;
m_HasMultiCostItems = false;
SetupConstants();
RefreshInventory(true);
}
VendorComponent::~VendorComponent() = default;
void VendorComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags) {
outBitStream->Write(bIsInitialUpdate || m_DirtyVendor);
if (bIsInitialUpdate || m_DirtyVendor) {
outBitStream->Write(m_HasStandardCostItems);
outBitStream->Write(m_HasMultiCostItems);
if (!bIsInitialUpdate) m_DirtyVendor = false;
}
outBitStream->Write1();
outBitStream->Write1(); // Has standard items (Required for vendors with missions.)
outBitStream->Write(HasCraftingStation()); // Has multi use items
}
void VendorComponent::OnUse(Entity* originator) {
@@ -30,74 +28,97 @@ void VendorComponent::OnUse(Entity* originator) {
GameMessages::SendVendorStatusUpdate(m_Parent, originator->GetSystemAddress());
}
void VendorComponent::RefreshInventory(bool isCreation) {
SetHasStandardCostItems(false);
SetHasMultiCostItems(false);
m_Inventory.clear();
float VendorComponent::GetBuyScalar() const {
return m_BuyScalar;
}
// Custom code for Max vanity NPC and Mr.Ree cameras
if(isCreation && m_Parent->GetLOT() == 9749 && Game::server->GetZoneID() == 1201) {
SetupMaxCustomVendor();
float VendorComponent::GetSellScalar() const {
return m_SellScalar;
}
void VendorComponent::SetBuyScalar(float value) {
m_BuyScalar = value;
}
void VendorComponent::SetSellScalar(float value) {
m_SellScalar = value;
}
std::map<LOT, int>& VendorComponent::GetInventory() {
return m_Inventory;
}
bool VendorComponent::HasCraftingStation() {
// As far as we know, only Umami has a crafting station
return m_Parent->GetLOT() == 13800;
}
void VendorComponent::RefreshInventory(bool isCreation) {
//Custom code for Max vanity NPC
if (m_Parent->GetLOT() == 9749 && Game::server->GetZoneID() == 1201) {
if (!isCreation) return;
m_Inventory.insert({ 11909, 0 }); //Top hat w frog
m_Inventory.insert({ 7785, 0 }); //Flash bulb
m_Inventory.insert({ 12764, 0 }); //Big fountain soda
m_Inventory.insert({ 12241, 0 }); //Hot cocoa (from fb)
return;
}
m_Inventory.clear();
auto* lootMatrixTable = CDClientManager::Instance().GetTable<CDLootMatrixTable>();
const auto lootMatrices = lootMatrixTable->Query([=](CDLootMatrix entry) { return (entry.LootMatrixIndex == m_LootMatrixID); });
std::vector<CDLootMatrix> lootMatrices = lootMatrixTable->Query([=](CDLootMatrix entry) { return (entry.LootMatrixIndex == m_LootMatrixID); });
if (lootMatrices.empty()) return;
// Done with lootMatrix table
auto* lootTableTable = CDClientManager::Instance().GetTable<CDLootTableTable>();
auto* itemComponentTable = CDClientManager::Instance().GetTable<CDItemComponentTable>();
auto* compRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
for (const auto& lootMatrix : lootMatrices) {
int lootTableID = lootMatrix.LootTableIndex;
auto vendorItems = lootTableTable->Query([=](CDLootTable entry) { return (entry.LootTableIndex == lootTableID); });
std::vector<CDLootTable> vendorItems = lootTableTable->Query([=](CDLootTable entry) { return (entry.LootTableIndex == lootTableID); });
if (lootMatrix.maxToDrop == 0 || lootMatrix.minToDrop == 0) {
for (const auto& item : vendorItems) {
if (!m_HasStandardCostItems || !m_HasMultiCostItems) {
auto itemComponentID = compRegistryTable->GetByIDAndType(item.itemid, eReplicaComponentType::ITEM, -1);
if (itemComponentID == -1) {
Game::logger->Log("VendorComponent", "Attempted to add item %i with ItemComponent ID -1 to vendor %i inventory. Not adding item!", itemComponentID, m_Parent->GetLOT());
continue;
}
auto itemComponent = itemComponentTable->GetItemComponentByID(itemComponentID);
if (!m_HasStandardCostItems && itemComponent.baseValue != -1) SetHasStandardCostItems(true);
if (!m_HasMultiCostItems && !itemComponent.currencyCosts.empty()) SetHasMultiCostItems(true);
}
m_Inventory.push_back(SoldItem(item.itemid, item.sortPriority));
for (CDLootTable item : vendorItems) {
m_Inventory.insert({ item.itemid, item.sortPriority });
}
} else {
auto randomCount = GeneralUtils::GenerateRandomNumber<int32_t>(lootMatrix.minToDrop, lootMatrix.maxToDrop);
for (size_t i = 0; i < randomCount; i++) {
if (vendorItems.empty()) break;
auto randomItemIndex = GeneralUtils::GenerateRandomNumber<int32_t>(0, vendorItems.size() - 1);
const auto& randomItem = vendorItems.at(randomItemIndex);
const auto& randomItem = vendorItems[randomItemIndex];
vendorItems.erase(vendorItems.begin() + randomItemIndex);
if (!m_HasStandardCostItems || !m_HasMultiCostItems) {
auto itemComponentID = compRegistryTable->GetByIDAndType(randomItem.itemid, eReplicaComponentType::ITEM, -1);
if (itemComponentID == -1) {
Game::logger->Log("VendorComponent", "Attempted to add item %i with ItemComponent ID -1 to vendor %i inventory. Not adding item!", itemComponentID, m_Parent->GetLOT());
continue;
}
auto itemComponent = itemComponentTable->GetItemComponentByID(itemComponentID);
if (!m_HasStandardCostItems && itemComponent.baseValue != -1) SetHasStandardCostItems(true);
if (!m_HasMultiCostItems && !itemComponent.currencyCosts.empty()) SetHasMultiCostItems(true);
}
m_Inventory.push_back(SoldItem(randomItem.itemid, randomItem.sortPriority));
m_Inventory.insert({ randomItem.itemid, randomItem.sortPriority });
}
}
}
HandleMrReeCameras();
//Because I want a vendor to sell these cameras
if (m_Parent->GetLOT() == 13569) {
auto randomCamera = GeneralUtils::GenerateRandomNumber<int32_t>(0, 2);
switch (randomCamera) {
case 0:
m_Inventory.insert({ 16253, 0 }); //Grungagroid
break;
case 1:
m_Inventory.insert({ 16254, 0 }); //Hipstabrick
break;
case 2:
m_Inventory.insert({ 16204, 0 }); //Megabrixel snapshot
break;
default:
break;
}
}
// Callback timer to refresh this inventory.
if (m_RefreshTimeSeconds > 0.0) {
m_Parent->AddCallbackTimer(m_RefreshTimeSeconds, [this]() {
RefreshInventory();
m_Parent->AddCallbackTimer(m_RefreshTimeSeconds, [this]() {
RefreshInventory();
});
}
Game::entityManager->SerializeEntity(m_Parent);
GameMessages::SendVendorStatusUpdate(m_Parent, UNASSIGNED_SYSTEM_ADDRESS);
}
@@ -108,47 +129,12 @@ void VendorComponent::SetupConstants() {
auto* vendorComponentTable = CDClientManager::Instance().GetTable<CDVendorComponentTable>();
std::vector<CDVendorComponent> vendorComps = vendorComponentTable->Query([=](CDVendorComponent entry) { return (entry.id == componentID); });
if (vendorComps.empty()) return;
auto vendorData = vendorComps.at(0);
if (vendorData.buyScalar == 0.0) m_BuyScalar = Game::zoneManager->GetWorldConfig()->vendorBuyMultiplier;
else m_BuyScalar = vendorData.buyScalar;
m_SellScalar = vendorData.sellScalar;
m_RefreshTimeSeconds = vendorData.refreshTimeSeconds;
m_LootMatrixID = vendorData.LootMatrixIndex;
m_BuyScalar = vendorComps[0].buyScalar;
m_SellScalar = vendorComps[0].sellScalar;
m_RefreshTimeSeconds = vendorComps[0].refreshTimeSeconds;
m_LootMatrixID = vendorComps[0].LootMatrixIndex;
}
bool VendorComponent::SellsItem(const LOT item) const {
return std::count_if(m_Inventory.begin(), m_Inventory.end(), [item](const SoldItem& lhs) {
return lhs.lot == item;
}) > 0;
}
void VendorComponent::SetupMaxCustomVendor(){
SetHasStandardCostItems(true);
m_Inventory.push_back(SoldItem(11909, 0)); // Top hat w frog
m_Inventory.push_back(SoldItem(7785, 0)); // Flash bulb
m_Inventory.push_back(SoldItem(12764, 0)); // Big fountain soda
m_Inventory.push_back(SoldItem(12241, 0)); // Hot cocoa (from fb)
}
void VendorComponent::HandleMrReeCameras(){
if (m_Parent->GetLOT() == 13569) {
SetHasStandardCostItems(true);
auto randomCamera = GeneralUtils::GenerateRandomNumber<int32_t>(0, 2);
LOT camera = 0;
DluAssert(randomCamera >= 0 && randomCamera <= 2);
switch (randomCamera) {
case 0:
camera = 16253; // Grungagroid
break;
case 1:
camera = 16254; // Hipstabrick
break;
case 2:
camera = 16204; // Megabrixel snapshot
break;
}
m_Inventory.push_back(SoldItem(camera, 0));
}
return m_Inventory.find(item) != m_Inventory.end();
}

View File

@@ -9,54 +9,91 @@
#include "RakNetTypes.h"
#include "eReplicaComponentType.h"
struct SoldItem {
SoldItem(const LOT lot, const int32_t sortPriority) {
this->lot = lot;
this->sortPriority = sortPriority;
};
LOT lot = 0;
int32_t sortPriority = 0;
};
/**
* A component for vendor NPCs. A vendor sells items to the player.
*/
class VendorComponent : public Component {
public:
inline static const eReplicaComponentType ComponentType = eReplicaComponentType::VENDOR;
static const eReplicaComponentType ComponentType = eReplicaComponentType::VENDOR;
VendorComponent(Entity* parent);
~VendorComponent() override;
void Serialize(RakNet::BitStream* outBitStream, bool bIsInitialUpdate, unsigned int& flags);
void OnUse(Entity* originator) override;
/**
* Gets the buy scaler
* @return the buy scaler
*/
float GetBuyScalar() const;
/**
* Sets the buy scalar.
* @param value the new value.
*/
void SetBuyScalar(float value);
/**
* Gets the buy scaler
* @return the buy scaler
*/
float GetSellScalar() const;
/**
* Sets the sell scalar.
* @param value the new value.
*/
void SetSellScalar(float value);
/**
* True if the NPC LOT is 13800, the only NPC with a crafting station.
*/
bool HasCraftingStation();
/**
* Gets the list if items the vendor sells.
* @return the list of items.
*/
std::map<LOT, int>& GetInventory();
/**
* Refresh the inventory of this vendor.
*/
void RefreshInventory(bool isCreation = false);
/**
* Called on startup of vendor to setup the variables for the component.
*/
void SetupConstants();
bool SellsItem(const LOT item) const;
float GetBuyScalar() const { return m_BuyScalar; }
float GetSellScalar() const { return m_SellScalar; }
void SetBuyScalar(const float value) { m_BuyScalar = value; }
void SetSellScalar(const float value) { m_SellScalar = value; }
const std::vector<SoldItem>& GetInventory() { return m_Inventory; }
void SetHasMultiCostItems(const bool hasMultiCostItems) {
if (m_HasMultiCostItems == hasMultiCostItems) return;
m_HasMultiCostItems = hasMultiCostItems;
m_DirtyVendor = true;
}
void SetHasStandardCostItems(const bool hasStandardCostItems) {
if (m_HasStandardCostItems == hasStandardCostItems) return;
m_HasStandardCostItems = hasStandardCostItems;
m_DirtyVendor = true;
}
private:
void SetupMaxCustomVendor();
void HandleMrReeCameras();
float m_BuyScalar = 0.0f;
float m_SellScalar = 0.0f;
float m_RefreshTimeSeconds = 0.0f;
uint32_t m_LootMatrixID = 0;
std::vector<SoldItem> m_Inventory;
bool m_DirtyVendor = false;
bool m_HasStandardCostItems = false;
bool m_HasMultiCostItems = false;
/**
* The buy scalar.
*/
float m_BuyScalar;
/**
* The sell scalar.
*/
float m_SellScalar;
/**
* The refresh time of this vendors' inventory.
*/
float m_RefreshTimeSeconds;
/**
* Loot matrix id of this vendor.
*/
uint32_t m_LootMatrixID;
/**
* The list of items the vendor sells.
*/
std::map<LOT, int> m_Inventory;
};
#endif // VENDORCOMPONENT_H

View File

@@ -42,17 +42,16 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
CBITSTREAM;
// Get the entity
Entity* entity = Game::entityManager->GetEntity(objectID);
Entity* entity = EntityManager::Instance()->GetEntity(objectID);
User* usr = UserManager::Instance()->GetUser(sysAddr);
if (!entity) {
Game::logger->Log("GameMessageHandler", "Failed to find associated entity (%llu), aborting GM (%X)!", objectID, messageID);
return;
}
if (messageID != eGameMessageType::READY_FOR_UPDATES) Game::logger->LogDebug("GameMessageHandler", "received game message ID: %i", messageID);
switch (messageID) {
case eGameMessageType::UN_USE_BBB_MODEL: {
@@ -74,11 +73,11 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
break;
}
case eGameMessageType::EQUIP_INVENTORY:
case eGameMessageType::EQUIP_ITEM:
GameMessages::HandleEquipItem(inStream, entity);
break;
case eGameMessageType::UN_EQUIP_INVENTORY:
case eGameMessageType::UN_EQUIP_ITEM:
GameMessages::HandleUnequipItem(inStream, entity);
break;
@@ -123,9 +122,9 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
auto* destroyable = entity->GetComponent<DestroyableComponent>();
destroyable->SetImagination(destroyable->GetImagination());
Game::entityManager->SerializeEntity(entity);
EntityManager::Instance()->SerializeEntity(entity);
std::vector<Entity*> racingControllers = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::RACING_CONTROL);
std::vector<Entity*> racingControllers = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::RACING_CONTROL);
for (Entity* racingController : racingControllers) {
auto* racingComponent = racingController->GetComponent<RacingControlComponent>();
if (racingComponent != nullptr) {
@@ -133,12 +132,12 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
}
}
Entity* zoneControl = Game::entityManager->GetZoneControlEntity();
Entity* zoneControl = EntityManager::Instance()->GetZoneControlEntity();
for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) {
script->OnPlayerLoaded(zoneControl, player);
}
std::vector<Entity*> scriptedActs = Game::entityManager->GetEntitiesByComponent(eReplicaComponentType::SCRIPT);
std::vector<Entity*> scriptedActs = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::SCRIPT);
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)) {
@@ -171,7 +170,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
// After we've done our thing, tell the client they're ready
GameMessages::SendPlayerReady(entity, sysAddr);
GameMessages::SendPlayerReady(Game::zoneManager->GetZoneControlObject(), sysAddr);
GameMessages::SendPlayerReady(dZoneManager::Instance()->GetZoneControlObject(), sysAddr);
break;
}
@@ -249,11 +248,11 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
dest->SetHealth(4);
dest->SetArmor(0);
dest->SetImagination(6);
Game::entityManager->SerializeEntity(entity);
EntityManager::Instance()->SerializeEntity(entity);
}*/
break;
}
case eGameMessageType::GET_HOT_PROPERTY_DATA: {
case eGameMessageType::HANDLE_HOT_PROPERTY_DATA: {
GameMessages::HandleGetHotPropertyData(inStream, entity, sysAddr);
break;
}
@@ -548,7 +547,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
GameMessages::HandleBBBSaveRequest(inStream, entity, sysAddr);
break;
case eGameMessageType::CONTROL_BEHAVIORS:
case eGameMessageType::CONTROL_BEHAVIOR:
GameMessages::HandleControlBehaviors(inStream, entity, sysAddr);
break;
@@ -561,7 +560,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
break;
case eGameMessageType::ZONE_PROPERTY_MODEL_ROTATED:
Game::entityManager->GetZoneControlEntity()->OnZonePropertyModelRotated(usr->GetLastUsedChar()->GetEntity());
EntityManager::Instance()->GetZoneControlEntity()->OnZonePropertyModelRotated(usr->GetLastUsedChar()->GetEntity());
break;
case eGameMessageType::UPDATE_PROPERTY_OR_MODEL_FOR_FILTER_CHECK:
@@ -597,11 +596,11 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
GameMessages::HandleRequestDie(inStream, entity, sysAddr);
break;
case eGameMessageType::NOTIFY_SERVER_VEHICLE_ADD_PASSIVE_BOOST_ACTION:
case eGameMessageType::VEHICLE_NOTIFY_SERVER_ADD_PASSIVE_BOOST_ACTION:
GameMessages::HandleVehicleNotifyServerAddPassiveBoostAction(inStream, entity, sysAddr);
break;
case eGameMessageType::NOTIFY_SERVER_VEHICLE_REMOVE_PASSIVE_BOOST_ACTION:
case eGameMessageType::VEHICLE_NOTIFY_SERVER_REMOVE_PASSIVE_BOOST_ACTION:
GameMessages::HandleVehicleNotifyServerRemovePassiveBoostAction(inStream, entity, sysAddr);
break;
@@ -669,7 +668,7 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
case eGameMessageType::DISMOUNT_COMPLETE:
GameMessages::HandleDismountComplete(inStream, entity, sysAddr);
break;
case eGameMessageType::DECTIVATE_BUBBLE_BUFF:
case eGameMessageType::DEACTIVATE_BUBBLE_BUFF:
GameMessages::HandleDeactivateBubbleBuff(inStream, entity);
break;
case eGameMessageType::ACTIVATE_BUBBLE_BUFF:
@@ -681,20 +680,8 @@ void GameMessageHandler::HandleMessage(RakNet::BitStream* inStream, const System
case eGameMessageType::REQUEST_ACTIVITY_EXIT:
GameMessages::HandleRequestActivityExit(inStream, entity);
break;
case eGameMessageType::ADD_DONATION_ITEM:
GameMessages::HandleAddDonationItem(inStream, entity, sysAddr);
break;
case eGameMessageType::REMOVE_DONATION_ITEM:
GameMessages::HandleRemoveDonationItem(inStream, entity, sysAddr);
break;
case eGameMessageType::CONFIRM_DONATION_ON_PLAYER:
GameMessages::HandleConfirmDonationOnPlayer(inStream, entity);
break;
case eGameMessageType::CANCEL_DONATION_ON_PLAYER:
GameMessages::HandleCancelDonationOnPlayer(inStream, entity);
break;
default:
Game::logger->LogDebug("GameMessageHandler", "Unknown game message ID: %i", messageID);
// Game::logger->Log("GameMessageHandler", "Unknown game message ID: %i", messageID);
break;
}
}

Some files were not shown because too many files have changed in this diff Show More