mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-11-10 02:08:20 +00:00
Merge pull request #590 Fix instances not stopping on all players leaving
Address order of deletion of entities on server to allow scripted activities to properly remove players
This commit is contained in:
commit
f4b89a8925
@ -99,22 +99,6 @@ Entity::~Entity() {
|
|||||||
m_Character->SaveXMLToDatabase();
|
m_Character->SaveXMLToDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CancelAllTimers();
|
CancelAllTimers();
|
||||||
CancelCallbackTimers();
|
CancelCallbackTimers();
|
||||||
|
|
||||||
|
@ -217,37 +217,42 @@ void EntityManager::UpdateEntities(const float deltaTime) {
|
|||||||
|
|
||||||
m_EntitiesToKill.clear();
|
m_EntitiesToKill.clear();
|
||||||
|
|
||||||
for (const auto& entry : m_EntitiesToDelete)
|
for (const auto entry : m_EntitiesToDelete)
|
||||||
{
|
{
|
||||||
auto* entity = GetEntity(entry);
|
// Get all this info first before we delete the player.
|
||||||
|
auto entityToDelete = GetEntity(entry);
|
||||||
|
|
||||||
m_Entities.erase(entry);
|
auto networkIdToErase = entityToDelete->GetNetworkId();
|
||||||
|
|
||||||
const auto& iter = std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entity);
|
const auto& ghostingToDelete = std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entityToDelete);
|
||||||
|
|
||||||
if (iter != m_EntitiesToGhost.end())
|
if (entityToDelete)
|
||||||
{
|
{
|
||||||
m_EntitiesToGhost.erase(iter);
|
// If we are a player run through the player destructor.
|
||||||
}
|
if (entityToDelete->IsPlayer())
|
||||||
|
|
||||||
if (entity != nullptr)
|
|
||||||
{
|
|
||||||
if (entity->GetNetworkId() != 0)
|
|
||||||
{
|
{
|
||||||
m_LostNetworkIds.push(entity->GetNetworkId());
|
delete dynamic_cast<Player*>(entityToDelete);
|
||||||
}
|
|
||||||
|
|
||||||
if (entity->IsPlayer())
|
|
||||||
{
|
|
||||||
delete dynamic_cast<Player*>(entity);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
delete entity;
|
delete entityToDelete;
|
||||||
}
|
}
|
||||||
|
|
||||||
entity = nullptr;
|
entityToDelete = nullptr;
|
||||||
|
|
||||||
|
if (networkIdToErase != 0)
|
||||||
|
{
|
||||||
|
m_LostNetworkIds.push(networkIdToErase);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ghostingToDelete != m_EntitiesToGhost.end())
|
||||||
|
{
|
||||||
|
m_EntitiesToGhost.erase(ghostingToDelete);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Entities.erase(entry);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_EntitiesToDelete.clear();
|
m_EntitiesToDelete.clear();
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "dZoneManager.h"
|
#include "dZoneManager.h"
|
||||||
#include "CharacterComponent.h"
|
#include "CharacterComponent.h"
|
||||||
#include "Mail.h"
|
#include "Mail.h"
|
||||||
|
#include "CppScripts.h"
|
||||||
|
|
||||||
std::vector<Player*> Player::m_Players = {};
|
std::vector<Player*> Player::m_Players = {};
|
||||||
|
|
||||||
@ -329,5 +330,21 @@ Player::~Player()
|
|||||||
return;
|
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);
|
m_Players.erase(iter);
|
||||||
}
|
}
|
||||||
|
@ -91,9 +91,27 @@ void NjMonastryBossInstance::OnPlayerLoaded(Entity *self, Entity *player) {
|
|||||||
|
|
||||||
void NjMonastryBossInstance::OnPlayerExit(Entity *self, Entity *player) {
|
void NjMonastryBossInstance::OnPlayerExit(Entity *self, Entity *player) {
|
||||||
UpdatePlayer(self, player->GetObjectID(), true);
|
UpdatePlayer(self, player->GetObjectID(), true);
|
||||||
//TODO: Add functionality to dynamically turn off the large team variable when enough players leave.
|
// Fetch the total players loaded from the vars
|
||||||
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"PlayerLeft", 0, 0,
|
auto totalPlayersLoaded = self->GetVar<std::vector<LWOOBJID> >(TotalPlayersLoadedVariable);
|
||||||
player->GetObjectID(), "", UNASSIGNED_SYSTEM_ADDRESS);
|
|
||||||
|
// Find the player to remove
|
||||||
|
auto playerToRemove = std::find(totalPlayersLoaded.begin(), totalPlayersLoaded.end(), player->GetObjectID());
|
||||||
|
|
||||||
|
// If we found the player remove them from out list of players
|
||||||
|
if (playerToRemove != totalPlayersLoaded.end()) {
|
||||||
|
totalPlayersLoaded.erase(playerToRemove);
|
||||||
|
} else {
|
||||||
|
Game::logger->Log("NjMonastryBossInstance", "Failed to remove player at exit.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the players loaded var back
|
||||||
|
self->SetVar<std::vector<LWOOBJID>>(TotalPlayersLoadedVariable, totalPlayersLoaded);
|
||||||
|
|
||||||
|
// Since this is an exit method, check if enough players have left. If enough have left
|
||||||
|
// resize the instance to account for such.
|
||||||
|
if (totalPlayersLoaded.size() <= 2) self->SetVar<bool>(LargeTeamVariable, false);
|
||||||
|
|
||||||
|
GameMessages::SendNotifyClientObject(self->GetObjectID(), u"PlayerLeft", 0, 0, player->GetObjectID(), "", UNASSIGNED_SYSTEM_ADDRESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NjMonastryBossInstance::OnActivityTimerDone(Entity *self, const std::string &name) {
|
void NjMonastryBossInstance::OnActivityTimerDone(Entity *self, const std::string &name) {
|
||||||
|
@ -144,8 +144,9 @@ void SGCannon::OnMessageBoxResponse(Entity *self, Entity *sender, int32_t button
|
|||||||
if (player != nullptr) {
|
if (player != nullptr) {
|
||||||
if (button == 1 && identifier == u"Shooting_Gallery_Stop")
|
if (button == 1 && identifier == u"Shooting_Gallery_Stop")
|
||||||
{
|
{
|
||||||
static_cast<Player*>(player)->SendToZone(1300);
|
UpdatePlayer(self, player->GetObjectID(), true);
|
||||||
|
RemovePlayer(player->GetObjectID());
|
||||||
|
StopGame(self, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user