DarkflameServer/dGame/Player.cpp
Aaron Kimbrell e97ae92624
Make logger automatically put a newline (#675)
at the end of the line
remove all the newlines in log calls
2022-07-24 21:26:51 -05:00

351 lines
7.6 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 "CppScripts.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;
}
SystemAddress Player::GetSystemAddress() const
{
return m_SystemAddress;
}
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(COMPONENT_TYPE_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(COMPONENT_TYPE_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);
}