Zone in process for player is now delayed until player is no longer on pending spawn list, assures player_entry is called after and spells bonuses are properly assigned to the player.

This commit is contained in:
Emagi 2025-08-09 08:36:44 -04:00
parent 1c61c95f4a
commit 5d1dbf962d
3 changed files with 46 additions and 22 deletions

View File

@ -8392,7 +8392,7 @@ void WorldDatabase::LoadCharacterSpellEffects(int32 char_id, Client* client, int
}
else
{
lua_spell->AddCharIDTarget(player->GetCharacterID(), 0);
spellProcess->AddLuaSpellTarget(lua_spell, player->GetID());
}
player->MSpellEffects.releasewritelock();
continue;
@ -8421,14 +8421,14 @@ void WorldDatabase::LoadCharacterSpellEffects(int32 char_id, Client* client, int
info->spell_effects[effect_slot].total_time = total_time;
info->spell_effects[effect_slot].spell = lua_spell;
lua_spell->AddCharIDTarget(player->GetCharacterID(), 0);
lua_spell->slot_pos = slot_pos;
if(!isExistingLuaSpell)
lua_spell->caster = player; // TODO: get actual player
lua_spell->zone = player->GetZone();
spellProcess->AddLuaSpellTarget(lua_spell, player->GetID());
player->MSpellEffects.releasewritelock();
if(!isMaintained)

View File

@ -135,7 +135,7 @@ extern BrokerManager broker;
using namespace std;
Client::Client(EQStream* ieqs) : underworld_cooldown_timer(5000), pos_update(125), quest_pos_timer(2000), lua_debug_timer(30000), delayTimer(500), transmuteID(0), temp_placement_timer(10), spawn_removal_timer(250) {
Client::Client(EQStream* ieqs) : underworld_cooldown_timer(5000), zone_enter_timer(500), pos_update(125), quest_pos_timer(2000), lua_debug_timer(30000), delayTimer(500), transmuteID(0), temp_placement_timer(10), spawn_removal_timer(250) {
eqs = ieqs;
ip = eqs->GetrIP();
port = ntohs(eqs->GetrPort());
@ -735,8 +735,22 @@ void Client::SendControlGhost(int32 send_id, int8 unknown2) {
}
}
void Client::SendCharInfo() {
EQ2Packet* app;
void Client::BeginPreCharInfo() {
if (!IsReadyForSpawns()) {
if (GetPlayer()->GetMap()) {
auto loc = glm::vec3(GetPlayer()->GetX(), GetPlayer()->GetZ(), GetPlayer()->GetY());
uint32 GridID = 0;
float new_z = GetPlayer()->FindBestZ(loc, nullptr, &GridID);
GetPlayer()->SetLocation(GridID);
}
SetReadyForSpawns(true);
}
else {
LogWrite(PLAYER__ERROR, 0, "Player", "ERROR! Player %s is already past stage BeginPreCharInfo, zone enter timer running: %u..", GetPlayer()->GetName(), zone_enter_timer.Enabled());
return;
}
player->CalculateApplyWeight();
player->SetEquippedItemAppearances();
@ -765,6 +779,13 @@ void Client::SendCharInfo() {
}
GetCurrentZone()->AddSpawn(player);
zone_enter_timer.Start();
}
void Client::SendCharInfo() {
zone_enter_timer.Disable();
if (IsReloadingZone() && (zoning_x || zoning_y || zoning_z)) {
GetPlayer()->SetX(zoning_x);
GetPlayer()->SetY(zoning_y);
@ -779,7 +800,7 @@ void Client::SendCharInfo() {
if (guild)
guild->GuildMemberLogin(this, firstlogin);
app = player->GetPlayerItemList()->serialize(GetPlayer(), GetVersion());
EQ2Packet* app = player->GetPlayerItemList()->serialize(GetPlayer(), GetVersion());
if (app) {
LogWrite(CCLIENT__PACKET, 0, "Client", "Dump/Print Packet in func: %s, line: %i", __FUNCTION__, __LINE__);
//DumpPacket(app);
@ -920,6 +941,10 @@ void Client::SendCharInfo() {
GetPlayer()->SetReturningFromLD(false);
broker.LockActiveItemsForClient(this);
GetPlayer()->GetZone()->GetSpellProcess()->SendSpellBookUpdate(this);
pos_update.Start();
quest_pos_timer.Start();
}
void Client::SendZoneSpawns() {
@ -1607,20 +1632,7 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
}
case OP_DoneLoadingEntityResourcesMsg: {
LogWrite(OPCODE__DEBUG, 1, "Opcode", "Opcode 0x%X (%i): OP_DoneLoadingEntityResourcesMsg", opcode, opcode);
if (!IsReadyForSpawns()) {
if (GetPlayer()->GetMap()) {
auto loc = glm::vec3(GetPlayer()->GetX(), GetPlayer()->GetZ(), GetPlayer()->GetY());
uint32 GridID = 0;
float new_z = GetPlayer()->FindBestZ(loc, nullptr, &GridID);
GetPlayer()->SetLocation(GridID);
}
SetReadyForSpawns(true);
}
player->CalculateApplyWeight();
SendCharInfo();
GetPlayer()->GetZone()->GetSpellProcess()->SendSpellBookUpdate(this);
pos_update.Start();
quest_pos_timer.Start();
BeginPreCharInfo();
break;
}
case OP_LootItemsRequestMsg: {
@ -3867,6 +3879,16 @@ bool Client::Process(bool zone_process) {
temp_placement_timer.Disable();
}
}
if(zone_enter_timer.Check() && GetCurrentZone()) {
Spawn* spawn_ready = GetCurrentZone()->GetSpawnByID(GetPlayer()->GetID());
if(spawn_ready) {
SendCharInfo();
zone_enter_timer.Disable(); // no longer need to run this timer
}
else {
LogWrite(PLAYER__INFO, 0, "Player", "Player %s pending to zone..", GetPlayer()->GetName());
}
}
if (GetCurrentZone() && pos_update.Check())
{
ProcessStateCommands();

View File

@ -272,6 +272,7 @@ public:
void SendZoneSpawns();
void HandleVerbRequest(EQApplicationPacket* app);
void SendControlGhost(int32 send_id = 0xFFFFFFFF, int8 unknown2 = 0);
void BeginPreCharInfo();
void SendCharInfo();
void SendLoginDeniedBadVersion();
void SendCharPOVGhost();
@ -838,6 +839,7 @@ private:
enum NewLoginState { LOGIN_NONE, LOGIN_DELAYED, LOGIN_ALLOWED, LOGIN_INITIAL_LOAD, LOGIN_SEND };
NewLoginState new_client_login; // 1 = delayed state, 2 = let client in
Timer underworld_cooldown_timer;
Timer zone_enter_timer;
Timer pos_update;
Timer quest_pos_timer;
Timer lua_debug_timer;