void CZoneEntities::DecreaseZoneCounter(CCharEntity* PChar) { DSP_DEBUG_BREAK_IF(PChar == nullptr); DSP_DEBUG_BREAK_IF(PChar->loc.zone != m_zone); //remove pets if (PChar->PPet != nullptr) { charutils::BuildingCharPetAbilityTable(PChar, (CPetEntity*)PChar->PPet, 0);//blank the pet commands if (PChar->PPet->isCharmed) { petutils::DespawnPet(PChar); } else { PChar->PPet->status = STATUS_DISAPPEAR; if (((CPetEntity*)(PChar->PPet))->getPetType() == PETTYPE_AVATAR) PChar->setModifier(MOD_AVATAR_PERPETUATION, 0); } // It may have been nullptred by DespawnPet if (PChar->PPet != nullptr) { PChar->PPet->PBattleAI->SetCurrentAction(ACTION_NONE); DeletePET(PChar->PPet);//remove the TID for this pet for (EntityList_t::const_iterator it = m_charList.begin(); it != m_charList.end(); ++it) { //inform other players of the pets removal CCharEntity* PCurrentChar = (CCharEntity*)it->second; SpawnIDList_t::iterator PET = PCurrentChar->SpawnPETList.find(PChar->PPet->id); if (PET != PCurrentChar->SpawnPETList.end()) { PCurrentChar->SpawnPETList.erase(PET); PCurrentChar->pushPacket(new CEntityUpdatePacket(PChar->PPet, ENTITY_DESPAWN, UPDATE_NONE)); } } PChar->PPet = nullptr; } } //remove bcnm status if (m_zone->m_BattlefieldHandler != nullptr && PChar->StatusEffectContainer->HasStatusEffect(EFFECT_BATTLEFIELD)) { if (m_zone->m_BattlefieldHandler->disconnectFromBcnm(PChar)){ ShowDebug("Removed %s from the BCNM they were in as they have left the zone.\n", PChar->GetName()); } if (PChar->loc.destination == 0){ //this player is disconnecting/logged out, so move them to the entrance //move depending on zone int pos[4] = { 0, 0, 0, 0 }; battlefieldutils::getStartPosition(m_zone->GetID(), pos); if (pos != nullptr){ PChar->loc.p.x = pos[0]; PChar->loc.p.y = pos[1]; PChar->loc.p.z = pos[2]; PChar->loc.p.rotation = pos[3]; PChar->updatemask |= UPDATE_POS; charutils::SaveCharPosition(PChar); } else{ ShowWarning("%s has disconnected from the BCNM but cannot move them to the lobby as the lobby position is unknown!\n", PChar->GetName()); } } } else if (m_zone->m_BattlefieldHandler != nullptr && PChar->StatusEffectContainer->HasStatusEffect(EFFECT_DYNAMIS, 0)) { if (m_zone->m_BattlefieldHandler->disconnectFromDynamis(PChar)){ ShowDebug("Removed %s from the BCNM they were in as they have left the zone.\n", PChar->GetName()); } if (PChar->loc.destination == 0){ //this player is disconnecting/logged out, so move them to the entrance //move depending on zone int pos[4] = { 0, 0, 0, 0 }; battlefieldutils::getStartPosition(m_zone->GetID(), pos); if (!(pos[0] == 0 && pos[1] == 0 && pos[2] == 0 && pos[3] == 0)){ PChar->loc.p.x = pos[0]; PChar->loc.p.y = pos[1]; PChar->loc.p.z = pos[2]; PChar->loc.p.rotation = pos[3]; PChar->updatemask |= UPDATE_POS; charutils::SaveCharPosition(PChar); } else{ ShowWarning("%s has disconnected from the BCNM but cannot move them to the lobby as the lobby position is unknown!\n", PChar->GetName()); } } } for (auto PCharIt : m_charList) { CCharEntity* PCurrentChar = (CCharEntity*)PCharIt.second; if (PCurrentChar->PBattleAI->m_PMagicState->GetTarget() == PChar) { PCurrentChar->PBattleAI->m_PMagicState->ClearTarget(); } } for (auto PMobIt : m_mobList) { CMobEntity* PCurrentMob = (CMobEntity*)PMobIt.second; PCurrentMob->PEnmityContainer->Clear(PChar->id); if (PCurrentMob->m_OwnerID.id == PChar->id) { PCurrentMob->m_OwnerID.clean(); PCurrentMob->updatemask |= UPDATE_STATUS; } if (PCurrentMob->PBattleAI->m_PMagicState->GetTarget() == PChar) { PCurrentMob->PBattleAI->m_PMagicState->ClearTarget(); } if (PCurrentMob->PBattleAI->GetBattleSubTarget() == PChar) { PCurrentMob->PBattleAI->SetBattleSubTarget(nullptr); } } for (auto PPetIt : m_petList) { CPetEntity* PCurrentPet = (CPetEntity*)PPetIt.second; if (PCurrentPet->PBattleAI->m_PMagicState->GetTarget() == PChar) { PCurrentPet->PBattleAI->m_PMagicState->ClearTarget(); } if (PCurrentPet->PBattleAI->GetBattleSubTarget() == PChar) { PCurrentPet->PBattleAI->SetBattleSubTarget(nullptr); } } // TODO: могут возникать проблемы с переходом между одной и той же зоной (zone == prevzone) m_charList.erase(PChar->targid); ShowDebug(CL_CYAN"CZone:: %s DecreaseZoneCounter <%u> %s\n" CL_RESET, m_zone->GetName(), m_charList.size(), PChar->GetName()); }
void CZone::DecreaseZoneCounter(CCharEntity* PChar) { DSP_DEBUG_BREAK_IF(PChar == NULL); DSP_DEBUG_BREAK_IF(PChar->loc.zone != this); //remove pets if(PChar->PPet != NULL) { charutils::BuildingCharPetAbilityTable(PChar,(CPetEntity*)PChar->PPet,0);//blank the pet commands if(PChar->PPet->isCharmed) { petutils::DespawnPet(PChar); } else { PChar->PPet->status = STATUS_DISAPPEAR; if( ((CPetEntity*)(PChar->PPet))->getPetType() == PETTYPE_AVATAR ) PChar->setModifier(MOD_AVATAR_PERPETUATION, 0); } // It may have been nulled by DespawnPet if(PChar->PPet != NULL) { PChar->PPet->PBattleAI->SetCurrentAction(ACTION_NONE); DeletePET(PChar->PPet);//remove the TID for this pet for (EntityList_t::const_iterator it = m_charList.begin() ; it != m_charList.end() ; ++it) { //inform other players of the pets removal CCharEntity* PCurrentChar = (CCharEntity*)it->second; SpawnIDList_t::iterator PET = PCurrentChar->SpawnPETList.find(PChar->PPet->id); if( PET != PCurrentChar->SpawnPETList.end() ) { PCurrentChar->SpawnPETList.erase(PET); PCurrentChar->pushPacket(new CEntityUpdatePacket(PChar->PPet, ENTITY_DESPAWN)); } } PChar->PPet = NULL; } } //remove bcnm status if(m_InstanceHandler != NULL && PChar->StatusEffectContainer->HasStatusEffect(EFFECT_BATTLEFIELD)) { if(m_InstanceHandler->disconnectFromBcnm(PChar)){ ShowDebug("Removed %s from the BCNM they were in as they have left the zone.\n",PChar->GetName()); } if(PChar->loc.destination==0){ //this player is disconnecting/logged out, so move them to the entrance //move depending on zone int pos[4] = {0,0,0,0}; instanceutils::getStartPosition(m_zoneID,pos); if(pos!=NULL){ PChar->loc.p.x = pos[0]; PChar->loc.p.y = pos[1]; PChar->loc.p.z = pos[2]; PChar->loc.p.rotation = pos[3]; charutils::SaveCharPosition(PChar); } else{ ShowWarning("%s has disconnected from the BCNM but cannot move them to the lobby as the lobby position is unknown!\n",PChar->GetName()); } } } else if(m_InstanceHandler != NULL && PChar->StatusEffectContainer->HasStatusEffect(EFFECT_DYNAMIS, 0)) { if(m_InstanceHandler->disconnectFromDynamis(PChar)){ ShowDebug("Removed %s from the BCNM they were in as they have left the zone.\n",PChar->GetName()); } if(PChar->loc.destination==0){ //this player is disconnecting/logged out, so move them to the entrance //move depending on zone int pos[4] = {0,0,0,0}; instanceutils::getStartPosition(m_zoneID,pos); if(pos!=NULL){ PChar->loc.p.x = pos[0]; PChar->loc.p.y = pos[1]; PChar->loc.p.z = pos[2]; PChar->loc.p.rotation = pos[3]; charutils::SaveCharPosition(PChar); } else{ ShowWarning("%s has disconnected from the BCNM but cannot move them to the lobby as the lobby position is unknown!\n",PChar->GetName()); } } } for (EntityList_t::const_iterator it = m_mobList.begin() ; it != m_mobList.end() ; ++it) { CMobEntity* PCurrentMob = (CMobEntity*)it->second; PCurrentMob->PEnmityContainer->Clear(PChar->id); if(PCurrentMob->m_OwnerID.id == PChar->id){ PCurrentMob->m_OwnerID.clean(); } } // TODO: могут возникать проблемы с переходом между одной и той же зоной (zone == prevzone) m_charList.erase(PChar->targid); ShowDebug(CL_CYAN"CZone:: %s DecreaseZoneCounter <%u> %s\n" CL_RESET, GetName(), m_charList.size(),PChar->GetName()); if (ZoneTimer && m_charList.empty()) { ZoneTimer->m_type = CTaskMgr::TASK_REMOVE; ZoneTimer = NULL; HealAllMobs(); } else { for (EntityList_t::const_iterator it = m_charList.begin() ; it != m_charList.end() ; ++it) { CCharEntity* PCurrentChar = (CCharEntity*)it->second; SpawnIDList_t::iterator PC = PCurrentChar->SpawnPCList.find(PChar->id); if( PC != PCurrentChar->SpawnPCList.end() ) { PCurrentChar->SpawnPCList.erase(PC); PCurrentChar->pushPacket(new CCharPacket(PChar,ENTITY_DESPAWN)); } } } if (PChar->m_LevelRestriction != 0) { if (PChar->PParty) { if (PChar->PParty->GetSyncTarget() == PChar || PChar->PParty->GetLeader() == PChar) { PChar->PParty->SetSyncTarget(NULL, 551); } if (PChar->PParty->GetSyncTarget() != NULL) { uint8 count = 0; for (uint32 i = 0; i < PChar->PParty->members.size(); ++i) { if (PChar->PParty->members.at(i) != PChar && PChar->PParty->members.at(i)->getZone() == PChar->PParty->GetSyncTarget()->getZone()) { count++; } } if (count < 2) //3, because one is zoning out - thus at least 2 will be left { PChar->PParty->SetSyncTarget(NULL, 552); } } } PChar->StatusEffectContainer->DelStatusEffectSilent(EFFECT_LEVEL_SYNC); PChar->StatusEffectContainer->DelStatusEffectSilent(EFFECT_LEVEL_RESTRICTION); } if (PChar->PTreasurePool != NULL) // TODO: условие для устранения проблем с MobHouse, надо блин решить ее раз и навсегда { PChar->PTreasurePool->DelMember(PChar); } for (regionList_t::const_iterator region = m_regionList.begin(); region != m_regionList.end(); ++region) { if ((*region)->GetRegionID() == PChar->m_InsideRegionID) { luautils::OnRegionLeave(PChar, *region); break; } } PChar->loc.zone = NULL; PChar->loc.prevzone = m_zoneID; PChar->SpawnPCList.clear(); PChar->SpawnNPCList.clear(); PChar->SpawnMOBList.clear(); PChar->SpawnPETList.clear(); }