mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-11-23 05:57:20 +00:00
ec00f5fd9d
Use const everywhere that makes sense return const variables when it makes sense const functions and variables again, where it makes sense No raw access and modifications to protected members Move template definitions to tcc file idk how I feel about this one
301 lines
7.5 KiB
C++
301 lines
7.5 KiB
C++
#include "Player.h"
|
|
|
|
#include <ctime>
|
|
|
|
#include "Character.h"
|
|
#include "Database.h"
|
|
#include "MissionComponent.h"
|
|
#include "UserManager.h"
|
|
#include "EntityManager.h"
|
|
#include "dLogger.h"
|
|
#include "ZoneInstanceManager.h"
|
|
#include "WorldPackets.h"
|
|
#include "dZoneManager.h"
|
|
#include "CharacterComponent.h"
|
|
#include "Mail.h"
|
|
#include "User.h"
|
|
#include "CppScripts.h"
|
|
#include "Loot.h"
|
|
#include "eReplicaComponentType.h"
|
|
|
|
std::vector<Player*> Player::m_Players = {};
|
|
|
|
Player::Player(const LWOOBJID& objectID, const EntityInfo info, User* user, Entity* parentEntity) : Entity(objectID, info, parentEntity) {
|
|
m_ParentUser = user;
|
|
m_Character = m_ParentUser->GetLastUsedChar();
|
|
m_ParentUser->SetLoggedInChar(objectID);
|
|
m_GMLevel = m_Character->GetGMLevel();
|
|
m_SystemAddress = m_ParentUser->GetSystemAddress();
|
|
m_DroppedLoot = {};
|
|
m_DroppedCoins = 0;
|
|
|
|
m_GhostReferencePoint = NiPoint3::ZERO;
|
|
m_GhostOverridePoint = NiPoint3::ZERO;
|
|
m_GhostOverride = false;
|
|
m_ObservedEntitiesLength = 256;
|
|
m_ObservedEntitiesUsed = 0;
|
|
m_ObservedEntities.resize(m_ObservedEntitiesLength);
|
|
|
|
m_Character->SetEntity(this);
|
|
|
|
const auto& iter = std::find(m_Players.begin(), m_Players.end(), this);
|
|
|
|
if (iter != m_Players.end()) {
|
|
return;
|
|
}
|
|
|
|
m_Players.push_back(this);
|
|
}
|
|
|
|
User* Player::GetParentUser() const {
|
|
return m_ParentUser;
|
|
}
|
|
|
|
void Player::SetSystemAddress(const SystemAddress& value) {
|
|
m_SystemAddress = value;
|
|
}
|
|
|
|
void Player::SetRespawnPos(const NiPoint3& position) {
|
|
m_respawnPos = position;
|
|
|
|
m_Character->SetRespawnPoint(dZoneManager::Instance()->GetZone()->GetWorldID(), position);
|
|
}
|
|
|
|
void Player::SetRespawnRot(const NiQuaternion& rotation) {
|
|
m_respawnRot = rotation;
|
|
}
|
|
|
|
NiPoint3 Player::GetRespawnPosition() const {
|
|
return m_respawnPos;
|
|
}
|
|
|
|
NiQuaternion Player::GetRespawnRotation() const {
|
|
return m_respawnRot;
|
|
}
|
|
|
|
void Player::SendMail(const LWOOBJID sender, const std::string& senderName, const std::string& subject, const std::string& body, LOT attachment, uint16_t attachmentCount) const {
|
|
Mail::SendMail(sender, senderName, this, subject, body, attachment, attachmentCount);
|
|
}
|
|
|
|
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 = EntityManager::Instance()->GetEntity(objid);
|
|
|
|
if (entity == nullptr) {
|
|
return;
|
|
}
|
|
|
|
const auto sysAddr = entity->GetSystemAddress();
|
|
|
|
auto* character = entity->GetCharacter();
|
|
auto characterComponent = entity->GetComponent<CharacterComponent>();
|
|
|
|
if (character != nullptr && characterComponent != nullptr) {
|
|
character->SetZoneID(zoneID);
|
|
character->SetZoneInstance(zoneInstance);
|
|
character->SetZoneClone(zoneClone);
|
|
|
|
characterComponent->SetLastRocketConfig(u"");
|
|
|
|
character->SaveXMLToDatabase();
|
|
}
|
|
|
|
WorldPackets::SendTransferToWorld(sysAddr, serverIP, serverPort, mythranShift);
|
|
|
|
EntityManager::Instance()->DestructEntity(entity);
|
|
return;
|
|
});
|
|
}
|
|
|
|
void Player::AddLimboConstruction(LWOOBJID objectId) {
|
|
const auto& iter = std::find(m_LimboConstructions.begin(), m_LimboConstructions.end(), objectId);
|
|
|
|
if (iter != m_LimboConstructions.end()) {
|
|
return;
|
|
}
|
|
|
|
m_LimboConstructions.push_back(objectId);
|
|
}
|
|
|
|
void Player::RemoveLimboConstruction(LWOOBJID objectId) {
|
|
const auto& iter = std::find(m_LimboConstructions.begin(), m_LimboConstructions.end(), objectId);
|
|
|
|
if (iter == m_LimboConstructions.end()) {
|
|
return;
|
|
}
|
|
|
|
m_LimboConstructions.erase(iter);
|
|
}
|
|
|
|
void Player::ConstructLimboEntities() {
|
|
for (const auto objectId : m_LimboConstructions) {
|
|
auto* entity = EntityManager::Instance()->GetEntity(objectId);
|
|
|
|
if (entity == nullptr) {
|
|
continue;
|
|
}
|
|
|
|
EntityManager::Instance()->ConstructEntity(entity, m_SystemAddress);
|
|
}
|
|
|
|
m_LimboConstructions.clear();
|
|
}
|
|
|
|
std::map<LWOOBJID, Loot::Info>& Player::GetDroppedLoot() {
|
|
return m_DroppedLoot;
|
|
}
|
|
|
|
const NiPoint3& Player::GetGhostReferencePoint() const {
|
|
return m_GhostOverride ? m_GhostOverridePoint : m_GhostReferencePoint;
|
|
}
|
|
|
|
const NiPoint3& Player::GetOriginGhostReferencePoint() const {
|
|
return m_GhostReferencePoint;
|
|
}
|
|
|
|
void Player::SetGhostReferencePoint(const NiPoint3& value) {
|
|
m_GhostReferencePoint = value;
|
|
}
|
|
|
|
void Player::SetGhostOverridePoint(const NiPoint3& value) {
|
|
m_GhostOverridePoint = value;
|
|
}
|
|
|
|
const NiPoint3& Player::GetGhostOverridePoint() const {
|
|
return m_GhostOverridePoint;
|
|
}
|
|
|
|
void Player::SetGhostOverride(bool value) {
|
|
m_GhostOverride = value;
|
|
}
|
|
|
|
bool Player::GetGhostOverride() const {
|
|
return m_GhostOverride;
|
|
}
|
|
|
|
void Player::ObserveEntity(int32_t id) {
|
|
for (int32_t i = 0; i < m_ObservedEntitiesUsed; i++) {
|
|
if (m_ObservedEntities[i] == 0 || m_ObservedEntities[i] == id) {
|
|
m_ObservedEntities[i] = id;
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
const auto index = m_ObservedEntitiesUsed++;
|
|
|
|
if (m_ObservedEntitiesUsed > m_ObservedEntitiesLength) {
|
|
m_ObservedEntities.resize(m_ObservedEntitiesLength + m_ObservedEntitiesLength);
|
|
|
|
m_ObservedEntitiesLength = m_ObservedEntitiesLength + m_ObservedEntitiesLength;
|
|
}
|
|
|
|
m_ObservedEntities[index] = id;
|
|
}
|
|
|
|
bool Player::IsObserved(int32_t id) {
|
|
for (int32_t i = 0; i < m_ObservedEntitiesUsed; i++) {
|
|
if (m_ObservedEntities[i] == id) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void Player::GhostEntity(int32_t id) {
|
|
for (int32_t i = 0; i < m_ObservedEntitiesUsed; i++) {
|
|
if (m_ObservedEntities[i] == id) {
|
|
m_ObservedEntities[i] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
Player* Player::GetPlayer(const SystemAddress& sysAddr) {
|
|
auto* entity = UserManager::Instance()->GetUser(sysAddr)->GetLastUsedChar()->GetEntity();
|
|
|
|
return static_cast<Player*>(entity);
|
|
}
|
|
|
|
Player* Player::GetPlayer(const std::string& name) {
|
|
const auto characters = EntityManager::Instance()->GetEntitiesByComponent(eReplicaComponentType::CHARACTER);
|
|
|
|
for (auto* character : characters) {
|
|
if (!character->IsPlayer()) continue;
|
|
|
|
if (character->GetCharacter()->GetName() == name) {
|
|
return static_cast<Player*>(character);
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
Player* Player::GetPlayer(LWOOBJID playerID) {
|
|
for (auto* player : m_Players) {
|
|
if (player->GetObjectID() == playerID) {
|
|
return player;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
const std::vector<Player*>& Player::GetAllPlayers() {
|
|
return m_Players;
|
|
}
|
|
|
|
uint64_t Player::GetDroppedCoins() {
|
|
return m_DroppedCoins;
|
|
}
|
|
|
|
void Player::SetDroppedCoins(uint64_t value) {
|
|
m_DroppedCoins = value;
|
|
}
|
|
|
|
Player::~Player() {
|
|
Game::logger->Log("Player", "Deleted player");
|
|
|
|
for (int32_t i = 0; i < m_ObservedEntitiesUsed; i++) {
|
|
const auto id = m_ObservedEntities[i];
|
|
|
|
if (id == 0) {
|
|
continue;
|
|
}
|
|
|
|
auto* entity = EntityManager::Instance()->GetGhostCandidate(id);
|
|
|
|
if (entity != nullptr) {
|
|
entity->SetObservers(entity->GetObservers() - 1);
|
|
}
|
|
}
|
|
|
|
m_LimboConstructions.clear();
|
|
|
|
const auto& iter = std::find(m_Players.begin(), m_Players.end(), this);
|
|
|
|
if (iter == m_Players.end()) {
|
|
return;
|
|
}
|
|
|
|
if (IsPlayer()) {
|
|
Entity* zoneControl = EntityManager::Instance()->GetZoneControlEntity();
|
|
for (CppScripts::Script* script : CppScripts::GetEntityScripts(zoneControl)) {
|
|
script->OnPlayerExit(zoneControl, this);
|
|
}
|
|
|
|
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)) {
|
|
script->OnPlayerExit(scriptEntity, this);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
m_Players.erase(iter);
|
|
}
|